Example #1
0
def agenda_permissions(meeting, schedule, user):
    # do this in positive logic.
    cansee = False
    canedit= False
    requestor= None

    try:
        requestor = user.get_profile()
    except:
        pass

    #sys.stdout.write("requestor: %s for sched: %s \n" % ( requestor, schedule ))
    if has_role(user, 'Secretariat'):
        cansee = True
        # secretariat is not superuser for edit!

    if (has_role(user, 'Area Director') and schedule.visible):
        cansee = True

    if (has_role(user, 'IAB Chair') and schedule.visible):
        cansee = True

    if (has_role(user, 'IRTF Chair') and schedule.visible):
        cansee = True

    if schedule.public:
        cansee = True

    if requestor is not None and schedule.owner == requestor:
        cansee = True
        canedit = True

    return cansee,canedit
Example #2
0
File: forms.py Project: mcr/ietfdb
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.get_profile()
    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],)
    # NomCom, RSOC Chair, IAOC Chair aren't supported by has_role()
    elif Role.objects.filter(name="chair",
                             group__acronym__startswith="nomcom",
                             group__state="active",
                             group__type="ietf",
                             person=person):
        f = (FROM_LIST[7],)
    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],)
    return zip(f,f)
Example #3
0
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.get_profile()
    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], )
    # NomCom, RSOC Chair, IAOC Chair aren't supported by has_role()
    elif Role.objects.filter(name="chair",
                             group__acronym__startswith="nomcom",
                             group__state="active",
                             group__type="ietf",
                             person=person):
        f = (FROM_LIST[7], )
    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], )
    return zip(f, f)
Example #4
0
File: ajax.py Project: mcr/ietfdb
def readonly(request, meeting_num, schedule_id):
    meeting = get_meeting(meeting_num)
    schedule = get_schedule_by_id(meeting, schedule_id)

    secretariat = False
    write_perm  = False

    cansee,canedit = agenda_permissions(meeting, schedule, request.user)
    read_only = not canedit

    user = request.user
    if has_role(user, "Secretariat"):
        secretariat = True
        write_perm  = True

    if has_role(user, "Area Director"):
        write_perm  = True

    try:
        person = user.get_profile()
        if person is not None and schedule.owner == user.person:
            read_only = False
    except:
        # specific error if user has no profile...
        pass

    return json.dumps(
        {'secretariat': secretariat,
         'write_perm':  write_perm,
         'owner_href':  schedule.owner.url(request.get_host_protocol()),
         'read_only':   read_only})
Example #5
0
def agenda_permissions(meeting, schedule, user):
    # do this in positive logic.
    cansee = False
    canedit = False
    requestor = None

    try:
        requestor = user.get_profile()
    except:
        pass

    #sys.stdout.write("requestor: %s for sched: %s \n" % ( requestor, schedule ))
    if has_role(user, 'Secretariat'):
        cansee = True
        # secretariat is not superuser for edit!

    if (has_role(user, 'Area Director') and schedule.visible):
        cansee = True

    if (has_role(user, 'IAB Chair') and schedule.visible):
        cansee = True

    if (has_role(user, 'IRTF Chair') and schedule.visible):
        cansee = True

    if schedule.public:
        cansee = True

    if requestor is not None and schedule.owner == requestor:
        cansee = True
        canedit = True

    return cansee, canedit
Example #6
0
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.get_profile()

    if request.method == 'POST':
        form = ChangeStateForm(request.POST)
        if form.is_valid():
            clean = form.cleaned_data
            review_state = clean['review_state']
            comment = clean['comment'].rstrip()

            if comment:
                c = DocEvent(type="added_comment", doc=review, by=login)
                c.desc = comment
                c.save()

            if review_state != review.get_state():
                save_document_in_history(review)

                old_description = review.friendly_state()
                review.set_state(review_state)
                new_description = review.friendly_state()

                log_state_changed(request, review, login, new_description, old_description)

                review.time = datetime.datetime.now()
                review.save()

                if review_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('help_conflict_review_states'),
                                   ),
                              context_instance=RequestContext(request))
Example #7
0
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.is_chair(user)
Example #8
0
def template_edit(request,
                  acronym,
                  template_id,
                  base_template='dbtemplate/template_edit.html',
                  formclass=DBTemplateForm,
                  extra_context=None):
    group = get_object_or_404(Group, acronym=acronym)
    chairs = group.role_set.filter(name__slug='chair')
    extra_context = extra_context or {}

    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 = get_object_or_404(DBTemplate, id=template_id, group=group)
    if request.method == 'POST':
        form = formclass(instance=template, data=request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('..')
    else:
        form = formclass(instance=template)

    context = {
        'template': template,
        'group': group,
        'form': form,
    }
    context.update(extra_context)
    return render_to_response(base_template, context, RequestContext(request))
Example #9
0
    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.get_profile()
        all_roles = chain(
            group.role_set.filter(name__in=('chair', 'secr')),
            group.parent.role_set.filter(name__in=('ad', 'chair')))
        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 session.timeslot_set.filter(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
        })
Example #10
0
def render_ballot_icon(user, doc):
    if not doc:
        return ""

    if doc.type_id == "draft":
        s = doc.get_state("draft-iesg")
        if s and s.name not in BALLOT_ACTIVE_STATES:
            return ""
    elif doc.type_id == "charter":
        if doc.get_state_slug() not in ("intrev", "iesgrev"):
            return ""

    ballot = doc.latest_event(BallotDocEvent, type="created_ballot")
    if not ballot:
        return ""

    edit_position_url = urlreverse('ietf.idrfc.views_ballot.edit_position',
                                   kwargs=dict(name=doc.name,
                                               ballot_id=ballot.pk))

    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)

    cm = ""
    if has_role(user, "Area Director"):
        cm = ' oncontextmenu="editBallot(\'' + str(
            edit_position_url) + '\');return false;"'

    res = [
        '<table class="ballot_icon" title="IESG Evaluation Record (click to show more, right-click to edit position)" onclick="showBallot(\''
        + doc.name + '\',\'' + str(edit_position_url) + '\')"' + cm + '>'
    ]

    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 ad.user_id == user.id:
            c += " my"

        res.append('<td class="%s" />' % c)

    res.append("</tr>")
    res.append("</table>")

    return "".join(res)
Example #11
0
def add_preapproval(request):
    groups = Group.objects.filter(type="wg").exclude(
        state="conclude").order_by("acronym").distinct()

    if not has_role(request.user, "Secretariat"):
        groups = groups.filter(role__person=request.user.get_profile())

    if request.method == "POST":
        form = PreapprovalForm(request.POST)
        form.groups = groups
        if form.is_valid():
            p = Preapproval()
            p.name = form.cleaned_data["name"]
            p.by = request.user.get_profile()
            p.save()

            return HttpResponseRedirect(
                urlreverse("submit_approvals") + "#preapprovals")
    else:
        form = PreapprovalForm()

    return render_to_response('submit/add_preapproval.html', {
        'selected': 'approvals',
        'groups': groups,
        'form': form
    },
                              context_instance=RequestContext(request))
Example #12
0
def edit_consensus(request, name):
    """Change whether the draft is a consensus document or not."""

    doc = get_object_or_404(Document, type="draft", name=name)

    if not (has_role(request.user, ("Secretariat", "Area Director"))
            or is_authorized_in_doc_stream(request.user, doc)):
        return HttpResponseForbidden("You do not have the necessary permissions to view this page")

    e = doc.latest_event(ConsensusDocEvent, type="changed_consensus")
    prev_consensus = e and e.consensus

    if request.method == 'POST':
        form = ConsensusForm(request.POST)
        if form.is_valid():
            if form.cleaned_data["consensus"] != bool(prev_consensus):
                e = ConsensusDocEvent(doc=doc, type="changed_consensus", by=request.user.get_profile())
                e.consensus = form.cleaned_data["consensus"] == "Yes"

                e.desc = "Changed consensus to <b>%s</b> from %s" % (nice_consensus(e.consensus),
                                                                     nice_consensus(prev_consensus))

                e.save()

            return HttpResponseRedirect(urlreverse('doc_view', kwargs={'name': doc.name}))

    else:
        form = ConsensusForm(initial=dict(consensus=nice_consensus(prev_consensus).replace("Unknown", "")))

    return render_to_response('idrfc/change_consensus.html',
                              {'form': form,
                               'doc': doc,
                              },
                              context_instance = RequestContext(request))
Example #13
0
File: group.py Project: mcr/ietfdb
def get_my_groups(user,conclude=False):
    '''
    Takes a Django user object (from request)
    Returns a list of groups the user has access to.  Rules are as follows
    secretariat - has access to all groups
    area director - has access to all groups in their area
    wg chair or secretary - has acceses to their own group
    chair of irtf has access to all irtf groups
    
    If user=None than all groups are returned.
    concluded=True means include concluded groups.  Need this to upload materials for groups
    after they've been concluded.  it happens.
    '''
    my_groups = set()
    states = ['bof','proposed','active']
    if conclude: 
        states.append('conclude')
    all_groups = Group.objects.filter(type__in=('wg','rg','ag','team'),state__in=states).order_by('acronym')
    if user == None:
        return all_groups
    else:
        person = user.get_profile()
    
    if has_role(user,'Secretariat'):
        return all_groups
    
    for group in all_groups:
        if group.role_set.filter(person=person,name__in=('chair','secr')):
            my_groups.add(group)
            continue
        if group.parent and group.parent.role_set.filter(person=person,name__in=('ad','chair')):
            my_groups.add(group)
            continue
    
    return list(my_groups)
Example #14
0
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.is_chair(user)
Example #15
0
File: views.py Project: mcr/ietfdb
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':
            url = reverse('sessions_no_session', kwargs={'acronym':request.POST['group']})
            return HttpResponseRedirect(url)
        else:
            redirect_url = reverse('sessions_new', kwargs={'acronym':request.POST['group']})
            return HttpResponseRedirect(redirect_url)
        
    meeting = get_meeting()
    scheduled_groups,unscheduled_groups = groups_by_session(request.user, meeting)
    
    # 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, {}),
    )
Example #16
0
def change_intention(request, name):
    """Change the intended publication status of a Document of type 'draft' , notifying parties 
       as necessary and logging the change as a comment."""
    doc = get_object_or_404(Document, docalias__name=name)
    if doc.type_id != 'draft':
        raise Http404

    if not (has_role(request.user, ("Secretariat", "Area Director"))
            or is_authorized_in_doc_stream(request.user, doc)):
        return HttpResponseForbidden(
            "You do not have the necessary permissions to view this page")

    login = request.user.get_profile()

    if request.method == 'POST':
        form = ChangeIntentionForm(request.POST)
        if form.is_valid():
            new_level = form.cleaned_data['intended_std_level']
            comment = form.cleaned_data['comment'].strip()
            old_level = doc.intended_std_level

            if new_level != old_level:
                save_document_in_history(doc)

                doc.intended_std_level = new_level

                e = DocEvent(doc=doc, by=login, type='changed_document')
                e.desc = u"Intended Status changed to <b>%s</b> from %s" % (
                    new_level, old_level)
                e.save()

                email_desc = e.desc

                if comment:
                    c = DocEvent(doc=doc, by=login, type="added_comment")
                    c.desc = comment
                    c.save()
                    email_desc += "\n" + c.desc

                doc.time = e.time
                doc.save()

                email_owner(request, doc, doc.ad, login, email_desc)

            return HttpResponseRedirect(doc.get_absolute_url())

    else:
        intended_std_level = doc.intended_std_level
        form = ChangeIntentionForm(initial=dict(
            intended_std_level=intended_std_level))

    return render_to_response('idrfc/change_intended_status.html',
                              dict(
                                  form=form,
                                  doc=doc,
                              ),
                              context_instance=RequestContext(request))
Example #17
0
def reset_charter_milestones(request, acronym):
    """Reset charter milestones to the currently in-use milestones."""
    login = request.user.get_profile()

    group = get_object_or_404(Group, acronym=acronym)

    if (not has_role(request.user, ("Area Director", "Secretariat")) and
        not group.role_set.filter(name="chair", person=login)):
        return HttpResponseForbidden("You are not chair of this group.")

    current_milestones = group.groupmilestone_set.filter(state="active")
    charter_milestones = group.groupmilestone_set.filter(state="charter")

    if request.method == 'POST':
        try:
            milestone_ids = [int(v) for v in request.POST.getlist("milestone")]
        except ValueError as e:
            return HttpResponseBadRequest("error in list of ids - %s" % e)

        # delete existing
        for m in charter_milestones:
            save_milestone_in_history(m)

            m.state_id = "deleted"
            m.save()

            DocEvent.objects.create(type="changed_charter_milestone",
                                    doc=group.charter,
                                    desc='Deleted milestone "%s"' % m.desc,
                                    by=login,
                                    )

        # add current
        for m in current_milestones.filter(id__in=milestone_ids):
            new = GroupMilestone.objects.create(group=m.group,
                                                state_id="charter",
                                                desc=m.desc,
                                                due=m.due,
                                                resolved=m.resolved,
                                                )
            new.docs = m.docs.all()

            DocEvent.objects.create(type="changed_charter_milestone",
                                    doc=group.charter,
                                    desc='Added milestone "%s", due %s, from current group milestones' % (new.desc, new.due.strftime("%B %Y")),
                                    by=login,
                                    )


        return redirect('wg_edit_charter_milestones', acronym=group.acronym)

    return render_to_response('wginfo/reset_charter_milestones.html',
                              dict(group=group,
                                   charter_milestones=charter_milestones,
                                   current_milestones=current_milestones,
                                   ),
                              context_instance=RequestContext(request))
Example #18
0
def change_stream(request, name):
    """Change the stream of a Document of type 'draft', notifying parties as necessary
    and logging the change as a comment."""
    doc = get_object_or_404(Document, docalias__name=name)
    if not doc.type_id=='draft':
        raise Http404()

    if not (has_role(request.user, ("Area Director", "Secretariat")) or
            (request.user.is_authenticated() and
             Role.objects.filter(name="chair",
                                 group__acronym__in=StreamName.objects.values_list("slug", flat=True),
                                 person__user=request.user))):
        return HttpResponseForbidden("You do not have permission to view this page")

    login = request.user.get_profile()

    if request.method == 'POST':
        form = ChangeStreamForm(request.POST)
        if form.is_valid():
            new_stream = form.cleaned_data['stream']
            comment = form.cleaned_data['comment'].strip()
            old_stream = doc.stream

            if new_stream != old_stream:
                save_document_in_history(doc)
                
                doc.stream = new_stream
                doc.group = Group.objects.get(type="individ")

                e = DocEvent(doc=doc,by=login,type='changed_document')
                e.desc = u"Stream changed to <b>%s</b> from %s"% (new_stream, old_stream or "None")
                e.save()

                email_desc = e.desc

                if comment:
                    c = DocEvent(doc=doc,by=login,type="added_comment")
                    c.desc = comment
                    c.save()
                    email_desc += "\n"+c.desc
                
                doc.time = e.time
                doc.save()

                email_stream_changed(request, doc, old_stream, new_stream, email_desc)

            return HttpResponseRedirect(doc.get_absolute_url())

    else:
        stream = doc.stream
        form = ChangeStreamForm(initial=dict(stream=stream))

    return render_to_response('idrfc/change_stream.html',
                              dict(form=form,
                                   doc=doc,
                                   ),
                              context_instance=RequestContext(request))
Example #19
0
File: utils.py Project: mcr/ietfdb
def get_approvable_submissions(user):
    if not user.is_authenticated():
        return []

    res = IdSubmissionDetail.objects.filter(status=INITIAL_VERSION_APPROVAL_REQUESTED).order_by('-submission_date')
    if has_role(user, "Secretariat"):
        return res

    # those we can reach as chair
    return res.filter(group_acronym__role__name="chair", group_acronym__role__person__user=user)
Example #20
0
File: utils.py Project: mcr/ietfdb
def get_recently_approved(user, since):
    if not user.is_authenticated():
        return []

    res = IdSubmissionDetail.objects.distinct().filter(status__in=[POSTED, POSTED_BY_SECRETARIAT], submission_date__gte=since, revision="00").order_by('-submission_date')
    if has_role(user, "Secretariat"):
        return res

    # those we can reach as chair
    return res.filter(group_acronym__role__name="chair", group_acronym__role__person__user=user)
Example #21
0
def render_ballot_icon(user, doc):
    if not doc:
        return ""

    if doc.type_id == "draft":
        s = doc.get_state("draft-iesg")
        if s and s.name not in BALLOT_ACTIVE_STATES:
            return ""
    elif doc.type_id == "charter":
        if doc.get_state_slug() not in ("intrev", "iesgrev"):
            return ""

    ballot = doc.latest_event(BallotDocEvent, type="created_ballot")
    if not ballot:
        return ""

    edit_position_url = urlreverse('ietf.idrfc.views_ballot.edit_position', kwargs=dict(name=doc.name, ballot_id=ballot.pk))

    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)

    cm = ""
    if has_role(user, "Area Director"):
        cm = ' oncontextmenu="editBallot(\''+str(edit_position_url)+'\');return false;"'

    res = ['<table class="ballot_icon" title="IESG Evaluation Record (click to show more, right-click to edit position)" onclick="showBallot(\'' + doc.name + '\',\'' + str(edit_position_url) + '\')"' + cm + '>']

    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 ad.user_id == user.id:
            c += " my"

        res.append('<td class="%s" />' % c)

    res.append("</tr>")
    res.append("</table>")

    return "".join(res)
Example #22
0
File: views.py Project: mcr/ietfdb
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_to_response('dbtemplate/template_list.html',
        {'template_list': template_list,
         'group': group,
        }, RequestContext(request))
Example #23
0
def change_intention(request, name):
    """Change the intended publication status of a Document of type 'draft' , notifying parties 
       as necessary and logging the change as a comment."""
    doc = get_object_or_404(Document, docalias__name=name)
    if doc.type_id != 'draft':
        raise Http404

    if not (has_role(request.user, ("Secretariat", "Area Director"))
            or is_authorized_in_doc_stream(request.user, doc)):
        return HttpResponseForbidden("You do not have the necessary permissions to view this page")

    login = request.user.get_profile()

    if request.method == 'POST':
        form = ChangeIntentionForm(request.POST)
        if form.is_valid():
            new_level = form.cleaned_data['intended_std_level']
            comment = form.cleaned_data['comment'].strip()
            old_level = doc.intended_std_level

            if new_level != old_level:
                save_document_in_history(doc)
                
                doc.intended_std_level = new_level

                e = DocEvent(doc=doc,by=login,type='changed_document')
                e.desc = u"Intended Status changed to <b>%s</b> from %s"% (new_level,old_level) 
                e.save()

                email_desc = e.desc

                if comment:
                    c = DocEvent(doc=doc,by=login,type="added_comment")
                    c.desc = comment
                    c.save()
                    email_desc += "\n"+c.desc
                
                doc.time = e.time
                doc.save()

                email_owner(request, doc, doc.ad, login, email_desc)

            return HttpResponseRedirect(doc.get_absolute_url())

    else:
        intended_std_level = doc.intended_std_level
        form = ChangeIntentionForm(initial=dict(intended_std_level=intended_std_level))

    return render_to_response('idrfc/change_intended_status.html',
                              dict(form=form,
                                   doc=doc,
                                   ),
                              context_instance=RequestContext(request))
Example #24
0
def get_approvable_submissions(user):
    if not user.is_authenticated():
        return []

    res = IdSubmissionDetail.objects.filter(
        status=INITIAL_VERSION_APPROVAL_REQUESTED).order_by('-submission_date')
    if has_role(user, "Secretariat"):
        return res

    # those we can reach as chair
    return res.filter(group_acronym__role__name="chair",
                      group_acronym__role__person__user=user)
Example #25
0
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_to_response('dbtemplate/template_list.html', {
        'template_list': template_list,
        'group': group,
    }, RequestContext(request))
Example #26
0
def get_recently_approved(user, since):
    if not user.is_authenticated():
        return []

    res = IdSubmissionDetail.objects.distinct().filter(
        status__in=[POSTED, POSTED_BY_SECRETARIAT],
        submission_date__gte=since,
        revision="00").order_by('-submission_date')
    if has_role(user, "Secretariat"):
        return res

    # those we can reach as chair
    return res.filter(group_acronym__role__name="chair",
                      group_acronym__role__person__user=user)
Example #27
0
File: utils.py Project: mcr/ietfdb
def get_preapprovals(user):
    if not user.is_authenticated():
        return []

    posted = IdSubmissionDetail.objects.distinct().filter(status__in=[POSTED, POSTED_BY_SECRETARIAT]).values_list('filename', flat=True)
    res = Preapproval.objects.exclude(name__in=posted).order_by("-time").select_related('by')
    if has_role(user, "Secretariat"):
        return res

    acronyms = [g.acronym for g in Group.objects.filter(role__person__user=user, type="wg")]

    res = res.filter(name__regex="draft-[^-]+-(%s)-.*" % "|".join(acronyms))

    return res
Example #28
0
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

    '''
    # getting numerous errors when people try to access using the wrong account
    try:
        person = request.user.get_profile()
    except Person.DoesNotExist:
        return HttpResponseForbidden('ACCESS DENIED: user=%s' %
                                     request.META['REMOTE_USER'])

    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, {}),
    )
Example #29
0
File: views.py Project: mcr/ietfdb
def view(request, acronym):
    '''
    This view displays the session request info
    '''
    meeting = get_meeting()
    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')
    
    # if there are no session requests yet, redirect to new session request page
    if not sessions:
        redirect_url = reverse('sessions_new', kwargs={'acronym':acronym})
        return HttpResponseRedirect(redirect_url)
    
    # 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.get_profile()):
            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', {
        'session': session,
        'activities': activities,
        'meeting': meeting,
        'group': group,
        'session_conflicts': session_conflicts,
        'show_approve_button': show_approve_button},
        RequestContext(request, {}),
    )
Example #30
0
File: ajax.py Project: mcr/ietfdb
def agenda_update(request, meeting, schedule):
    # authorization was enforced by the @group_require decorator above.

    # forms are completely useless for update actions that want to
    # accept a subset of values.
    update_dict = QueryDict(request.raw_post_data, encoding=request._encoding)

    #log.debug("99 meeting.agenda: %s / %s / %s" %
    #          (schedule, update_dict, request.raw_post_data))

    user = request.user
    if has_role(user, "Secretariat"):
        if "public" in update_dict:
            value1 = True
            value = update_dict["public"]
            if value == "0" or value == 0 or value=="false":
                value1 = False
            log.debug("setting public for %s to %s" % (schedule, value1))
            schedule.public = value1

    if "visible" in update_dict:
        value1 = True
        value = update_dict["visible"]
        if value == "0" or value == 0 or value=="false":
            value1 = False
        log.debug("setting visible for %s to %s" % (schedule, value1))
        schedule.visible = value1

    if "name" in update_dict:
        value = update_dict["name"]
        log.debug("setting name for %s to %s" % (schedule, value))
        schedule.name = value

    schedule.save()

    # enforce that a non-public schedule can not be the public one.
    if meeting.agenda == schedule and not schedule.public:
        meeting.agenda = None
        meeting.save()

    if "HTTP_ACCEPT" in request.META and "application/json" in request.META['HTTP_ACCEPT']:
        return HttpResponse(json.dumps(schedule.json_dict(request.get_host_protocol())),
                            mimetype="application/json")
    else:
        return HttpResponseRedirect(
            reverse(edit_agenda, args=[meeting.number, schedule.name]))
Example #31
0
    def process_view(self, request, view_func, view_args, view_kwargs):
        # need to initialize user, it doesn't get set when running tests for example

        if request.path.startswith('/secr/'):
            user = ''
            request.user_is_secretariat = False
            
            if request.user.is_anonymous(): 
                return render_to_response('401.html', {'user':user})
            
            if 'REMOTE_USER' in request.META:
                # do custom auth
                if has_role(request.user,'Secretariat'):
                    request.user_is_secretariat = True
                    
            return None

        return None
Example #32
0
    def process_view(self, request, view_func, view_args, view_kwargs):
        # need to initialize user, it doesn't get set when running tests for example

        if request.path.startswith('/secr/'):
            user = ''
            request.user_is_secretariat = False

            if request.user.is_anonymous():
                return render_to_response('401.html', {'user': user})

            if 'REMOTE_USER' in request.META:
                # do custom auth
                if has_role(request.user, 'Secretariat'):
                    request.user_is_secretariat = True

            return None

        return None
Example #33
0
File: views.py Project: mcr/ietfdb
def approve(request, acronym):
    '''
    This view approves the third session.  For use by ADs or Secretariat.
    '''
    meeting = get_meeting()
    group = get_object_or_404(Group, acronym=acronym)
    session = Session.objects.get(meeting=meeting,group=group,status='apprw')
    
    if has_role(request.user,'Secretariat') or group.parent.role_set.filter(name='ad',person=request.user.get_profile()):
        session.status = SessionStatusName.objects.get(slug='appr')
        session.save()
        
        messages.success(request, 'Third session approved')
        url = reverse('sessions_view', kwargs={'acronym':acronym})
        return HttpResponseRedirect(url)
    else:
        # if an unauthorized user gets here return error
        messages.error(request, 'Not authorized to approve the third session')
        url = reverse('sessions_view', kwargs={'acronym':acronym})
        return HttpResponseRedirect(url)
Example #34
0
def check_access(user):
    '''
    This function takes a Django User object and returns true if the user has access to the
    Announcement app.  Accepted roles are:
    Secretariat, IAD, IAB Chair, IETF Chair, RSOC Chair, IAOC Chair, NomCom Chair, RSE Chair
    '''
    person = user.get_profile()
    groups_with_access = ("iab", "rsoc", "ietf", "iaoc", "rse")
    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="ietf",
                           person=person):
        return True
    
    return False
Example #35
0
def get_preapprovals(user):
    if not user.is_authenticated():
        return []

    posted = IdSubmissionDetail.objects.distinct().filter(
        status__in=[POSTED, POSTED_BY_SECRETARIAT]).values_list('filename',
                                                                flat=True)
    res = Preapproval.objects.exclude(
        name__in=posted).order_by("-time").select_related('by')
    if has_role(user, "Secretariat"):
        return res

    acronyms = [
        g.acronym
        for g in Group.objects.filter(role__person__user=user, type="wg")
    ]

    res = res.filter(name__regex="draft-[^-]+-(%s)-.*" % "|".join(acronyms))

    return res
Example #36
0
File: views.py Project: mcr/ietfdb
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

    '''
    # getting numerous errors when people try to access using the wrong account
    try:
        person = request.user.get_profile()
    except Person.DoesNotExist:
        return HttpResponseForbidden('ACCESS DENIED: user=%s' % request.META['REMOTE_USER'])
        
    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,{}), 
    )
Example #37
0
File: views.py Project: mcr/ietfdb
def edit_agendas(request, num=None, order=None):

    #if request.method == 'POST':
    #    return agenda_create(request, num, schedule_name)

    meeting = get_meeting(num)
    user = request.user

    schedules = meeting.schedule_set
    if not has_role(user, 'Secretariat'):
        schedules = schedules.filter(visible = True) | schedules.filter(owner = user.get_profile())

    schedules = schedules.order_by('owner', 'name')

    return HttpResponse(render_to_string("meeting/agenda_list.html",
                                         {"meeting":   meeting,
                                          "sitefqdn":  request.get_host_protocol(),
                                          "schedules": schedules.all()
                                          },
                                         RequestContext(request)),
                        mimetype="text/html")
Example #38
0
def approve(request, acronym):
    '''
    This view approves the third session.  For use by ADs or Secretariat.
    '''
    meeting = get_meeting()
    group = get_object_or_404(Group, acronym=acronym)
    session = Session.objects.get(meeting=meeting, group=group, status='apprw')

    if has_role(request.user, 'Secretariat') or group.parent.role_set.filter(
            name='ad', person=request.user.get_profile()):
        session.status = SessionStatusName.objects.get(slug='appr')
        session.save()

        messages.success(request, 'Third session approved')
        url = reverse('sessions_view', kwargs={'acronym': acronym})
        return HttpResponseRedirect(url)
    else:
        # if an unauthorized user gets here return error
        messages.error(request, 'Not authorized to approve the third session')
        url = reverse('sessions_view', kwargs={'acronym': acronym})
        return HttpResponseRedirect(url)
Example #39
0
def edit_consensus(request, name):
    """Change whether the draft is a consensus document or not."""

    doc = get_object_or_404(Document, type="draft", name=name)

    if not (has_role(request.user, ("Secretariat", "Area Director"))
            or is_authorized_in_doc_stream(request.user, doc)):
        return HttpResponseForbidden(
            "You do not have the necessary permissions to view this page")

    e = doc.latest_event(ConsensusDocEvent, type="changed_consensus")
    prev_consensus = e and e.consensus

    if request.method == 'POST':
        form = ConsensusForm(request.POST)
        if form.is_valid():
            if form.cleaned_data["consensus"] != bool(prev_consensus):
                e = ConsensusDocEvent(doc=doc,
                                      type="changed_consensus",
                                      by=request.user.get_profile())
                e.consensus = form.cleaned_data["consensus"] == "Yes"

                e.desc = "Changed consensus to <b>%s</b> from %s" % (
                    nice_consensus(
                        e.consensus), nice_consensus(prev_consensus))

                e.save()

            return HttpResponseRedirect(
                urlreverse('doc_view', kwargs={'name': doc.name}))

    else:
        form = ConsensusForm(initial=dict(
            consensus=nice_consensus(prev_consensus).replace("Unknown", "")))

    return render_to_response('idrfc/change_consensus.html', {
        'form': form,
        'doc': doc,
    },
                              context_instance=RequestContext(request))
Example #40
0
def edit_agendas(request, num=None, order=None):

    #if request.method == 'POST':
    #    return agenda_create(request, num, schedule_name)

    meeting = get_meeting(num)
    user = request.user

    schedules = meeting.schedule_set
    if not has_role(user, 'Secretariat'):
        schedules = schedules.filter(visible=True) | schedules.filter(
            owner=user.get_profile())

    schedules = schedules.order_by('owner', 'name')

    return HttpResponse(render_to_string(
        "meeting/agenda_list.html", {
            "meeting": meeting,
            "sitefqdn": request.get_host_protocol(),
            "schedules": schedules.all()
        }, RequestContext(request)),
                        mimetype="text/html")
Example #41
0
File: views.py Project: mcr/ietfdb
def template_edit(request, acronym, template_id, base_template='dbtemplate/template_edit.html', formclass=DBTemplateForm, extra_context=None):
    group = get_object_or_404(Group, acronym=acronym)
    chairs = group.role_set.filter(name__slug='chair')
    extra_context = extra_context or {}

    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 = get_object_or_404(DBTemplate, id=template_id, group=group)
    if request.method == 'POST':
        form = formclass(instance=template, data=request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('..')
    else:
        form = formclass(instance=template)

    context = {'template': template,
        'group': group,
        'form': form,
    }
    context.update(extra_context)
    return render_to_response(base_template, context, RequestContext(request))
Example #42
0
def get_my_groups(user, conclude=False):
    '''
    Takes a Django user object (from request)
    Returns a list of groups the user has access to.  Rules are as follows
    secretariat - has access to all groups
    area director - has access to all groups in their area
    wg chair or secretary - has acceses to their own group
    chair of irtf has access to all irtf groups
    
    If user=None than all groups are returned.
    concluded=True means include concluded groups.  Need this to upload materials for groups
    after they've been concluded.  it happens.
    '''
    my_groups = set()
    states = ['bof', 'proposed', 'active']
    if conclude:
        states.append('conclude')
    all_groups = Group.objects.filter(type__in=('wg', 'rg', 'ag', 'team'),
                                      state__in=states).order_by('acronym')
    if user == None:
        return all_groups
    else:
        person = user.get_profile()

    if has_role(user, 'Secretariat'):
        return all_groups

    for group in all_groups:
        if group.role_set.filter(person=person, name__in=('chair', 'secr')):
            my_groups.add(group)
            continue
        if group.parent and group.parent.role_set.filter(
                person=person, name__in=('ad', 'chair')):
            my_groups.add(group)
            continue

    return list(my_groups)
Example #43
0
File: views.py Project: mcr/ietfdb
def add_preapproval(request):
    groups = Group.objects.filter(type="wg").exclude(state="conclude").order_by("acronym").distinct()

    if not has_role(request.user, "Secretariat"):
        groups = groups.filter(role__person=request.user.get_profile())

    if request.method == "POST":
        form = PreapprovalForm(request.POST)
        form.groups = groups
        if form.is_valid():
            p = Preapproval()
            p.name = form.cleaned_data["name"]
            p.by = request.user.get_profile()
            p.save()

            return HttpResponseRedirect(urlreverse("submit_approvals") + "#preapprovals")
    else:
        form = PreapprovalForm()

    return render_to_response('submit/add_preapproval.html',
                              {'selected': 'approvals',
                               'groups': groups,
                               'form': form },
                              context_instance=RequestContext(request))
Example #44
0
def has_role(user, role_names):
    from ietf.ietfauth.decorators import has_role
    if not user:
        return False
    return has_role(user, role_names.split(','))
Example #45
0
def in_group(user, groups):
    if settings.USE_DB_REDESIGN_PROXY_CLASSES:
        return has_role(user, groups.replace("Area_Director", "Area Director"))

    return user and user.is_authenticated() and bool(
        user.groups.filter(name__in=groups.split(',')).values('name'))
Example #46
0
def edit_milestones(request, acronym, milestone_set="current"):
    # milestones_set + needs_review: we have several paths into this view
    #  AD/Secr. -> all actions on current + add new
    #  group chair -> limited actions on current + add new for review
    #  (re)charter -> all actions on existing in state charter + add new in state charter
    #
    # For charters we store the history on the charter document to not confuse people.

    login = request.user.get_profile()

    group = get_object_or_404(Group, acronym=acronym)

    needs_review = False
    if not has_role(request.user, ("Area Director", "Secretariat")):
        if group.role_set.filter(name="chair", person=login):
            if milestone_set == "current":
                needs_review = True
        else:
            return HttpResponseForbidden("You are not chair of this group.")

    if milestone_set == "current":
        title = "Edit milestones for %s %s" % (group.acronym, group.type.name)
        milestones = group.groupmilestone_set.filter(state__in=("active", "review"))
    elif milestone_set == "charter":
        title = "Edit charter milestones for %s %s" % (group.acronym, group.type.name)
        milestones = group.groupmilestone_set.filter(state="charter")

    forms = []

    milestones_dict = dict((str(m.id), m) for m in milestones)

    def due_month_year_to_date(c):
        y = c["due_year"]
        m = c["due_month"]
        return datetime.date(y, m, calendar.monthrange(y, m)[1])

    def set_attributes_from_form(f, m):
        c = f.cleaned_data
        m.group = group
        if milestone_set == "current":
            if needs_review:
                m.state = GroupMilestoneStateName.objects.get(slug="review")
            else:
                m.state = GroupMilestoneStateName.objects.get(slug="active")
        elif milestone_set == "charter":
            m.state = GroupMilestoneStateName.objects.get(slug="charter")
        m.desc = c["desc"]
        m.due = due_month_year_to_date(c)
        m.resolved = c["resolved"]

    def save_milestone_form(f):
        c = f.cleaned_data

        if f.milestone:
            m = f.milestone

            named_milestone = 'milestone "%s"' % m.desc
            if milestone_set == "charter":
                named_milestone = "charter " + named_milestone

            if c["delete"]:
                save_milestone_in_history(m)

                m.state_id = "deleted"
                m.save()

                return 'Deleted %s' % named_milestone

            # compute changes
            history = None

            changes = ['Changed %s' % named_milestone]

            if m.state_id == "review" and not needs_review and c["accept"] != "noaction":
                if not history:
                    history = save_milestone_in_history(m)

                if c["accept"] == "accept":
                    m.state_id = "active"
                    changes.append("set state to active from review, accepting new milestone")
                elif c["accept"] == "reject":
                    m.state_id = "deleted"
                    changes.append("set state to deleted from review, rejecting new milestone")


            if c["desc"] != m.desc and not needs_review:
                if not history:
                    history = save_milestone_in_history(m)
                m.desc = c["desc"]
                changes.append('set description to "%s"' % m.desc)


            c_due = due_month_year_to_date(c)
            if c_due != m.due:
                if not history:
                    history = save_milestone_in_history(m)
                changes.append('set due date to %s from %s' % (c_due.strftime("%B %Y"), m.due.strftime("%B %Y")))
                m.due = c_due

            resolved = c["resolved"]
            if resolved != m.resolved:
                if resolved and not m.resolved:
                    changes.append('resolved as "%s"' % resolved)
                elif not resolved and m.resolved:
                    changes.append("reverted to not being resolved")
                elif resolved and m.resolved:
                    changes.append('set resolution to "%s"' % resolved)

                if not history:
                    history = save_milestone_in_history(m)

                m.resolved = resolved

            new_docs = set(c["docs"])
            old_docs = set(m.docs.all())
            if new_docs != old_docs:
                added = new_docs - old_docs
                if added:
                    changes.append('added %s to milestone' % ", ".join(d.name for d in added))

                removed = old_docs - new_docs
                if removed:
                    changes.append('removed %s from milestone' % ", ".join(d.name for d in removed))

                if not history:
                    history = save_milestone_in_history(m)

                m.docs = new_docs

            if len(changes) > 1:
                m.save()

                return ", ".join(changes)

        else: # new milestone
            m = f.milestone = GroupMilestone()
            set_attributes_from_form(f, m)
            m.save()

            m.docs = c["docs"]

            named_milestone = 'milestone "%s"' % m.desc
            if milestone_set == "charter":
                named_milestone = "charter " + named_milestone

            if m.state_id in ("active", "charter"):
                return 'Added %s, due %s' % (named_milestone, m.due.strftime("%B %Y"))
            elif m.state_id == "review":
                return 'Added %s for review, due %s' % (named_milestone, m.due.strftime("%B %Y"))

    finished_milestone_text = "Done"

    form_errors = False

    if request.method == 'POST':
        # parse out individual milestone forms
        for prefix in request.POST.getlist("prefix"):
            if not prefix: # empty form
                continue

            # new milestones have non-existing ids so instance end up as None
            instance = milestones_dict.get(request.POST.get(prefix + "-id", ""), None)
            f = MilestoneForm(request.POST, prefix=prefix, instance=instance,
                              needs_review=needs_review)
            forms.append(f)

            form_errors = form_errors or not f.is_valid()

        action = request.POST.get("action", "review")
        if action == "review":
            for f in forms:
                if not f.is_valid():
                    continue

                # let's fill in the form milestone so we can output it in the template
                if not f.milestone:
                    f.milestone = GroupMilestone()
                set_attributes_from_form(f, f.milestone)
        elif action == "save" and not form_errors:
            changes = []
            for f in forms:
                change = save_milestone_form(f)

                if not change:
                    continue

                if milestone_set == "charter":
                    DocEvent.objects.create(doc=group.charter, type="changed_charter_milestone",
                                            by=login, desc=change)
                else:
                    MilestoneGroupEvent.objects.create(group=group, type="changed_milestone",
                                                       by=login, desc=change, milestone=f.milestone)

                changes.append(change)

            if milestone_set == "current":
                email_milestones_changed(request, group, changes)

            if milestone_set == "charter":
                return redirect('doc_view', name=group.charter.canonical_name())
            else:
                return redirect('wg_charter', acronym=group.acronym)
    else:
        for m in milestones:
            forms.append(MilestoneForm(instance=m, needs_review=needs_review))

    can_reset = milestone_set == "charter" and get_chartering_type(group.charter) == "rechartering"

    empty_form = MilestoneForm(needs_review=needs_review)

    forms.sort(key=lambda f: f.milestone.due if f.milestone else datetime.date.max)

    return render_to_response('wginfo/edit_milestones.html',
                              dict(group=group,
                                   title=title,
                                   forms=forms,
                                   form_errors=form_errors,
                                   empty_form=empty_form,
                                   milestone_set=milestone_set,
                                   finished_milestone_text=finished_milestone_text,
                                   needs_review=needs_review,
                                   can_reset=can_reset),
                              context_instance=RequestContext(request))
Example #47
0
def ballot_writeupnotes(request, name):
    """Editing of ballot write-up and notes"""
    charter = get_object_or_404(Document, type="charter", name=name)

    ballot = charter.latest_event(BallotDocEvent, type="created_ballot")
    if not ballot:
        raise Http404()

    login = request.user.get_profile()

    approval = charter.latest_event(WriteupDocEvent,
                                    type="changed_action_announcement")

    existing = charter.latest_event(WriteupDocEvent,
                                    type="changed_ballot_writeup_text")
    if not existing:
        existing = generate_ballot_writeup(request, charter)

    reissue = charter.latest_event(DocEvent, type="sent_ballot_announcement")

    form = BallotWriteupForm(initial=dict(ballot_writeup=existing.text))

    if request.method == 'POST' and ("save_ballot_writeup" in request.POST
                                     or "send_ballot" in request.POST):
        form = BallotWriteupForm(request.POST)
        if form.is_valid():
            t = form.cleaned_data["ballot_writeup"]
            if t != existing.text:
                e = WriteupDocEvent(doc=charter, by=login)
                e.by = login
                e.type = "changed_ballot_writeup_text"
                e.desc = "Ballot writeup was changed"
                e.text = t
                e.save()

            if "send_ballot" in request.POST and approval:
                if has_role(request.user,
                            "Area Director") and not charter.latest_event(
                                BallotPositionDocEvent,
                                type="changed_ballot_position",
                                ad=login,
                                ballot=ballot):
                    # sending the ballot counts as a yes
                    pos = BallotPositionDocEvent(doc=charter, by=login)
                    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()

                msg = generate_issue_ballot_mail(request, charter, ballot)
                send_mail_preformatted(request, msg)

                e = DocEvent(doc=charter, by=login)
                e.by = login
                e.type = "sent_ballot_announcement"
                e.desc = "Ballot has been sent"
                e.save()

                return render_to_response(
                    'wgcharter/ballot_issued.html',
                    dict(doc=charter, ),
                    context_instance=RequestContext(request))

    return render_to_response(
        'wgcharter/ballot_writeupnotes.html',
        dict(
            charter=charter,
            ballot_issued=bool(
                charter.latest_event(type="sent_ballot_announcement")),
            ballot_writeup_form=form,
            reissue=reissue,
            approval=approval,
        ),
        context_instance=RequestContext(request))
Example #48
0
File: edit.py Project: mcr/ietfdb
def edit(request, acronym=None, action="edit"):
    """Edit or create a WG, notifying parties as
    necessary and logging changes as group events."""
    if action == "edit":
        wg = get_object_or_404(Group, acronym=acronym)
        new_wg = False
    elif action in ("create","charter"):
        wg = None
        new_wg = True
    else:
        raise Http404

    login = request.user.get_profile()

    if request.method == 'POST':
        form = WGForm(request.POST, wg=wg, confirmed=request.POST.get("confirmed", False))
        if form.is_valid():
            clean = form.cleaned_data
            if new_wg:
                try:
                    wg = Group.objects.get(acronym=clean["acronym"])
                    save_group_in_history(wg)
                    wg.time = datetime.datetime.now()
                    wg.save()
                except Group.DoesNotExist:
                    wg = Group.objects.create(name=clean["name"],
                                              acronym=clean["acronym"],
                                              type=GroupTypeName.objects.get(slug="wg"),
                                              state=clean["state"]
                                              )

                e = ChangeStateGroupEvent(group=wg, type="changed_state")
                e.time = wg.time
                e.by = login
                e.state_id = clean["state"].slug
                e.desc = "Group created in state %s" % clean["state"].name
                e.save()
            else:
                save_group_in_history(wg)


            if action=="charter" and not wg.charter:  # make sure we have a charter
                wg.charter = get_or_create_initial_charter(wg)

            changes = []
                
            def desc(attr, new, old):
                entry = "%(attr)s changed to <b>%(new)s</b> from %(old)s"
                if new_wg:
                    entry = "%(attr)s changed to <b>%(new)s</b>"
                    
                return entry % dict(attr=attr, new=new, old=old)

            def diff(attr, name):
                v = getattr(wg, attr)
                if clean[attr] != v:
                    changes.append(desc(name, clean[attr], v))
                    setattr(wg, attr, clean[attr])

            prev_acronym = wg.acronym

            # update the attributes, keeping track of what we're doing
            diff('name', "Name")
            diff('acronym', "Acronym")
            diff('state', "State")
            diff('ad', "Shepherding AD")
            diff('parent', "IETF Area")
            diff('list_email', "Mailing list email")
            diff('list_subscribe', "Mailing list subscribe address")
            diff('list_archive', "Mailing list archive")

            if not new_wg and wg.acronym != prev_acronym and wg.charter:
                save_document_in_history(wg.charter)
                DocAlias.objects.get_or_create(
                    name="charter-ietf-%s" % wg.acronym,
                    document=wg.charter,
                    )
                old = os.path.join(wg.charter.get_file_path(), 'charter-ietf-%s-%s.txt' % (prev_acronym, wg.charter.rev))
                if os.path.exists(old):
                    new = os.path.join(wg.charter.get_file_path(), 'charter-ietf-%s-%s.txt' % (wg.acronym, wg.charter.rev))
                    shutil.copy(old, new)

            # update roles
            for attr, slug, title in [('chairs', 'chair', "Chairs"), ('secretaries', 'secr', "Secretaries"), ('techadv', 'techadv', "Tech Advisors")]:
                new = clean[attr]
                old = Email.objects.filter(role__group=wg, role__name=slug).select_related("person")
                if set(new) != set(old):
                    changes.append(desc(title,
                                        ", ".join(x.get_name() for x in new),
                                        ", ".join(x.get_name() for x in old)))
                    wg.role_set.filter(name=slug).delete()
                    for e in new:
                        Role.objects.get_or_create(name_id=slug, email=e, group=wg, person=e.person)

            # update urls
            new_urls = clean['urls']
            old_urls = format_urls(wg.groupurl_set.order_by('url'), ", ")
            if ", ".join(sorted(new_urls)) != old_urls:
                changes.append(desc('Urls', ", ".join(sorted(new_urls)), old_urls))
                wg.groupurl_set.all().delete()
                # Add new ones
                for u in new_urls:
                    m = re.search('(?P<url>[\w\d:#@%/;$()~_?\+-=\\\.&]+)( \((?P<name>.+)\))?', u)
                    if m:
                        if m.group('name'):
                            url = GroupURL(url=m.group('url'), name=m.group('name'), group=wg)
                        else:
                            url = GroupURL(url=m.group('url'), name='', group=wg)
                        url.save()

            wg.time = datetime.datetime.now()

            if changes and not new_wg:
                for c in changes:
                    GroupEvent.objects.create(group=wg, by=login, type="info_changed", desc=c)

            wg.save()

            if action=="charter":
                return redirect('charter_submit', name=wg.charter.name, option="initcharter")

            return redirect('wg_charter', acronym=wg.acronym)
    else: # form.is_valid()
        if not new_wg:
            from ietf.person.forms import json_emails
            init = dict(name=wg.name,
                        acronym=wg.acronym,
                        state=wg.state,
                        chairs=Email.objects.filter(role__group=wg, role__name="chair"),
                        secretaries=Email.objects.filter(role__group=wg, role__name="secr"),
                        techadv=Email.objects.filter(role__group=wg, role__name="techadv"),
                        ad=wg.ad_id if wg.ad else None,
                        parent=wg.parent.id if wg.parent else None,
                        list_email=wg.list_email if wg.list_email else None,
                        list_subscribe=wg.list_subscribe if wg.list_subscribe else None,
                        list_archive=wg.list_archive if wg.list_archive else None,
                        urls=format_urls(wg.groupurl_set.all()),
                        )
        else:
            init = dict(ad=login.id if has_role(request.user, "Area Director") else None,
                        )
        form = WGForm(initial=init, wg=wg)

    return render_to_response('wginfo/edit.html',
                              dict(wg=wg,
                                   form=form,
                                   action=action,
                                   user=request.user,
                                   login=login),
                              context_instance=RequestContext(request))
Example #49
0
def reset_charter_milestones(request, acronym):
    """Reset charter milestones to the currently in-use milestones."""
    login = request.user.get_profile()

    group = get_object_or_404(Group, acronym=acronym)

    if (not has_role(request.user, ("Area Director", "Secretariat"))
            and not group.role_set.filter(name="chair", person=login)):
        return HttpResponseForbidden("You are not chair of this group.")

    current_milestones = group.groupmilestone_set.filter(state="active")
    charter_milestones = group.groupmilestone_set.filter(state="charter")

    if request.method == 'POST':
        try:
            milestone_ids = [int(v) for v in request.POST.getlist("milestone")]
        except ValueError as e:
            return HttpResponseBadRequest("error in list of ids - %s" % e)

        # delete existing
        for m in charter_milestones:
            save_milestone_in_history(m)

            m.state_id = "deleted"
            m.save()

            DocEvent.objects.create(
                type="changed_charter_milestone",
                doc=group.charter,
                desc='Deleted milestone "%s"' % m.desc,
                by=login,
            )

        # add current
        for m in current_milestones.filter(id__in=milestone_ids):
            new = GroupMilestone.objects.create(
                group=m.group,
                state_id="charter",
                desc=m.desc,
                due=m.due,
                resolved=m.resolved,
            )
            new.docs = m.docs.all()

            DocEvent.objects.create(
                type="changed_charter_milestone",
                doc=group.charter,
                desc=
                'Added milestone "%s", due %s, from current group milestones' %
                (new.desc, new.due.strftime("%B %Y")),
                by=login,
            )

        return redirect('wg_edit_charter_milestones', acronym=group.acronym)

    return render_to_response('wginfo/reset_charter_milestones.html',
                              dict(
                                  group=group,
                                  charter_milestones=charter_milestones,
                                  current_milestones=current_milestones,
                              ),
                              context_instance=RequestContext(request))
Example #50
0
File: views.py Project: mcr/ietfdb
def select(request, meeting_num):
    '''
    A screen to select which group you want to upload material for.  Users of this view area
    Secretariat staff and community (WG Chairs, ADs, etc).  Only those groups with sessions
    scheduled for the given meeting will appear in drop-downs.  For Group and IRTF selects, the
    value will be group.acronym to use in pretty URLs.  Since Training sessions have no acronym
    we'll use the session id.
    '''
    if request.method == 'POST':
        if request.POST.get('group',None):
            redirect_url = reverse('proceedings_upload_unified', kwargs={'meeting_num':meeting_num,'acronym':request.POST['group']})
            return HttpResponseRedirect(redirect_url)
        else:
            messages.error(request, 'No Group selected')

        
    meeting = get_object_or_404(Meeting, number=meeting_num)
    user = request.user
    person = user.get_profile()
    groups_session, groups_no_session = groups_by_session(user, meeting)
    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
    
    # initialize group form
    wgs = filter(lambda x: x.type_id in ('wg','ag','team'),groups_session)
    group_form = GroupSelectForm(choices=build_choices(wgs))
        
    # intialize IRTF form, only show if user is sec or irtf chair
    if has_role(user,'Secretariat') or person.role_set.filter(name__slug='chair',group__type__slug__in=('irtf','rg')):
        rgs = filter(lambda x: x.type_id == 'rg',groups_session)
        irtf_form = GroupSelectForm(choices=build_choices(rgs))
    else:
        irtf_form = None
        
    # initialize Training form, this select widget needs to have a session id, because it's
    # utilmately the session that we associate material with
    # NOTE: there are two ways to query for the groups we want, the later seems more specific
    if has_role(user,'Secretariat'):
        choices = []
        #for session in Session.objects.filter(meeting=meeting).exclude(name=""):
        for session in Session.objects.filter(meeting=meeting,timeslot__type='other').order_by('name'):
            choices.append((session.id,session.timeslot_set.all()[0].name))
        training_form = GroupSelectForm(choices=choices)
    else:
        training_form = None
    
    # iniialize plenary form
    if has_role(user,['Secretariat','IETF Chair','IAB Chair']):
        choices = []
        for session in Session.objects.filter(meeting=meeting,
                                              timeslot__type='plenary').order_by('name'):
            choices.append((session.id,session.timeslot_set.all()[0].name))
        plenary_form = GroupSelectForm(choices=choices)
    else:
        plenary_form = None
        
    # count PowerPoint files waiting to be converted
    if has_role(user,'Secretariat'):
        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()
    else:
        ppt_count = 0
        
    return render_to_response('proceedings/select.html', {
        'group_form': group_form,
        'irtf_form': irtf_form,
        'training_form': training_form,
        'plenary_form': plenary_form,
        'meeting': meeting,
        'last_run': last_run,
        'proceedings_url': proceedings_url,
        'ppt_count': ppt_count},
        RequestContext(request,{}), 
    )
Example #51
0
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.get_profile()

    if request.method == 'POST':
        form = ChangeStateForm(request.POST)
        if form.is_valid():
            clean = form.cleaned_data
            review_state = clean['review_state']
            comment = clean['comment'].rstrip()

            if comment:
                c = DocEvent(type="added_comment", doc=review, by=login)
                c.desc = comment
                c.save()

            if review_state != review.get_state():
                save_document_in_history(review)

                old_description = review.friendly_state()
                review.set_state(review_state)
                new_description = review.friendly_state()

                log_state_changed(request, review, login, new_description,
                                  old_description)

                review.time = datetime.datetime.now()
                review.save()

                if review_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('help_conflict_review_states'),
        ),
        context_instance=RequestContext(request))
Example #52
0
def change_stream(request, name):
    """Change the stream of a Document of type 'draft', notifying parties as necessary
    and logging the change as a comment."""
    doc = get_object_or_404(Document, docalias__name=name)
    if not doc.type_id == 'draft':
        raise Http404()

    if not (has_role(request.user, ("Area Director", "Secretariat")) or
            (request.user.is_authenticated() and Role.objects.filter(
                name="chair",
                group__acronym__in=StreamName.objects.values_list("slug",
                                                                  flat=True),
                person__user=request.user))):
        return HttpResponseForbidden(
            "You do not have permission to view this page")

    login = request.user.get_profile()

    if request.method == 'POST':
        form = ChangeStreamForm(request.POST)
        if form.is_valid():
            new_stream = form.cleaned_data['stream']
            comment = form.cleaned_data['comment'].strip()
            old_stream = doc.stream

            if new_stream != old_stream:
                save_document_in_history(doc)

                doc.stream = new_stream
                doc.group = Group.objects.get(type="individ")

                e = DocEvent(doc=doc, by=login, type='changed_document')
                e.desc = u"Stream changed to <b>%s</b> from %s" % (
                    new_stream, old_stream or "None")
                e.save()

                email_desc = e.desc

                if comment:
                    c = DocEvent(doc=doc, by=login, type="added_comment")
                    c.desc = comment
                    c.save()
                    email_desc += "\n" + c.desc

                doc.time = e.time
                doc.save()

                email_stream_changed(request, doc, old_stream, new_stream,
                                     email_desc)

            return HttpResponseRedirect(doc.get_absolute_url())

    else:
        stream = doc.stream
        form = ChangeStreamForm(initial=dict(stream=stream))

    return render_to_response('idrfc/change_stream.html',
                              dict(
                                  form=form,
                                  doc=doc,
                              ),
                              context_instance=RequestContext(request))
Example #53
0
def edit(request, acronym=None, action="edit"):
    """Edit or create a WG, notifying parties as
    necessary and logging changes as group events."""
    if action == "edit":
        wg = get_object_or_404(Group, acronym=acronym)
        new_wg = False
    elif action in ("create", "charter"):
        wg = None
        new_wg = True
    else:
        raise Http404

    login = request.user.get_profile()

    if request.method == 'POST':
        form = WGForm(request.POST,
                      wg=wg,
                      confirmed=request.POST.get("confirmed", False))
        if form.is_valid():
            clean = form.cleaned_data
            if new_wg:
                try:
                    wg = Group.objects.get(acronym=clean["acronym"])
                    save_group_in_history(wg)
                    wg.time = datetime.datetime.now()
                    wg.save()
                except Group.DoesNotExist:
                    wg = Group.objects.create(
                        name=clean["name"],
                        acronym=clean["acronym"],
                        type=GroupTypeName.objects.get(slug="wg"),
                        state=clean["state"])

                e = ChangeStateGroupEvent(group=wg, type="changed_state")
                e.time = wg.time
                e.by = login
                e.state_id = clean["state"].slug
                e.desc = "Group created in state %s" % clean["state"].name
                e.save()
            else:
                save_group_in_history(wg)

            if action == "charter" and not wg.charter:  # make sure we have a charter
                wg.charter = get_or_create_initial_charter(wg)

            changes = []

            def desc(attr, new, old):
                entry = "%(attr)s changed to <b>%(new)s</b> from %(old)s"
                if new_wg:
                    entry = "%(attr)s changed to <b>%(new)s</b>"

                return entry % dict(attr=attr, new=new, old=old)

            def diff(attr, name):
                v = getattr(wg, attr)
                if clean[attr] != v:
                    changes.append(desc(name, clean[attr], v))
                    setattr(wg, attr, clean[attr])

            prev_acronym = wg.acronym

            # update the attributes, keeping track of what we're doing
            diff('name', "Name")
            diff('acronym', "Acronym")
            diff('state', "State")
            diff('ad', "Shepherding AD")
            diff('parent', "IETF Area")
            diff('list_email', "Mailing list email")
            diff('list_subscribe', "Mailing list subscribe address")
            diff('list_archive', "Mailing list archive")

            if not new_wg and wg.acronym != prev_acronym and wg.charter:
                save_document_in_history(wg.charter)
                DocAlias.objects.get_or_create(
                    name="charter-ietf-%s" % wg.acronym,
                    document=wg.charter,
                )
                old = os.path.join(
                    wg.charter.get_file_path(),
                    'charter-ietf-%s-%s.txt' % (prev_acronym, wg.charter.rev))
                if os.path.exists(old):
                    new = os.path.join(
                        wg.charter.get_file_path(), 'charter-ietf-%s-%s.txt' %
                        (wg.acronym, wg.charter.rev))
                    shutil.copy(old, new)

            # update roles
            for attr, slug, title in [('chairs', 'chair', "Chairs"),
                                      ('secretaries', 'secr', "Secretaries"),
                                      ('techadv', 'techadv', "Tech Advisors")]:
                new = clean[attr]
                old = Email.objects.filter(
                    role__group=wg, role__name=slug).select_related("person")
                if set(new) != set(old):
                    changes.append(
                        desc(title, ", ".join(x.get_name() for x in new),
                             ", ".join(x.get_name() for x in old)))
                    wg.role_set.filter(name=slug).delete()
                    for e in new:
                        Role.objects.get_or_create(name_id=slug,
                                                   email=e,
                                                   group=wg,
                                                   person=e.person)

            # update urls
            new_urls = clean['urls']
            old_urls = format_urls(wg.groupurl_set.order_by('url'), ", ")
            if ", ".join(sorted(new_urls)) != old_urls:
                changes.append(
                    desc('Urls', ", ".join(sorted(new_urls)), old_urls))
                wg.groupurl_set.all().delete()
                # Add new ones
                for u in new_urls:
                    m = re.search(
                        '(?P<url>[\w\d:#@%/;$()~_?\+-=\\\.&]+)( \((?P<name>.+)\))?',
                        u)
                    if m:
                        if m.group('name'):
                            url = GroupURL(url=m.group('url'),
                                           name=m.group('name'),
                                           group=wg)
                        else:
                            url = GroupURL(url=m.group('url'),
                                           name='',
                                           group=wg)
                        url.save()

            wg.time = datetime.datetime.now()

            if changes and not new_wg:
                for c in changes:
                    GroupEvent.objects.create(group=wg,
                                              by=login,
                                              type="info_changed",
                                              desc=c)

            wg.save()

            if action == "charter":
                return redirect('charter_submit',
                                name=wg.charter.name,
                                option="initcharter")

            return redirect('wg_charter', acronym=wg.acronym)
    else:  # form.is_valid()
        if not new_wg:
            from ietf.person.forms import json_emails
            init = dict(
                name=wg.name,
                acronym=wg.acronym,
                state=wg.state,
                chairs=Email.objects.filter(role__group=wg,
                                            role__name="chair"),
                secretaries=Email.objects.filter(role__group=wg,
                                                 role__name="secr"),
                techadv=Email.objects.filter(role__group=wg,
                                             role__name="techadv"),
                ad=wg.ad_id if wg.ad else None,
                parent=wg.parent.id if wg.parent else None,
                list_email=wg.list_email if wg.list_email else None,
                list_subscribe=wg.list_subscribe
                if wg.list_subscribe else None,
                list_archive=wg.list_archive if wg.list_archive else None,
                urls=format_urls(wg.groupurl_set.all()),
            )
        else:
            init = dict(ad=login.id
                        if has_role(request.user, "Area Director") else None, )
        form = WGForm(initial=init, wg=wg)

    return render_to_response('wginfo/edit.html',
                              dict(wg=wg,
                                   form=form,
                                   action=action,
                                   user=request.user,
                                   login=login),
                              context_instance=RequestContext(request))
Example #54
0
def ballot_writeupnotesREDESIGN(request, name):
    """Editing of ballot write-up and notes"""
    doc = get_object_or_404(Document, docalias__name=name)

    login = request.user.get_profile()

    existing = doc.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text")
    if not existing:
        existing = generate_ballot_writeup(request, doc)
        
    form = BallotWriteupForm(initial=dict(ballot_writeup=existing.text))

    if request.method == 'POST' and "save_ballot_writeup" in request.POST or "issue_ballot" in request.POST:
        form = BallotWriteupForm(request.POST)
        if form.is_valid():
            t = form.cleaned_data["ballot_writeup"]
            if t != existing.text:
                e = WriteupDocEvent(doc=doc, by=login)
                e.by = login
                e.type = "changed_ballot_writeup_text"
                e.desc = "Ballot writeup was changed"
                e.text = t
                e.save()

            if "issue_ballot" in request.POST:
                create_ballot_if_not_open(doc, login, "approve")
                ballot = doc.latest_event(BallotDocEvent, type="created_ballot")

                if has_role(request.user, "Area Director") and not doc.latest_event(BallotPositionDocEvent, ad=login, ballot=ballot):
                    # sending the ballot counts as a yes
                    pos = BallotPositionDocEvent(doc=doc, 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()

                approval = doc.latest_event(WriteupDocEvent, type="changed_ballot_approval_text")
                if not approval:
                    approval = generate_approval_mail(request, doc)

                msg = generate_issue_ballot_mail(request, doc, ballot)
                send_mail_preformatted(request, msg)
                send_mail_preformatted(request, msg, extra=extra_automation_headers(doc),
                                       override={ "To": "IANA <*****@*****.**>", "CC": None, "Bcc": None , "Reply-To": None})

                e = DocEvent(doc=doc, by=login)
                e.by = login
                e.type = "sent_ballot_announcement"
                e.desc = "Ballot has been issued"
                e.save()

                return render_to_response('idrfc/ballot_issued.html',
                                          dict(doc=doc,
                                               back_url=doc.get_absolute_url()),
                                          context_instance=RequestContext(request))
                        

    need_intended_status = ""
    if not doc.intended_std_level:
        need_intended_status = doc.file_tag()

    return render_to_response('idrfc/ballot_writeupnotesREDESIGN.html',
                              dict(doc=doc,
                                   back_url=doc.get_absolute_url(),
                                   ballot_issued=bool(doc.latest_event(type="sent_ballot_announcement")),
                                   ballot_writeup_form=form,
                                   need_intended_status=need_intended_status,
                                   ),
                              context_instance=RequestContext(request))
Example #55
0
def view(request, acronym):
    '''
    This view displays the session request info
    '''
    meeting = get_meeting()
    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')

    # if there are no session requests yet, redirect to new session request page
    if not sessions:
        redirect_url = reverse('sessions_new', kwargs={'acronym': acronym})
        return HttpResponseRedirect(redirect_url)

    # 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.get_profile()):
            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',
        {
            'session': session,
            'activities': activities,
            'meeting': meeting,
            'group': group,
            'session_conflicts': session_conflicts,
            'show_approve_button': show_approve_button
        },
        RequestContext(request, {}),
    )
Example #56
0
def edit_milestones(request, acronym, milestone_set="current"):
    # milestones_set + needs_review: we have several paths into this view
    #  AD/Secr. -> all actions on current + add new
    #  group chair -> limited actions on current + add new for review
    #  (re)charter -> all actions on existing in state charter + add new in state charter
    #
    # For charters we store the history on the charter document to not confuse people.

    login = request.user.get_profile()

    group = get_object_or_404(Group, acronym=acronym)

    needs_review = False
    if not has_role(request.user, ("Area Director", "Secretariat")):
        if group.role_set.filter(name="chair", person=login):
            if milestone_set == "current":
                needs_review = True
        else:
            return HttpResponseForbidden("You are not chair of this group.")

    if milestone_set == "current":
        title = "Edit milestones for %s %s" % (group.acronym, group.type.name)
        milestones = group.groupmilestone_set.filter(state__in=("active",
                                                                "review"))
    elif milestone_set == "charter":
        title = "Edit charter milestones for %s %s" % (group.acronym,
                                                       group.type.name)
        milestones = group.groupmilestone_set.filter(state="charter")

    forms = []

    milestones_dict = dict((str(m.id), m) for m in milestones)

    def due_month_year_to_date(c):
        y = c["due_year"]
        m = c["due_month"]
        return datetime.date(y, m, calendar.monthrange(y, m)[1])

    def set_attributes_from_form(f, m):
        c = f.cleaned_data
        m.group = group
        if milestone_set == "current":
            if needs_review:
                m.state = GroupMilestoneStateName.objects.get(slug="review")
            else:
                m.state = GroupMilestoneStateName.objects.get(slug="active")
        elif milestone_set == "charter":
            m.state = GroupMilestoneStateName.objects.get(slug="charter")
        m.desc = c["desc"]
        m.due = due_month_year_to_date(c)
        m.resolved = c["resolved"]

    def save_milestone_form(f):
        c = f.cleaned_data

        if f.milestone:
            m = f.milestone

            named_milestone = 'milestone "%s"' % m.desc
            if milestone_set == "charter":
                named_milestone = "charter " + named_milestone

            if c["delete"]:
                save_milestone_in_history(m)

                m.state_id = "deleted"
                m.save()

                return 'Deleted %s' % named_milestone

            # compute changes
            history = None

            changes = ['Changed %s' % named_milestone]

            if m.state_id == "review" and not needs_review and c[
                    "accept"] != "noaction":
                if not history:
                    history = save_milestone_in_history(m)

                if c["accept"] == "accept":
                    m.state_id = "active"
                    changes.append(
                        "set state to active from review, accepting new milestone"
                    )
                elif c["accept"] == "reject":
                    m.state_id = "deleted"
                    changes.append(
                        "set state to deleted from review, rejecting new milestone"
                    )

            if c["desc"] != m.desc and not needs_review:
                if not history:
                    history = save_milestone_in_history(m)
                m.desc = c["desc"]
                changes.append('set description to "%s"' % m.desc)

            c_due = due_month_year_to_date(c)
            if c_due != m.due:
                if not history:
                    history = save_milestone_in_history(m)
                changes.append(
                    'set due date to %s from %s' %
                    (c_due.strftime("%B %Y"), m.due.strftime("%B %Y")))
                m.due = c_due

            resolved = c["resolved"]
            if resolved != m.resolved:
                if resolved and not m.resolved:
                    changes.append('resolved as "%s"' % resolved)
                elif not resolved and m.resolved:
                    changes.append("reverted to not being resolved")
                elif resolved and m.resolved:
                    changes.append('set resolution to "%s"' % resolved)

                if not history:
                    history = save_milestone_in_history(m)

                m.resolved = resolved

            new_docs = set(c["docs"])
            old_docs = set(m.docs.all())
            if new_docs != old_docs:
                added = new_docs - old_docs
                if added:
                    changes.append('added %s to milestone' %
                                   ", ".join(d.name for d in added))

                removed = old_docs - new_docs
                if removed:
                    changes.append('removed %s from milestone' %
                                   ", ".join(d.name for d in removed))

                if not history:
                    history = save_milestone_in_history(m)

                m.docs = new_docs

            if len(changes) > 1:
                m.save()

                return ", ".join(changes)

        else:  # new milestone
            m = f.milestone = GroupMilestone()
            set_attributes_from_form(f, m)
            m.save()

            m.docs = c["docs"]

            named_milestone = 'milestone "%s"' % m.desc
            if milestone_set == "charter":
                named_milestone = "charter " + named_milestone

            if m.state_id in ("active", "charter"):
                return 'Added %s, due %s' % (named_milestone,
                                             m.due.strftime("%B %Y"))
            elif m.state_id == "review":
                return 'Added %s for review, due %s' % (
                    named_milestone, m.due.strftime("%B %Y"))

    finished_milestone_text = "Done"

    form_errors = False

    if request.method == 'POST':
        # parse out individual milestone forms
        for prefix in request.POST.getlist("prefix"):
            if not prefix:  # empty form
                continue

            # new milestones have non-existing ids so instance end up as None
            instance = milestones_dict.get(
                request.POST.get(prefix + "-id", ""), None)
            f = MilestoneForm(request.POST,
                              prefix=prefix,
                              instance=instance,
                              needs_review=needs_review)
            forms.append(f)

            form_errors = form_errors or not f.is_valid()

        action = request.POST.get("action", "review")
        if action == "review":
            for f in forms:
                if not f.is_valid():
                    continue

                # let's fill in the form milestone so we can output it in the template
                if not f.milestone:
                    f.milestone = GroupMilestone()
                set_attributes_from_form(f, f.milestone)
        elif action == "save" and not form_errors:
            changes = []
            for f in forms:
                change = save_milestone_form(f)

                if not change:
                    continue

                if milestone_set == "charter":
                    DocEvent.objects.create(doc=group.charter,
                                            type="changed_charter_milestone",
                                            by=login,
                                            desc=change)
                else:
                    MilestoneGroupEvent.objects.create(
                        group=group,
                        type="changed_milestone",
                        by=login,
                        desc=change,
                        milestone=f.milestone)

                changes.append(change)

            if milestone_set == "current":
                email_milestones_changed(request, group, changes)

            if milestone_set == "charter":
                return redirect('doc_view',
                                name=group.charter.canonical_name())
            else:
                return redirect('wg_charter', acronym=group.acronym)
    else:
        for m in milestones:
            forms.append(MilestoneForm(instance=m, needs_review=needs_review))

    can_reset = milestone_set == "charter" and get_chartering_type(
        group.charter) == "rechartering"

    empty_form = MilestoneForm(needs_review=needs_review)

    forms.sort(
        key=lambda f: f.milestone.due if f.milestone else datetime.date.max)

    return render_to_response(
        'wginfo/edit_milestones.html',
        dict(group=group,
             title=title,
             forms=forms,
             form_errors=form_errors,
             empty_form=empty_form,
             milestone_set=milestone_set,
             finished_milestone_text=finished_milestone_text,
             needs_review=needs_review,
             can_reset=can_reset),
        context_instance=RequestContext(request))
Example #57
0
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':
            url = reverse('sessions_no_session',
                          kwargs={'acronym': request.POST['group']})
            return HttpResponseRedirect(url)
        else:
            redirect_url = reverse('sessions_new',
                                   kwargs={'acronym': request.POST['group']})
            return HttpResponseRedirect(redirect_url)

    meeting = get_meeting()
    scheduled_groups, unscheduled_groups = groups_by_session(
        request.user, meeting)

    # 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, {}),
    )
Example #58
0
def edit_shepherd_writeup(request, name):
    """Change this document's shepherd writeup"""
    doc = get_object_or_404(Document, type="draft", name=name)

    can_edit_stream_info = is_authorized_in_doc_stream(request.user, doc)
    can_edit_shepherd_writeup = can_edit_stream_info or user_is_person(
        request.user, doc.shepherd) or has_role(request.user,
                                                ["Area Director"])

    if not can_edit_shepherd_writeup:
        return HttpResponseForbidden(
            "You do not have the necessary permissions to view this page")

    login = request.user.get_profile()

    if request.method == 'POST':
        if "submit_response" in request.POST:
            form = ShepherdWriteupUploadForm(request.POST, request.FILES)
            if form.is_valid():

                from_file = form.cleaned_data['txt']
                if from_file:
                    writeup = from_file
                else:
                    writeup = form.cleaned_data['content']

                e = WriteupDocEvent(doc=doc,
                                    by=login,
                                    type="changed_protocol_writeup")
                e.desc = "Changed document writeup"
                e.text = writeup
                e.save()

                return HttpResponseRedirect(
                    urlreverse('doc_view', kwargs={'name': doc.name}))

        elif "reset_text" in request.POST:

            init = {
                "content":
                render_to_string("doc/shepherd_writeup.txt", dict(doc=doc))
            }
            form = ShepherdWriteupUploadForm(initial=init)

        # Protect against handcrufted malicious posts
        else:
            form = None

    else:
        form = None

    if not form:
        init = {"content": ""}

        previous_writeup = doc.latest_event(WriteupDocEvent,
                                            type="changed_protocol_writeup")
        if previous_writeup:
            init["content"] = previous_writeup.text
        else:
            init["content"] = render_to_string(
                "doc/shepherd_writeup.txt",
                dict(doc=doc),
            )
        form = ShepherdWriteupUploadForm(initial=init)

    return render_to_response('idrfc/change_shepherd_writeup.html', {
        'form': form,
        'doc': doc,
    },
                              context_instance=RequestContext(request))
Example #59
0
def edit_shepherd_writeup(request, name):
    """Change this document's shepherd writeup"""
    doc = get_object_or_404(Document, type="draft", name=name)

    can_edit_stream_info = is_authorized_in_doc_stream(request.user, doc)
    can_edit_shepherd_writeup = can_edit_stream_info or user_is_person(request.user, doc.shepherd) or has_role(request.user, ["Area Director"])

    if not can_edit_shepherd_writeup:
        return HttpResponseForbidden("You do not have the necessary permissions to view this page")

    login = request.user.get_profile()

    if request.method == 'POST':
        if "submit_response" in request.POST:
            form = ShepherdWriteupUploadForm(request.POST, request.FILES)
            if form.is_valid():
                
                from_file = form.cleaned_data['txt']
                if from_file:
                     writeup = from_file
                else:
                     writeup = form.cleaned_data['content']

                e = WriteupDocEvent(doc=doc, by=login, type="changed_protocol_writeup")
                e.desc = "Changed document writeup"
                e.text = writeup
                e.save()
            
                return HttpResponseRedirect(urlreverse('doc_view', kwargs={'name': doc.name}))

        elif "reset_text" in request.POST:

            init = { "content": render_to_string("doc/shepherd_writeup.txt",dict(doc=doc))}
            form = ShepherdWriteupUploadForm(initial=init)

        # Protect against handcrufted malicious posts
        else:
            form = None

    else:
        form = None

    if not form:
        init = { "content": ""}

        previous_writeup = doc.latest_event(WriteupDocEvent,type="changed_protocol_writeup")
        if previous_writeup:
            init["content"] = previous_writeup.text
        else:
            init["content"] = render_to_string("doc/shepherd_writeup.txt",
                                                dict(doc=doc),
                                              )
        form = ShepherdWriteupUploadForm(initial=init)

    return render_to_response('idrfc/change_shepherd_writeup.html',
                              {'form': form,
                               'doc' : doc,
                              },
                              context_instance=RequestContext(request))