11import subprocess , os
22
3- from django .http import HttpResponse
3+ from django .http import HttpResponse , HttpResponseForbidden
44from django .shortcuts import render_to_response
55from django .template import RequestContext
66from django .template .loader import render_to_string
7+ from django .conf import settings
78from django import forms
89from django .db .models import Q
10+ from django .contrib .auth .models import User
911
10- from ietf .ietfauth .decorators import role_required
12+ from ietf .ietfauth .decorators import role_required , has_role
1113from ietf .doc .models import *
1214from ietf .sync import iana , rfceditor
1315from ietf .sync .discrepancies import find_discrepancies
@@ -22,58 +24,79 @@ def discrepancies(request):
2224 dict (sections = sections ),
2325 context_instance = RequestContext (request ))
2426
27+ def notify (request , org , notification ):
28+ """Notify that something has changed at another site to trigger a
29+ run of one of the sync scripts."""
2530
26- class UpdateIanaForm (forms .Form ):
27- protocols_page = forms .BooleanField (initial = False , required = False , help_text = "For when a reference to an RFC has been added to <a href=\" %s\" >the IANA protocols page</a>" % iana .PROTOCOLS_URL )
28- changes = forms .BooleanField (initial = False , required = False , help_text = "For new changes at <a href=\" %s\" >the changes JSON dump</a>" % iana .CHANGES_URL )
29-
30- def update_iana (request ):
31- if request .method == 'POST' :
32- form = UpdateIanaForm (request .POST )
33- if form .is_valid ():
34- failed = False
35- if form .cleaned_data ["protocols_page" ]:
36- failed = failed or subprocess .call (["python" , os .path .join (SYNC_BIN_PATH , "iana-protocols-updates" )])
37- if form .cleaned_data ["changes" ]:
38- failed = failed or subprocess .call (["python" , os .path .join (SYNC_BIN_PATH , "iana-changes-updates" )])
39-
40- if failed :
41- return HttpResponse ("FAIL" )
42- else :
43- return HttpResponse ("OK" )
44- else :
45- form = UpdateIanaForm ()
46-
47- return render_to_response ('sync/update.html' ,
48- dict (form = form ,
49- org = "IANA" ,
50- ),
51- context_instance = RequestContext (request ))
31+ known_orgs = {
32+ "iana" : "IANA" ,
33+ "rfceditor" : "RFC Editor" ,
34+ }
35+
36+ if org not in known_orgs :
37+ raise Http404
38+
39+ # handle auth, to make it easier for the other end, you can send
40+ # the username/password as POST parameters instead of having to
41+ # visit the login page
42+ user = request .user
43+
44+ username = request .POST .get ("username" ) or request .GET .get ("username" )
45+ password = request .POST .get ("password" ) or request .GET .get ("password" )
46+
47+ if username and password :
48+ if settings .SERVER_MODE == "production" and not request .is_secure ():
49+ return HttpResponseForbidden ("You must use HTTPS when sending username/password" )
50+
51+ if not user .is_authenticated ():
52+ try :
53+ user = User .objects .get (username = username )
54+ except User .DoesNotExist :
55+ return HttpResponse ("Invalid username/password" )
56+
57+ if not user .check_password (password ):
58+ return HttpResponse ("Invalid username/password" )
59+
60+ if not has_role (user , ("Secretariat" , known_orgs [org ])):
61+ return HttpResponseForbidden ("You do not have the necessary permissions to view this page" )
62+
63+ known_notifications = {
64+ "protocols" : "an added reference to an RFC at <a href=\" %s\" >the IANA protocols page</a>" % iana .PROTOCOLS_URL ,
65+ "changes" : "new changes at <a href=\" %s\" >the changes JSON dump</a>" % iana .CHANGES_URL ,
66+ "queue" : "new changes to <a href=\" %s\" >queue2.xml</a>" % rfceditor .QUEUE_URL ,
67+ "index" : "new changes to <a href=\" %s\" >rfc-index.xml</a>" % rfceditor .INDEX_URL ,
68+ }
69+
70+ if notification not in known_notifications :
71+ raise Http404
72+
73+ if request .method == "POST" :
74+ def runscript (name ):
75+ p = subprocess .Popen (["python" , os .path .join (SYNC_BIN_PATH , name )],
76+ stdout = subprocess .PIPE , stderr = subprocess .STDOUT )
77+ out , _ = p .communicate ()
78+ return (p .returncode , out )
79+
80+ if notification == "protocols" :
81+ failed , out = runscript ("iana-protocols-updates" )
82+
83+ if notification == "changes" :
84+ failed , out = runscript ("iana-changes-updates" )
85+
86+ if notification == "queue" :
87+ failed , out = runscript ("rfc-editor-queue-updates" )
88+
89+ if notification == "index" :
90+ failed , out = runscript ("rfc-editor-index-updates" )
5291
92+ if failed :
93+ return HttpResponse ("FAIL\n \n " + out , content_type = "text/plain" )
94+ else :
95+ return HttpResponse ("OK" , content_type = "text/plain" )
5396
54- class UpdateRFCEditorForm (forms .Form ):
55- queue = forms .BooleanField (initial = False , required = False , help_text = "For when <a href=\" %s\" >queue2.xml</a> has been updated" % rfceditor .QUEUE_URL )
56- index = forms .BooleanField (initial = False , required = False , help_text = "For when <a href=\" %s\" >rfc-index.xml</a> has been updated" % rfceditor .INDEX_URL )
57-
58- def update_rfc_editor (request ):
59- if request .method == 'POST' :
60- form = UpdateRFCEditorForm (request .POST )
61- if form .is_valid ():
62- failed = False
63- if form .cleaned_data ["queue" ]:
64- failed = failed or subprocess .call (["python" , os .path .join (SYNC_BIN_PATH , "rfc-editor-queue-updates" )])
65- if form .cleaned_data ["index" ]:
66- failed = failed or subprocess .call (["python" , os .path .join (SYNC_BIN_PATH , "rfc-editor-index-updates" )])
67-
68- if failed :
69- return HttpResponse ("FAIL" )
70- else :
71- return HttpResponse ("OK" )
72- else :
73- form = UpdateRFCEditorForm ()
74-
75- return render_to_response ('sync/update.html' ,
76- dict (form = form ,
77- org = "RFC Editor" ,
97+ return render_to_response ('sync/notify.html' ,
98+ dict (org = known_orgs [org ],
99+ notification = notification ,
100+ help_text = known_notifications [notification ],
78101 ),
79102 context_instance = RequestContext (request ))
0 commit comments