def test_authentication_new_user( db, rf, requests_mock, settings, create_user, email, expected_count, ): settings.OIDC_CREATE_USER = create_user settings.OIDC_UPDATE_USER = create_user user_model = get_user_model() assert user_model.objects.filter(username="******").count() == 0 userinfo = {"sub": "1", "email": email} requests_mock.get(settings.OIDC_OP_USER_ENDPOINT, text=json.dumps(userinfo)) request = rf.get("/openid", HTTP_AUTHORIZATION="Bearer Token") try: user, _ = OIDCAuthentication().authenticate(request) except AuthenticationFailed: assert not create_user else: assert user.email == email assert user_model.objects.count() == expected_count
def test_authentication_existing_identity( db, rf, requests_mock, settings, identity, get_claims, ): claims = get_claims(id_claim="matching_id", groups_claim=[], email_claim="*****@*****.**") requests_mock.get(settings.OIDC_OP_USER_ENDPOINT, text=json.dumps(claims)) assert Identity.objects.count() == 1 request = rf.get("/openid", HTTP_AUTHORIZATION="Bearer Token") HistoricalRecords.thread.request = request result = OIDCAuthentication().authenticate(request) user, auth = result assert user.is_authenticated assert user.identity == identity assert Identity.objects.count() == 1
def test_authentication( db, user, rf, authentication_header, authenticated, error, is_id_token, requests_mock, settings, ): userinfo = {"sub": "1"} requests_mock.get(settings.OIDC_OP_USER_ENDPOINT, text=json.dumps(userinfo)) if not is_id_token: userinfo = {"client_id": "test_client", "sub": "1"} requests_mock.get(settings.OIDC_OP_USER_ENDPOINT, status_code=status.HTTP_401_UNAUTHORIZED) requests_mock.post(settings.OIDC_OP_INTROSPECT_ENDPOINT, text=json.dumps(userinfo)) request = rf.get("/openid", HTTP_AUTHORIZATION=authentication_header) try: result = OIDCAuthentication().authenticate(request) except exceptions.AuthenticationFailed: assert error else: if result: key = "userinfo" if is_id_token else "introspection" user, auth = result assert user.is_authenticated assert ( cache.get(f"auth.{key}.{hashlib.sha256(b'Token').hexdigest()}") == userinfo)
def test_authentication_multiple_existing_identity( db, rf, requests_mock, settings, identity_factory, get_claims, caplog, ): identity = identity_factory(idp_id="matching_id") identity_factory(email="*****@*****.**") claims = get_claims(id_claim="matching_id", groups_claim=[], email_claim="*****@*****.**") requests_mock.get(settings.OIDC_OP_USER_ENDPOINT, text=json.dumps(claims)) assert Identity.objects.count() == 2 request = rf.get("/openid", HTTP_AUTHORIZATION="Bearer Token") HistoricalRecords.thread.request = request result = OIDCAuthentication().authenticate(request) user, auth = result assert user.is_authenticated assert user.identity == identity assert Identity.objects.count() == 2 assert ( caplog.records[0].msg == "Found one Identity with same idp_id and one with same email. Matching on idp_id." )
def test_authentication_idp_502(db, rf, requests_mock, settings): requests_mock.get(settings.OIDC_OP_USER_ENDPOINT, status_code=status.HTTP_502_BAD_GATEWAY) request = rf.get("/openid", HTTP_AUTHORIZATION="Bearer Token") with pytest.raises(HTTPError): OIDCAuthentication().authenticate(request)
def test_authentication_dev( db, rf, requests_mock, settings, debug, ): settings.OIDC_DRF_AUTH_BACKEND = ( "alexandria.oidc_auth.authentication.DevelopmentAuthenticationBackend" ) settings.DEBUG = debug request = rf.get("/openid", HTTP_AUTHORIZATION="Bearer Token") if debug: user, _ = OIDCAuthentication().authenticate(request) assert user.groups == ["dev-group", "secondary-group"] assert user.username == "dev" else: with pytest.raises(ImproperlyConfigured) as exc: user = OIDCAuthentication().authenticate(request) assert exc.match("The Dev auth backend can only be used in DEBUG mode!")
def test_authentication_idp_missing_claim(db, rf, requests_mock, settings): settings.OIDC_USERNAME_CLAIM = "missing" userinfo = {"sub": "1"} requests_mock.get(settings.OIDC_OP_USER_ENDPOINT, text=json.dumps(userinfo)) request = rf.get("/openid", HTTP_AUTHORIZATION="Bearer Token") with pytest.raises(AuthenticationFailed): OIDCAuthentication().authenticate(request)
def test_authentication_no_client(db, rf, requests_mock, settings, claims): requests_mock.get(settings.OIDC_OP_USER_ENDPOINT, status_code=status.HTTP_401_UNAUTHORIZED) requests_mock.post(settings.OIDC_OP_INTROSPECT_ENDPOINT, text=json.dumps(claims)) request = rf.get("/openid", HTTP_AUTHORIZATION="Bearer Token") with pytest.raises(AuthenticationFailed): OIDCAuthentication().authenticate(request)
class TestDRF(TestCase): @override_settings(OIDC_OP_TOKEN_ENDPOINT='https://server.example.com/token') @override_settings(OIDC_OP_USER_ENDPOINT='https://server.example.com/user') @override_settings(OIDC_RP_CLIENT_ID='example_id') @override_settings(OIDC_RP_CLIENT_SECRET='client_secret') def setUp(self): self.auth = OIDCAuthentication(backend=mock.Mock()) self.request = RequestFactory().get('/', HTTP_AUTHORIZATION='Bearer faketoken') def test_authenticate_returns_none_if_no_access_token(self): with mock.patch.object(self.auth, 'get_access_token', return_value=None): ret = self.auth.authenticate(self.request) self.assertIsNone(ret) def test_authenticate_raises_authenticationfailed_if_backend_returns_no_user(self): self.auth.backend.get_or_create_user.return_value = None with self.assertRaises(exceptions.AuthenticationFailed): self.auth.authenticate(self.request) def test_authenticate_raises_authenticationfailed_on_suspiciousoperation(self): self.auth.backend.get_or_create_user.side_effect = SuspiciousOperation with self.assertRaises(exceptions.AuthenticationFailed): self.auth.authenticate(self.request) def test_returns_user_and_token_if_backend_returns_user(self): user = mock.Mock() self.auth.backend.get_or_create_user.return_value = user ret = self.auth.authenticate(self.request) self.assertEqual(ret[0], user) self.assertEqual(ret[1], 'faketoken')
def test_authentication_email_update( db, rf, requests_mock, settings, user, expected_email, ): userinfo = {"sub": "1", "email": expected_email} requests_mock.get(settings.OIDC_OP_USER_ENDPOINT, text=json.dumps(userinfo)) request = rf.get("/openid", HTTP_AUTHORIZATION="Bearer Token") user, _ = OIDCAuthentication().authenticate(request) assert user.email == expected_email
def test_authentication( db, rf, authentication_header, authenticated, error, is_id_token, requests_mock, settings, claims, ): requests_mock.get(settings.OIDC_OP_USER_ENDPOINT, text=json.dumps(claims)) assert Identity.objects.count() == 0 if not is_id_token: claims["client_id"] = "test_client" requests_mock.get(settings.OIDC_OP_USER_ENDPOINT, status_code=status.HTTP_401_UNAUTHORIZED) requests_mock.post(settings.OIDC_OP_INTROSPECT_ENDPOINT, text=json.dumps(claims)) request = rf.get("/openid", HTTP_AUTHORIZATION=authentication_header) HistoricalRecords.thread.request = request try: result = OIDCAuthentication().authenticate(request) except exceptions.AuthenticationFailed: assert error else: if authenticated: key = "userinfo" if is_id_token else "introspection" user, auth = result assert user.is_authenticated assert auth == authentication_header.split(" ")[1] assert ( cache.get(f"auth.{key}.{hashlib.sha256(b'Token').hexdigest()}") == claims) assert Identity.objects.count() == 1 else: assert result is None
def setUp(self): self.auth = OIDCAuthentication(backend=mock.Mock()) self.request = RequestFactory().get( '/', HTTP_AUTHORIZATION='Bearer faketoken')