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})
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})
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
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)
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))