11import os , datetime , shutil , textwrap , json
22
3- from django .http import HttpResponse , HttpResponseRedirect , HttpResponseNotFound , Http404
3+ from django .http import HttpResponse , HttpResponseRedirect , HttpResponseNotFound , HttpResponseForbidden , Http404
44from django .shortcuts import render_to_response , get_object_or_404 , redirect
55from django .core .urlresolvers import reverse as urlreverse
66from django .template import RequestContext
99from django .utils .safestring import mark_safe
1010from django .conf import settings
1111from django .contrib import messages
12+ from django .contrib .auth .decorators import login_required
1213
1314import debug # pyflakes:ignore
1415
2122 approved_revision , default_review_text , default_action_text , email_state_changed ,
2223 generate_ballot_writeup , generate_issue_ballot_mail , next_approved_revision , next_revision )
2324from ietf .group .models import ChangeStateGroupEvent , MilestoneGroupEvent
24- from ietf .group .utils import save_group_in_history , save_milestone_in_history
25+ from ietf .group .utils import save_group_in_history , save_milestone_in_history , can_manage_group_type
2526from ietf .iesg .models import TelechatDate
2627from ietf .ietfauth .utils import has_role , role_required
2728from ietf .name .models import GroupStateName
3334
3435
3536class ChangeStateForm (forms .Form ):
36- charter_state = forms .ModelChoiceField (State .objects .filter (used = True , type = "charter" , slug__in = [ "infrev" , "intrev" , "extrev" , "iesgrev" ] ), label = "Charter state" , empty_label = None , required = False )
37+ charter_state = forms .ModelChoiceField (State .objects .filter (used = True , type = "charter" ), label = "Charter state" , empty_label = None , required = False )
3738 initial_time = forms .IntegerField (initial = 0 , label = "Review time" , help_text = "(in weeks)" , required = False )
3839 message = forms .CharField (widget = forms .Textarea , help_text = "Leave blank to change state without notifying the Secretariat" , required = False , label = mark_safe ("Message to<br> Secretariat" ))
3940 comment = forms .CharField (widget = forms .Textarea , help_text = "Optional comment for the charter history" , required = False )
4041 def __init__ (self , * args , ** kwargs ):
4142 self .hide = kwargs .pop ('hide' , None )
43+ group = kwargs .pop ('group' )
4244 super (ChangeStateForm , self ).__init__ (* args , ** kwargs )
45+ state_field = self .fields ["charter_state" ]
46+ if group .type_id == "wg" :
47+ state_field .queryset = state_field .queryset .filter (slug__in = ("infrev" , "intrev" , "extrev" , "iesgrev" ))
48+ else :
49+ state_field .queryset = state_field .queryset .filter (slug__in = ("notrev" , "approved" ))
4350 # hide requested fields
4451 if self .hide :
4552 for f in self .hide :
4653 self .fields [f ].widget = forms .HiddenInput
4754
48- @role_required ( "Area Director" , "Secretariat" )
55+ @login_required
4956def change_state (request , name , option = None ):
5057 """Change state of charter, notifying parties as necessary and
5158 logging the change as a comment."""
5259 charter = get_object_or_404 (Document , type = "charter" , name = name )
5360 group = charter .group
5461
62+ if not can_manage_group_type (request .user , group .type_id ):
63+ return HttpResponseForbidden ("You don't have permission to access this view" )
64+
5565 chartering_type = get_chartering_type (charter )
5666
5767 initial_review = charter .latest_event (InitialReviewDocEvent , type = "initial_review" )
@@ -61,13 +71,17 @@ def change_state(request, name, option=None):
6171 login = request .user .person
6272
6373 if request .method == 'POST' :
64- form = ChangeStateForm (request .POST )
74+ form = ChangeStateForm (request .POST , group = group )
6575 if form .is_valid ():
6676 clean = form .cleaned_data
6777 charter_rev = charter .rev
6878
6979 if option in ("initcharter" , "recharter" ):
70- charter_state = State .objects .get (used = True , type = "charter" , slug = "infrev" )
80+ if group .type_id == "wg" :
81+ charter_state = State .objects .get (used = True , type = "charter" , slug = "infrev" )
82+ else :
83+ charter_state = clean ['charter_state' ]
84+
7185 # make sure we have the latest revision set, if we
7286 # abandoned a charter before, we could have reset the
7387 # revision to latest approved
@@ -142,6 +156,8 @@ def change_state(request, name, option=None):
142156 default_action_text (group , charter , login )
143157 elif charter_state .slug == "iesgrev" :
144158 create_ballot_if_not_open (charter , login , "approve" )
159+ elif charter_state .slug == "approved" :
160+ fix_charter_revision_after_approval (charter , login )
145161
146162 if charter_state .slug == "infrev" and clean ["initial_time" ] and clean ["initial_time" ] != 0 :
147163 e = InitialReviewDocEvent (type = "initial_review" , by = login , doc = charter )
@@ -151,10 +167,10 @@ def change_state(request, name, option=None):
151167
152168 return redirect ('doc_view' , name = charter .name )
153169 else :
154- if option == "recharter" :
170+ if option == "recharter" and group . type_id == "wg" :
155171 hide = ['initial_time' , 'charter_state' , 'message' ]
156172 init = dict ()
157- elif option == "initcharter" :
173+ elif option == "initcharter" and group . type_id == "wg" :
158174 hide = ['charter_state' ]
159175 init = dict (initial_time = 1 , message = '%s has initiated chartering of the proposed %s:\n "%s" (%s).' % (login .plain_name (), group .type .name , group .name , group .acronym ))
160176 elif option == "abandon" :
@@ -164,7 +180,7 @@ def change_state(request, name, option=None):
164180 hide = ['initial_time' ]
165181 s = charter .get_state ()
166182 init = dict (charter_state = s .pk if s else None )
167- form = ChangeStateForm (hide = hide , initial = init )
183+ form = ChangeStateForm (hide = hide , initial = init , group = group )
168184
169185 prev_charter_state = None
170186 charter_hists = DocHistory .objects .filter (doc = charter ).exclude (states__type = "charter" , states__slug = charter .get_state_slug ()).order_by ("-time" )[:1 ]
@@ -352,17 +368,16 @@ def save(self, group, rev):
352368 else :
353369 destination .write (self .cleaned_data ['content' ].encode ("utf-8" ))
354370
355- @role_required ('Area Director' ,'Secretariat' )
356- def submit (request , name = None , acronym = None , option = None ):
357- if name :
358- if not name .startswith ('charter-' ):
359- name = "charter-ietf-" + name
360- elif acronym :
361- name = "charter-ietf-" + acronym
371+ @login_required
372+ def submit (request , name = None , option = None ):
373+ if not name .startswith ('charter-' ):
374+ raise Http404
375+
362376 charter = get_object_or_404 (Document , type = "charter" , name = name )
363377 group = charter .group
364378
365- login = request .user .person
379+ if not can_manage_group_type (request .user , group .type_id ):
380+ return HttpResponseForbidden ("You don't have permission to access this view" )
366381
367382 path = os .path .join (settings .CHARTER_PATH , '%s-%s.txt' % (charter .canonical_name (), charter .rev ))
368383 not_uploaded_yet = charter .rev .endswith ("-00" ) and not os .path .exists (path )
@@ -386,7 +401,7 @@ def submit(request, name=None, acronym=None, option=None):
386401
387402 charter .rev = next_rev
388403
389- e = NewRevisionDocEvent (doc = charter , by = login , type = "new_revision" )
404+ e = NewRevisionDocEvent (doc = charter , by = request . user . person , type = "new_revision" )
390405 e .desc = "New version available: <b>%s-%s.txt</b>" % (charter .canonical_name (), charter .rev )
391406 e .rev = charter .rev
392407 e .save ()
@@ -423,7 +438,8 @@ def submit(request, name=None, acronym=None, option=None):
423438 return render_to_response ('doc/charter/submit.html' ,
424439 {'form' : form ,
425440 'next_rev' : next_rev ,
426- 'group' : group },
441+ 'group' : group ,
442+ 'name' : name },
427443 context_instance = RequestContext (request ))
428444
429445class AnnouncementTextForm (forms .Form ):
@@ -568,6 +584,26 @@ def ballot_writeupnotes(request, name):
568584 ),
569585 context_instance = RequestContext (request ))
570586
587+ def fix_charter_revision_after_approval (charter , by ):
588+ # according to spec, 00-02 becomes 01, so copy file and record new revision
589+ try :
590+ old = os .path .join (charter .get_file_path (), '%s-%s.txt' % (charter .canonical_name (), charter .rev ))
591+ new = os .path .join (charter .get_file_path (), '%s-%s.txt' % (charter .canonical_name (), next_approved_revision (charter .rev )))
592+ shutil .copy (old , new )
593+ except IOError :
594+ return HttpResponse ("There was an error copying %s to %s" %
595+ ('%s-%s.txt' % (charter .canonical_name (), charter .rev ),
596+ '%s-%s.txt' % (charter .canonical_name (), next_approved_revision (charter .rev ))))
597+
598+ e = NewRevisionDocEvent (doc = charter , by = by , type = "new_revision" )
599+ e .rev = next_approved_revision (charter .rev )
600+ e .desc = "New version available: <b>%s-%s.txt</b>" % (charter .canonical_name (), e .rev )
601+ e .save ()
602+
603+ charter .rev = e .rev
604+ charter .time = e .time
605+ charter .save ()
606+
571607@role_required ("Secretariat" )
572608def approve (request , name ):
573609 """Approve charter, changing state, fixing revision, copying file to final location."""
@@ -618,24 +654,7 @@ def approve(request, name):
618654
619655 e = add_state_change_event (charter , login , prev_charter_state , new_charter_state )
620656
621- # according to spec, 00-02 becomes 01, so copy file and record new revision
622- try :
623- old = os .path .join (charter .get_file_path (), '%s-%s.txt' % (charter .canonical_name (), charter .rev ))
624- new = os .path .join (charter .get_file_path (), '%s-%s.txt' % (charter .canonical_name (), next_approved_revision (charter .rev )))
625- shutil .copy (old , new )
626- except IOError :
627- return HttpResponse ("There was an error copying %s to %s" %
628- ('%s-%s.txt' % (charter .canonical_name (), charter .rev ),
629- '%s-%s.txt' % (charter .canonical_name (), next_approved_revision (charter .rev ))))
630-
631- e = NewRevisionDocEvent (doc = charter , by = login , type = "new_revision" )
632- e .rev = next_approved_revision (charter .rev )
633- e .desc = "New version available: <b>%s-%s.txt</b>" % (charter .canonical_name (), e .rev )
634- e .save ()
635-
636- charter .rev = e .rev
637- charter .time = e .time
638- charter .save ()
657+ fix_charter_revision_after_approval (charter , login )
639658
640659 email_secretariat (request , group , "Charter state changed to %s" % new_charter_state .name , change_description )
641660
0 commit comments