Exemplo n.º 1
0
 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())
Exemplo n.º 2
0
    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",
        )
Exemplo n.º 3
0
 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)
Exemplo n.º 4
0
    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})
Exemplo n.º 5
0
    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",
        )
Exemplo n.º 6
0
 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,
         }],
     )
Exemplo n.º 7
0
 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)
Exemplo n.º 8
0
 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"), )),
     )
Exemplo n.º 9
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())
Exemplo n.º 10
0
 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)
Exemplo n.º 11
0
    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)
Exemplo n.º 12
0
 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())
Exemplo n.º 13
0
 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)
Exemplo n.º 14
0
 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,
     )
Exemplo n.º 15
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)
Exemplo n.º 16
0
    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})
Exemplo n.º 17
0
 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)
Exemplo n.º 18
0
    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())
Exemplo n.º 19
0
    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()
Exemplo n.º 20
0
 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)
Exemplo n.º 21
0
 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)
Exemplo n.º 22
0
 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)
Exemplo n.º 23
0
 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")
             ]
         },
     )
Exemplo n.º 24
0
 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}",
         },
     )
Exemplo n.º 25
0
 def test_is_group_member(self):
     """Test expr_is_group_member"""
     self.assertFalse(BaseEvaluator.expr_is_group_member(create_test_admin_user(), name="test"))
Exemplo n.º 26
0
 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)
Exemplo n.º 27
0
 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)
Exemplo n.º 28
0
 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="******")
Exemplo n.º 30
0
 def setUp(self) -> None:
     super().setUp()
     self.user = User.objects.create(username="******")
     self.admin = create_test_admin_user()
     self.client.force_login(self.user)