def test_invalid_institutional_identity_provider(self): with self.assertRaises(InvalidInstitutionalIndentityProvider) as e: Institution.is_valid_identity_provider( 'https://idp.invalid-identity-provider.ac.uk/shibboleth' ) self.assertEqual( str(e.exception), 'Identity provider is not supported.' )
def test_valid_institutional_identity_provider(self): self.assertTrue( Institution.is_valid_identity_provider( 'https://idp.bangor.ac.uk/shibboleth'))
def process_request(self, request): # The identity of external collaborators is managed within the django application. # Therefore, exclude the external collaborator login form from the SCW Remote User # Middleware. if request.path.startswith(reverse('external-login')): return # AuthenticationMiddleware is required so that request.user exists. if not hasattr(request, 'user'): raise ImproperlyConfigured( "The Django remote user auth middleware requires the authentication middleware to " " be installed. Edit your MIDDLEWARE setting to insert " "'django.contrib.auth.middleware.AuthenticationMiddleware' " "before the RemoteUserMiddleware class.") # Prevent the user from logging in if the django application requires the user to # reauthenticate with their shibboleth identity provider. # This will require the user to close their browser. if request.session.get( settings.SHIBBOLETH_FORCE_REAUTH_SESSION_KEY) == True: return # Locate the required headers. try: username = request.META[self.header] identity_provider = request.META['Shib-Identity-Provider'] except KeyError: # If the required headers do not exist then return, leaving request.user set to # AnonymousUser by the AuthenticationMiddleware. return # If we got an empty value for REMOTE USER header, it's an anonymous user. if not username: if self.force_logout_if_no_header and request.user.is_authenticated: self._remove_invalid_user(request) return # Ensure the Shib-Identity-Provider is supported / valid. try: Institution.is_valid_identity_provider(identity_provider) except InvalidIndentityProvider: return # The REMOTE USER header may return the authenticated user's email address or username. email_regex = r'(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)' if not re.match(email_regex, username): # Must append the institutions base domain to the username. institution = Institution.objects.get( identity_provider=identity_provider) username = '******'.join([username, institution.base_domain]) # 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: if request.user.username == self.clean_username(username, request): return else: self._remove_invalid_user(request) # Make sure we have all required Shibboleth elements before proceeding. shib_meta, error = ShibbolethRemoteUserMiddleware.parse_attributes( request) # Add parsed attributes to the session. request.session['shib'] = shib_meta request.session['shib']['username'] = username # Override if error: raise ShibbolethValidationError( 'All required Shibboleth elements not found. %s' % shib_meta) # We are seeing this user for the first time in this session, attempt to authenticate # the user. user = auth.authenticate(remote_user=username, shib_meta=shib_meta) if user: # Set request.user and persist user in the session by logging the user in. request.user = user auth.login(request, user) else: # Redirect the user to apply for an account. url_name = resolve(request.path_info).url_name if url_name != 'register': return HttpResponseRedirect(reverse('register'))