def test_request_auth_code(self): """test request param""" provider = OAuth2Provider.objects.create( name="test", client_id=generate_id(), client_secret=generate_key(), authorization_flow=create_test_flow(), redirect_uris="http://testserver", signing_key=create_test_cert(), ) header = b64encode(f"{provider.client_id}:{provider.client_secret}". encode()).decode() user = create_test_admin_user() code = AuthorizationCode.objects.create(code="foobar", provider=provider, user=user) request = self.factory.post( "/", data={ "grant_type": GRANT_TYPE_AUTHORIZATION_CODE, "code": code.code, "redirect_uri": "http://testserver", }, HTTP_AUTHORIZATION=f"Basic {header}", ) params = TokenParams.parse(request, provider, provider.client_id, provider.client_secret) self.assertEqual(params.provider, provider) with self.assertRaises(TokenError): TokenParams.parse(request, provider, provider.client_id, generate_key())
def test_true(self): """Positive password case""" request = PolicyRequest(get_anonymous_user()) request.context["password"] = generate_key() + "1ee!!!" # nosec result: PolicyResult = self.policy.passes(request) self.assertTrue(result.passing) self.assertEqual(result.messages, tuple())
def setUp(self) -> None: super().setUp() ObjectManager().run() self.app = Application.objects.create(name="test", slug="test") self.provider: OAuth2Provider = OAuth2Provider.objects.create( name="test", client_id=generate_id(), client_secret=generate_key(), authorization_flow=create_test_flow(), redirect_uris="", signing_key=create_test_cert(), ) self.provider.property_mappings.set(ScopeMapping.objects.all()) # Needs to be assigned to an application for iss to be set self.app.provider = self.provider self.app.save() self.user = create_test_admin_user() self.token: RefreshToken = RefreshToken.objects.create( provider=self.provider, user=self.user, access_token=generate_id(), refresh_token=generate_id(), _scope="openid user profile", _id_token=json.dumps(asdict(IDToken("foo", "bar"), )), )
def test_device_challenge_duo(self): """Test duo""" request = self.request_factory.get("/") stage = AuthenticatorDuoStage.objects.create( name="test", client_id=generate_id(), client_secret=generate_key(), api_hostname="", ) duo_device = DuoDevice.objects.create( user=self.user, stage=stage, ) duo_mock = MagicMock(auth=MagicMock( return_value={ "result": "allow", "status": "allow", "status_msg": "Success. Logging you in...", })) failed_duo_mock = MagicMock(auth=MagicMock( return_value={"result": "deny"})) with patch( "authentik.stages.authenticator_duo.models.AuthenticatorDuoStage.client", duo_mock, ): self.assertEqual( duo_device.pk, validate_challenge_duo(duo_device.pk, request, self.user)) with patch( "authentik.stages.authenticator_duo.models.AuthenticatorDuoStage.client", failed_duo_mock, ): with self.assertRaises(ValidationError): validate_challenge_duo(duo_device.pk, request, self.user)
def test_request_refresh_token(self): """test request param""" provider = OAuth2Provider.objects.create( name="test", client_id=generate_id(), client_secret=generate_key(), authorization_flow=create_test_flow(), redirect_uris="http://local.invalid", signing_key=create_test_cert(), ) header = b64encode(f"{provider.client_id}:{provider.client_secret}". encode()).decode() user = create_test_admin_user() token: RefreshToken = RefreshToken.objects.create( provider=provider, user=user, refresh_token=generate_id(), ) request = self.factory.post( "/", data={ "grant_type": GRANT_TYPE_REFRESH_TOKEN, "refresh_token": token.refresh_token, "redirect_uri": "http://local.invalid", }, HTTP_AUTHORIZATION=f"Basic {header}", ) params = TokenParams.parse(request, provider, provider.client_id, provider.client_secret) self.assertEqual(params.provider, provider)
def test_used_by(self): """Test used_by endpoint""" self.client.force_login(create_test_admin_user()) keypair = create_test_cert() provider = OAuth2Provider.objects.create( name="test", client_id="test", client_secret=generate_key(), authorization_flow=create_test_flow(), redirect_uris="http://localhost", signing_key=keypair, ) response = self.client.get( reverse( "authentik_api:certificatekeypair-used-by", kwargs={"pk": keypair.pk}, )) self.assertEqual(200, response.status_code) self.assertJSONEqual( response.content.decode(), [{ "app": "authentik_providers_oauth2", "model_name": "oauth2provider", "pk": str(provider.pk), "name": str(provider), "action": DeleteAction.SET_NULL.name, }], )
def setUp(self): super().setUp() self.password = generate_key() self.user = User.objects.create_user(username="******", email="*****@*****.**", password=self.password) # OAuthSource for the login view source = OAuthSource.objects.create(name="test", slug="test") self.flow = Flow.objects.create( name="test-identification", slug="test-identification", designation=FlowDesignation.AUTHENTICATION, ) self.stage = IdentificationStage.objects.create( name="identification", user_fields=[UserFields.E_MAIL], ) self.stage.sources.set([source]) self.stage.save() FlowStageBinding.objects.create( target=self.flow, stage=self.stage, order=0, )
def test_refresh_token_revoke(self): """test request param""" provider = OAuth2Provider.objects.create( name="test", client_id=generate_id(), client_secret=generate_key(), authorization_flow=create_test_flow(), redirect_uris="http://testserver", signing_key=create_test_cert(), ) # Needs to be assigned to an application for iss to be set self.app.provider = provider self.app.save() header = b64encode(f"{provider.client_id}:{provider.client_secret}". encode()).decode() user = create_test_admin_user() token: RefreshToken = RefreshToken.objects.create( provider=provider, user=user, refresh_token=generate_id(), ) # Create initial refresh token response = self.client.post( reverse("authentik_providers_oauth2:token"), data={ "grant_type": GRANT_TYPE_REFRESH_TOKEN, "refresh_token": token.refresh_token, "redirect_uri": "http://testserver", }, HTTP_AUTHORIZATION=f"Basic {header}", ) new_token: RefreshToken = (RefreshToken.objects.filter( user=user).exclude(pk=token.pk).first()) # Post again with initial token -> get new refresh token # and revoke old one response = self.client.post( reverse("authentik_providers_oauth2:token"), data={ "grant_type": GRANT_TYPE_REFRESH_TOKEN, "refresh_token": new_token.refresh_token, "redirect_uri": "http://local.invalid", }, HTTP_AUTHORIZATION=f"Basic {header}", ) self.assertEqual(response.status_code, 200) # Post again with old token, is now revoked and should error response = self.client.post( reverse("authentik_providers_oauth2:token"), data={ "grant_type": GRANT_TYPE_REFRESH_TOKEN, "refresh_token": new_token.refresh_token, "redirect_uri": "http://local.invalid", }, HTTP_AUTHORIZATION=f"Basic {header}", ) self.assertEqual(response.status_code, 400) self.assertTrue( Event.objects.filter( action=EventAction.SUSPICIOUS_REQUEST).exists())
def test_true(self): """Positive password case""" policy = HaveIBeenPwendPolicy.objects.create(name="test_true", ) request = PolicyRequest(get_anonymous_user()) request.context["password"] = generate_key() result: PolicyResult = policy.passes(request) self.assertTrue(result.passing) self.assertEqual(result.messages, tuple())
def test_set_password(self): """Test Direct password set""" self.client.force_login(self.admin) new_pw = generate_key() response = self.client.post( reverse("authentik_api:user-set-password", kwargs={"pk": self.admin.pk}), data={"password": new_pw}, ) self.assertEqual(response.status_code, 204) self.admin.refresh_from_db() self.assertTrue(self.admin.check_password(new_pw))
def create_refresh_token(self, user: User, scope: list[str], request: HttpRequest) -> "RefreshToken": """Create and populate a RefreshToken object.""" token = RefreshToken( user=user, provider=self, refresh_token=generate_key(), expires=timezone.now() + timedelta_from_string(self.token_validity), scope=scope, ) token.access_token = token.create_access_token(user, request) return token
def test_check_server_overlap(self): """Test check_server_overlap""" token = generate_key() api = PlexAuth(self.source, token) with Mocker() as mocker: mocker.get("https://plex.tv/api/v2/resources", json=RESOURCES_RESPONSE) self.assertFalse(api.check_server_overlap()) self.source.allowed_servers = ["allowed"] self.source.save() with Mocker() as mocker: mocker.get("https://plex.tv/api/v2/resources", json=RESOURCES_RESPONSE) self.assertTrue(api.check_server_overlap())
def test_refresh_token_view(self): """test request param""" provider = OAuth2Provider.objects.create( name="test", client_id=generate_id(), client_secret=generate_key(), authorization_flow=create_test_flow(), redirect_uris="http://local.invalid", signing_key=create_test_cert(), ) # Needs to be assigned to an application for iss to be set self.app.provider = provider self.app.save() header = b64encode(f"{provider.client_id}:{provider.client_secret}". encode()).decode() user = create_test_admin_user() token: RefreshToken = RefreshToken.objects.create( provider=provider, user=user, refresh_token=generate_id(), ) response = self.client.post( reverse("authentik_providers_oauth2:token"), data={ "grant_type": GRANT_TYPE_REFRESH_TOKEN, "refresh_token": token.refresh_token, "redirect_uri": "http://local.invalid", }, HTTP_AUTHORIZATION=f"Basic {header}", HTTP_ORIGIN="http://local.invalid", ) new_token: RefreshToken = (RefreshToken.objects.filter( user=user).exclude(pk=token.pk).first()) self.assertEqual(response["Access-Control-Allow-Credentials"], "true") self.assertEqual(response["Access-Control-Allow-Origin"], "http://local.invalid") self.assertJSONEqual( response.content.decode(), { "access_token": new_token.access_token, "refresh_token": new_token.refresh_token, "token_type": "bearer", "expires_in": 2592000, "id_token": provider.encode(new_token.id_token.to_dict(), ), }, ) self.validate_jwt(new_token, provider)
def test_get_user_info(self): """Test get_user_info""" token = generate_key() api = PlexAuth(self.source, token) with Mocker() as mocker: mocker.get("https://plex.tv/api/v2/user", json=USER_INFO_RESPONSE) self.assertEqual( api.get_user_info(), ( { "username": "******", "email": "*****@*****.**", "name": "title" }, 1234123419, ), )
def setUp(self): super().setUp() self.password = generate_key() self.user = User.objects.create_user(username="******", email="*****@*****.**", password=self.password) self.flow = Flow.objects.create( name="test-password", slug="test-password", designation=FlowDesignation.AUTHENTICATION, ) self.stage = PasswordStage.objects.create(name="password", backends=[BACKEND_INBUILT]) self.binding = FlowStageBinding.objects.create(target=self.flow, stage=self.stage, order=2)
def test_password_change(self): """test password change flow""" # Ensure that password stage has change_flow set flow = Flow.objects.get( slug="default-password-change", designation=FlowDesignation.STAGE_CONFIGURATION, ) stage = PasswordStage.objects.get(name="default-authentication-password") stage.configure_flow = flow stage.save() new_password = generate_key() self.driver.get( self.url( "authentik_core:if-flow", flow_slug="default-authentication-flow", ) ) self.login() self.wait_for_url(self.if_user_url("/library")) self.driver.get( self.url( "authentik_flows:configure", stage_uuid=PasswordStage.objects.first().stage_uuid, ) ) flow_executor = self.get_shadow_root("ak-flow-executor") prompt_stage = self.get_shadow_root("ak-stage-prompt", flow_executor) prompt_stage.find_element(By.CSS_SELECTOR, "input[name=password]").send_keys(new_password) prompt_stage.find_element(By.CSS_SELECTOR, "input[name=password_repeat]").send_keys( new_password ) prompt_stage.find_element(By.CSS_SELECTOR, "input[name=password_repeat]").send_keys( Keys.ENTER ) self.wait_for_url(self.if_user_url("/library")) # Because self.user is cached, we need to get the user manually here user = User.objects.get(username=self.user.username) self.assertTrue(user.check_password(new_password))
def test_full_implicit(self): """Test full authorization""" flow = Flow.objects.create(slug="empty") provider = OAuth2Provider.objects.create( name="test", client_id="test", client_secret=generate_key(), authorization_flow=flow, redirect_uris="http://localhost", signing_key=create_test_cert(), ) Application.objects.create(name="app", slug="app", provider=provider) state = generate_id() user = create_test_admin_user() self.client.force_login(user) # Step 1, initiate params and get redirect to flow self.client.get( reverse("authentik_providers_oauth2:authorize"), data={ "response_type": "id_token", "client_id": "test", "state": state, "scope": "openid", "redirect_uri": "http://localhost", }, ) response = self.client.get( reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}), ) token: RefreshToken = RefreshToken.objects.filter(user=user).first() self.assertJSONEqual( response.content.decode(), { "component": "xak-flow-redirect", "type": ChallengeTypes.REDIRECT.value, "to": (f"http://localhost#access_token={token.access_token}" f"&id_token={provider.encode(token.id_token.to_dict())}&token_type=bearer" f"&expires_in=60&state={state}"), }, ) self.validate_jwt(token, provider)
def test_auth_code_view(self): """test request param""" provider = OAuth2Provider.objects.create( name="test", client_id=generate_id(), client_secret=generate_key(), authorization_flow=create_test_flow(), redirect_uris="http://local.invalid", signing_key=create_test_cert(), ) # Needs to be assigned to an application for iss to be set self.app.provider = provider self.app.save() header = b64encode(f"{provider.client_id}:{provider.client_secret}". encode()).decode() user = create_test_admin_user() code = AuthorizationCode.objects.create(code="foobar", provider=provider, user=user, is_open_id=True) response = self.client.post( reverse("authentik_providers_oauth2:token"), data={ "grant_type": GRANT_TYPE_AUTHORIZATION_CODE, "code": code.code, "redirect_uri": "http://local.invalid", }, HTTP_AUTHORIZATION=f"Basic {header}", ) new_token: RefreshToken = RefreshToken.objects.filter( user=user).first() self.assertJSONEqual( response.content.decode(), { "access_token": new_token.access_token, "refresh_token": new_token.refresh_token, "token_type": "bearer", "expires_in": 2592000, "id_token": provider.encode(new_token.id_token.to_dict(), ), }, ) self.validate_jwt(new_token, provider)
def setUp(self): self.client_secret = generate_key() self.prepare_dex_config() super().setUp()
"""LDAP Source API tests""" from rest_framework.test import APITestCase from authentik.lib.generators import generate_key from authentik.sources.ldap.api import LDAPSourceSerializer from authentik.sources.ldap.models import LDAPSource LDAP_PASSWORD = generate_key() class LDAPAPITests(APITestCase): """LDAP API tests""" def test_sync_users_password_valid(self): """Check that single source with sync_users_password is valid""" serializer = LDAPSourceSerializer( data={ "name": "foo", "slug": " foo", "server_uri": "ldaps://1.2.3.4", "bind_cn": "", "bind_password": LDAP_PASSWORD, "base_dn": "dc=foo", "sync_users_password": True, }) self.assertTrue(serializer.is_valid()) def test_sync_users_password_invalid(self): """Ensure only a single source with password sync can be created""" LDAPSource.objects.create( name="foo", slug="foo",
def setUp(self): self.client_id = generate_id() self.client_secret = generate_key() self.app_slug = generate_id(20) super().setUp()
def setUp(self): self.client_id = generate_id() self.client_secret = generate_key() self.application_slug = "test" super().setUp()
def setUp(self) -> None: self.client_id = generate_id() self.client_secret = generate_key() self.source_slug = "oauth1-test" super().setUp()
def create_access_token(self, user: User, request: HttpRequest) -> str: """Create access token with a similar format as Okta, Keycloak, ADFS""" token = self.create_id_token(user, request).to_dict() token["cid"] = self.provider.client_id token["uid"] = generate_key() return self.provider.encode(token)