def login_begin(request, attribute_set='default'): """Begin an MojeID login request.""" if mojeid_settings.MOJEID_SESSION_NEXT_PAGE_ATTR in request.session: del request.session[mojeid_settings.MOJEID_SESSION_NEXT_PAGE_ATTR] # create consumer, start login process consumer = MojeIDConsumer(DjangoOpenIDStore()) openid_request = consumer.begin(create_service()) # Request user details. attributes = get_attribute_query(attribute_set) # save settings set name for response handler request.session[SESSION_ATTR_SET_KEY] = attribute_set fetch_request = ax.FetchRequest() for attribute, required in attributes: fetch_request.add(attribute.generate_ax_attrinfo(required)) if attributes: openid_request.addExtension(fetch_request) if mojeid_settings.MOJEID_LOGIN_METHOD != 'ANY' or \ mojeid_settings.MOJEID_MAX_AUTH_AGE is not None: # set authentication method to OTP or CERT if mojeid_settings.MOJEID_LOGIN_METHOD == "OTP": auth_method = [pape.AUTH_MULTI_FACTOR] elif mojeid_settings.MOJEID_LOGIN_METHOD == "CERT": auth_method = [pape.AUTH_PHISHING_RESISTANT] else: auth_method = None pape_request = pape.Request( preferred_auth_policies=auth_method, max_auth_age=mojeid_settings.MOJEID_MAX_AUTH_AGE, ) openid_request.addExtension(pape_request) # Construct the request completion URL return_to = request.build_absolute_uri(reverse(login_complete)) # get 'next page' and save it to the session redirect_to = sanitise_redirect_url(OpenIDBackend.get_redirect_to(request)) if redirect_to: request.session[mojeid_settings.MOJEID_SESSION_NEXT_PAGE_ATTR] = redirect_to # Realm should be always something like 'https://example.org/openid/' realm = getattr(settings, 'MOJEID_REALM', None) if not realm: realm = request.build_absolute_uri(reverse(top)) # we always use POST request form_html = openid_request.htmlMarkup( realm, return_to, form_tag_attrs={'id': 'openid_message'}) return HttpResponse(form_html, content_type='text/html; charset=UTF-8')
def cleanup_associations(self, request, queryset): store = DjangoOpenIDStore() count = store.cleanupAssociations() self.message_user(request, _("%d expired associations removed") % count)
def cleanup_nonces(self, request, queryset): store = DjangoOpenIDStore() count = store.cleanupNonces() self.message_user(request, _("%d expired nonces removed") % count)
def handle_noargs(self, **options): store = DjangoOpenIDStore() store.cleanup()
def login_complete(request): # Get addres where to redirect after the login redirect_to = sanitise_redirect_url( request.session.get(mojeid_settings.MOJEID_SESSION_NEXT_PAGE_ATTR)) attribute_set = request.session.get(SESSION_ATTR_SET_KEY, 'default') # clean the session if mojeid_settings.MOJEID_SESSION_NEXT_PAGE_ATTR in request.session: del request.session[mojeid_settings.MOJEID_SESSION_NEXT_PAGE_ATTR] if SESSION_ATTR_SET_KEY in request.session: del request.session[SESSION_ATTR_SET_KEY] # Get OpenID response and test whether it is valid endpoint = create_service() message = Message.fromPostArgs(request.REQUEST) consumer = MojeIDConsumer(DjangoOpenIDStore()) try: openid_response = consumer.complete( message, endpoint, request.build_absolute_uri()) except HTTPFetchingError: # if not using association and can't contact MojeID server return render_failure(request, errors.EndpointError()) # Check whether the user is already logged in user_orig = OpenIDBackend.get_user_from_request(request) user_model = get_user_model() if openid_response.status == SUCCESS: try: if user_orig: # Send a signal to obtain HttpResponse resp = associate_user.send( sender=__name__, request=request, openid_response=openid_response, attribute_set=attribute_set, redirect=redirect_to ) resp = [r[1] for r in resp if isinstance(r[1], HttpResponse)] if resp: # Return first valid response return resp[0] # Create association with currently logged in user OpenIDBackend.associate_openid_response(user_orig, openid_response) else: # Authenticate mojeID user. # Send a signal to obtain HttpResponse resp = authenticate_user.send( sender=__name__, request=request, openid_response=openid_response, attribute_set=attribute_set, redirect=redirect_to ) resp = [r[1] for r in resp if isinstance(r[1], HttpResponse)] if resp: # Return first valid response return resp[0] # Perform a default action user_new = OpenIDBackend.authenticate_using_all_backends( openid_response=openid_response, attribute_set=attribute_set) if not user_new: # Failed to create a user return render_failure(request, errors.UnknownUser()) if not OpenIDBackend.is_user_active(user_new): # user is deactivated return render_failure(request, errors.DisabledAccount(user_new)) # Create an association with the new user OpenIDBackend.associate_user_with_session(request, user_new) except DjangoOpenIDException as e: # Something went wrong user_id = None try: # Try to get user id user_id = UserOpenID.objects.get(claimed_id=openid_response.identity_url).user_id except (UserOpenID.DoesNotExist, user_model.DoesNotExist): # Report an error with identity_url user_login_report.send( sender=__name__, request=request, username=openid_response.identity_url, method='openid', success=False ) # Report an error with the username user_login_report.send( sender=__name__, request=request, username=openid_response.identity_url, user_id=user_id, method='openid', success=False ) # Render the failure page return render_failure(request, errors.AuthenticationFailed(e)) response = HttpResponseRedirect(redirect_to) # Send signal to log the successful login attempt user_login_report.send( sender=__name__, request=request, user_id=user_orig.id if user_orig else user_new.id, method='openid', success=True ) return response # Render other failures elif openid_response.status == FAILURE: user_login_report.send( sender=__name__, request=request, username=openid_response.identity_url, method='openid', success=False ) return render_failure(request, errors.OpenIDAuthenticationFailed(openid_response)) elif openid_response.status == CANCEL: user_login_report.send( sender=__name__, request=request, username=openid_response.identity_url, method='openid', success=False ) return render_failure(request, errors.OpenIDAuthenticationCanceled()) else: user_login_report.send( sender=__name__, request=request, username=openid_response.identity_url, method='openid', success=False ) return render_failure(request, errors.OpenIDUnknownResponseType(openid_response))
def make_consumer(request): """Create an OpenID Consumer object for the given Django request.""" # Give the OpenID library its own space in the session object. session = request.session.setdefault('OPENID', {}) store = DjangoOpenIDStore() return Consumer(session, store)