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_duplicate_data(self): """Test with duplicate data, should trigger error""" user = create_test_admin_user() plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()]) session = self.client.session plan.context[PLAN_CONTEXT_PROMPT] = { "username": user.username, "attribute_some-custom-attribute": "test", "some_ignored_attribute": "bar", } session[SESSION_KEY_PLAN] = plan session.save() response = self.client.get( reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})) self.assertEqual(response.status_code, 200) self.assertStageResponse( response, self.flow, component="ak-stage-access-denied", )
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_api_diagram(self): """Test flow diagram.""" user = create_test_admin_user() self.client.force_login(user) flow = Flow.objects.create( name="test-default-context", slug="test-default-context", designation=FlowDesignation.AUTHENTICATION, ) false_policy = DummyPolicy.objects.create(result=False, wait_min=1, wait_max=2) FlowStageBinding.objects.create( target=flow, stage=DummyStage.objects.create(name="dummy1"), order=0 ) binding2 = FlowStageBinding.objects.create( target=flow, stage=DummyStage.objects.create(name="dummy2"), order=1, re_evaluate_policies=True, ) PolicyBinding.objects.create(policy=false_policy, target=binding2, order=0) response = self.client.get( reverse("authentik_api:flow-diagram", kwargs={"slug": flow.slug}) ) self.assertEqual(response.status_code, 200) self.assertJSONEqual(response.content, {"diagram": DIAGRAM_EXPECTED})
def test_request_attributes_invalid(self): """Test full SAML Request/Response flow, fully signed""" user = create_test_admin_user() http_request = get_request("/", user=user) # First create an AuthNRequest request_proc = RequestProcessor(self.source, http_request, "test_state") request = request_proc.build_auth_n() # Create invalid PropertyMapping scope = SAMLPropertyMapping.objects.create(name="test", saml_name="test", expression="q") self.provider.property_mappings.add(scope) # To get an assertion we need a parsed request (parsed by provider) parsed_request = AuthNRequestParser(self.provider).parse( b64encode(request.encode()).decode(), "test_state") # Now create a response and convert it to string (provider) response_proc = AssertionProcessor(self.provider, http_request, parsed_request) self.assertIn(user.username, response_proc.build_response()) events = Event.objects.filter(action=EventAction.CONFIGURATION_ERROR, ) self.assertTrue(events.exists()) self.assertEqual( events.first().context["message"], "Failed to evaluate property-mapping: name 'q' is not defined", )
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) -> None: super().setUp() self.mapping = PropertyMapping.objects.create( name="dummy", expression="""return {'foo': 'bar'}""" ) self.user = create_test_admin_user() self.client.force_login(self.user)
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_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_builder_api_invalid(self): """Test Builder (via API) (invalid)""" self.client.force_login(create_test_admin_user()) response = self.client.post( reverse("authentik_api:certificatekeypair-generate"), data={}, ) self.assertEqual(response.status_code, 400)
def test_types(self): """Test Stage's types endpoint""" user = create_test_admin_user() self.client.force_login(user) response = self.client.get( reverse("authentik_api:stage-types"), ) self.assertEqual(response.status_code, 200)
def test_builder_api(self): """Test Builder (via API)""" self.client.force_login(create_test_admin_user()) self.client.post( reverse("authentik_api:certificatekeypair-generate"), data={ "common_name": "foo", "subject_alt_name": "bar,baz", "validity_days": 3 }, ) self.assertTrue(CertificateKeyPair.objects.filter(name="foo").exists())
def setUp(self): super().setUp() # pylint: disable=invalid-name self.maxDiff = None self.wait_timeout = 60 self.driver = self._get_driver() self.driver.maximize_window() self.driver.implicitly_wait(30) self.wait = WebDriverWait(self.driver, self.wait_timeout) self.logger = get_logger() self.user = create_test_admin_user() if specs := self.get_container_specs(): self.container = self._start_container(specs)
def setUp(self) -> None: self.user = create_test_admin_user() self.allowed = Application.objects.create(name="allowed", slug="allowed") self.denied = Application.objects.create(name="denied", slug="denied") PolicyBinding.objects.create( target=self.denied, policy=DummyPolicy.objects.create(name="deny", result=False, wait_min=1, wait_max=2), order=0, )
def test_create_default_multiple(self): """Test attempted creation of multiple default tenants""" Tenant.objects.create( domain="foo", default=True, branding_title="custom", event_retention="weeks=3", ) user = create_test_admin_user() self.client.force_login(user) response = self.client.post( reverse("authentik_api:tenant-list"), data={"domain": "bar", "default": True} ) self.assertEqual(response.status_code, 400)
def test_api_diagram_no_stages(self): """Test flow diagram with no stages.""" user = create_test_admin_user() self.client.force_login(user) flow = Flow.objects.create( name="test-default-context", slug="test-default-context", designation=FlowDesignation.AUTHENTICATION, ) response = self.client.get( reverse("authentik_api:flow-diagram", kwargs={"slug": flow.slug}) ) self.assertEqual(response.status_code, 200) self.assertJSONEqual(response.content, {"diagram": DIAGRAM_SHORT_EXPECTED})
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_request_attributes(self): """Test full SAML Request/Response flow, fully signed""" user = create_test_admin_user() http_request = get_request("/", user=user) # First create an AuthNRequest request_proc = RequestProcessor(self.source, http_request, "test_state") request = request_proc.build_auth_n() # To get an assertion we need a parsed request (parsed by provider) parsed_request = AuthNRequestParser(self.provider).parse( b64encode(request.encode()).decode(), "test_state") # Now create a response and convert it to string (provider) response_proc = AssertionProcessor(self.provider, http_request, parsed_request) self.assertIn(user.username, response_proc.build_response())
def benchmark_flows(self, proc_count): """Get full recovery link""" flow = Flow.objects.get(slug="default-authentication-flow") user = create_test_admin_user() manager = Manager() return_dict = manager.dict() jobs = [] db.connections.close_all() for i in range(proc_count): proc = FlowPlanProcess(i, return_dict, flow, user) jobs.append(proc) proc.start() for proc in jobs: proc.join() return return_dict.values()
def test_certificate_download(self): """Test certificate export (download)""" self.client.force_login(create_test_admin_user()) keypair = create_test_cert() response = self.client.get( reverse( "authentik_api:certificatekeypair-view-certificate", kwargs={"pk": keypair.pk}, )) self.assertEqual(200, response.status_code) response = self.client.get( reverse( "authentik_api:certificatekeypair-view-certificate", kwargs={"pk": keypair.pk}, ) + "?download", ) self.assertEqual(200, response.status_code) self.assertIn("Content-Disposition", response)
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 test_invalid_username(self): """Test challenge_response validation""" user = create_test_admin_user() plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()]) self.prompt_data["username_prompt"] = user.username challenge_response = PromptChallengeResponse(None, stage=self.stage, plan=plan, data=self.prompt_data) self.assertEqual(challenge_response.is_valid(), False) self.assertEqual( challenge_response.errors, { "username_prompt": [ ErrorDetail(string="Username is already taken.", code="invalid") ] }, )
def test_full_code(self): """Test full authorization""" flow = Flow.objects.create(slug="empty") provider = OAuth2Provider.objects.create( name="test", client_id="test", authorization_flow=flow, redirect_uris="foo://localhost", ) 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": "code", "client_id": "test", "state": state, "redirect_uri": "foo://localhost", }, ) response = self.client.get( reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}), ) code: AuthorizationCode = AuthorizationCode.objects.filter( user=user).first() self.assertJSONEqual( response.content.decode(), { "component": "xak-flow-redirect", "type": ChallengeTypes.REDIRECT.value, "to": f"foo://localhost?code={code.code}&state={state}", }, )
def test_is_group_member(self): """Test expr_is_group_member""" self.assertFalse(BaseEvaluator.expr_is_group_member(create_test_admin_user(), name="test"))
def test_list(self): """Test API List""" self.client.force_login(create_test_admin_user()) response = self.client.get( reverse("authentik_api:certificatekeypair-list", )) self.assertEqual(200, response.status_code)
def setUp(self) -> None: super().setUp() self.pbm = PolicyBindingModel.objects.create() self.user = create_test_admin_user() self.group = self.user.ak_groups.first() self.client.force_login(self.user)
def test_user_by(self): """Test expr_user_by""" user = create_test_admin_user() self.assertIsNotNone(BaseEvaluator.expr_user_by(username=user.username)) self.assertIsNone(BaseEvaluator.expr_user_by(username="******")) self.assertIsNone(BaseEvaluator.expr_user_by(foo="bar"))
def setUp(self) -> None: super().setUp() self.user = create_test_admin_user() self.other_user = User.objects.create(username="******")
def setUp(self) -> None: super().setUp() self.user = User.objects.create(username="******") self.admin = create_test_admin_user() self.client.force_login(self.user)