Exemple #1
0
 def decorator(request, *args, **kwargs):
     # Do nothing if the remoteuser backend isn't activated
     if (('shibboleth.backends.ShibbolethRemoteUserBackend'
          not in settings.AUTHENTICATION_BACKENDS)):
         pass
     else:
         shib = ShibbolethRemoteUserMiddleware()
         # Process the request with the Shib middlemare,
         # which will log the user in if we can.
         shib.process_request(request)
     return func(request, *args, **kwargs)
Exemple #2
0
    def setUp(self):
        self.remove_user('*****@*****.**')

        self.middleware = ShibbolethRemoteUserMiddleware()
        self.factory = RequestFactory()
        # Create an instance of a GET request.
        self.request = self.factory.get('/foo/')

        self.request.user = self.user
        self.request.user.is_authenticated = lambda: False
        self.request.cloud_mode = False
        self.request.session = self.client.session

        self.request.META = {}
        self.request.META['Shibboleth-eppn'] = '*****@*****.**'
        self.request.META['REMOTE_USER'] = '******'
        self.request.META['givenname'] = 'test_gname'
        self.request.META['surname'] = 'test_sname'
Exemple #3
0
    def test_get_role_by_affiliation(self):
        obj = ShibbolethRemoteUserMiddleware()

        assert obj._get_role_by_affiliation('*****@*****.**') == 'staff'
        assert obj._get_role_by_affiliation('*****@*****.**') == 'staff'
        assert obj._get_role_by_affiliation('*****@*****.**') == 'student'

        # test jokers
        assert obj._get_role_by_affiliation('*****@*****.**') == 'student'
        assert obj._get_role_by_affiliation('*****@*****.**') == 'aaa'
        assert obj._get_role_by_affiliation('*****@*****.**') == 'guest'
Exemple #4
0
    def setUp(self):
        self.remove_user('*****@*****.**')

        self.middleware = ShibbolethRemoteUserMiddleware()
        self.factory = RequestFactory()
        # Create an instance of a GET request.
        self.request = self.factory.get('/sso/')

        self.request.user = self.user
        self.request.user.is_authenticated = lambda: False
        self.request.cloud_mode = False
        self.request.session = self.client.session

        self.request.META = {}
        self.request.META['Shibboleth-eppn'] = '*****@*****.**'
        self.request.META['REMOTE_USER'] = '******'
        self.request.META['givenname'] = 'test_gname'
        self.request.META['surname'] = 'test_sname'
        self.request.META['Shibboleth-displayName'] = 'Sample Developer'
        self.request.META['Shibboleth-affiliation'] = '[email protected];[email protected];[email protected];[email protected]'

        # default settings
        assert getattr(settings, 'SHIB_ACTIVATE_AFTER_CREATION', True) is True
Exemple #5
0
    def setUp(self):
        self.middleware = ShibbolethRemoteUserMiddleware()

        self.factory = RequestFactory()

        # Create an instance of a GET request.
        self.request = self.factory.get('/foo/')
        # self.request = Mock()

        self.request.user = self.user
        self.request.user.is_authenticated = lambda: False
        self.request.cloud_mode = False
        self.request.session = {}

        self.request.META = {}
        self.request.META['REMOTE_USER'] = self.user.username
        self.request.META['eppn'] = 'test eppn'
        self.request.META['givenname'] = 'test_gname'
        self.request.META['surname'] = 'test_sname'
    def setUp(self):
        self.remove_user('*****@*****.**')

        self.middleware = ShibbolethRemoteUserMiddleware()
        self.factory = RequestFactory()
        # Create an instance of a GET request.
        self.request = self.factory.get('/foo/')

        self.request.user = self.user
        self.request.user.is_authenticated = lambda: False
        self.request.cloud_mode = False
        self.request.session = self.client.session

        self.request.META = {}
        self.request.META['Shibboleth-eppn'] = '*****@*****.**'
        self.request.META['REMOTE_USER'] = '******'
        self.request.META['givenname'] = 'test_gname'
        self.request.META['surname'] = 'test_sname'

        # default settings
        assert getattr(settings, 'SHIB_ACTIVATE_AFTER_CREATION', True) is True
 def test_inheritance_middleware(self):
     from shibboleth.middleware import ShibbolethRemoteUserMiddleware
     middleware = ShibbolethRemoteUserMiddleware()
     assert hasattr(middleware, "_remove_invalid_user")
     assert hasattr(middleware, "clean_username")
class ShibbolethRemoteUserMiddlewareTest(BaseTestCase):
    def setUp(self):
        self.remove_user('*****@*****.**')

        self.middleware = ShibbolethRemoteUserMiddleware()
        self.factory = RequestFactory()
        # Create an instance of a GET request.
        self.request = self.factory.get('/foo/')

        self.request.user = self.user
        self.request.user.is_authenticated = lambda: False
        self.request.cloud_mode = False
        self.request.session = self.client.session

        self.request.META = {}
        self.request.META['Shibboleth-eppn'] = '*****@*****.**'
        self.request.META['REMOTE_USER'] = '******'
        self.request.META['givenname'] = 'test_gname'
        self.request.META['surname'] = 'test_sname'
        self.request.META['Shibboleth-displayName'] = 'Sample Developer'
        self.request.META[
            'Shibboleth-affiliation'] = '[email protected];[email protected];[email protected];[email protected]'

        # default settings
        assert getattr(settings, 'SHIB_ACTIVATE_AFTER_CREATION', True) is True

    @patch(
        'shibboleth.middleware.SHIB_ATTRIBUTE_MAP', {
            "Shibboleth-eppn": (True, "username"),
            "givenname": (False, "givenname"),
            "surname": (False, "surname"),
            "emailaddress": (False, "contact_email"),
            "organization": (False, "institution"),
            "Shibboleth-displayName": (False, "display_name"),
        })
    def test_can_process(self):
        assert len(Profile.objects.all()) == 0

        self.middleware.process_request(self.request)
        assert self.request.user.username == '*****@*****.**'

        assert len(Profile.objects.all()) == 1
        assert self.request.shib_login is True
        assert Profile.objects.all()[0].user == '*****@*****.**'
        assert Profile.objects.all()[0].nickname == 'Sample Developer'

    @override_settings(
        SHIBBOLETH_AFFILIATION_ROLE_MAP={
            '*****@*****.**': 'staff',
            '*****@*****.**': 'staff',
            '*****@*****.**': 'student',
        })
    @patch(
        'shibboleth.middleware.SHIB_ATTRIBUTE_MAP', {
            "Shibboleth-eppn": (True, "username"),
            "givenname": (False, "givenname"),
            "surname": (False, "surname"),
            "emailaddress": (False, "contact_email"),
            "organization": (False, "institution"),
            "Shibboleth-affiliation": (False, "affiliation"),
            "Shibboleth-displayName": (False, "display_name"),
        })
    def test_can_process_user_role(self):
        assert len(Profile.objects.all()) == 0

        self.middleware.process_request(self.request)
        assert self.request.user.username == '*****@*****.**'

        assert len(Profile.objects.all()) == 1
        assert self.request.shib_login is True
        assert Profile.objects.all()[0].user == '*****@*****.**'
        assert Profile.objects.all()[0].nickname == 'Sample Developer'
        assert User.objects.get(self.request.user.username).role == 'staff'

    @pytest.mark.skipif(
        TRAVIS,
        reason=
        "TODO: this test can only be run seperately due to the url module init in django, we may need to reload url conf: https://gist.github.com/anentropic/9ac47f6518c88fa8d2b0"
    )
    def test_process_inactive_user(self):
        """Inactive user is created, and no profile is created.
        """
        assert len(Profile.objects.all()) == 0

        with self.settings(SHIB_ACTIVATE_AFTER_CREATION=False):
            # reload our shibboleth.backends module, so it picks up the settings change
            reload(backends)

            resp = self.middleware.process_request(self.request)
            assert resp.url == '/shib-complete/'
            assert len(Profile.objects.all()) == 0

        # now reload again, so it reverts to original settings
        reload(backends)

    def test_make_profile_for_display_name(self):
        assert len(Profile.objects.all()) == 0

        self.middleware.make_profile(
            self.user, {
                'display_name': 'display name',
                'givenname': 'g',
                'surname': 's',
                'institution': 'i',
                'contact_email': '*****@*****.**'
            })

        assert len(Profile.objects.all()) == 1
        assert Profile.objects.all()[0].nickname == 'display name'

    def test_make_profile_for_givenname_surname(self):
        assert len(Profile.objects.all()) == 0

        self.middleware.make_profile(
            self.user, {
                'givenname': 'g',
                'surname': 's',
                'institution': 'i',
                'contact_email': '*****@*****.**'
            })

        assert len(Profile.objects.all()) == 1
        assert Profile.objects.all()[0].nickname == 'g s'

    def test_make_profile_for_name_missing(self):
        assert len(Profile.objects.all()) == 0

        self.middleware.make_profile(self.user, {
            'institution': 'i',
            'contact_email': '*****@*****.**'
        })

        assert len(Profile.objects.all()) == 1
        assert Profile.objects.all()[0].nickname == ''
Exemple #9
0
class ShibbolethRemoteUserMiddlewareTest(BaseTestCase):
    def setUp(self):
        self.middleware = ShibbolethRemoteUserMiddleware()

        self.factory = RequestFactory()

        # Create an instance of a GET request.
        self.request = self.factory.get('/foo/')
        # self.request = Mock()

        self.request.user = self.user
        self.request.user.is_authenticated = lambda: False
        self.request.cloud_mode = False
        self.request.session = {}

        self.request.META = {}
        self.request.META['REMOTE_USER'] = self.user.username
        self.request.META['eppn'] = 'test eppn'
        self.request.META['givenname'] = 'test_gname'
        self.request.META['surname'] = 'test_sname'

    # def test_can_process(self):
    #     assert len(Profile.objects.all()) == 0

    #     self.middleware.process_request(self.request)

    #     assert len(Profile.objects.all()) == 1
    #     assert self.request.shib_login is True

    def test_make_profile_for_display_name(self):
        assert len(Profile.objects.all()) == 0

        self.middleware.make_profile(self.user, {
            'display_name': 'display name',
            'givenname': 'g',
            'surname': 's',
            'institution': 'i',
            'contact_email': '*****@*****.**'
        })

        assert len(Profile.objects.all()) == 1
        assert Profile.objects.all()[0].nickname == 'display name'

    def test_make_profile_for_givenname_surname(self):
        assert len(Profile.objects.all()) == 0

        self.middleware.make_profile(self.user, {
            'givenname': 'g',
            'surname': 's',
            'institution': 'i',
            'contact_email': '*****@*****.**'
        })

        assert len(Profile.objects.all()) == 1
        assert Profile.objects.all()[0].nickname == 'g s'

    def test_make_profile_for_name_missing(self):
        assert len(Profile.objects.all()) == 0

        self.middleware.make_profile(self.user, {
            'institution': 'i',
            'contact_email': '*****@*****.**'
        })

        assert len(Profile.objects.all()) == 1
        assert Profile.objects.all()[0].nickname == ''
Exemple #10
0
class ShibbolethRemoteUserMiddlewareTest(BaseTestCase):
    def setUp(self):
        self.remove_user('*****@*****.**')

        self.middleware = ShibbolethRemoteUserMiddleware()
        self.factory = RequestFactory()
        # Create an instance of a GET request.
        self.request = self.factory.get('/foo/')

        self.request.user = self.user
        self.request.user.is_authenticated = lambda: False
        self.request.cloud_mode = False
        self.request.session = self.client.session

        self.request.META = {}
        self.request.META['Shibboleth-eppn'] = '*****@*****.**'
        self.request.META['REMOTE_USER'] = '******'
        self.request.META['givenname'] = 'test_gname'
        self.request.META['surname'] = 'test_sname'

    def test_can_process(self):
        assert len(Profile.objects.all()) == 0

        self.middleware.process_request(self.request)
        assert len(Profile.objects.all()) == 1
        assert self.request.shib_login is True

    def test_process_inactive_user(self):
        """Inactive user is created, and no profile is created.
        """
        assert len(Profile.objects.all()) == 0

        with self.settings(SHIB_ACTIVATE_AFTER_CREATION=False):
            # reload our shibboleth.backends module, so it picks up the settings change
            reload(backends)

            resp = self.middleware.process_request(self.request)
            assert resp.url == 'shib-complete'
            assert len(Profile.objects.all()) == 0

        # now reload again, so it reverts to original settings
        reload(backends)

    def test_make_profile_for_display_name(self):
        assert len(Profile.objects.all()) == 0

        self.middleware.make_profile(
            self.user, {
                'display_name': 'display name',
                'givenname': 'g',
                'surname': 's',
                'institution': 'i',
                'contact_email': '*****@*****.**'
            })

        assert len(Profile.objects.all()) == 1
        assert Profile.objects.all()[0].nickname == 'display name'

    def test_make_profile_for_givenname_surname(self):
        assert len(Profile.objects.all()) == 0

        self.middleware.make_profile(
            self.user, {
                'givenname': 'g',
                'surname': 's',
                'institution': 'i',
                'contact_email': '*****@*****.**'
            })

        assert len(Profile.objects.all()) == 1
        assert Profile.objects.all()[0].nickname == 'g s'

    def test_make_profile_for_name_missing(self):
        assert len(Profile.objects.all()) == 0

        self.middleware.make_profile(self.user, {
            'institution': 'i',
            'contact_email': '*****@*****.**'
        })

        assert len(Profile.objects.all()) == 1
        assert Profile.objects.all()[0].nickname == ''
Exemple #11
0
    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'))
class ShibbolethRemoteUserMiddlewareTest(BaseTestCase):
    def setUp(self):
        self.remove_user('*****@*****.**')

        self.middleware = ShibbolethRemoteUserMiddleware()
        self.factory = RequestFactory()
        # Create an instance of a GET request.
        self.request = self.factory.get('/foo/')

        self.request.user = self.user
        self.request.user.is_authenticated = lambda: False
        self.request.cloud_mode = False
        self.request.session = self.client.session

        self.request.META = {}
        self.request.META['Shibboleth-eppn'] = '*****@*****.**'
        self.request.META['REMOTE_USER'] = '******'
        self.request.META['givenname'] = 'test_gname'
        self.request.META['surname'] = 'test_sname'

        # default settings
        assert getattr(settings, 'SHIB_ACTIVATE_AFTER_CREATION', True) is True

    def test_can_process(self):
        assert len(Profile.objects.all()) == 0

        self.middleware.process_request(self.request)
        assert len(Profile.objects.all()) == 1
        assert self.request.shib_login is True

    @pytest.mark.skipif(TRAVIS, reason="TODO: this test can only be run seperately due to the url module init in django, we may need to reload url conf: https://gist.github.com/anentropic/9ac47f6518c88fa8d2b0")
    def test_process_inactive_user(self):
        """Inactive user is created, and no profile is created.
        """
        assert len(Profile.objects.all()) == 0

        with self.settings(SHIB_ACTIVATE_AFTER_CREATION=False):
            # reload our shibboleth.backends module, so it picks up the settings change
            reload(backends)

            resp = self.middleware.process_request(self.request)
            assert resp.url == '/shib-complete/'
            assert len(Profile.objects.all()) == 0

        # now reload again, so it reverts to original settings
        reload(backends)

    def test_make_profile_for_display_name(self):
        assert len(Profile.objects.all()) == 0

        self.middleware.make_profile(self.user, {
            'display_name': 'display name',
            'givenname': 'g',
            'surname': 's',
            'institution': 'i',
            'contact_email': '*****@*****.**'
        })

        assert len(Profile.objects.all()) == 1
        assert Profile.objects.all()[0].nickname == 'display name'

    def test_make_profile_for_givenname_surname(self):
        assert len(Profile.objects.all()) == 0

        self.middleware.make_profile(self.user, {
            'givenname': 'g',
            'surname': 's',
            'institution': 'i',
            'contact_email': '*****@*****.**'
        })

        assert len(Profile.objects.all()) == 1
        assert Profile.objects.all()[0].nickname == 'g s'

    def test_make_profile_for_name_missing(self):
        assert len(Profile.objects.all()) == 0

        self.middleware.make_profile(self.user, {
            'institution': 'i',
            'contact_email': '*****@*****.**'
        })

        assert len(Profile.objects.all()) == 1
        assert Profile.objects.all()[0].nickname == ''