Example #1
0
def saml_details(request):
    redirect_to = reverse('saml_details')
    saml_session = saml.is_saml_session(request)

    if request.method == 'POST':
        if 'login' in request.POST:
            if request.user.is_authenticated():
                person = request.user
                institute = person.institute
                if institute.saml_entityid:
                    redirect_to = reverse("saml_details")
                    url = saml.build_shib_url(request, redirect_to,
                            institute.saml_entityid)
                    return HttpResponseRedirect(url)
                else:
                    return HttpResponseBadRequest("<h1>Bad Request</h1>")
            else:
                return HttpResponseBadRequest("<h1>Bad Request</h1>")

        elif 'register' in request.POST:
            if request.user.is_authenticated() and saml_session:
                person = request.user
                person = saml.add_saml_data(
                        person, request)
                person.save()
                url = reverse("saml_details")
                return HttpResponseRedirect(url)
            else:
                return HttpResponseBadRequest("<h1>Bad Request</h1>")

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

        else:
            return HttpResponseBadRequest("<h1>Bad Request</h1>")


    attrs = {}
    if saml_session:
        attrs, _ = saml.parse_attributes(request)
        saml_session = True

    person = None
    if request.user.is_authenticated():
        person = request.user

    return render_to_response('people/saml_detail.html',
            {'attrs': attrs, 'saml_session': saml_session,
                'person': person, },
            context_instance=RequestContext(request))
Example #2
0
def new_application(request):
    """ A new application by a user to start a new project. """
    # Note default kgapplications/index.html will display error if user logged
    # in.
    if not settings.ALLOW_REGISTRATIONS:
        return render(
            template_name='kgapplications/project_common_disabled.html',
            context={},
            request=request)

    roles = {'is_applicant', 'is_authorised'}

    if not request.user.is_authenticated():
        attrs, _ = saml.parse_attributes(request)
        defaults = {'email': attrs['email']}
        form = forms.UnauthenticatedInviteUserApplicationForm(
            request.POST or None, initial=defaults)
        if request.method == 'POST':
            if form.is_valid():
                email = form.cleaned_data['email']
                applicant, existing_person = get_applicant_from_email(email)
                assert not existing_person

                application = ProjectApplication()
                application.applicant = applicant
                application.save()

                state_machine = get_application_state_machine()
                state_machine.start(request, application, roles)
                # we do not show unauthenticated users the application at this
                # stage.
                url = reverse('index')
                return HttpResponseRedirect(url)
        return render(
            template_name='kgapplications/'
            'project_common_invite_unauthenticated.html',
            context={'form': form, },
            request=request)
    else:
        if request.method == 'POST':
            person = request.user

            application = ProjectApplication()
            application.applicant = person
            application.save()

            state_machine = get_application_state_machine()
            response = state_machine.start(request, application, roles)
            return response
        return render(
            template_name='kgapplications/'
            'project_common_invite_authenticated.html',
            context={},
            request=request)
Example #3
0
def saml_details(request):
    redirect_to = reverse('kg_profile_saml')
    saml_session = saml.is_saml_session(request)

    if request.method == 'POST':
        if 'login' in request.POST:
            if request.user.is_authenticated:
                person = request.user
                institute = person.institute
                if institute.saml_entityid:
                    url = saml.build_shib_url(
                        request, redirect_to,
                        institute.saml_entityid)
                    return HttpResponseRedirect(url)
                else:
                    return HttpResponseBadRequest("<h1>Bad Request</h1>")
            else:
                return HttpResponseBadRequest("<h1>Bad Request</h1>")

        elif 'register' in request.POST:
            if request.user.is_authenticated and saml_session:
                person = request.user
                person = saml.add_saml_data(
                    person, request)
                person.save()
                return HttpResponseRedirect(redirect_to)
            else:
                return HttpResponseBadRequest("<h1>Bad Request</h1>")

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

        else:
            return HttpResponseBadRequest("<h1>Bad Request</h1>")

    attrs = {}
    if saml_session:
        attrs, _ = saml.parse_attributes(request)
        saml_session = True

    person = None
    if request.user.is_authenticated:
        person = request.user

    return render(
        template_name='karaage/people/profile_saml.html',
        context={
            'attrs': attrs, 'saml_session': saml_session, 'person': person, },
        request=request)
def saml_login(request):
    redirect_to = reverse('index')
    if 'next' in request.GET:
        redirect_to = request.GET['next']
    error = None
    saml_session = saml.is_saml_session(request)

    form = saml.SAMLInstituteForm(request.POST or None)
    if request.method == 'POST':
        if 'login' in request.POST and form.is_valid():
            institute = form.cleaned_data['institute']
            url = saml.build_shib_url(
                request, redirect_to,
                institute.saml_entityid)
            return HttpResponseRedirect(url)
        elif 'logout' in request.POST:
            if saml_session:
                url = saml.logout_url(request)
                return HttpResponseRedirect(url)
            else:
                return HttpResponseBadRequest("<h1>Bad Request</h1>")
        else:
            return HttpResponseBadRequest("<h1>Bad Request</h1>")
    elif request.user.is_authenticated():
        error = "You are already logged in."
    elif saml_session:
        attrs, error = saml.parse_attributes(request)
        saml_id = attrs['persistent_id']
        try:
            Person.objects.get(saml_id=saml_id)
            # This should not happen, suggests a fault in the saml middleware
            error = "Shibboleth session established " \
                    "but you did not get logged in. "
        except Person.DoesNotExist:
            email = attrs['email']
            try:
                Person.objects.get(email=email)
                error = "Cannot log in with this shibboleth account. " \
                        "Please try using the Karaage login instead."
            except Person.DoesNotExist:
                if apps.is_installed("karaage.plugins.kgapplications"):
                    app_url = reverse('kg_application_new')
                    return HttpResponseRedirect(app_url)
                else:
                    error = "Cannot log in with shibboleth as " \
                            "we do not recognise your shibboleth id."

    return render(
        template_name='karaage/people/profile_login_saml.html',
        context={'form': form, 'error': error, 'saml_session': saml_session, },
        request=request)
Example #5
0
def _get_applicant_from_saml(request):
    attrs, _ = saml.parse_attributes(request)
    saml_id = attrs['persistent_id']
    try:
        return Person.objects.get(saml_id=saml_id)
    except Person.DoesNotExist:
        pass

    try:
        return Applicant.objects.get(saml_id=saml_id)
    except Applicant.DoesNotExist:
        pass

    return None
Example #6
0
    def process_request(self, request):
        # AuthenticationMiddleware is required so that request.user exists.
        if not hasattr(request, 'user'):
            raise ImproperlyConfigured(
                "The Django SAML user auth middleware requires the"
                " authentication middleware to be installed.  Edit your"
                " MIDDLEWARE_CLASSES setting to insert"
                " 'django.contrib.auth.middleware.AuthenticationMiddleware'"
                " before the SamlUserMiddleware class.")

        # If the user is already authenticated and that user is the user we are
        # getting passed in the headers, then the correct user is already
        # persisted in the session and we don't need to continue.
        if request.user.is_authenticated:
            return

        # Is this a shib session?
        if not saml.is_saml_session(request):
            return

        # Can we get the shib attributes we need?
        attrs, error = saml.parse_attributes(request)
        if error:
            return render(template_name='saml_error.html',
                          context={'shib_attrs': attrs},
                          request=request)

        # What is our persistent_id?
        saml_id = attrs['persistent_id']
        assert saml_id

        # We are seeing this user for the first time in this session, attempt
        # to authenticate the user.
        try:
            person = Person.objects.get(saml_id=saml_id)
        except Person.DoesNotExist:
            return

        # User is valid.  Set request.user and persist user in the session
        # by logging the user in.
        request.user = person
        # We must set the model backend here manually as we skip
        # the call to auth.authenticate().
        request.user.backend = 'django.contrib.auth.backends.ModelBackend'
        auth.login(request, person)
Example #7
0
def saml_login(request):
    redirect_to = reverse('kg_profile_login_saml')
    if 'next' in request.REQUEST:
        redirect_to = request.REQUEST['next']
    error = None
    saml_session = saml.is_saml_session(request)

    form = saml.SAMLInstituteForm(request.POST or None)
    if request.method == 'POST':
        if 'login' in request.POST and form.is_valid():
            institute = form.cleaned_data['institute']
            url = saml.build_shib_url(
                request, redirect_to,
                institute.saml_entityid)
            return HttpResponseRedirect(url)
        elif 'logout' in request.POST:
            if saml_session:
                url = saml.logout_url(request)
                return HttpResponseRedirect(url)
            else:
                return HttpResponseBadRequest("<h1>Bad Request</h1>")
        else:
            return HttpResponseBadRequest("<h1>Bad Request</h1>")
    elif request.user.is_authenticated():
# JH fix the bug
        return HttpResponseRedirect(redirect_to)
#        error = "You are already logged in."
    elif saml_session:
        attrs, error = saml.parse_attributes(request)
        saml_id = attrs['persistent_id']
        try:
            Person.objects.get(saml_id=saml_id)
            error = "Shibboleth session established " \
                    "but you did not get logged in."
        except Person.DoesNotExist:
            error = "Cannot log in with shibboleth as " \
                    "we do not know your shibboleth id."

    return render_to_response(
        'karaage/people/profile_login_saml.html',
        {'form': form, 'error': error, 'saml_session': saml_session, },
        context_instance=RequestContext(request))
Example #8
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)
Example #9
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))
Example #10
0
    def view(self, request, application, label, roles, actions):
        """ Process the view request at the current step. """

        # if user is logged and and not applicant, steal the
        # application
        if 'is_applicant' in roles:
            # 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 application.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.change(
                            application.application_ptr,
                            "Stolen application from %s" % old_applicant)
                        messages.success(
                            request,
                            "Stolen application from %s" % old_applicant)
                        url = base.get_url(request, application, roles, label)
                        return HttpResponseRedirect(url)
                    else:
                        return render_to_response(
                            'kgapplications/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 ('is_leader' in roles or 'is_delegate' in roles) \
                and 'is_admin' not in roles \
                and 'is_applicant' not in roles:
            actions = ['reopen']
            if 'reopen' in request.POST:
                return 'reopen'
            return render_to_response(
                'kgapplications/project_aed_for_leader.html', {
                    'application': application,
                    'actions': actions,
                    'roles': roles,
                },
                context_instance=RequestContext(request))

        # otherwise do the default behaviour for StateWithSteps
        return super(StateApplicantEnteringDetails, self) \
            .view(request, application, label, roles, actions)
Example #11
0
    def view(self, request, application, label, roles, 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, roles, 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, roles, 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('kgapplications/project_aed_shibboleth.html',
                                  {
                                      'form': form,
                                      'done': done,
                                      'status': status,
                                      'actions': actions,
                                      'roles': roles,
                                      'application': application,
                                      'attrs': attrs,
                                      'saml_session': saml_session,
                                  },
                                  context_instance=RequestContext(request))
    def view(self, request, application, label, roles, actions):
        """ Process the view request at the current step. """

        # if user is logged and and not applicant, steal the
        # application
        if "is_applicant" in roles:
            # 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 application.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.change(application.application_ptr, "Stolen application from %s" % old_applicant)
                        messages.success(request, "Stolen application from %s" % old_applicant)
                        url = base.get_url(request, application, roles, label)
                        return HttpResponseRedirect(url)
                    else:
                        return render_to_response(
                            "kgapplications/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 ("is_leader" in roles or "is_delegate" in roles) and "is_admin" not in roles and "is_applicant" not in roles:
            actions = ["reopen"]
            if "reopen" in request.POST:
                return "reopen"
            return render_to_response(
                "kgapplications/project_aed_for_leader.html",
                {"application": application, "actions": actions, "roles": roles},
                context_instance=RequestContext(request),
            )

        # otherwise do the default behaviour for StateWithSteps
        return super(StateApplicantEnteringDetails, self).view(request, application, label, roles, actions)
Example #13
0
def new_application(request):
    """ A new application by a user to start a new project. """
    # Note default kgapplications/index.html will display error if user logged
    # in.
    if not settings.ALLOW_REGISTRATIONS:
        return render(
            template_name='kgapplications/project_common_disabled.html',
            context={},
            request=request)

    roles = {'is_applicant', 'is_authorised'}

    if not request.user.is_authenticated:
        attrs, _ = saml.parse_attributes(request)
        defaults = {'email': attrs['email']}
        form = forms.UnauthenticatedInviteUserApplicationForm(request.POST
                                                              or None,
                                                              initial=defaults)
        if request.method == 'POST':
            if form.is_valid():
                email = form.cleaned_data['email']
                applicant, existing_person = get_applicant_from_email(email)

                # If applicant is None then there were multiple persons found.
                # This should never happen as the
                # UnauthenticatedInviteUserApplicationForm form disallows
                # existing users applying unauthenticated.
                assert applicant is not None
                # Similarly existing_person should always be False here.
                assert not existing_person

                application = ProjectApplication()
                application.applicant = applicant
                application.save()

                state_machine = get_application_state_machine()
                state_machine.start(request, application, roles)
                # we do not show unauthenticated users the application at this
                # stage.
                url = reverse('index')
                return HttpResponseRedirect(url)
        return render(template_name='kgapplications/'
                      'project_common_invite_unauthenticated.html',
                      context={
                          'form': form,
                      },
                      request=request)
    else:
        if request.method == 'POST':
            person = request.user

            application = ProjectApplication()
            application.applicant = person
            application.save()

            state_machine = get_application_state_machine()
            response = state_machine.start(request, application, roles)
            return response
        return render(template_name='kgapplications/'
                      'project_common_invite_authenticated.html',
                      context={},
                      request=request)