Exemplo n.º 1
0
def application_unauthenticated(request, token, state=None, label=None):
    """ An unauthenticated user is trying to access an application. """
    application = base.get_application(secret_token=token, expires__gt=datetime.datetime.now())

    # redirect user to real url if possible.
    if request.user.is_authenticated():
        if request.user == application.applicant:
            url = base.get_url(request, application, {"is_applicant": True}, label)
            return HttpResponseRedirect(url)

    state_machine = base.get_state_machine(application)
    return state_machine.process(request, application, state, label, {"is_applicant": True})
Exemplo n.º 2
0
def invitation_token(request, token, state=None, label=None):
    """An authenticated user is trying to access an application using
    a token."""
    application = base.get_application(
        secret_token=token, expires__gt=datetime.datetime.now())

    # If the applicant is a real Person, don't allow the application
    # to be stolen.
    if application.content_type.model != 'applicant':
        return redirect('index')

    # redirect user to real url if possible.
    if request.user.is_authenticated():
        if request.user == application.applicant:
            url = base.get_url(request, application, {'is_applicant': True},
                               label)
            return HttpResponseRedirect(url)

    state_machine = base.get_state_machine(application)
    return state_machine.process(request, application, state, label,
                                 {'is_applicant': True})
Exemplo n.º 3
0
    def view(self, request, application, label, auth, actions):
        """ Process the view request at the current step. """

        # if the user is not the applicant, the steps don't apply.
        if not auth['is_applicant'] or auth['is_admin']:
            return super(StateWithSteps, self).view(request, application, label, auth, actions)

        # was label supplied?
        if label is None:
            # no label given, find first step and redirect to it.
            this_id = self._order[0]
            url = base.get_url(request, application, auth, this_id)
            return HttpResponseRedirect(url)
        else:
            # label was given, get the step position and id for it
            this_id = label
            if this_id not in self._steps:
                return HttpResponseBadRequest("<h1>Bad Request</h1>")
            position = self._order.index(this_id)

        # get the step given the label
        this_step =  self._steps[this_id]

        # define list of allowed actions for step
        step_actions = {}
        if 'cancel' in actions:
            step_actions['cancel'] = "state:cancel"
        if 'submit' in actions and position == len(self._order)-1:
            step_actions['submit'] = "state:submit"
        if position > 0:
            step_actions['prev'] = self._order[position-1]
        if position < len(self._order)-1:
            step_actions['next'] = self._order[position+1]

        # process the request
        if request.method == "GET":
            # if GET request, state changes are not allowed
            response = this_step.view(
                    request, application, this_id, auth, step_actions.keys())
            assert isinstance(response, HttpResponse)
            return response
        elif request.method == "POST":
            # if POST request, state changes are allowed
            response = this_step.view(
                    request, application, this_id, auth, step_actions.keys())
            assert response is not None

            # If it was a HttpResponse, just return it
            if isinstance(response, HttpResponse):
                return response
            else:
                # try to lookup the response
                if response not in step_actions:
                    raise RuntimeError(
                            "Invalid response '%s' from step '%s'" %
                            (response, this_step))
                action = step_actions[response]

                # process the required action
                if action.startswith("state:"):
                    return action[6:]
                else:
                    url = base.get_url(request, application, auth, action)
                    return HttpResponseRedirect(url)

        # We only understand GET or POST requests
        else:
            return HttpResponseBadRequest("<h1>Bad Request</h1>")

        # If we get this far, something went wrong.
        assert False
Exemplo n.º 4
0
    def view(self, request, application, label, auth, actions):
        """ Process the view request at the current step. """

        # if user is logged and and not applicant, steal the
        # application
        if auth['is_applicant']:
            # if we got this far, then we either we are logged in as applicant, or
            # we know the secret for this application.

            new_person = None

            attrs, _ = saml.parse_attributes(request)
            saml_id = attrs['persistent_id']
            if saml_id is not None:
                query = Person.objects.filter(saml_id=saml_id)
                if query.content_type.model == "person":
                    query = query.exclude(pk=application.applicant.pk)
                if query.count() > 0:
                    new_person = Person.objects.get(saml_id=saml_id)
                    reason = "SAML id is already in use by existing person."
                    details = ("It is not possible to continue this application " +
                        "as is because the saml identity already exists " +
                        "as a registered user.")
                del query

            if request.user.is_authenticated():
                new_person = request.user
                reason = "%s was logged in and accessed the secret URL." % new_person
                details = ("If you want to access this application "+
                    "as %s " % application.applicant +
                    "without %s stealing it, " % new_person +
                    "you will have to ensure %s is " % new_person +
                    "logged out first.")

            if new_person is not None:
                if application.applicant != new_person:
                    if 'steal' in request.POST:
                        old_applicant = application.applicant
                        application.applicant = new_person
                        application.save()
                        log(request.user, application.application_ptr,
                                1, "Stolen application from %s", old_applicant)
                        messages.success(
                                request,
                                "Stolen application from %s", old_applicant)
                        url = base.get_url(request, application, auth, label)
                        return HttpResponseRedirect(url)
                    else:
                        return render_to_response(
                                'applications/project_aed_steal.html',
                                {'application': application, 'person': new_person,
                                    'reason': reason, 'details': details, },
                                context_instance=RequestContext(request))

        # if the user is the leader, show him the leader specific page.
        if (auth['is_leader'] or auth['is_delegate']) and not auth['is_admin'] and not auth['is_applicant']:
            actions = ['reopen']
            if 'reopen' in request.POST:
                return 'reopen'
            return render_to_response(
                    'applications/project_aed_for_leader.html',
                    {'application': application, 'actions': actions, 'auth': auth, },
                    context_instance=RequestContext(request))

        # otherwise do the default behaviour for StateWithSteps
        return super(StateApplicantEnteringDetails, self).view(request, application, label, auth, actions)
Exemplo n.º 5
0
    def view(self, request, application, label, auth, actions):
        """ Django view method. """
        status = None
        applicant = application.applicant
        attrs = []

        saml_session = saml.is_saml_session(request)

        # certain actions are supported regardless of what else happens
        if 'cancel' in request.POST:
            return "cancel"
        if 'prev' in request.POST:
            return 'prev'

        # test for conditions where shibboleth registration not required
        if applicant.saml_id is not None:
            status = "You have already registered a shibboleth id."
            form = None
            done = True

        elif application.content_type.model != 'applicant':
            status = "You are already registered in the system."
            form = None
            done = True

        elif (applicant.institute is not None and
                applicant.institute.saml_entityid is None):
            status = "Your institute does not have shibboleth registered."
            form = None
            done = True

        elif Institute.objects.filter(saml_entityid__isnull=False).count() == 0:
            status = "No institutes support shibboleth here."
            form = None
            done = True

        else:
            # shibboleth registration is required

            # Do construct the form
            form = saml.SAMLInstituteForm(request.POST or None,
                    initial = {'institute': applicant.institute})
            done = False
            status = None

            # Was it a POST request?
            if request.method == 'POST':

                # Did the login form get posted?
                if 'login' in request.POST and form.is_valid():
                    institute = form.cleaned_data['institute']
                    applicant.institute = institute
                    applicant.save()
                    # We do not set application.insitute here, that happens
                    # when application, if it is a ProjectApplication, is
                    # submitted

                    # if institute supports shibboleth, redirect back here via
                    # shibboleth, otherwise redirect directly back he.
                    url = base.get_url(request, application, auth, label)
                    if institute.saml_entityid is not None:
                        url = saml.build_shib_url(
                                request, url, institute.saml_entityid)
                    return HttpResponseRedirect(url)

                # Did we get a register request?
                elif 'register' in request.POST:
                    if saml_session:
                        applicant = _get_applicant_from_saml(request)
                        if applicant is not None:
                            application.applicant = applicant
                            application.save()
                        else:
                            applicant = application.applicant

                        applicant = saml.add_saml_data(
                                applicant, request)
                        applicant.save()

                        url = base.get_url(request, application, auth, label)
                        return HttpResponseRedirect(url)
                    else:
                        return HttpResponseBadRequest("<h1>Bad Request</h1>")

                # Did we get a logout request?
                elif 'logout' in request.POST:
                    if saml_session:
                        url = saml.logout_url(request)
                        return HttpResponseRedirect(url)
                    else:
                        return HttpResponseBadRequest("<h1>Bad Request</h1>")

            # did we get a shib session yet?
            if saml_session:
                attrs, _ = saml.parse_attributes(request)
                saml_session = True


        # if we are done, we can proceed to next state
        if request.method == 'POST':
            if done:
                for action in actions:
                    if action in request.POST:
                        return action
                return HttpResponseBadRequest("<h1>Bad Request</h1>")
            else:
                status = "Please register with Shibboleth before proceeding."

        # render the page
        return render_to_response(
                'applications/project_aed_shibboleth.html',
                {'form': form, 'done': done, 'status': status,
                    'actions': actions, 'auth': auth, 'application': application,
                    'attrs': attrs, 'saml_session': saml_session,},
                context_instance=RequestContext(request))