Exemple #1
0
    def test_totp_validate(self):
        """test flow with otp stages"""
        sleep(1)
        # Setup TOTP Device
        user = USER()
        device = TOTPDevice.objects.create(user=user, confirmed=True, digits=6)

        flow: Flow = Flow.objects.get(slug="default-authentication-flow")
        FlowStageBinding.objects.create(
            target=flow,
            order=30,
            stage=AuthenticatorValidateStage.objects.create())

        self.driver.get(self.url("authentik_core:if-flow",
                                 flow_slug=flow.slug))
        self.login()

        # Get expected token
        totp = TOTP(device.bin_key, device.step, device.t0, device.digits,
                    device.drift)

        flow_executor = self.get_shadow_root("ak-flow-executor")
        validation_stage = self.get_shadow_root(
            "ak-stage-authenticator-validate", flow_executor)
        code_stage = self.get_shadow_root(
            "ak-stage-authenticator-validate-code", validation_stage)

        code_stage.find_element(By.CSS_SELECTOR,
                                "input[name=code]").send_keys(totp.token())
        code_stage.find_element(By.CSS_SELECTOR,
                                "input[name=code]").send_keys(Keys.ENTER)
        self.wait_for_url(self.if_admin_url("/library"))
        self.assert_user(USER())
Exemple #2
0
    def test_authorization_logout(self):
        """test OpenID Provider flow with logout"""
        sleep(1)
        # Bootstrap all needed objects
        authorization_flow = Flow.objects.get(
            slug="default-provider-authorization-implicit-consent")
        provider = OAuth2Provider.objects.create(
            name="grafana",
            client_type=ClientTypes.CONFIDENTIAL,
            client_id=self.client_id,
            client_secret=self.client_secret,
            rsa_key=CertificateKeyPair.objects.first(),
            redirect_uris="http://localhost:3000/login/generic_oauth",
            authorization_flow=authorization_flow,
        )
        provider.property_mappings.set(
            ScopeMapping.objects.filter(scope_name__in=[
                SCOPE_OPENID, SCOPE_OPENID_EMAIL, SCOPE_OPENID_PROFILE
            ]))
        provider.save()
        Application.objects.create(
            name="Grafana",
            slug=APPLICATION_SLUG,
            provider=provider,
        )

        self.driver.get("http://localhost:3000")
        self.driver.find_element(By.CLASS_NAME, "btn-service--oauth").click()
        self.login()
        self.wait_for_url("http://localhost:3000/?orgId=1")
        self.driver.get("http://localhost:3000/profile")
        self.assertEqual(
            self.driver.find_element(By.CLASS_NAME, "page-header__title").text,
            USER().name,
        )
        self.assertEqual(
            self.driver.find_element(
                By.CSS_SELECTOR, "input[name=name]").get_attribute("value"),
            USER().name,
        )
        self.assertEqual(
            self.driver.find_element(
                By.CSS_SELECTOR, "input[name=email]").get_attribute("value"),
            USER().email,
        )
        self.assertEqual(
            self.driver.find_element(
                By.CSS_SELECTOR, "input[name=login]").get_attribute("value"),
            USER().email,
        )
        self.driver.get("http://localhost:3000/logout")
        self.wait_for_url(
            self.url(
                "authentik_providers_oauth2:end-session",
                application_slug=APPLICATION_SLUG,
            ))
        self.driver.find_element(By.ID, "logout").click()
Exemple #3
0
    def test_authorization_consent_explicit(self):
        """test OpenID Provider flow (default authorization flow with explicit consent)"""
        sleep(1)
        # Bootstrap all needed objects
        authorization_flow = Flow.objects.get(
            slug="default-provider-authorization-explicit-consent"
        )
        provider = OAuth2Provider.objects.create(
            name=self.application_slug,
            authorization_flow=authorization_flow,
            client_type=ClientTypes.CONFIDENTIAL,
            client_id=self.client_id,
            client_secret=self.client_secret,
            rsa_key=CertificateKeyPair.objects.first(),
            redirect_uris="http://localhost:9009/implicit/",
        )
        provider.property_mappings.set(
            ScopeMapping.objects.filter(
                scope_name__in=[SCOPE_OPENID, SCOPE_OPENID_EMAIL, SCOPE_OPENID_PROFILE]
            )
        )
        provider.save()
        app = Application.objects.create(
            name=self.application_slug,
            slug=self.application_slug,
            provider=provider,
        )
        self.container = self.setup_client()

        self.driver.get("http://localhost:9009/implicit/")
        sleep(2)
        self.login()

        self.wait.until(
            ec.presence_of_element_located((By.CSS_SELECTOR, "ak-flow-executor"))
        )

        flow_executor = self.get_shadow_root("ak-flow-executor")
        consent_stage = self.get_shadow_root("ak-stage-consent", flow_executor)

        self.assertIn(
            app.name,
            consent_stage.find_element(By.CSS_SELECTOR, "#header-text").text,
        )
        consent_stage.find_element(
            By.CSS_SELECTOR,
            ("[type=submit]"),
        ).click()

        self.wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "pre")))
        sleep(1)
        body = loads(self.driver.find_element(By.CSS_SELECTOR, "pre").text)

        self.assertEqual(body["profile"]["nickname"], USER().username)
        self.assertEqual(body["profile"]["name"], USER().name)
        self.assertEqual(body["profile"]["email"], USER().email)
Exemple #4
0
    def test_authorization_consent_implied(self):
        """test OAuth Provider flow (default authorization flow with implied consent)"""
        # Bootstrap all needed objects
        authorization_flow = Flow.objects.get(
            slug="default-provider-authorization-implicit-consent"
        )
        provider = OAuth2Provider.objects.create(
            name="grafana",
            client_id=self.client_id,
            client_secret=self.client_secret,
            client_type=ClientTypes.CONFIDENTIAL,
            redirect_uris="http://localhost:3000/login/github",
            authorization_flow=authorization_flow,
        )
        Application.objects.create(
            name="Grafana",
            slug="grafana",
            provider=provider,
        )

        self.driver.get("http://localhost:3000")
        self.driver.find_element(By.CLASS_NAME, "btn-service--github").click()
        self.login()

        self.wait_for_url("http://localhost:3000/?orgId=1")
        self.driver.get("http://localhost:3000/profile")
        self.assertEqual(
            self.driver.find_element(By.CLASS_NAME, "page-header__title").text,
            USER().username,
        )
        self.assertEqual(
            self.driver.find_element(By.CSS_SELECTOR, "input[name=name]").get_attribute(
                "value"
            ),
            USER().username,
        )
        self.assertEqual(
            self.driver.find_element(
                By.CSS_SELECTOR, "input[name=email]"
            ).get_attribute("value"),
            USER().email,
        )
        self.assertEqual(
            self.driver.find_element(
                By.CSS_SELECTOR, "input[name=login]"
            ).get_attribute("value"),
            USER().username,
        )
Exemple #5
0
    def initial_stages(self):
        """Fill out initial stages"""
        # Identification stage, click enroll
        flow_executor = self.get_shadow_root("ak-flow-executor")
        identification_stage = self.get_shadow_root(
            "ak-stage-identification", flow_executor
        )
        wait = WebDriverWait(identification_stage, self.wait_timeout)

        wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "#enroll")))
        identification_stage.find_element(By.CSS_SELECTOR, "#enroll").click()

        # First prompt stage
        flow_executor = self.get_shadow_root("ak-flow-executor")
        prompt_stage = self.get_shadow_root("ak-stage-prompt", flow_executor)
        wait = WebDriverWait(prompt_stage, self.wait_timeout)

        wait.until(
            ec.presence_of_element_located((By.CSS_SELECTOR, "input[name=username]"))
        )
        prompt_stage.find_element(By.CSS_SELECTOR, "input[name=username]").send_keys(
            "foo"
        )
        prompt_stage.find_element(By.CSS_SELECTOR, "input[name=password]").send_keys(
            USER().username
        )
        prompt_stage.find_element(
            By.CSS_SELECTOR, "input[name=password_repeat]"
        ).send_keys(USER().username)
        prompt_stage.find_element(By.CSS_SELECTOR, ".pf-c-button").click()

        # Second prompt stage
        flow_executor = self.get_shadow_root("ak-flow-executor")
        prompt_stage = self.get_shadow_root("ak-stage-prompt", flow_executor)
        wait = WebDriverWait(prompt_stage, self.wait_timeout)

        wait.until(
            ec.presence_of_element_located((By.CSS_SELECTOR, "input[name=name]"))
        )
        prompt_stage.find_element(By.CSS_SELECTOR, "input[name=name]").send_keys(
            "some name"
        )
        prompt_stage.find_element(By.CSS_SELECTOR, "input[name=email]").send_keys(
            "*****@*****.**"
        )
        prompt_stage.find_element(By.CSS_SELECTOR, ".pf-c-button").click()
Exemple #6
0
    def test_totp_setup(self):
        """test TOTP Setup stage"""
        flow: Flow = Flow.objects.get(slug="default-authentication-flow")

        self.driver.get(self.url("authentik_core:if-flow",
                                 flow_slug=flow.slug))
        self.login()

        self.wait_for_url(self.if_admin_url("/library"))
        self.assert_user(USER())

        self.driver.get(
            self.url(
                "authentik_flows:configure",
                stage_uuid=AuthenticatorTOTPStage.objects.first().stage_uuid,
            ))

        flow_executor = self.get_shadow_root("ak-flow-executor")
        totp_stage = self.get_shadow_root("ak-stage-authenticator-totp",
                                          flow_executor)
        wait = WebDriverWait(totp_stage, self.wait_timeout)

        wait.until(
            ec.presence_of_element_located(
                (By.CSS_SELECTOR, "input[name=otp_uri]")))
        otp_uri = totp_stage.find_element(
            By.CSS_SELECTOR, "input[name=otp_uri]").get_attribute("value")

        # Parse the OTP URI, extract the secret and get the next token
        otp_args = urlparse(otp_uri)
        self.assertEqual(otp_args.scheme, "otpauth")
        otp_qs = parse_qs(otp_args.query)
        secret_key = b32decode(otp_qs["secret"][0])

        totp = TOTP(secret_key)

        totp_stage.find_element(By.CSS_SELECTOR,
                                "input[name=code]").send_keys(totp.token())
        totp_stage.find_element(By.CSS_SELECTOR,
                                "input[name=code]").send_keys(Keys.ENTER)
        sleep(3)

        self.assertTrue(
            TOTPDevice.objects.filter(user=USER(), confirmed=True).exists())
Exemple #7
0
 def test_login(self):
     """test default login flow"""
     self.driver.get(
         self.url(
             "authentik_core:if-flow",
             flow_slug="default-authentication-flow",
         ))
     self.login()
     self.wait_for_url(self.if_admin_url("/library"))
     self.assert_user(USER())
Exemple #8
0
    def test_static_setup(self):
        """test Static OTP Setup stage"""
        flow: Flow = Flow.objects.get(slug="default-authentication-flow")

        self.driver.get(self.url("authentik_core:if-flow",
                                 flow_slug=flow.slug))
        self.login()

        self.wait_for_url(self.if_admin_url("/library"))
        self.assert_user(USER())

        self.driver.get(
            self.url(
                "authentik_flows:configure",
                stage_uuid=AuthenticatorStaticStage.objects.first().stage_uuid,
            ))

        # Remember the current URL as we should end up back here
        destination_url = self.driver.current_url

        flow_executor = self.get_shadow_root("ak-flow-executor")
        authenticator_stage = self.get_shadow_root(
            "ak-stage-authenticator-static", flow_executor)
        token = authenticator_stage.find_element(
            By.CSS_SELECTOR, ".ak-otp-tokens li:nth-child(1)").text

        authenticator_stage.find_element(By.CSS_SELECTOR,
                                         "button[type=submit]").click()

        self.wait_for_url(destination_url)
        sleep(1)

        self.assertTrue(
            StaticDevice.objects.filter(user=USER(), confirmed=True).exists())
        device = StaticDevice.objects.filter(user=USER(),
                                             confirmed=True).first()
        self.assertTrue(
            StaticToken.objects.filter(token=token, device=device).exists())
Exemple #9
0
    def test_sp_initiated_implicit(self):
        """test SAML Provider flow SP-initiated flow (implicit consent)"""
        # Bootstrap all needed objects
        authorization_flow = Flow.objects.get(
            slug="default-provider-authorization-implicit-consent")
        provider: SAMLProvider = SAMLProvider.objects.create(
            name="saml-test",
            acs_url="http://localhost:9009/saml/acs",
            audience="authentik-e2e",
            issuer="authentik-e2e",
            sp_binding=SAMLBindings.POST,
            authorization_flow=authorization_flow,
            signing_kp=CertificateKeyPair.objects.first(),
        )
        provider.property_mappings.set(SAMLPropertyMapping.objects.all())
        provider.save()
        Application.objects.create(
            name="SAML",
            slug="authentik-saml",
            provider=provider,
        )
        self.container = self.setup_client(provider)
        self.driver.get("http://localhost:9009")
        self.login()
        self.wait_for_url("http://localhost:9009/")

        body = loads(self.driver.find_element(By.CSS_SELECTOR, "pre").text)

        self.assertEqual(
            body["attr"]
            ["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"],
            [USER().name],
        )
        self.assertEqual(
            body["attr"]
            ["http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"],
            [USER().username],
        )
        self.assertEqual(
            body["attr"]
            ["http://schemas.goauthentik.io/2021/02/saml/username"],
            [USER().username],
        )
        self.assertEqual(
            body["attr"]["http://schemas.goauthentik.io/2021/02/saml/uid"],
            [str(USER().pk)],
        )
        self.assertEqual(
            body["attr"]
            ["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"],
            [USER().email],
        )
        self.assertEqual(
            body["attr"]
            ["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"],
            [USER().email],
        )
Exemple #10
0
    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_client_secret()

        self.driver.get(
            self.url(
                "authentik_core:if-flow",
                flow_slug="default-authentication-flow",
            ))
        self.login()
        self.wait_for_url(self.if_admin_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_admin_url("/library"))
        # Because USER() is cached, we need to get the user manually here
        user = User.objects.get(username=USER().username)
        self.assertTrue(user.check_password(new_password))
    def test_authorization_consent_implied(self):
        """test OpenID Provider flow (default authorization flow with implied consent)"""
        sleep(1)
        # Bootstrap all needed objects
        authorization_flow = Flow.objects.get(
            slug="default-provider-authorization-implicit-consent"
        )
        provider = OAuth2Provider.objects.create(
            name=self.application_slug,
            client_type=ClientTypes.CONFIDENTIAL,
            client_id=self.client_id,
            client_secret=self.client_secret,
            rsa_key=CertificateKeyPair.objects.first(),
            redirect_uris="http://localhost:9009/auth/callback",
            authorization_flow=authorization_flow,
        )
        provider.property_mappings.set(
            ScopeMapping.objects.filter(
                scope_name__in=[SCOPE_OPENID, SCOPE_OPENID_EMAIL, SCOPE_OPENID_PROFILE]
            )
        )
        provider.save()
        Application.objects.create(
            name=self.application_slug,
            slug=self.application_slug,
            provider=provider,
        )
        self.container = self.setup_client()

        self.driver.get("http://localhost:9009")
        self.login()
        self.wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "pre")))
        body = loads(self.driver.find_element(By.CSS_SELECTOR, "pre").text)

        self.assertEqual(body["IDTokenClaims"]["nickname"], USER().username)
        self.assertEqual(body["UserInfo"]["nickname"], USER().username)

        self.assertEqual(body["IDTokenClaims"]["name"], USER().name)
        self.assertEqual(body["UserInfo"]["name"], USER().name)

        self.assertEqual(body["IDTokenClaims"]["email"], USER().email)
        self.assertEqual(body["UserInfo"]["email"], USER().email)
    def test_authorization_consent_explicit(self):
        """test OAuth Provider flow (default authorization flow with explicit consent)"""
        # Bootstrap all needed objects
        authorization_flow = Flow.objects.get(
            slug="default-provider-authorization-explicit-consent")
        provider = OAuth2Provider.objects.create(
            name="grafana",
            client_id=self.client_id,
            client_secret=self.client_secret,
            client_type=ClientTypes.CONFIDENTIAL,
            redirect_uris="http://localhost:3000/login/github",
            authorization_flow=authorization_flow,
        )
        app = Application.objects.create(
            name="Grafana",
            slug="grafana",
            provider=provider,
        )

        self.driver.get("http://localhost:3000")
        self.driver.find_element(By.CLASS_NAME, "btn-service--github").click()
        self.login()

        sleep(3)
        self.wait.until(
            ec.presence_of_element_located(
                (By.CSS_SELECTOR, "ak-flow-executor")))

        flow_executor = self.get_shadow_root("ak-flow-executor")
        consent_stage = self.get_shadow_root("ak-stage-consent", flow_executor)

        self.assertIn(
            app.name,
            consent_stage.find_element(By.CSS_SELECTOR, "#header-text").text,
        )
        self.assertEqual(
            "GitHub Compatibility: Access you Email addresses",
            consent_stage.find_element(
                By.CSS_SELECTOR, "[data-permission-code='user:email']").text,
        )
        consent_stage.find_element(
            By.CSS_SELECTOR,
            ("[type=submit]"),
        ).click()

        self.wait_for_url("http://localhost:3000/?orgId=1")
        self.driver.get("http://localhost:3000/profile")
        self.assertEqual(
            self.driver.find_element(By.CLASS_NAME, "page-header__title").text,
            USER().username,
        )
        self.assertEqual(
            self.driver.find_element(
                By.CSS_SELECTOR, "input[name=name]").get_attribute("value"),
            USER().username,
        )
        self.assertEqual(
            self.driver.find_element(
                By.CSS_SELECTOR, "input[name=email]").get_attribute("value"),
            USER().email,
        )
        self.assertEqual(
            self.driver.find_element(
                By.CSS_SELECTOR, "input[name=login]").get_attribute("value"),
            USER().username,
        )
Exemple #13
0
    def test_authorization_consent_explicit(self):
        """test OpenID Provider flow (default authorization flow with explicit consent)"""
        sleep(1)
        # Bootstrap all needed objects
        authorization_flow = Flow.objects.get(
            slug="default-provider-authorization-explicit-consent")
        provider = OAuth2Provider.objects.create(
            name="grafana",
            authorization_flow=authorization_flow,
            client_type=ClientTypes.CONFIDENTIAL,
            client_id=self.client_id,
            client_secret=self.client_secret,
            rsa_key=CertificateKeyPair.objects.first(),
            redirect_uris="http://localhost:3000/login/generic_oauth",
        )
        provider.property_mappings.set(
            ScopeMapping.objects.filter(scope_name__in=[
                SCOPE_OPENID, SCOPE_OPENID_EMAIL, SCOPE_OPENID_PROFILE
            ]))
        provider.save()
        app = Application.objects.create(
            name="Grafana",
            slug=APPLICATION_SLUG,
            provider=provider,
        )

        self.driver.get("http://localhost:3000")
        self.driver.find_element(By.CLASS_NAME, "btn-service--oauth").click()
        self.login()

        self.wait.until(
            ec.presence_of_element_located(
                (By.CSS_SELECTOR, "ak-flow-executor")))
        sleep(1)

        flow_executor = self.get_shadow_root("ak-flow-executor")
        consent_stage = self.get_shadow_root("ak-stage-consent", flow_executor)

        self.assertIn(
            app.name,
            consent_stage.find_element(By.CSS_SELECTOR, "#header-text").text,
        )
        consent_stage.find_element(
            By.CSS_SELECTOR,
            ("[type=submit]"),
        ).click()

        self.wait_for_url("http://localhost:3000/?orgId=1")
        self.driver.get("http://localhost:3000/profile")

        self.assertEqual(
            self.driver.find_element(By.CLASS_NAME, "page-header__title").text,
            USER().name,
        )
        self.assertEqual(
            self.driver.find_element(
                By.CSS_SELECTOR, "input[name=name]").get_attribute("value"),
            USER().name,
        )
        self.assertEqual(
            self.driver.find_element(
                By.CSS_SELECTOR, "input[name=email]").get_attribute("value"),
            USER().email,
        )
        self.assertEqual(
            self.driver.find_element(
                By.CSS_SELECTOR, "input[name=login]").get_attribute("value"),
            USER().email,
        )