def can_manage_group_type(user, group_type): if group_type == "rg": return has_role(user, ('IRTF Chair', 'Secretariat')) elif group_type == "wg": return has_role(user, ('Area Director', 'Secretariat')) return has_role(user, 'Secretariat')
def _find_person_in_emails(liaison, person): '''Returns true if person corresponds with any of the email addresses associated with this liaison statement''' if not person: return False emails = ','.join(e for e in [liaison.response_contacts, liaison.cc_contacts, liaison.to_contacts,liaison.technical_contacts] if e) for email in emails.split(','): name, addr = parseaddr(email) try: validate_email(addr) except ValidationError: continue if person.email_set.filter(address=addr): return True elif addr in ('*****@*****.**', '*****@*****.**') and has_role(person.user, "IETF Chair"): return True elif addr in ('*****@*****.**', '*****@*****.**') and has_role(person.user, "IAB Chair"): return True elif addr in ('*****@*****.**', ) and has_role(person.user, "IAB Executive Director"): return True return False
def can_edit_liaison(user, liaison): '''Returns True if user has edit / approval authority. True if: - user is Secretariat - liaison is outgoing and user has approval authority - user is liaison manager of all SDOs involved ''' if not user.is_authenticated: return False if has_role(user, "Secretariat"): return True if liaison.is_outgoing() and liaison in approvable_liaison_statements( user): return True if has_role(user, "Liaison Manager"): person = get_person_for_user(user) for group in chain(liaison.from_groups.filter(type_id='sdo'), liaison.to_groups.filter(type_id='sdo')): if not person.role_set.filter(group=group, name='liaiman'): return False else: return True return False
def _find_person_in_emails(liaison, person): '''Returns true if person corresponds with any of the email addresses associated with this liaison statement''' if not person: return False emails = ','.join(e for e in [ liaison.response_contacts, liaison.cc_contacts, liaison.to_contacts, liaison.technical_contacts ] if e) for email in emails.split(','): name, addr = parseaddr(email) try: validate_email(addr) except ValidationError: continue if person.email_set.filter(address=addr): return True elif addr in ('*****@*****.**', '*****@*****.**') and has_role( person.user, "IETF Chair"): return True elif addr in ('*****@*****.**', '*****@*****.**') and has_role( person.user, "IAB Chair"): return True elif addr in ('*****@*****.**', ) and has_role( person.user, "IAB Executive Director"): return True return False
def get_from_choices(user): ''' This function returns a choices tuple containing all the Announced From choices. Including leadership chairs and other entities. ''' person = user.person if has_role(user,'Secretariat'): f = FROM_LIST elif has_role(user,'IETF Chair'): f = (FROM_LIST[2],FROM_LIST[5]) elif has_role(user,'IAB Chair'): f = (FROM_LIST[6],) elif has_role(user,'IAD'): f = (FROM_LIST[9],FROM_LIST[12],FROM_LIST[18],FROM_LIST[11],) #RSOC Chair, IAOC Chair aren't supported by has_role() elif Role.objects.filter(person=person, group__acronym='rsoc', name="chair"): f = (FROM_LIST[13],) elif Role.objects.filter(person=person, group__acronym='iaoc', name="chair"): f = (FROM_LIST[11],) elif Role.objects.filter(person=person, group__acronym='rse', name="chair"): f = (FROM_LIST[15],) elif Role.objects.filter(person=person, group__acronym='iab', name='execdir'): f = (FROM_LIST[6],FROM_LIST[16]) elif Role.objects.filter(person=person, group__acronym='mentor', name="chair"): f = (FROM_LIST[17],) elif Role.objects.filter(person=person, group__acronym='isoc', name="ceo"): f = (FROM_LIST[18],) elif Role.objects.filter(person=person, group__acronym='ietf-trust', name="chair"): f = (FROM_LIST[12],) # NomCom nomcoms = Role.objects.filter(name="chair", group__acronym__startswith="nomcom", group__state="active", group__type="nomcom", person=person) if nomcoms: year = nomcoms[0].group.acronym[-4:] alias = 'NomCom Chair %s <*****@*****.**>' % (year,year) f = (alias,) return zip(f,f)
def needs_approval(group,person): '''Returns True if the person does not have authority to send a Liaison Statement from group. For outgoing Liaison Statements only''' user = person.user if group.acronym in ('ietf','iesg') and has_role(user, 'IETF Chair'): return False if group.acronym == 'iab' and (has_role(user,'IAB Chair') or has_role(user,'IAB Executive Director')): return False if group.type_id == 'area' and group.role_set.filter(name='ad',person=person): return False if group.type_id == 'wg' and group.parent and group.parent.role_set.filter(name='ad',person=person): return False return True
def set_to_fields(self): '''Set to_groups and to_contacts options and initial value based on user accessing the form''' # set options. if the user is a Liaison Manager and nothing more, reduce set to his SDOs if has_role(self.user, "Liaison Manager") and not self.person.role_set.filter(name__in=('ad','chair'),group__state='active'): queryset = Group.objects.filter(type="sdo", state="active", role__person=self.person, role__name="liaiman").distinct().order_by('name') else: # get all outgoing entities queryset = Group.objects.filter(type="sdo", state="active").order_by('name') self.fields['to_groups'].queryset = queryset # set initial if has_role(self.user, "Liaison Manager"): self.fields['to_groups'].initial = [queryset.first()]
def __init__(self, user, doc, *args, **kwargs): super(RequestReviewForm, self).__init__(*args, **kwargs) self.doc = doc f = self.fields["team"] f.queryset = active_review_teams() f.initial = [ group.pk for group in f.queryset if can_manage_review_requests_for_team( user, group, allow_personnel_outside_team=False) ] self.fields['type'].queryset = self.fields['type'].queryset.filter( used=True, reviewteamsettings__group__in=self.fields["team"].queryset ).distinct() self.fields['type'].widget = forms.RadioSelect( choices=[t for t in self.fields['type'].choices if t[0]]) self.fields["requested_rev"].label = "Document revision" if has_role(user, "Secretariat"): self.fields["requested_by"] = SearchablePersonField() else: self.fields["requested_by"].widget = forms.HiddenInput() self.fields["requested_by"].initial = user.person.pk
def wrapper(request, *args, **kwargs): # short circuit. secretariat user has full access if has_role(request.user, "Secretariat"): return func(request, *args, **kwargs) return render(request, 'unauthorized.html', {'user_name': request.user.person})
def wrapper(request, *args, **kwargs): session = None # short circuit. secretariat user has full access if has_role(request.user,'Secretariat'): return func(request, *args, **kwargs) # get the parent group if 'acronym' in kwargs: acronym = kwargs['acronym'] group = get_object_or_404(Group,acronym=acronym) elif 'session_id' in kwargs: session = get_object_or_404(Session, id=kwargs['session_id']) group = session.group elif 'slide_id' in kwargs: slide = get_object_or_404(Document, name=kwargs['slide_id']) session = slide.session_set.all()[0] group = session.group login = request.user.person groups = [group] if group.parent: groups.append(group.parent) all_roles = Role.objects.filter(group__in=groups,name__in=('ad','chair','secr')) if login in [ r.person for r in all_roles ]: return func(request, *args, **kwargs) # if session is plenary allow ietf/iab chairs if session and get_timeslot(session).type.slug=='plenary': if login.role_set.filter(name='chair',group__acronym__in=('iesg','iab')): return func(request, *args, **kwargs) # if we get here access is denied return render_to_response('unauthorized.html',{ 'user_name':login, 'group_name':group.acronym} )
def downref_registry(request): title = "Downref registry" add_button = has_role(request.user, "Area Director") or has_role( request.user, "Secretariat") downref_doc_pairs = [] downref_relations = RelatedDocument.objects.filter( relationship_id='downref-approval') for rel in downref_relations: downref_doc_pairs.append((rel.target.document, rel.source)) return render(request, 'doc/downref.html', { "doc_pairs": downref_doc_pairs, "title": title, "add_button": add_button, })
def select_interim(request): ''' A screen to select which group you want to upload Interim material for. Works for Secretariat staff and external (ADs, chairs, etc) ''' if request.method == 'POST': redirect_url = reverse('proceedings_interim', kwargs={'acronym':request.POST['group']}) return HttpResponseRedirect(redirect_url) if has_role(request.user, "Secretariat"): # initialize working groups form choices = build_choices(Group.objects.active_wgs()) group_form = GroupSelectForm(choices=choices) # per Alexa, not supporting Interim IRTF meetings at this time # intialize IRTF form #choices = build_choices(Group.objects.filter(type='wg', state='active') #irtf_form = GroupSelectForm(choices=choices) else: # these forms aren't used for non-secretariat groups = get_my_groups(request.user) choices = build_choices(groups) group_form = GroupSelectForm(choices=choices) return render_to_response('proceedings/interim_select.html', { 'group_form': group_form}, #'irtf_form': irtf_form, RequestContext(request,{}), )
def check_access(user): ''' This function takes a Django User object and returns true if the user has access to the Announcement app. ''' person = user.person groups_with_access = ("iab", "rsoc", "ietf", "iaoc", "rse", "mentor","ietf-trust") if Role.objects.filter(person=person, group__acronym__in=groups_with_access, name="chair") or has_role(user, ["Secretariat","IAD"]): return True if Role.objects.filter(name="chair", group__acronym__startswith="nomcom", group__state="active", group__type="nomcom", person=person): return True if Role.objects.filter(person=person, group__acronym='iab', name='execdir'): return True if Role.objects.filter(person=person, group__acronym='isoc', name='ceo'): return True return False
def is_chair(user, year): if not user or not year: return False nomcom = get_nomcom_by_year(year=year) if has_role(user, "Secretariat"): return True return nomcom.group.has_role(user, "chair")
def main(request): ''' Display list of groups the user has access to. Template variables form: a select box populated with unscheduled groups meeting: the current meeting scheduled_sessions: ''' # check for locked flag is_locked = check_app_locked() if is_locked and not has_role(request.user,'Secretariat'): message = get_lock_message() return render_to_response('sreq/locked.html', { 'message': message}, RequestContext(request, {}), ) # TODO this is not currently used in the main template if request.method == 'POST': button_text = request.POST.get('submit', '') if button_text == 'Group will not meet': return redirect('sessions_no_session', acronym=request.POST['group']) else: return redirect('sessions_new', acronym=request.POST['group']) meeting = get_meeting() scheduled_groups,unscheduled_groups = groups_by_session(request.user, meeting) # warn if there are no associated groups if not scheduled_groups and not unscheduled_groups: messages.warning(request, 'The account %s is not associated with any groups. If you have multiple Datatracker accounts you may try another or report a problem to [email protected]' % request.user) # load form select with unscheduled groups choices = zip([ g.pk for g in unscheduled_groups ], [ str(g) for g in unscheduled_groups ]) form = GroupSelectForm(choices=choices) # add session status messages for use in template for group in scheduled_groups: sessions = group.session_set.filter(meeting=meeting) if sessions.count() < 3: group.status_message = sessions[0].status else: group.status_message = 'First two sessions: %s, Third session: %s' % (sessions[0].status,sessions[2].status) # add not meeting indicators for use in template for group in unscheduled_groups: if group.session_set.filter(meeting=meeting,status='notmeet'): group.not_meeting = True return render_to_response('sreq/main.html', { 'is_locked': is_locked, 'form': form, 'meeting': meeting, 'scheduled_groups': scheduled_groups, 'unscheduled_groups': unscheduled_groups}, RequestContext(request, {}), )
def needs_approval(group, person): '''Returns True if the person does not have authority to send a Liaison Statement from group. For outgoing Liaison Statements only''' user = person.user if group.acronym in ('ietf', 'iesg') and has_role(user, 'IETF Chair'): return False if group.acronym == 'iab' and (has_role(user, 'IAB Chair') or has_role( user, 'IAB Executive Director')): return False if group.type_id == 'area' and group.role_set.filter(name='ad', person=person): return False if group.type_id == 'wg' and group.parent and group.parent.role_set.filter( name='ad', person=person): return False return True
def can_access_review_stats_for_team(user, team): if not user.is_authenticated: return False return (Role.objects.filter( name__in=("secr", "reviewer"), person__user=user, group=team).exists() or has_role(user, ["Secretariat", "Area Director"]))
def show(request, id): """View of individual declaration""" ipr = get_object_or_404(IprDisclosureBase, id=id).get_child() if not has_role(request.user, 'Secretariat'): if ipr.state.slug == 'removed': return render(request, "ipr/removed.html", {'ipr': ipr}) elif ipr.state.slug != 'posted': raise Http404 return render( request, "ipr/details_view.html", { 'ipr': ipr, 'in_force_ipr_rfc': ipr_rfc_number(ipr.time, ipr.is_thirdparty), 'tabs': get_details_tabs(ipr, 'Disclosure'), 'choices_abc': [ i.desc for i in IprLicenseTypeName.objects.filter(slug__in=[ 'no-license', 'royalty-free', 'reasonable', ]) ], 'updates_iprs': ipr.relatedipr_source_set.all(), 'updated_by_iprs': ipr.relatedipr_target_set.filter(source__state="posted") })
def agenda_permission_api(request, num, owner, name): meeting = get_meeting(num) person = get_person_by_email(owner) schedule = get_schedule_by_name(meeting, person, name) save_perm = False secretariat = False cansee = False canedit = False owner_href = "" if schedule is not None: cansee, canedit, secretariat = agenda_permissions( meeting, schedule, request.user) owner_href = request.build_absolute_uri(schedule.owner.json_url()) if has_role(request.user, "Area Director") or secretariat: save_perm = True return HttpResponse(json.dumps({ 'secretariat': secretariat, 'save_perm': save_perm, 'read_only': canedit == False, 'owner_href': owner_href }), content_type="application/json")
def select(request, meeting_num): ''' Provide the secretariat only functions related to meeting materials management ''' if not has_role(request.user,'Secretariat'): return HttpResponseRedirect(reverse('ietf.meeting.views.materials_editable_groups', kwargs={'num':meeting_num})) meeting = get_object_or_404(Meeting, number=meeting_num) proceedings_url = get_proceedings_url(meeting) # get the time proceedings were generated path = os.path.join(settings.SECR_PROCEEDINGS_DIR,meeting.number,'index.html') if os.path.exists(path): last_run = datetime.datetime.fromtimestamp(os.path.getmtime(path)) else: last_run = None # count PowerPoint files waiting to be converted # TODO : This should look at SessionPresentation instead ppt = Document.objects.filter(session__meeting=meeting,type='slides',external_url__endswith='.ppt').exclude(states__slug='deleted') pptx = Document.objects.filter(session__meeting=meeting,type='slides',external_url__endswith='.pptx').exclude(states__slug='deleted') ppt_count = ppt.count() + pptx.count() return render(request, 'proceedings/select.html', { 'meeting': meeting, 'last_run': last_run, 'proceedings_url': proceedings_url, 'ppt_count': ppt_count}, )
def main(request): ''' List IETF Meetings. If the user is Secratariat list includes all meetings otherwise show only those meetings whose corrections submission date has not passed. **Templates:** * ``proceedings/main.html`` **Template Variables:** * meetings, interim_meetings, today ''' if has_role(request.user,'Secretariat'): meetings = Meeting.objects.filter(type='ietf').order_by('-number') else: # select meetings still within the cutoff period meetings = Meeting.objects.filter(type='ietf',date__gt=datetime.datetime.today() - datetime.timedelta(days=settings.SUBMISSION_CORRECTION_DAYS)).order_by('number') groups = get_my_groups(request.user) interim_meetings = Meeting.objects.filter(type='interim',session__group__in=groups).order_by('-date') # tac on group for use in templates for m in interim_meetings: m.group = m.session_set.all()[0].group # we today's date to see if we're past the submissio cutoff today = datetime.date.today() return render_to_response('proceedings/main.html',{ 'meetings': meetings, 'interim_meetings': interim_meetings, 'today': today}, RequestContext(request,{}), )
def main(request): ''' List IETF Meetings. If the user is Secratariat list includes all meetings otherwise show only those meetings whose corrections submission date has not passed. **Templates:** * ``proceedings/main.html`` **Template Variables:** * meetings, interim_meetings, today ''' if has_role(request.user,'Secretariat'): meetings = Meeting.objects.filter(type='ietf').order_by('-number') else: # select meetings still within the cutoff period today = datetime.date.today() meetings = [m for m in Meeting.objects.filter(type='ietf').order_by('-number') if m.get_submission_correction_date()>=today] groups = get_my_groups(request.user) interim_meetings = Meeting.objects.filter(type='interim',session__group__in=groups,session__status='sched').order_by('-date') # tac on group for use in templates for m in interim_meetings: m.group = m.session_set.first().group # we today's date to see if we're past the submissio cutoff today = datetime.date.today() return render(request, 'proceedings/main.html',{ 'meetings': meetings, 'interim_meetings': interim_meetings, 'today': today}, )
def new(request, acronym): ''' This view gathers details for a new session request. The user proceeds to confirm() to create the request. ''' group = get_object_or_404(Group, acronym=acronym) meeting = get_meeting() session_conflicts = session_conflicts_as_string(group, meeting) # check if app is locked is_locked = check_app_locked() if is_locked and not has_role(request.user,'Secretariat'): messages.warning(request, "The Session Request Tool is closed") return redirect('sessions') if request.method == 'POST': button_text = request.POST.get('submit', '') if button_text == 'Cancel': return redirect('sessions') form = SessionForm(request.POST) if form.is_valid(): # check if request already exists for this group if Session.objects.filter(group=group,meeting=meeting).exclude(status__in=('deleted','notmeet')): messages.warning(request, 'Sessions for working group %s have already been requested once.' % group.acronym) return redirect('sessions') # save in user session request.session['session_form'] = form.data return redirect('sessions_confirm',acronym=acronym) # the "previous" querystring causes the form to be returned # pre-populated with data from last meeeting's session request elif request.method == 'GET' and request.GET.has_key('previous'): previous_meeting = Meeting.objects.get(number=str(int(meeting.number) - 1)) previous_sessions = Session.objects.filter(meeting=previous_meeting,group=group).exclude(status__in=('notmeet','deleted')).order_by('id') if not previous_sessions: messages.warning(request, 'This group did not meet at %s' % previous_meeting) return redirect('sessions_new', acronym=acronym) initial = get_initial_session(previous_sessions) add_essential_people(group,initial) if 'resources' in initial: initial['resources'] = [x.pk for x in initial['resources']] form = SessionForm(initial=initial) else: initial={} add_essential_people(group,initial) form = SessionForm(initial=initial) return render_to_response('sreq/new.html', { 'meeting': meeting, 'form': form, 'group': group, 'session_conflicts': session_conflicts}, RequestContext(request, {}), )
def document_writeup(request, name): doc = get_object_or_404(Document, docalias__name=name) top = render_document_top(request, doc, "writeup", name) def text_from_writeup(event_type): e = doc.latest_event(WriteupDocEvent, type=event_type) if e: return e.text else: return "" sections = [] if doc.type_id == "draft": writeups = [] sections.append(("Approval Announcement", "<em>Draft</em> of message to be sent <em>after</em> approval:", writeups)) writeups.append(("Announcement", text_from_writeup("changed_ballot_approval_text"), urlreverse("doc_ballot_approvaltext", kwargs=dict(name=doc.name)))) writeups.append(("Ballot Text", text_from_writeup("changed_ballot_writeup_text"), urlreverse("doc_ballot_writeupnotes", kwargs=dict(name=doc.name)))) elif doc.type_id == "charter": sections.append(("WG Review Announcement", "", [("WG Review Announcement", text_from_writeup("changed_review_announcement"), urlreverse("ietf.doc.views_charter.announcement_text", kwargs=dict(name=doc.name, ann="review")))] )) sections.append(("WG Action Announcement", "", [("WG Action Announcement", text_from_writeup("changed_action_announcement"), urlreverse("ietf.doc.views_charter.announcement_text", kwargs=dict(name=doc.name, ann="action")))] )) if doc.latest_event(BallotDocEvent, type="created_ballot"): sections.append(("Ballot Announcement", "", [("Ballot Announcement", text_from_writeup("changed_ballot_writeup_text"), urlreverse("ietf.doc.views_charter.ballot_writeupnotes", kwargs=dict(name=doc.name)))] )) if not sections: raise Http404 return render_to_response("doc/document_writeup.html", dict(doc=doc, top=top, sections=sections, can_edit=has_role(request.user, ("Area Director", "Secretariat")), ), context_instance=RequestContext(request))
def wrapper(request, *args, **kwargs): # short circuit. secretariat user has full access if has_role(request.user, "Secretariat"): return func(request, *args, **kwargs) return render_to_response('unauthorized.html',{ 'user_name':request.user.person} )
def ballot_icon(context, doc): user = context.get("user") if not doc: return "" if not showballoticon(doc): return "" ballot = doc.active_ballot() if not ballot: return "" def sort_key(t): _, pos = t if not pos: return (2, 0) elif pos.pos.blocking: return (0, pos.pos.order) else: return (1, pos.pos.order) positions = list(doc.active_ballot().active_ad_positions().items()) positions.sort(key=sort_key) right_click_string = '' if has_role(user, "Area Director"): right_click_string = 'oncontextmenu="window.location.href=\'%s\';return false;"' % urlreverse('ietf.doc.views_ballot.edit_position', kwargs=dict(name=doc.name, ballot_id=ballot.pk)) res = ['<a %s href="%s" data-toggle="modal" data-target="#modal-%d" title="IESG positions (click to show more)" class="ballot-icon"><table>' % ( right_click_string, urlreverse("ietf.doc.views_doc.ballot_popup", kwargs=dict(name=doc.name, ballot_id=ballot.pk)), ballot.pk)] res.append("<tr>") for i, (ad, pos) in enumerate(positions): if i > 0 and i % 5 == 0: res.append("</tr><tr>") c = "position-%s" % (pos.pos.slug if pos else "norecord") if user_is_person(user, ad): c += " my" res.append('<td class="%s"></td>' % c) # add sufficient table calls to last row to avoid HTML validation warning while (i + 1) % 5 != 0: res.append('<td class="empty"></td>') i = i + 1 res.append("</tr></table></a>") # XXX FACELIFT: Loading via href will go away in bootstrap 4. # See http://getbootstrap.com/javascript/#modals-usage res.append('<div id="modal-%d" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true"><div class="modal-dialog modal-lg"><div class="modal-content"></div></div></div>' % ballot.pk) return "".join(res)
def change_state(request, name, option=None): """Change state of an IESG review for IETF conflicts in other stream's documents, notifying parties as necessary and logging the change as a comment.""" review = get_object_or_404(Document, type="conflrev", name=name) login = request.user.person if request.method == 'POST': form = ChangeStateForm(request.POST) if form.is_valid(): clean = form.cleaned_data new_state = clean['review_state'] comment = clean['comment'].rstrip() if comment: c = DocEvent(type="added_comment", doc=review, by=login) c.desc = comment c.save() prev_state = review.get_state() if new_state != prev_state: save_document_in_history(review) review.set_state(new_state) add_state_change_event(review, login, prev_state, new_state) review.time = datetime.datetime.now() review.save() if new_state.slug == "iesgeval": create_ballot_if_not_open(review, login, "conflrev") ballot = review.latest_event(BallotDocEvent, type="created_ballot") if has_role(request.user, "Area Director") and not review.latest_event(BallotPositionDocEvent, ad=login, ballot=ballot, type="changed_ballot_position"): # The AD putting a conflict review into iesgeval who doesn't already have a position is saying "yes" pos = BallotPositionDocEvent(doc=review, by=login) pos.ballot = ballot pos.type = "changed_ballot_position" pos.ad = login pos.pos_id = "yes" pos.desc = "[Ballot Position Update] New position, %s, has been recorded for %s" % (pos.pos.name, pos.ad.plain_name()) pos.save() send_conflict_eval_email(request,review) return redirect('doc_view', name=review.name) else: s = review.get_state() init = dict(review_state=s.pk if s else None) form = ChangeStateForm(initial=init) return render_to_response('doc/change_state.html', dict(form=form, doc=review, login=login, help_url=reverse('state_help', kwargs=dict(type="conflict-review")), ), context_instance=RequestContext(request))
def get_groups_for_person(person): '''Returns queryset of internal Groups the person has interesting roles in. This is a refactor of IETFHierarchyManager.get_entities_for_person(). If Person is None or Secretariat or Liaison Manager all internal IETF groups are returned. ''' if person == None or has_role(person.user, "Secretariat") or has_role(person.user, "Liaison Manager"): # collect all internal IETF groups queries = [Q(acronym__in=('ietf','iesg','iab')), Q(type='area',state='active'), Q(type='wg',state='active')] else: # Interesting roles, as Group queries queries = [Q(role__person=person,role__name='chair',acronym='ietf'), Q(role__person=person,role__name__in=('chair','execdir'),acronym='iab'), Q(role__person=person,role__name='ad',type='area',state='active'), Q(role__person=person,role__name__in=('chair','secretary'),type='wg',state='active'), Q(parent__role__person=person,parent__role__name='ad',type='wg',state='active')] return Group.objects.filter(reduce(operator.or_,queries)).order_by('acronym').distinct()
def change_state(request, name, option=None): """Change state of an IESG review for IETF conflicts in other stream's documents, notifying parties as necessary and logging the change as a comment.""" review = get_object_or_404(Document, type="conflrev", name=name) login = request.user.person if request.method == 'POST': form = ChangeStateForm(request.POST) if form.is_valid(): clean = form.cleaned_data new_state = clean['review_state'] comment = clean['comment'].rstrip() if comment: c = DocEvent(type="added_comment", doc=review, rev=review.rev, by=login) c.desc = comment c.save() prev_state = review.get_state() if new_state != prev_state: events = [] review.set_state(new_state) events.append(add_state_change_event(review, login, prev_state, new_state)) review.save_with_history(events) if new_state.slug == "iesgeval": create_ballot_if_not_open(review, login, "conflrev") ballot = review.latest_event(BallotDocEvent, type="created_ballot") if has_role(request.user, "Area Director") and not review.latest_event(BallotPositionDocEvent, ad=login, ballot=ballot, type="changed_ballot_position"): # The AD putting a conflict review into iesgeval who doesn't already have a position is saying "yes" pos = BallotPositionDocEvent(doc=review, rev=review.rev, by=login) pos.ballot = ballot pos.type = "changed_ballot_position" pos.ad = login pos.pos_id = "yes" pos.desc = "[Ballot Position Update] New position, %s, has been recorded for %s" % (pos.pos.name, pos.ad.plain_name()) pos.save() # Consider mailing that position to 'ballot_saved' send_conflict_eval_email(request,review) return redirect('ietf.doc.views_doc.document_main', name=review.name) else: s = review.get_state() init = dict(review_state=s.pk if s else None) form = ChangeStateForm(initial=init) return render(request, 'doc/change_state.html', dict(form=form, doc=review, login=login, help_url=reverse('ietf.doc.views_help.state_help', kwargs=dict(type="conflict-review")), ))
def can_view_interim_request(meeting, user): '''Returns True if the user can see the pending interim request in the pending interim view''' if meeting.type.slug != 'interim': return False if has_role(user, 'Secretariat'): return True person = get_person_for_user(user) session = meeting.session_set.first() if not session: return False group = session.group if has_role(user, 'Area Director') and group.type.slug == 'wg': return True if has_role(user, 'IRTF Chair') and group.type.slug == 'rg': return True if group.role_set.filter(name='chair', person=person): return True return False
def can_adopt_draft(user, doc): if not user.is_authenticated(): return False if has_role(user, "Secretariat"): return True #The IRTF chair can adopt a draft into any RG if has_role(user, "IRTF Chair"): return (doc.stream_id in (None, "irtf") and doc.group.type_id == "individ") return (doc.stream_id in (None, "ietf", "irtf") and doc.group.type_id == "individ" and Role.objects.filter(name__in=("chair", "delegate", "secr"), group__type__in=("wg", "rg"), group__state="active", person__user=user).exists())
def can_manage_review_requests_for_team(user, team, allow_personnel_outside_team=True): if not user.is_authenticated: return False return (Role.objects.filter(name="secr", person__user=user, group=team).exists() or (allow_personnel_outside_team and has_role(user, "Secretariat")))
def ballot_icon(context, doc): user = context.get("user") if not doc: return "" if not showballoticon(doc): return "" ballot = doc.active_ballot() if not ballot: return "" def sort_key(t): _, pos = t if not pos: return (2, 0) elif pos.pos.blocking: return (0, pos.pos.order) else: return (1, pos.pos.order) positions = list(doc.active_ballot().active_ad_positions().items()) positions.sort(key=sort_key) edit_position_url = "" if has_role(user, "Area Director"): edit_position_url = urlreverse('ietf.doc.views_ballot.edit_position', kwargs=dict(name=doc.name, ballot_id=ballot.pk)) title = "IESG positions (click to show more%s)" % (", right-click to edit position" if edit_position_url else "") res = ['<a href="%s" data-popup="%s" data-edit="%s" title="%s" class="ballot-icon"><table>' % ( urlreverse("doc_ballot", kwargs=dict(name=doc.name, ballot_id=ballot.pk)), urlreverse("ietf.doc.views_doc.ballot_popup", kwargs=dict(name=doc.name, ballot_id=ballot.pk)), edit_position_url, title )] res.append("<tr>") for i, (ad, pos) in enumerate(positions): if i > 0 and i % 5 == 0: res.append("</tr>") res.append("<tr>") c = "position-%s" % (pos.pos.slug if pos else "norecord") if user_is_person(user, ad): c += " my" res.append('<td class="%s" />' % c) res.append("</tr>") res.append("</table></a>") return "".join(res)
def can_provide_status_update(user, group): if not group.type_id in ['wg', 'rg', 'ag', 'team']: return False return has_role(user, 'Secretariat') or group.has_role( user, ( "chair", "delegate", "secr", "ad", ))
def approvable_submissions_for_user(user): if not user.is_authenticated(): return [] res = Submission.objects.filter(state="grp-appr").order_by('-submission_date') if has_role(user, "Secretariat"): return res # those we can reach as chair return res.filter(group__role__name="chair", group__role__person__user=user)
def recently_approved_by_user(user, since): if not user.is_authenticated(): return [] res = Submission.objects.distinct().filter(state="posted", submission_date__gte=since, rev="00").order_by('-submission_date') if has_role(user, "Secretariat"): return res # those we can reach as chair return res.filter(group__role__name="chair", group__role__person__user=user)
def stream_documents(request, acronym): streams = [ s.slug for s in StreamName.objects.all().exclude(slug__in=['ietf', 'legacy']) ] if not acronym in streams: raise Http404("No such stream: %s" % acronym) group = get_object_or_404(Group, acronym=acronym) editable = has_role(request.user, "Secretariat") or group.has_role(request.user, "chair") stream = StreamName.objects.get(slug=acronym) form = SearchForm({'by':'stream', 'stream':acronym, 'rfcs':'on', 'activedrafts':'on'}) docs, meta = retrieve_search_results(form) return render_to_response('group/stream_documents.html', {'stream':stream, 'docs':docs, 'meta':meta, 'editable':editable }, context_instance=RequestContext(request))
def view(request, acronym, num = None): ''' This view displays the session request info ''' meeting = get_meeting(num) group = get_object_or_404(Group, acronym=acronym) sessions = Session.objects.filter(~Q(status__in=('canceled','notmeet','deleted')),meeting=meeting,group=group).order_by('id') # check if app is locked is_locked = check_app_locked() if is_locked: messages.warning(request, "The Session Request Tool is closed") # if there are no session requests yet, redirect to new session request page if not sessions: if is_locked: return redirect('sessions') else: return redirect('sessions_new', acronym=acronym) # TODO simulate activity records activities = [{'act_date':sessions[0].requested.strftime('%b %d, %Y'), 'act_time':sessions[0].requested.strftime('%H:%M:%S'), 'activity':'New session was requested', 'act_by':sessions[0].requested_by}] if sessions[0].scheduled: activities.append({'act_date':sessions[0].scheduled.strftime('%b %d, %Y'), 'act_time':sessions[0].scheduled.strftime('%H:%M:%S'), 'activity':'Session was scheduled', 'act_by':'Secretariat'}) # other groups that list this group in their conflicts session_conflicts = session_conflicts_as_string(group, meeting) show_approve_button = False # if sessions include a 3rd session waiting approval and the user is a secretariat or AD of the group # display approve button if sessions.filter(status='apprw'): if has_role(request.user,'Secretariat') or group.parent.role_set.filter(name='ad',person=request.user.person): show_approve_button = True # build session dictionary (like querydict from new session request form) for use in template session = get_initial_session(sessions) return render_to_response('sreq/view.html', { 'is_locked': is_locked, 'session': session, 'activities': activities, 'meeting': meeting, 'group': group, 'session_conflicts': session_conflicts, 'show_approve_button': show_approve_button}, RequestContext(request, {}), )
def new(request, acronym): ''' This view gathers details for a new session request. The user proceeds to confirm() to create the request. ''' group = get_object_or_404(Group, acronym=acronym) meeting = get_meeting() session_conflicts = session_conflicts_as_string(group, meeting) # check if app is locked is_locked = check_app_locked() if is_locked and not has_role(request.user,'Secretariat'): messages.warning(request, "The Session Request Tool is closed") return redirect('ietf.secr.sreq.views.main') if request.method == 'POST': button_text = request.POST.get('submit', '') if button_text == 'Cancel': return redirect('ietf.secr.sreq.views.main') form = SessionForm(request.POST) if form.is_valid(): # check if request already exists for this group if Session.objects.filter(group=group,meeting=meeting).exclude(status__in=('deleted','notmeet')): messages.warning(request, 'Sessions for working group %s have already been requested once.' % group.acronym) return redirect('ietf.secr.sreq.views.main') return confirm(request, acronym) # the "previous" querystring causes the form to be returned # pre-populated with data from last meeeting's session request elif request.method == 'GET' and request.GET.has_key('previous'): previous_meeting = Meeting.objects.get(number=str(int(meeting.number) - 1)) previous_sessions = Session.objects.filter(meeting=previous_meeting,group=group).exclude(status__in=('notmeet','deleted')).order_by('id') if not previous_sessions: messages.warning(request, 'This group did not meet at %s' % previous_meeting) return redirect('ietf.secr.sreq.views.new', acronym=acronym) initial = get_initial_session(previous_sessions) add_essential_people(group,initial) if 'resources' in initial: initial['resources'] = [x.pk for x in initial['resources']] form = SessionForm(initial=initial) else: initial={} add_essential_people(group,initial) form = SessionForm(initial=initial) return render(request, 'sreq/new.html', { 'meeting': meeting, 'form': form, 'group': group, 'session_conflicts': session_conflicts}, )
def _can_take_care(liaison, user): '''Returns True if user can take care of awaiting actions associated with this liaison''' if not liaison.deadline or liaison.action_taken: return False if user.is_authenticated(): if has_role(user, "Secretariat"): return True else: return _find_person_in_emails(liaison, get_person_for_user(user)) return False
def _can_take_care(liaison, user): '''Returns True if user can take care of awaiting actions associated with this liaison''' if not liaison.deadline or liaison.action_taken: return False if user.is_authenticated: if has_role(user, "Secretariat"): return True else: return _find_person_in_emails(liaison, get_person_for_user(user)) return False
def post_only(group,person): '''Returns true if the user is restricted to post_only (vs. post_and_send) for this group. This is for incoming liaison statements. - Secretariat have full access. - Authorized Individuals have full access for the group they are associated with - Liaison Managers can post only ''' if group.type_id == 'sdo' and ( not(has_role(person.user,"Secretariat") or group.role_set.filter(name='auth',person=person)) ): return True else: return False
def _can_reply(liaison, user): '''Returns true if the user can send a reply to this liaison''' if user.is_authenticated(): person = get_person_for_user(user) if has_role(user, "Secretariat"): return True if liaison.is_outgoing() and Role.objects.filter(group__in=liaison.to_groups.all(),person=person,name='auth'): return True if not liaison.is_outgoing() and Role.objects.filter(group__in=liaison.from_groups.all(),person=person,name='liaiman'): return True return False
def template_list(request, acronym): group = get_object_or_404(Group, acronym=acronym) chairs = group.role_set.filter(name__slug='chair') if not has_role(request.user, "Secretariat") and not chairs.filter(person__user=request.user).count(): return HttpResponseForbidden("You are not authorized to access this view") template_list = DBTemplate.objects.filter(group=group) return render(request, 'dbtemplate/template_list.html', {'template_list': template_list, 'group': group, })
def history(request, id): """Show the history for a specific IPR disclosure""" ipr = get_object_or_404(IprDisclosureBase, id=id).get_child() if not has_role(request.user, 'Secretariat'): if ipr.state.slug != 'posted': raise Http404 events = ipr.iprevent_set.all().order_by("-time", "-id").select_related("by") if not has_role(request.user, "Secretariat"): events = events.exclude(type='private_comment') return render( request, "ipr/details_history.html", { 'events': events, 'ipr': ipr, 'tabs': get_details_tabs(ipr, 'History'), 'selected_tab_entry': 'history' })
def agenda_permissions(meeting, schedule, user): # do this in positive logic. cansee = False canedit = False secretariat = False if has_role(user, 'Secretariat'): cansee = True secretariat = True # NOTE: secretariat is not superuser for edit! elif schedule.public: cansee = True elif schedule.visible and has_role(user, ['Area Director', 'IAB Chair', 'IRTF Chair']): cansee = True if user_is_person(user, schedule.owner): cansee = True canedit = True return cansee, canedit, secretariat
def template_list(request, acronym): group = get_object_or_404(Group, acronym=acronym) chairs = group.role_set.filter(name__slug='chair') if not has_role(request.user, "Secretariat") and not (request.user.id and chairs.filter(person__user=request.user).count()): return HttpResponseForbidden("You are not authorized to access this view") template_list = DBTemplate.objects.filter(group=group) return render(request, 'dbtemplate/template_list.html', {'template_list': template_list, 'group': group, })
def set_group_options(self): '''Set group options based on user accessing the form''' if has_role(self.user, "Secretariat"): return # don't reduce group options q_objects = Q() if has_role(self.user, "Area Director"): q_objects.add(Q(type="wg", state__in=("active", "proposed", "bof")), Q.OR) if has_role(self.user, "IRTF Chair"): q_objects.add(Q(type="rg", state__in=("active", "proposed")), Q.OR) if has_role(self.user, "WG Chair"): q_objects.add(Q(type="wg", state__in=("active", "proposed", "bof"), role__person=self.person, role__name="chair"), Q.OR) if has_role(self.user, "RG Chair"): q_objects.add(Q(type="rg", state__in=("active", "proposed"), role__person=self.person, role__name="chair"), Q.OR) queryset = Group.objects.filter(q_objects).distinct().order_by('acronym') self.fields['group'].queryset = queryset # if there's only one possibility make it the default if len(queryset) == 1: self.fields['group'].initial = queryset[0]
def show_that_mail_was_sent(request,leadline,msg,bcc): if request and request.user: from ietf.ietfauth.utils import has_role if has_role(request.user,['Area Director','Secretariat','IANA','RFC Editor','ISE','IAD','IRTF Chair','WG Chair','RG Chair','WG Secretary','RG Secretary']): info = "%s at %s %s\n" % (leadline,datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),settings.TIME_ZONE) info += "Subject: %s\n" % msg.get('Subject','[no subject]') info += "To: %s\n" % msg.get('To','[no to]') if msg.get('Cc'): info += "Cc: %s\n" % msg.get('Cc') if bcc: info += "Bcc: %s\n" % bcc messages.info(request,info,extra_tags='preformatted',fail_silently=True)
def approvable_submissions_for_user(user): if not user.is_authenticated: return [] res = Submission.objects.filter( state="grp-appr").order_by('-submission_date') if has_role(user, "Secretariat"): return res # those we can reach as chair return res.filter(group__role__name="chair", group__role__person__user=user)
def can_adopt_draft(user, doc): if not user.is_authenticated: return False if has_role(user, "Secretariat"): return True #The IRTF chair can adopt a draft into any RG if has_role(user, "IRTF Chair"): return (doc.stream_id in (None, "irtf") and doc.group.type_id == "individ") roles = Role.objects.filter(name__in=("chair", "delegate", "secr"), group__type__in=("wg", "rg", "ag", ), group__state="active", person__user=user) role_groups = [ r.group for r in roles ] return (doc.stream_id in (None, "ietf", "irtf") and (doc.group.type_id == "individ" or (doc.group in role_groups and len(role_groups)>1)) and roles.exists())
def set_from_fields(self): '''Set from_groups and from_contact options and initial value based on user accessing the form.''' if self.instance.is_outgoing(): self.fields['from_groups'].choices = get_internal_choices(self.user) else: if has_role(self.user, "Secretariat"): queryset = Group.objects.filter(type="sdo").order_by('name') else: queryset = Group.objects.filter(type="sdo", role__person=self.person, role__name__in=("liaiman", "auth")).distinct().order_by('name') self.fields['from_contact'].widget.attrs['readonly'] = True self.fields['from_groups'].queryset = queryset
def view(request, acronym, num = None): ''' This view displays the session request info ''' meeting = get_meeting(num) group = get_object_or_404(Group, acronym=acronym) sessions = Session.objects.filter(~Q(status__in=('canceled','notmeet','deleted')),meeting=meeting,group=group).order_by('id') # check if app is locked is_locked = check_app_locked() if is_locked: messages.warning(request, "The Session Request Tool is closed") # if there are no session requests yet, redirect to new session request page if not sessions: if is_locked: return redirect('ietf.secr.sreq.views.main') else: return redirect('ietf.secr.sreq.views.new', acronym=acronym) # TODO simulate activity records activities = [{'act_date':sessions[0].requested.strftime('%b %d, %Y'), 'act_time':sessions[0].requested.strftime('%H:%M:%S'), 'activity':'New session was requested', 'act_by':sessions[0].requested_by}] if sessions[0].scheduled: activities.append({'act_date':sessions[0].scheduled.strftime('%b %d, %Y'), 'act_time':sessions[0].scheduled.strftime('%H:%M:%S'), 'activity':'Session was scheduled', 'act_by':'Secretariat'}) # other groups that list this group in their conflicts session_conflicts = session_conflicts_as_string(group, meeting) show_approve_button = False # if sessions include a 3rd session waiting approval and the user is a secretariat or AD of the group # display approve button if sessions.filter(status='apprw'): if has_role(request.user,'Secretariat') or group.parent.role_set.filter(name='ad',person=request.user.person): show_approve_button = True # build session dictionary (like querydict from new session request form) for use in template session = get_initial_session(sessions) return render(request, 'sreq/view.html', { 'is_locked': is_locked, 'session': session, 'activities': activities, 'meeting': meeting, 'group': group, 'session_conflicts': session_conflicts, 'show_approve_button': show_approve_button}, )
def recently_approved_by_user(user, since): if not user.is_authenticated: return [] res = Submission.objects.distinct().filter( state="posted", submission_date__gte=since, rev="00").order_by('-submission_date') if has_role(user, "Secretariat"): return res # those we can reach as chair return res.filter(group__role__name="chair", group__role__person__user=user)
def post_only(group, person): '''Returns true if the user is restricted to post_only (vs. post_and_send) for this group. This is for incoming liaison statements. - Secretariat have full access. - Authorized Individuals have full access for the group they are associated with - Liaison Managers can post only ''' if group.type_id == 'sdo' and ( not (has_role(person.user, "Secretariat") or group.role_set.filter(name='auth', person=person))): return True else: return False
def set_to_fields(self): '''Set to_groups and to_contacts options and initial value based on user accessing the form. For incoming Liaisons, to_groups choices is the full set. ''' if self.instance.is_outgoing(): # if the user is a Liaison Manager and nothing more, reduce to set to his SDOs if has_role(self.user, "Liaison Manager") and not self.person.role_set.filter(name__in=('ad','chair'),group__state='active'): queryset = Group.objects.filter(type="sdo", role__person=self.person, role__name="liaiman").distinct().order_by('name') else: # get all outgoing entities queryset = Group.objects.filter(type="sdo").order_by('name') self.fields['to_groups'].queryset = queryset else: self.fields['to_groups'].choices = get_internal_choices(None)