diff --git a/acceptance/tests/idp-apple.spec.ts b/acceptance/tests/idp-apple.spec.ts new file mode 100644 index 00000000000..c599cd5bba8 --- /dev/null +++ b/acceptance/tests/idp-apple.spec.ts @@ -0,0 +1,128 @@ +import {test as base} from "@playwright/test"; +import {OtpType, PasswordUserWithOTP} from './user'; +import path from 'path'; +import dotenv from 'dotenv'; +import {loginScreenExpect, loginWithPassword} from "./login"; +import {startSink} from "./otp"; + +// Read from ".env" file. +dotenv.config({path: path.resolve(__dirname, '.env.local')}); + +const test = base.extend<{ user: PasswordUserWithOTP }>({ + user: async ({page}, use) => { + const user = new PasswordUserWithOTP({ + email: "otp_sms@example.com", + firstName: "first", + lastName: "last", + password: "Password1!", + organization: "", + type: OtpType.sms, + }); + + await user.ensure(page); + await use(user); + }, +}); + +// Note for all tests, in case Apple doesn't deliver all relevant information per default +// We should add an action in the needed cases + +test("login with Apple IDP", async ({user, page}) => { + // Given idp Apple is configured on the organization + // Given the user has Apple added as auth method + // User authenticates with Apple + // User is redirected back to login + // User is redirected to the app +}); + + +test("login with Apple IDP - error", async ({user, page}) => { + // Given idp Apple is configure on the organization + // Given the user Apple added as auth method + // User is redirected to Apple + // User authenticates with Apple and gets an error + // User is redirect back to login + // An error is shown to the user "Something went wrong in Apple Login" +}); + + + + + +test("login with Apple IDP, no user existing - auto register", async ({user, page}) => { + // Given idp Apple is configure on the organization as only authencation method + // Given idp Apple is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Apple + // User authenticates in Apple + // User is redirect to ZITADEL login + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Apple IDP, no user existing - auto register not possible", async ({user, page}) => { + // Given idp Apple is configure on the organization as only authencation method + // Given idp Apple is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Apple + // User authenticates in Apple + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // User will see the registration page with pre filled user information + // User fills missing information + // User clicks register button + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Apple IDP, no user existing - auto register enabled - manual creation disabled, creation not possible", async ({user, page}) => { + // Given idp Apple is configure on the organization as only authencation method + // Given idp Apple is configure with account creation not allowed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Apple + // User authenticates in Apple + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // Error message is shown, that registration of the user was not possible due to missing information +}); + +test("login with Apple IDP, no user linked - auto link", async ({user, page}) => { + // Given idp Apple is configure on the organization as only authencation method + // Given idp Apple is configure with account linking allowed, and linking set to existing email + // Given user with email address user@zitadel.com exists + + // User is automatically redirected to Apple + // User authenticates in Apple with user@zitadel.com + // User is redirect to ZITADEL login + // User is linked with existing user in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Apple IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp Apple is configure on the organization as only authencation method + // Given idp Apple is configure with manually account linking not allowed, and linking set to existing email + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to Apple + // User authenticates in Apple with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User will get an error message that account linking wasn't possible +}); + + +test("login with Apple IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp Apple is configure on the organization as only authencation method + // Given idp Apple is configure with manually account linking allowed, and linking set to existing email + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to Apple + // User authenticates in Apple with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User is prompted to link the account manually + // User is redirected to the app (default redirect url) +}); diff --git a/acceptance/tests/idp-generic-jwt.spec.ts b/acceptance/tests/idp-generic-jwt.spec.ts new file mode 100644 index 00000000000..6ca3558dd64 --- /dev/null +++ b/acceptance/tests/idp-generic-jwt.spec.ts @@ -0,0 +1,151 @@ +import {test as base} from "@playwright/test"; +import {OtpType, PasswordUserWithOTP} from './user'; +import path from 'path'; +import dotenv from 'dotenv'; +import {loginScreenExpect, loginWithPassword} from "./login"; +import {startSink} from "./otp"; + +// Read from ".env" file. +dotenv.config({path: path.resolve(__dirname, '.env.local')}); + +const test = base.extend<{ user: PasswordUserWithOTP }>({ + user: async ({page}, use) => { + const user = new PasswordUserWithOTP({ + email: "otp_sms@example.com", + firstName: "first", + lastName: "last", + password: "Password1!", + organization: "", + type: OtpType.sms, + }); + + await user.ensure(page); + await use(user); + }, +}); + +test("login with Generic JWT IDP - auto redirect", async ({user, page}) => { + // Given idp Generic JWT is configure on the organization as only authencation method + // Given the user has only idp Generic JWT added as auth method + + // User is automatically redirected to Generic JWT + // User authenticates in Generic JWT + // User is redirect to ZITADEL login + // User is redirected to the app (default redirect url) +}); + + +test("login with Generic JWT IDP - auto redirect, error", async ({user, page}) => { + // Given idp Generic JWT is configure on the organization as only authencation method + // Given the user has only idp Generic JWT added as auth method + + // User is automatically redirected to Generic JWT + // User authenticates in Generic JWT and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in Generic JWT Login" +}); + + +test("login with Generic JWT IDP", async ({user, page}) => { + // Given username password and idp Generic JWT is configure on the organization as authencation method + // Given the user has username password and Generic JWT configured + + // Login form shows username field and a Generic JWT Login button + // User clicks on the Generic JWT button + // User is redirected to Generic JWT + // User authenticates in Generic JWT and gets an error + // User is redirect to ZITADEL login automatically + // User is redirected to app automatically (default redirect url) +}); + + +test("login with Generic JWT IDP, error", async ({user, page}) => { + // Given username password and idp Generic JWT is configure on the organization as authencation method + // Given the user has username password and Generic JWT configured + + // Login form shows username field and a Generic JWT Login button + // User clicks on the Generic JWT button + // User is redirected to Generic JWT + // User authenticates in Generic JWT and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in Generic JWT Login" + // User can choose password for authentication +}); + +test("login with Generic JWT IDP, no user existing - auto register", async ({user, page}) => { + // Given idp Generic JWT is configure on the organization as only authencation method + // Given idp Generic JWT is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Generic JWT + // User authenticates in Generic JWT + // User is redirect to ZITADEL login + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Generic JWT IDP, no user existing - auto register not possible", async ({user, page}) => { + // Given idp Generic JWT is configure on the organization as only authencation method + // Given idp Generic JWT is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Generic JWT + // User authenticates in Generic JWT + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // User will see the registration page with pre filled user information + // User fills missing information + // User clicks register button + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Generic JWT IDP, no user existing - auto register enabled - manual creation disabled, creation not possible", async ({user, page}) => { + // Given idp Generic JWT is configure on the organization as only authencation method + // Given idp Generic JWT is configure with account creation not allowed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Generic JWT + // User authenticates in Generic JWT + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // Error message is shown, that registration of the user was not possible due to missing information +}); + +test("login with Generic JWT IDP, no user linked - auto link", async ({user, page}) => { + // Given idp Generic JWT is configure on the organization as only authencation method + // Given idp Generic JWT is configure with account linking allowed, and linking set to existing email + // Given user with email address user@zitadel.com exists + + // User is automatically redirected to Generic JWT + // User authenticates in Generic JWT with user@zitadel.com + // User is redirect to ZITADEL login + // User is linked with existing user in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Generic JWT IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp Generic JWT is configure on the organization as only authencation method + // Given idp Generic JWT is configure with manually account linking not allowed, and linking set to existing email + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to Generic JWT + // User authenticates in Generic JWT with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User will get an error message that account linking wasn't possible +}); + + +test("login with Generic JWT IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp Generic JWT is configure on the organization as only authencation method + // Given idp Generic JWT is configure with manually account linking allowed, and linking set to existing email + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to Generic JWT + // User authenticates in Generic JWT with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User is prompted to link the account manually + // User is redirected to the app (default redirect url) +}); diff --git a/acceptance/tests/idp-generic-oauth.spec.ts b/acceptance/tests/idp-generic-oauth.spec.ts new file mode 100644 index 00000000000..0d55f399737 --- /dev/null +++ b/acceptance/tests/idp-generic-oauth.spec.ts @@ -0,0 +1,152 @@ +import {test as base} from "@playwright/test"; +import {OtpType, PasswordUserWithOTP} from './user'; +import path from 'path'; +import dotenv from 'dotenv'; +import {loginScreenExpect, loginWithPassword} from "./login"; +import {startSink} from "./otp"; + +// Read from ".env" file. +dotenv.config({path: path.resolve(__dirname, '.env.local')}); + +const test = base.extend<{ user: PasswordUserWithOTP }>({ + user: async ({page}, use) => { + const user = new PasswordUserWithOTP({ + email: "otp_sms@example.com", + firstName: "first", + lastName: "last", + password: "Password1!", + organization: "", + type: OtpType.sms, + }); + + await user.ensure(page); + await use(user); + }, +}); + + +test("login with Generic OAuth IDP - auto redirect", async ({user, page}) => { + // Given idp Generic OAuth is configure on the organization as only authencation method + // Given the user has only idp Generic OAuth added as auth method + + // User is automatically redirected to Generic OAuth + // User authenticates in Generic OAuth + // User is redirect to ZITADEL login + // User is redirected to the app (default redirect url) +}); + + +test("login with Generic OAuth IDP - auto redirect, error", async ({user, page}) => { + // Given idp Generic OAuth is configure on the organization as only authencation method + // Given the user has only idp Generic OAuth added as auth method + + // User is automatically redirected to Generic OAuth + // User authenticates in Generic OAuth and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in Generic OAuth Login" +}); + + +test("login with Generic OAuth IDP", async ({user, page}) => { + // Given username password and idp Generic OAuth is configure on the organization as authencation method + // Given the user has username password and Generic OAuth configured + + // Login form shows username field and a Generic OAuth Login button + // User clicks on the Generic OAuth button + // User is redirected to Generic OAuth + // User authenticates in Generic OAuth and gets an error + // User is redirect to ZITADEL login automatically + // User is redirected to app automatically (default redirect url) +}); + + +test("login with Generic OAuth IDP, error", async ({user, page}) => { + // Given username password and idp Generic OAuth is configure on the organization as authencation method + // Given the user has username password and Generic OAuth configured + + // Login form shows username field and a Generic OAuth Login button + // User clicks on the Generic OAuth button + // User is redirected to Generic OAuth + // User authenticates in Generic OAuth and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in Generic OAuth Login" + // User can choose password for authentication +}); + +test("login with Generic OAuth IDP, no user existing - auto register", async ({user, page}) => { + // Given idp Generic OAuth is configure on the organization as only authencation method + // Given idp Generic OAuth is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Generic OAuth + // User authenticates in Generic OAuth + // User is redirect to ZITADEL login + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Generic OAuth IDP, no user existing - auto register not possible", async ({user, page}) => { + // Given idp Generic OAuth is configure on the organization as only authencation method + // Given idp Generic OAuth is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Generic OAuth + // User authenticates in Generic OAuth + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // User will see the registration page with pre filled user information + // User fills missing information + // User clicks register button + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Generic OAuth IDP, no user existing - auto register enabled - manual creation disabled, creation not possible", async ({user, page}) => { + // Given idp Generic OAuth is configure on the organization as only authencation method + // Given idp Generic OAuth is configure with account creation not allowed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Generic OAuth + // User authenticates in Generic OAuth + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // Error message is shown, that registration of the user was not possible due to missing information +}); + +test("login with Generic OAuth IDP, no user linked - auto link", async ({user, page}) => { + // Given idp Generic OAuth is configure on the organization as only authencation method + // Given idp Generic OAuth is configure with account linking allowed, and linking set to existing email + // Given user with email address user@zitadel.com exists + + // User is automatically redirected to Generic OAuth + // User authenticates in Generic OAuth with user@zitadel.com + // User is redirect to ZITADEL login + // User is linked with existing user in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Generic OAuth IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp Generic OAuth is configure on the organization as only authencation method + // Given idp Generic OAuth is configure with manually account linking not allowed, and linking set to existing email + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to Generic OAuth + // User authenticates in Generic OAuth with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User will get an error message that account linking wasn't possible +}); + + +test("login with Generic OAuth IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp Generic OAuth is configure on the organization as only authencation method + // Given idp Generic OAuth is configure with manually account linking allowed, and linking set to existing email + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to Generic OAuth + // User authenticates in Generic OAuth with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User is prompted to link the account manually + // User is redirected to the app (default redirect url) +}); diff --git a/acceptance/tests/idp-generic-oidc.spec.ts b/acceptance/tests/idp-generic-oidc.spec.ts new file mode 100644 index 00000000000..ed19a50a732 --- /dev/null +++ b/acceptance/tests/idp-generic-oidc.spec.ts @@ -0,0 +1,153 @@ +import {test as base} from "@playwright/test"; +import {OtpType, PasswordUserWithOTP} from './user'; +import path from 'path'; +import dotenv from 'dotenv'; +import {loginScreenExpect, loginWithPassword} from "./login"; +import {startSink} from "./otp"; + +// Read from ".env" file. +dotenv.config({path: path.resolve(__dirname, '.env.local')}); + +const test = base.extend<{ user: PasswordUserWithOTP }>({ + user: async ({page}, use) => { + const user = new PasswordUserWithOTP({ + email: "otp_sms@example.com", + firstName: "first", + lastName: "last", + password: "Password1!", + organization: "", + type: OtpType.sms, + }); + + await user.ensure(page); + await use(user); + }, +}); + +// Note, we should use a provider such as Google to test this, where we know OIDC standard is properly implemented + +test("login with Generic OIDC IDP - auto redirect", async ({user, page}) => { + // Given idp Generic OIDC is configure on the organization as only authencation method + // Given the user has only idp Generic OIDC added as auth method + + // User is automatically redirected to Generic OIDC + // User authenticates in Generic OIDC + // User is redirect to ZITADEL login + // User is redirected to the app (default redirect url) +}); + + +test("login with Generic OIDC IDP - auto redirect, error", async ({user, page}) => { + // Given idp Generic OIDC is configure on the organization as only authencation method + // Given the user has only idp Generic OIDC added as auth method + + // User is automatically redirected to Generic OIDC + // User authenticates in Generic OIDC and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in Generic OIDC Login" +}); + + +test("login with Generic OIDC IDP", async ({user, page}) => { + // Given username password and idp Generic OIDC is configure on the organization as authencation method + // Given the user has username password and Generic OIDC configured + + // Login form shows username field and a Generic OIDC Login button + // User clicks on the Generic OIDC button + // User is redirected to Generic OIDC + // User authenticates in Generic OIDC and gets an error + // User is redirect to ZITADEL login automatically + // User is redirected to app automatically (default redirect url) +}); + + +test("login with Generic OIDC IDP, error", async ({user, page}) => { + // Given username password and idp Generic OIDC is configure on the organization as authencation method + // Given the user has username password and Generic OIDC configured + + // Login form shows username field and a Generic OIDC Login button + // User clicks on the Generic OIDC button + // User is redirected to Generic OIDC + // User authenticates in Generic OIDC and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in Generic OIDC Login" + // User can choose password for authentication +}); + +test("login with Generic OIDC IDP, no user existing - auto register", async ({user, page}) => { + // Given idp Generic OIDC is configure on the organization as only authencation method + // Given idp Generic OIDC is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Generic OIDC + // User authenticates in Generic OIDC + // User is redirect to ZITADEL login + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Generic OIDC IDP, no user existing - auto register not possible", async ({user, page}) => { + // Given idp Generic OIDC is configure on the organization as only authencation method + // Given idp Generic OIDC is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Generic OIDC + // User authenticates in Generic OIDC + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // User will see the registration page with pre filled user information + // User fills missing information + // User clicks register button + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Generic OIDC IDP, no user existing - auto register enabled - manual creation disabled, creation not possible", async ({user, page}) => { + // Given idp Generic OIDC is configure on the organization as only authencation method + // Given idp Generic OIDC is configure with account creation not allowed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Generic OIDC + // User authenticates in Generic OIDC + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // Error message is shown, that registration of the user was not possible due to missing information +}); + +test("login with Generic OIDC IDP, no user linked - auto link", async ({user, page}) => { + // Given idp Generic OIDC is configure on the organization as only authencation method + // Given idp Generic OIDC is configure with account linking allowed, and linking set to existing email + // Given user with email address user@zitadel.com exists + + // User is automatically redirected to Generic OIDC + // User authenticates in Generic OIDC with user@zitadel.com + // User is redirect to ZITADEL login + // User is linked with existing user in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Generic OIDC IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp Generic OIDC is configure on the organization as only authencation method + // Given idp Generic OIDC is configure with manually account linking not allowed, and linking set to existing email + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to Generic OIDC + // User authenticates in Generic OIDC with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User will get an error message that account linking wasn't possible +}); + + +test("login with Generic OIDC IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp Generic OIDC is configure on the organization as only authencation method + // Given idp Generic OIDC is configure with manually account linking allowed, and linking set to existing email + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to Generic OIDC + // User authenticates in Generic OIDC with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User is prompted to link the account manually + // User is redirected to the app (default redirect url) +}); diff --git a/acceptance/tests/idp-github-enterprise.spec.ts b/acceptance/tests/idp-github-enterprise.spec.ts new file mode 100644 index 00000000000..ee7f5d8a5be --- /dev/null +++ b/acceptance/tests/idp-github-enterprise.spec.ts @@ -0,0 +1,156 @@ +import {test as base} from "@playwright/test"; +import {OtpType, PasswordUserWithOTP} from './user'; +import path from 'path'; +import dotenv from 'dotenv'; +import {loginScreenExpect, loginWithPassword} from "./login"; +import {startSink} from "./otp"; + +// Read from ".env" file. +dotenv.config({path: path.resolve(__dirname, '.env.local')}); + +const test = base.extend<{ user: PasswordUserWithOTP }>({ + user: async ({page}, use) => { + const user = new PasswordUserWithOTP({ + email: "otp_sms@example.com", + firstName: "first", + lastName: "last", + password: "Password1!", + organization: "", + type: OtpType.sms, + }); + + await user.ensure(page); + await use(user); + }, +}); + + +test("login with GitHub Enterprise IDP - auto redirect", async ({user, page}) => { + // Given idp GitHub Enterprise is configure on the organization as only authencation method + // Given the user has only idp GitHub Enterprise added as auth method + + // User is automatically redirected to GitHub Enterprise + // User authenticates in GitHub Enterprise + // User is redirect to ZITADEL login + // User is redirected to the app (default redirect url) +}); + + +test("login with GitHub Enterprise IDP - auto redirect, error", async ({user, page}) => { + // Given idp GitHub Enterprise is configure on the organization as only authencation method + // Given the user has only idp GitHub Enterprise added as auth method + + // User is automatically redirected to GitHub Enterprise + // User authenticates in GitHub Enterprise and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in GitHub Enterprise Login" +}); + + +test("login with GitHub Enterprise IDP", async ({user, page}) => { + // Given username password and idp GitHub Enterprise is configure on the organization as authencation method + // Given the user has username password and GitHub Enterprise configured + + // Login form shows username field and a GitHub Enterprise Login button + // User clicks on the GitHub Enterprise button + // User is redirected to GitHub Enterprise + // User authenticates in GitHub Enterprise and gets an error + // User is redirect to ZITADEL login automatically + // User is redirected to app automatically (default redirect url) +}); + + +test("login with GitHub Enterprise IDP, error", async ({user, page}) => { + // Given username password and idp GitHub Enterprise is configure on the organization as authencation method + // Given the user has username password and GitHub Enterprise configured + + // Login form shows username field and a GitHub Enterprise Login button + // User clicks on the GitHub Enterprise button + // User is redirected to GitHub Enterprise + // User authenticates in GitHub Enterprise and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in GitHub Enterprise Login" + // User can choose password for authentication +}); + +test("login with GitHub Enterprise IDP, no user existing - auto register", async ({user, page}) => { + // Given idp GitHub Enterprise is configure on the organization as only authencation method + // Given idp GitHub Enterprise is configure with account creation alloweed, and automatic creation enabled + // Given ZITADEL Action is added to autofill missing user information + // Given no user exists yet + + // User is automatically redirected to GitHub Enterprise + // User authenticates in GitHub Enterprise + // User is redirect to ZITADEL login + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with GitHub Enterprise IDP, no user existing - auto register not possible", async ({user, page}) => { + // Given idp GitHub Enterprise is configure on the organization as only authencation method + // Given idp GitHub Enterprise is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to GitHub Enterprise + // User authenticates in GitHub Enterprise + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // User will see the registration page with pre filled user information + // User fills missing information + // User clicks register button + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with GitHub Enterprise IDP, no user existing - auto register enabled - manual creation disabled, creation not possible", async ({user, page}) => { + // Given idp GitHub Enterprise is configure on the organization as only authencation method + // Given idp GitHub Enterprise is configure with account creation not allowed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to GitHub Enterprise + // User authenticates in GitHub Enterprise + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // Error message is shown, that registration of the user was not possible due to missing information +}); + +test("login with GitHub Enterprise IDP, no user linked - auto link", async ({user, page}) => { + // Given idp GitHub Enterprise is configure on the organization as only authencation method + // Given idp GitHub Enterprise is configure with account linking allowed, and linking set to existing email + // Given ZITADEL Action is added to autofill missing user information + // Given user with email address user@zitadel.com exists + + // User is automatically redirected to GitHub Enterprise + // User authenticates in GitHub Enterprise with user@zitadel.com + // User is redirect to ZITADEL login + // User is linked with existing user in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with GitHub Enterprise IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp GitHub Enterprise is configure on the organization as only authencation method + // Given idp GitHub Enterprise is configure with manually account linking not allowed, and linking set to existing email + // Given ZITADEL Action is added to autofill missing user information + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to GitHub Enterprise + // User authenticates in GitHub Enterprise with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User will get an error message that account linking wasn't possible +}); + + +test("login with GitHub Enterprise IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp GitHub Enterprise is configure on the organization as only authencation method + // Given idp GitHub Enterprise is configure with manually account linking allowed, and linking set to existing email + // Given ZITADEL Action is added to autofill missing user information + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to GitHub Enterprise + // User authenticates in GitHub Enterprise with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User is prompted to link the account manually + // User is redirected to the app (default redirect url) +}); diff --git a/acceptance/tests/idp-github.spec.ts b/acceptance/tests/idp-github.spec.ts new file mode 100644 index 00000000000..0ac8c13193e --- /dev/null +++ b/acceptance/tests/idp-github.spec.ts @@ -0,0 +1,156 @@ +import {test as base} from "@playwright/test"; +import {OtpType, PasswordUserWithOTP} from './user'; +import path from 'path'; +import dotenv from 'dotenv'; +import {loginScreenExpect, loginWithPassword} from "./login"; +import {startSink} from "./otp"; + +// Read from ".env" file. +dotenv.config({path: path.resolve(__dirname, '.env.local')}); + +const test = base.extend<{ user: PasswordUserWithOTP }>({ + user: async ({page}, use) => { + const user = new PasswordUserWithOTP({ + email: "otp_sms@example.com", + firstName: "first", + lastName: "last", + password: "Password1!", + organization: "", + type: OtpType.sms, + }); + + await user.ensure(page); + await use(user); + }, +}); + + +test("login with GitHub IDP - auto redirect", async ({user, page}) => { + // Given idp GitHub is configure on the organization as only authencation method + // Given the user has only idp GitHub added as auth method + + // User is automatically redirected to GitHub + // User authenticates in GitHub + // User is redirect to ZITADEL login + // User is redirected to the app (default redirect url) +}); + + +test("login with GitHub IDP - auto redirect, error", async ({user, page}) => { + // Given idp GitHub is configure on the organization as only authencation method + // Given the user has only idp GitHub added as auth method + + // User is automatically redirected to GitHub + // User authenticates in GitHub and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in GitHub Login" +}); + + +test("login with GitHub IDP", async ({user, page}) => { + // Given username password and idp GitHub is configure on the organization as authencation method + // Given the user has username password and GitHub configured + + // Login form shows username field and a GitHub Login button + // User clicks on the GitHub button + // User is redirected to GitHub + // User authenticates in GitHub and gets an error + // User is redirect to ZITADEL login automatically + // User is redirected to app automatically (default redirect url) +}); + + +test("login with GitHub IDP, error", async ({user, page}) => { + // Given username password and idp GitHub is configure on the organization as authencation method + // Given the user has username password and GitHub configured + + // Login form shows username field and a GitHub Login button + // User clicks on the GitHub button + // User is redirected to GitHub + // User authenticates in GitHub and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in GitHub Login" + // User can choose password for authentication +}); + +test("login with GitHub IDP, no user existing - auto register", async ({user, page}) => { + // Given idp GitHub is configure on the organization as only authencation method + // Given idp GitHub is configure with account creation alloweed, and automatic creation enabled + // Given ZITADEL Action is added to autofill missing user information + // Given no user exists yet + + // User is automatically redirected to GitHub + // User authenticates in GitHub + // User is redirect to ZITADEL login + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with GitHub IDP, no user existing - auto register not possible", async ({user, page}) => { + // Given idp GitHub is configure on the organization as only authencation method + // Given idp GitHub is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to GitHub + // User authenticates in GitHub + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // User will see the registration page with pre filled user information + // User fills missing information + // User clicks register button + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with GitHub IDP, no user existing - auto register enabled - manual creation disabled, creation not possible", async ({user, page}) => { + // Given idp GitHub is configure on the organization as only authencation method + // Given idp GitHub is configure with account creation not allowed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to GitHub + // User authenticates in GitHub + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // Error message is shown, that registration of the user was not possible due to missing information +}); + +test("login with GitHub IDP, no user linked - auto link", async ({user, page}) => { + // Given idp GitHub is configure on the organization as only authencation method + // Given idp GitHub is configure with account linking allowed, and linking set to existing email + // Given ZITADEL Action is added to autofill missing user information + // Given user with email address user@zitadel.com exists + + // User is automatically redirected to GitHub + // User authenticates in GitHub with user@zitadel.com + // User is redirect to ZITADEL login + // User is linked with existing user in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with GitHub IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp GitHub is configure on the organization as only authencation method + // Given idp GitHub is configure with manually account linking not allowed, and linking set to existing email + // Given ZITADEL Action is added to autofill missing user information + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to GitHub + // User authenticates in GitHub with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User will get an error message that account linking wasn't possible +}); + + +test("login with GitHub IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp GitHub is configure on the organization as only authencation method + // Given idp GitHub is configure with manually account linking allowed, and linking set to existing email + // Given ZITADEL Action is added to autofill missing user information + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to GitHub + // User authenticates in GitHub with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User is prompted to link the account manually + // User is redirected to the app (default redirect url) +}); diff --git a/acceptance/tests/idp-gitlab-self-hosted.spec.ts b/acceptance/tests/idp-gitlab-self-hosted.spec.ts new file mode 100644 index 00000000000..00b0ec7c4af --- /dev/null +++ b/acceptance/tests/idp-gitlab-self-hosted.spec.ts @@ -0,0 +1,156 @@ +import {test as base} from "@playwright/test"; +import {OtpType, PasswordUserWithOTP} from './user'; +import path from 'path'; +import dotenv from 'dotenv'; +import {loginScreenExpect, loginWithPassword} from "./login"; +import {startSink} from "./otp"; + +// Read from ".env" file. +dotenv.config({path: path.resolve(__dirname, '.env.local')}); + +const test = base.extend<{ user: PasswordUserWithOTP }>({ + user: async ({page}, use) => { + const user = new PasswordUserWithOTP({ + email: "otp_sms@example.com", + firstName: "first", + lastName: "last", + password: "Password1!", + organization: "", + type: OtpType.sms, + }); + + await user.ensure(page); + await use(user); + }, +}); + + +test("login with Gitlab Self-Hosted IDP - auto redirect", async ({user, page}) => { + // Given idp Gitlab Self-Hosted is configure on the organization as only authencation method + // Given the user has only idp Gitlab Self-Hosted added as auth method + + // User is automatically redirected to Gitlab Self-Hosted + // User authenticates in Gitlab Self-Hosted + // User is redirect to ZITADEL login + // User is redirected to the app (default redirect url) +}); + + +test("login with Gitlab Self-Hosted IDP - auto redirect, error", async ({user, page}) => { + // Given idp Gitlab Self-Hosted is configure on the organization as only authencation method + // Given the user has only idp Gitlab Self-Hosted added as auth method + + // User is automatically redirected to Gitlab Self-Hosted + // User authenticates in Gitlab Self-Hosted and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in Gitlab Self-Hosted Login" +}); + + +test("login with Gitlab Self-Hosted IDP", async ({user, page}) => { + // Given username password and idp Gitlab Self-Hosted is configure on the organization as authencation method + // Given the user has username password and Gitlab Self-Hosted configured + + // Login form shows username field and a Gitlab Self-Hosted Login button + // User clicks on the Gitlab Self-Hosted button + // User is redirected to Gitlab Self-Hosted + // User authenticates in Gitlab Self-Hosted and gets an error + // User is redirect to ZITADEL login automatically + // User is redirected to app automatically (default redirect url) +}); + + +test("login with Gitlab Self-Hosted IDP, error", async ({user, page}) => { + // Given username password and idp Gitlab Self-Hosted is configure on the organization as authencation method + // Given the user has username password and Gitlab Self-Hosted configured + + // Login form shows username field and a Gitlab Self-Hosted Login button + // User clicks on the Gitlab Self-Hosted button + // User is redirected to Gitlab Self-Hosted + // User authenticates in Gitlab Self-Hosted and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in Gitlab Self-Hosted Login" + // User can choose password for authentication +}); + +test("login with Gitlab Self-Hosted IDP, no user existing - auto register", async ({user, page}) => { + // Given idp Gitlab Self-Hosted is configure on the organization as only authencation method + // Given idp Gitlab Self-Hosted is configure with account creation alloweed, and automatic creation enabled + // Given ZITADEL Action is added to autofill missing user information + // Given no user exists yet + + // User is automatically redirected to Gitlab Self-Hosted + // User authenticates in Gitlab Self-Hosted + // User is redirect to ZITADEL login + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Gitlab Self-Hosted IDP, no user existing - auto register not possible", async ({user, page}) => { + // Given idp Gitlab Self-Hosted is configure on the organization as only authencation method + // Given idp Gitlab Self-Hosted is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Gitlab Self-Hosted + // User authenticates in Gitlab Self-Hosted + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // User will see the registration page with pre filled user information + // User fills missing information + // User clicks register button + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Gitlab Self-Hosted IDP, no user existing - auto register enabled - manual creation disabled, creation not possible", async ({user, page}) => { + // Given idp Gitlab Self-Hosted is configure on the organization as only authencation method + // Given idp Gitlab Self-Hosted is configure with account creation not allowed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Gitlab Self-Hosted + // User authenticates in Gitlab Self-Hosted + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // Error message is shown, that registration of the user was not possible due to missing information +}); + +test("login with Gitlab Self-Hosted IDP, no user linked - auto link", async ({user, page}) => { + // Given idp Gitlab Self-Hosted is configure on the organization as only authencation method + // Given idp Gitlab Self-Hosted is configure with account linking allowed, and linking set to existing email + // Given ZITADEL Action is added to autofill missing user information + // Given user with email address user@zitadel.com exists + + // User is automatically redirected to Gitlab Self-Hosted + // User authenticates in Gitlab Self-Hosted with user@zitadel.com + // User is redirect to ZITADEL login + // User is linked with existing user in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Gitlab Self-Hosted IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp Gitlab Self-Hosted is configure on the organization as only authencation method + // Given idp Gitlab Self-Hosted is configure with manually account linking not allowed, and linking set to existing email + // Given ZITADEL Action is added to autofill missing user information + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to Gitlab Self-Hosted + // User authenticates in Gitlab Self-Hosted with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User will get an error message that account linking wasn't possible +}); + + +test("login with Gitlab Self-Hosted IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp Gitlab Self-Hosted is configure on the organization as only authencation method + // Given idp Gitlab Self-Hosted is configure with manually account linking allowed, and linking set to existing email + // Given ZITADEL Action is added to autofill missing user information + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to Gitlab Self-Hosted + // User authenticates in Gitlab Self-Hosted with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User is prompted to link the account manually + // User is redirected to the app (default redirect url) +}); diff --git a/acceptance/tests/idp-gitlab.spec.ts b/acceptance/tests/idp-gitlab.spec.ts new file mode 100644 index 00000000000..a94b1ac77d8 --- /dev/null +++ b/acceptance/tests/idp-gitlab.spec.ts @@ -0,0 +1,156 @@ +import {test as base} from "@playwright/test"; +import {OtpType, PasswordUserWithOTP} from './user'; +import path from 'path'; +import dotenv from 'dotenv'; +import {loginScreenExpect, loginWithPassword} from "./login"; +import {startSink} from "./otp"; + +// Read from ".env" file. +dotenv.config({path: path.resolve(__dirname, '.env.local')}); + +const test = base.extend<{ user: PasswordUserWithOTP }>({ + user: async ({page}, use) => { + const user = new PasswordUserWithOTP({ + email: "otp_sms@example.com", + firstName: "first", + lastName: "last", + password: "Password1!", + organization: "", + type: OtpType.sms, + }); + + await user.ensure(page); + await use(user); + }, +}); + + +test("login with Gitlab IDP - auto redirect", async ({user, page}) => { + // Given idp Gitlab is configure on the organization as only authencation method + // Given the user has only idp Gitlab added as auth method + + // User is automatically redirected to Gitlab + // User authenticates in Gitlab + // User is redirect to ZITADEL login + // User is redirected to the app (default redirect url) +}); + + +test("login with Gitlab IDP - auto redirect, error", async ({user, page}) => { + // Given idp Gitlab is configure on the organization as only authencation method + // Given the user has only idp Gitlab added as auth method + + // User is automatically redirected to Gitlab + // User authenticates in Gitlab and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in Gitlab Login" +}); + + +test("login with Gitlab IDP", async ({user, page}) => { + // Given username password and idp Gitlab is configure on the organization as authencation method + // Given the user has username password and Gitlab configured + + // Login form shows username field and a Gitlab Login button + // User clicks on the Gitlab button + // User is redirected to Gitlab + // User authenticates in Gitlab and gets an error + // User is redirect to ZITADEL login automatically + // User is redirected to app automatically (default redirect url) +}); + + +test("login with Gitlab IDP, error", async ({user, page}) => { + // Given username password and idp Gitlab is configure on the organization as authencation method + // Given the user has username password and Gitlab configured + + // Login form shows username field and a Gitlab Login button + // User clicks on the Gitlab button + // User is redirected to Gitlab + // User authenticates in Gitlab and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in Gitlab Login" + // User can choose password for authentication +}); + +test("login with Gitlab IDP, no user existing - auto register", async ({user, page}) => { + // Given idp Gitlab is configure on the organization as only authencation method + // Given idp Gitlab is configure with account creation alloweed, and automatic creation enabled + // Given ZITADEL Action is added to autofill missing user information + // Given no user exists yet + + // User is automatically redirected to Gitlab + // User authenticates in Gitlab + // User is redirect to ZITADEL login + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Gitlab IDP, no user existing - auto register not possible", async ({user, page}) => { + // Given idp Gitlab is configure on the organization as only authencation method + // Given idp Gitlab is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Gitlab + // User authenticates in Gitlab + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // User will see the registration page with pre filled user information + // User fills missing information + // User clicks register button + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Gitlab IDP, no user existing - auto register enabled - manual creation disabled, creation not possible", async ({user, page}) => { + // Given idp Gitlab is configure on the organization as only authencation method + // Given idp Gitlab is configure with account creation not allowed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Gitlab + // User authenticates in Gitlab + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // Error message is shown, that registration of the user was not possible due to missing information +}); + +test("login with Gitlab IDP, no user linked - auto link", async ({user, page}) => { + // Given idp Gitlab is configure on the organization as only authencation method + // Given idp Gitlab is configure with account linking allowed, and linking set to existing email + // Given ZITADEL Action is added to autofill missing user information + // Given user with email address user@zitadel.com exists + + // User is automatically redirected to Gitlab + // User authenticates in Gitlab with user@zitadel.com + // User is redirect to ZITADEL login + // User is linked with existing user in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Gitlab IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp Gitlab is configure on the organization as only authencation method + // Given idp Gitlab is configure with manually account linking not allowed, and linking set to existing email + // Given ZITADEL Action is added to autofill missing user information + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to Gitlab + // User authenticates in Gitlab with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User will get an error message that account linking wasn't possible +}); + + +test("login with Gitlab IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp Gitlab is configure on the organization as only authencation method + // Given idp Gitlab is configure with manually account linking allowed, and linking set to existing email + // Given ZITADEL Action is added to autofill missing user information + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to Gitlab + // User authenticates in Gitlab with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User is prompted to link the account manually + // User is redirected to the app (default redirect url) +}); diff --git a/acceptance/tests/idp-google.spec.ts b/acceptance/tests/idp-google.spec.ts new file mode 100644 index 00000000000..8c13449adde --- /dev/null +++ b/acceptance/tests/idp-google.spec.ts @@ -0,0 +1,151 @@ +import {test as base} from "@playwright/test"; +import {OtpType, PasswordUserWithOTP} from './user'; +import path from 'path'; +import dotenv from 'dotenv'; +import {loginScreenExpect, loginWithPassword} from "./login"; +import {startSink} from "./otp"; + +// Read from ".env" file. +dotenv.config({path: path.resolve(__dirname, '.env.local')}); + +const test = base.extend<{ user: PasswordUserWithOTP }>({ + user: async ({page}, use) => { + const user = new PasswordUserWithOTP({ + email: "otp_sms@example.com", + firstName: "first", + lastName: "last", + password: "Password1!", + organization: "", + type: OtpType.sms, + }); + + await user.ensure(page); + await use(user); + }, +}); + +test("login with Google IDP - auto redirect", async ({user, page}) => { + // Given idp Google is configure on the organization as only authencation method + // Given the user has only idp Google added as auth method + + // User is automatically redirected to Google + // User authenticates in Google + // User is redirect to ZITADEL login + // User is redirected to the app (default redirect url) +}); + + +test("login with Google IDP - auto redirect, error", async ({user, page}) => { + // Given idp Google is configure on the organization as only authencation method + // Given the user has only idp Google added as auth method + + // User is automatically redirected to Google + // User authenticates in Google and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in Google Login" +}); + + +test("login with Google IDP", async ({user, page}) => { + // Given username password and idp Google is configure on the organization as authencation method + // Given the user has username password and Google configured + + // Login form shows username field and a Google Login button + // User clicks on the Google button + // User is redirected to Google + // User authenticates in Google and gets an error + // User is redirect to ZITADEL login automatically + // User is redirected to app automatically (default redirect url) +}); + + +test("login with Google IDP, error", async ({user, page}) => { + // Given username password and idp Google is configure on the organization as authencation method + // Given the user has username password and Google configured + + // Login form shows username field and a Google Login button + // User clicks on the Google button + // User is redirected to Google + // User authenticates in Google and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in Google Login" + // User can choose password for authentication +}); + +test("login with Google IDP, no user existing - auto register", async ({user, page}) => { + // Given idp Google is configure on the organization as only authencation method + // Given idp Google is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Google + // User authenticates in Google + // User is redirect to ZITADEL login + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Google IDP, no user existing - auto register not possible", async ({user, page}) => { + // Given idp Google is configure on the organization as only authencation method + // Given idp Google is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Google + // User authenticates in Google + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // User will see the registration page with pre filled user information + // User fills missing information + // User clicks register button + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Google IDP, no user existing - auto register enabled - manual creation disabled, creation not possible", async ({user, page}) => { + // Given idp Google is configure on the organization as only authencation method + // Given idp Google is configure with account creation not allowed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Google + // User authenticates in Google + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // Error message is shown, that registration of the user was not possible due to missing information +}); + +test("login with Google IDP, no user linked - auto link", async ({user, page}) => { + // Given idp Google is configure on the organization as only authencation method + // Given idp Google is configure with account linking allowed, and linking set to existing email + // Given user with email address user@zitadel.com exists + + // User is automatically redirected to Google + // User authenticates in Google with user@zitadel.com + // User is redirect to ZITADEL login + // User is linked with existing user in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Google IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp Google is configure on the organization as only authencation method + // Given idp Google is configure with manually account linking not allowed, and linking set to existing email + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to Google + // User authenticates in Google with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User will get an error message that account linking wasn't possible +}); + + +test("login with Google IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp Google is configure on the organization as only authencation method + // Given idp Google is configure with manually account linking allowed, and linking set to existing email + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to Google + // User authenticates in Google with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User is prompted to link the account manually + // User is redirected to the app (default redirect url) +}); diff --git a/acceptance/tests/idp-ldap.spec.ts b/acceptance/tests/idp-ldap.spec.ts new file mode 100644 index 00000000000..fc667edee4c --- /dev/null +++ b/acceptance/tests/idp-ldap.spec.ts @@ -0,0 +1,151 @@ +import {test as base} from "@playwright/test"; +import {OtpType, PasswordUserWithOTP} from './user'; +import path from 'path'; +import dotenv from 'dotenv'; +import {loginScreenExpect, loginWithPassword} from "./login"; +import {startSink} from "./otp"; + +// Read from ".env" file. +dotenv.config({path: path.resolve(__dirname, '.env.local')}); + +const test = base.extend<{ user: PasswordUserWithOTP }>({ + user: async ({page}, use) => { + const user = new PasswordUserWithOTP({ + email: "otp_sms@example.com", + firstName: "first", + lastName: "last", + password: "Password1!", + organization: "", + type: OtpType.sms, + }); + + await user.ensure(page); + await use(user); + }, +}); + +test("login with LDAP IDP - auto redirect", async ({user, page}) => { + // Given idp LDAP is configure on the organization as only authencation method + // Given the user has only idp LDAP added as auth method + + // User is automatically redirected to LDAP + // User authenticates in LDAP + // User is redirect to ZITADEL login + // User is redirected to the app (default redirect url) +}); + + +test("login with LDAP IDP - auto redirect, error", async ({user, page}) => { + // Given idp LDAP is configure on the organization as only authencation method + // Given the user has only idp LDAP added as auth method + + // User is automatically redirected to LDAP + // User authenticates in LDAP and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in LDAP Login" +}); + + +test("login with LDAP IDP", async ({user, page}) => { + // Given username password and idp LDAP is configure on the organization as authencation method + // Given the user has username password and LDAP configured + + // Login form shows username field and a LDAP Login button + // User clicks on the LDAP button + // User is redirected to LDAP + // User authenticates in LDAP and gets an error + // User is redirect to ZITADEL login automatically + // User is redirected to app automatically (default redirect url) +}); + + +test("login with LDAP IDP, error", async ({user, page}) => { + // Given username password and idp LDAP is configure on the organization as authencation method + // Given the user has username password and LDAP configured + + // Login form shows username field and a LDAP Login button + // User clicks on the LDAP button + // User is redirected to LDAP + // User authenticates in LDAP and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in LDAP Login" + // User can choose password for authentication +}); + +test("login with LDAP IDP, no user existing - auto register", async ({user, page}) => { + // Given idp LDAP is configure on the organization as only authencation method + // Given idp LDAP is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to LDAP + // User authenticates in LDAP + // User is redirect to ZITADEL login + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with LDAP IDP, no user existing - auto register not possible", async ({user, page}) => { + // Given idp LDAP is configure on the organization as only authencation method + // Given idp LDAP is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to LDAP + // User authenticates in LDAP + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // User will see the registration page with pre filled user information + // User fills missing information + // User clicks register button + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with LDAP IDP, no user existing - auto register enabled - manual creation disabled, creation not possible", async ({user, page}) => { + // Given idp LDAP is configure on the organization as only authencation method + // Given idp LDAP is configure with account creation not allowed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to LDAP + // User authenticates in LDAP + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // Error message is shown, that registration of the user was not possible due to missing information +}); + +test("login with LDAP IDP, no user linked - auto link", async ({user, page}) => { + // Given idp LDAP is configure on the organization as only authencation method + // Given idp LDAP is configure with account linking allowed, and linking set to existing email + // Given user with email address user@zitadel.com exists + + // User is automatically redirected to LDAP + // User authenticates in LDAP with user@zitadel.com + // User is redirect to ZITADEL login + // User is linked with existing user in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with LDAP IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp LDAP is configure on the organization as only authencation method + // Given idp LDAP is configure with manually account linking not allowed, and linking set to existing email + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to LDAP + // User authenticates in LDAP with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User will get an error message that account linking wasn't possible +}); + + +test("login with LDAP IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp LDAP is configure on the organization as only authencation method + // Given idp LDAP is configure with manually account linking allowed, and linking set to existing email + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to LDAP + // User authenticates in LDAP with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User is prompted to link the account manually + // User is redirected to the app (default redirect url) +}); diff --git a/acceptance/tests/idp-microsoft.spec.ts b/acceptance/tests/idp-microsoft.spec.ts new file mode 100644 index 00000000000..26ffcc10642 --- /dev/null +++ b/acceptance/tests/idp-microsoft.spec.ts @@ -0,0 +1,154 @@ +import {test as base} from "@playwright/test"; +import {OtpType, PasswordUserWithOTP} from './user'; +import path from 'path'; +import dotenv from 'dotenv'; +import {loginScreenExpect, loginWithPassword} from "./login"; +import {startSink} from "./otp"; + +// Read from ".env" file. +dotenv.config({path: path.resolve(__dirname, '.env.local')}); + +const test = base.extend<{ user: PasswordUserWithOTP }>({ + user: async ({page}, use) => { + const user = new PasswordUserWithOTP({ + email: "otp_sms@example.com", + firstName: "first", + lastName: "last", + password: "Password1!", + organization: "", + type: OtpType.sms, + }); + + await user.ensure(page); + await use(user); + }, +}); + +// Note for all tests, in case Microsoft doesn't deliver all relevant information per default +// We should add an action in the needed cases + +test("login with Microsoft IDP - auto redirect", async ({user, page}) => { + // Given idp Microsoft is configure on the organization as only authencation method + // Given the user has only idp Microsoft added as auth method + + // User is automatically redirected to Microsoft + // User authenticates in Microsoft + // User is redirect to ZITADEL login + // User is redirected to the app (default redirect url) +}); + + +test("login with Microsoft IDP - auto redirect, error", async ({user, page}) => { + // Given idp Microsoft is configure on the organization as only authencation method + // Given the user has only idp Microsoft added as auth method + + // User is automatically redirected to Microsoft + // User authenticates in Microsoft and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in Microsoft Login" +}); + + +test("login with Microsoft IDP", async ({user, page}) => { + // Given username password and idp Microsoft is configure on the organization as authencation method + // Given the user has username password and Microsoft configured + + // Login form shows username field and a Microsoft Login button + // User clicks on the Microsoft button + // User is redirected to Microsoft + // User authenticates in Microsoft and gets an error + // User is redirect to ZITADEL login automatically + // User is redirected to app automatically (default redirect url) +}); + + +test("login with Microsoft IDP, error", async ({user, page}) => { + // Given username password and idp Microsoft is configure on the organization as authencation method + // Given the user has username password and Microsoft configured + + // Login form shows username field and a Microsoft Login button + // User clicks on the Microsoft button + // User is redirected to Microsoft + // User authenticates in Microsoft and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in Microsoft Login" + // User can choose password for authentication +}); + +test("login with Microsoft IDP, no user existing - auto register", async ({user, page}) => { + // Given idp Microsoft is configure on the organization as only authencation method + // Given idp Microsoft is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Microsoft + // User authenticates in Microsoft + // User is redirect to ZITADEL login + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Microsoft IDP, no user existing - auto register not possible", async ({user, page}) => { + // Given idp Microsoft is configure on the organization as only authencation method + // Given idp Microsoft is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Microsoft + // User authenticates in Microsoft + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // User will see the registration page with pre filled user information + // User fills missing information + // User clicks register button + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Microsoft IDP, no user existing - auto register enabled - manual creation disabled, creation not possible", async ({user, page}) => { + // Given idp Microsoft is configure on the organization as only authencation method + // Given idp Microsoft is configure with account creation not allowed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to Microsoft + // User authenticates in Microsoft + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // Error message is shown, that registration of the user was not possible due to missing information +}); + +test("login with Microsoft IDP, no user linked - auto link", async ({user, page}) => { + // Given idp Microsoft is configure on the organization as only authencation method + // Given idp Microsoft is configure with account linking allowed, and linking set to existing email + // Given user with email address user@zitadel.com exists + + // User is automatically redirected to Microsoft + // User authenticates in Microsoft with user@zitadel.com + // User is redirect to ZITADEL login + // User is linked with existing user in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with Microsoft IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp Microsoft is configure on the organization as only authencation method + // Given idp Microsoft is configure with manually account linking not allowed, and linking set to existing email + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to Microsoft + // User authenticates in Microsoft with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User will get an error message that account linking wasn't possible +}); + + +test("login with Microsoft IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp Microsoft is configure on the organization as only authencation method + // Given idp Microsoft is configure with manually account linking allowed, and linking set to existing email + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to Microsoft + // User authenticates in Microsoft with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User is prompted to link the account manually + // User is redirected to the app (default redirect url) +}); diff --git a/acceptance/tests/idp-saml.spec.ts b/acceptance/tests/idp-saml.spec.ts new file mode 100644 index 00000000000..890965180b5 --- /dev/null +++ b/acceptance/tests/idp-saml.spec.ts @@ -0,0 +1,157 @@ +import {test as base} from "@playwright/test"; +import {OtpType, PasswordUserWithOTP} from './user'; +import path from 'path'; +import dotenv from 'dotenv'; +import {loginScreenExpect, loginWithPassword} from "./login"; +import {startSink} from "./otp"; + +// Read from ".env" file. +dotenv.config({path: path.resolve(__dirname, '.env.local')}); + +const test = base.extend<{ user: PasswordUserWithOTP }>({ + user: async ({page}, use) => { + const user = new PasswordUserWithOTP({ + email: "otp_sms@example.com", + firstName: "first", + lastName: "last", + password: "Password1!", + organization: "", + type: OtpType.sms, + }); + + await user.ensure(page); + await use(user); + }, +}); + + +test("login with SAML IDP - auto redirect", async ({user, page}) => { + // Given idp SAML is configure on the organization as only authencation method + // Given ZITADEL Action is added to autofill missing user information + // Given the user has only idp SAML added as auth method + + // User is automatically redirected to SAML + // User authenticates in SAML + // User is redirect to ZITADEL login + // User is redirected to the app (default redirect url) +}); + + +test("login with SAML IDP - auto redirect, error", async ({user, page}) => { + // Given idp SAML is configure on the organization as only authencation method + // Given the user has only idp SAML added as auth method + + // User is automatically redirected to SAML + // User authenticates in SAML and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in SAML Login" +}); + + +test("login with SAML IDP", async ({user, page}) => { + // Given username password and idp SAML is configure on the organization as authencation method + // Given the user has username password and SAML configured + + // Login form shows username field and a SAML Login button + // User clicks on the SAML button + // User is redirected to SAML + // User authenticates in SAML and gets an error + // User is redirect to ZITADEL login automatically + // User is redirected to app automatically (default redirect url) +}); + + +test("login with SAML IDP, error", async ({user, page}) => { + // Given username password and idp SAML is configure on the organization as authencation method + // Given the user has username password and SAML configured + + // Login form shows username field and a SAML Login button + // User clicks on the SAML button + // User is redirected to SAML + // User authenticates in SAML and gets an error + // User is redirect to ZITADEL login + // Error is shown to the user "Something went wrong in SAML Login" + // User can choose password for authentication +}); + +test("login with SAML IDP, no user existing - auto register", async ({user, page}) => { + // Given idp SAML is configure on the organization as only authencation method + // Given idp SAML is configure with account creation alloweed, and automatic creation enabled + // Given ZITADEL Action is added to autofill missing user information + // Given no user exists yet + + // User is automatically redirected to SAML + // User authenticates in SAML + // User is redirect to ZITADEL login + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with SAML IDP, no user existing - auto register not possible", async ({user, page}) => { + // Given idp SAML is configure on the organization as only authencation method + // Given idp SAML is configure with account creation alloweed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to SAML + // User authenticates in SAML + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // User will see the registration page with pre filled user information + // User fills missing information + // User clicks register button + // User is created in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with SAML IDP, no user existing - auto register enabled - manual creation disabled, creation not possible", async ({user, page}) => { + // Given idp SAML is configure on the organization as only authencation method + // Given idp SAML is configure with account creation not allowed, and automatic creation enabled + // Given no user exists yet + + // User is automatically redirected to SAML + // User authenticates in SAML + // User is redirect to ZITADEL login + // Because of missing informaiton on the user auto creation is not possible + // Error message is shown, that registration of the user was not possible due to missing information +}); + +test("login with SAML IDP, no user linked - auto link", async ({user, page}) => { + // Given idp SAML is configure on the organization as only authencation method + // Given idp SAML is configure with account linking allowed, and linking set to existing email + // Given ZITADEL Action is added to autofill missing user information + // Given user with email address user@zitadel.com exists + + // User is automatically redirected to SAML + // User authenticates in SAML with user@zitadel.com + // User is redirect to ZITADEL login + // User is linked with existing user in ZITADEL + // User is redirected to the app (default redirect url) +}); + +test("login with SAML IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp SAML is configure on the organization as only authencation method + // Given idp SAML is configure with manually account linking not allowed, and linking set to existing email + // Given ZITADEL Action is added to autofill missing user information + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to SAML + // User authenticates in SAML with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User will get an error message that account linking wasn't possible +}); + + +test("login with SAML IDP, no user linked, user doesn't exist - no auto link", async ({user, page}) => { + // Given idp SAML is configure on the organization as only authencation method + // Given idp SAML is configure with manually account linking allowed, and linking set to existing email + // Given ZITADEL Action is added to autofill missing user information + // Given user with email address user@zitadel.com doesn't exists + + // User is automatically redirected to SAML + // User authenticates in SAML with user@zitadel.com + // User is redirect to ZITADEL login + // User with email address user@zitadel.com can not be found + // User is prompted to link the account manually + // User is redirected to the app (default redirect url) +}); diff --git a/acceptance/tests/login-configuration-possiblities.spec.ts b/acceptance/tests/login-configuration-possiblities.spec.ts new file mode 100644 index 00000000000..0f06bd94094 --- /dev/null +++ b/acceptance/tests/login-configuration-possiblities.spec.ts @@ -0,0 +1,86 @@ +import {test as base} from "@playwright/test"; +import {PasswordUser} from './user'; +import path from 'path'; +import dotenv from 'dotenv'; +import {loginScreenExpect, loginWithPassword, startLogin} from "./login"; +import {loginnameScreenExpect} from "./loginname-screen"; +import {passwordScreenExpect} from "./password-screen"; +import {loginname} from "./loginname"; +import {password} from "./password"; + +// Read from ".env" file. +dotenv.config({path: path.resolve(__dirname, '.env.local')}); + +const test = base.extend<{ user: PasswordUser }>({ + user: async ({page}, use) => { + const user = new PasswordUser({ + email: "password@example.com", + firstName: "first", + lastName: "last", + password: "Password1!", + organization: "", + }); + await user.ensure(page); + await use(user); + }, +}); + +test("login with mfa setup, mfa setup prompt", async ({user, page}) => { + // Given the organization has enabled at least one mfa types + // Given the user has a password but no mfa registered + // User authenticates with login name and password + // User is prompted to setup a mfa, mfa providers are listed, the user can choose the provider +}); + +test("login with mfa setup, no mfa setup prompt", async ({user, page}) => { + // Given the organization has set "multifactor init check time" to 0 + // Given the organization has enabled mfa types + // Given the user has a password but no mfa registered + // User authenticates with loginname and password + // user is directly loged in and not prompted to setup mfa + }); + +test("login with mfa setup, force mfa for local authenticated users", async ({user, page}) => { + // Given the organization has enabled force mfa for local authentiacted users + // Given the organization has enabled all possible mfa types + // Given the user has a password but no mfa registered + + // enter login name + // enter password + // User is prompted to setup a mfa, all possible mfa providers are listed, the user can choose the provider +}); + + +test("login with mfa setup, force mfa - local user", async ({user, page}) => { + // Given the organization has enabled force mfa for local authentiacted users + // Given the organization has enabled all possible mfa types + // Given the user has a password but no mfa registered + + // enter login name + // enter password + // User is prompted to setup a mfa, all possible mfa providers are listed, the user can choose the provider +}); + + +test("login with mfa setup, force mfa - external user", async ({user, page}) => { + // Given the organization has enabled force mfa + // Given the organization has enabled all possible mfa types + // Given the user has an idp but no mfa registered + + // enter login name + // redirect to configured external idp + // User is prompted to setup a mfa, all possible mfa providers are listed, the user can choose the provider +}); + + +test("login with mfa setup, force mfa - external user", async ({user, page}) => { + // Given the organization has a password lockout policy set to 1 on the max password attempts + // Given the user has only a password as auth methos + + // enter login name + // enter wrong password + // User will get an error "Wrong password" + // enter password + // User will get an error "Max password attempts reached - user is locked. Please reach out to your administrator" +}); + diff --git a/acceptance/tests/register.spec.ts b/acceptance/tests/register.spec.ts index ce95b61a042..f11ed673a64 100644 --- a/acceptance/tests/register.spec.ts +++ b/acceptance/tests/register.spec.ts @@ -28,3 +28,151 @@ test("register with passkey", async ({ page }) => { await registerWithPasskey(page, firstname, lastname, username); await loginScreenExpect(page, firstname + " " + lastname); }); + +test("register with username and password - only password enabled", async ({user, page}) => { + // Given on the default organization "username and password is allowed" is enabled + // Given on the default organization "username registeration allowed" is enabled + // Given on the default organization no idp is configured and enabled + // Given on the default organization passkey is not enabled + // Given user doesn't exist + + // Click on button "register new user" + // User is redirected to registration page + // Only password is shown as an option - no passkey + // User enters "firstname", "lastname", "username" and "password" + // User is redirected to app (default redirect url) +}); + +test("register with username and password - wrong password not enough characters", async ({user, page}) => { + // Given on the default organization "username and password is allowed" is enabled + // Given on the default organization "username registeration allowed" is enabled + // Given on the default organization no idp is configured and enabled + // Given on the default organization passkey is not enabled + // Given password policy is set to 8 characters and must include number, symbol, lower and upper letter + // Given user doesn't exist + + // Click on button "register new user" + // User is redirected to registration page + // Only password is shown as an option - no passkey + // User enters "firstname", "lastname", "username" and a password thats to short + // Error is shown "Password doesn't match the policy - it must have at least 8 characters" +}); + +test("register with username and password - wrong password number missing", async ({user, page}) => { + // Given on the default organization "username and password is allowed" is enabled + // Given on the default organization "username registeration allowed" is enabled + // Given on the default organization no idp is configured and enabled + // Given on the default organization passkey is not enabled + // Given password policy is set to 8 characters and must include number, symbol, lower and upper letter + // Given user doesn't exist + + // Click on button "register new user" + // User is redirected to registration page + // Only password is shown as an option - no passkey + // User enters "firstname", "lastname", "username" and a password without a number + // Error is shown "Password doesn't match the policy - number missing" +}); + +test("register with username and password - wrong password upper case missing", async ({user, page}) => { + // Given on the default organization "username and password is allowed" is enabled + // Given on the default organization "username registeration allowed" is enabled + // Given on the default organization no idp is configured and enabled + // Given on the default organization passkey is not enabled + // Given password policy is set to 8 characters and must include number, symbol, lower and upper letter + // Given user doesn't exist + + // Click on button "register new user" + // User is redirected to registration page + // Only password is shown as an option - no passkey + // User enters "firstname", "lastname", "username" and a password without an upper case + // Error is shown "Password doesn't match the policy - uppercase letter missing" +}); + +test("register with username and password - wrong password lower case missing", async ({user, page}) => { + // Given on the default organization "username and password is allowed" is enabled + // Given on the default organization "username registeration allowed" is enabled + // Given on the default organization no idp is configured and enabled + // Given on the default organization passkey is not enabled + // Given password policy is set to 8 characters and must include number, symbol, lower and upper letter + // Given user doesn't exist + + // Click on button "register new user" + // User is redirected to registration page + // Only password is shown as an option - no passkey + // User enters "firstname", "lastname", "username" and a password without an lower case + // Error is shown "Password doesn't match the policy - lowercase letter missing" +}); + + +test("register with username and password - wrong password symboo missing", async ({user, page}) => { + // Given on the default organization "username and password is allowed" is enabled + // Given on the default organization "username registeration allowed" is enabled + // Given on the default organization no idp is configured and enabled + // Given on the default organization passkey is not enabled + // Given password policy is set to 8 characters and must include number, symbol, lower and upper letter + // Given user doesn't exist + + // Click on button "register new user" + // User is redirected to registration page + // Only password is shown as an option - no passkey + // User enters "firstname", "lastname", "username" and a password without an symbol + // Error is shown "Password doesn't match the policy - symbol missing" +}); + +test("register with username and password - password and passkey enabled", async ({user, page}) => { + // Given on the default organization "username and password is allowed" is enabled + // Given on the default organization "username registeration allowed" is enabled + // Given on the default organization no idp is configured and enabled + // Given on the default organization passkey is enabled + // Given user doesn't exist + + // Click on button "register new user" + // User is redirected to registration page + // User enters "firstname", "lastname", "username" + // Password and passkey are shown as authentication option + // User clicks password + // User enters password + // User is redirected to app (default redirect url) +}); + +test("register with username and passkey - password and passkey enabled", async ({user, page}) => { + // Given on the default organization "username and password is allowed" is enabled + // Given on the default organization "username registeration allowed" is enabled + // Given on the default organization no idp is configured and enabled + // Given on the default organization passkey is enabled + // Given user doesn't exist + + // Click on button "register new user" + // User is redirected to registration page + // User enters "firstname", "lastname", "username" + // Password and passkey are shown as authentication option + // User clicks passkey + // Passkey is opened automatically + // User verifies passkey + // User is redirected to app (default redirect url) +}); + + +test("register with username and password - registration disabled", async ({user, page}) => { + // Given on the default organization "username and password is allowed" is enabled + // Given on the default organization "username registeration allowed" is enabled + // Given on the default organization no idp is configured and enabled + // Given user doesn't exist + + // Button "register new user" is not available +}); + +test("register with username and password - multiple registration options", async ({user, page}) => { + // Given on the default organization "username and password is allowed" is enabled + // Given on the default organization "username registeration allowed" is enabled + // Given on the default organization one idp is configured and enabled + // Given user doesn't exist + + // Click on button "register new user" + // User is redirected to registration options + // Local User and idp button are shown + // User clicks idp button + // User enters "firstname", "lastname", "username" and "password" + // User clicks next + // User is redirected to app (default redirect url) +}); diff --git a/acceptance/tests/username-passkey.spec.ts b/acceptance/tests/username-passkey.spec.ts index 552208f3246..f015049c5f7 100644 --- a/acceptance/tests/username-passkey.spec.ts +++ b/acceptance/tests/username-passkey.spec.ts @@ -24,3 +24,25 @@ test("username and passkey login", async ({ user, page }) => { await loginWithPasskey(page, user.getAuthenticatorId(), user.getUsername()); await loginScreenExpect(page, user.getFullName()); }); + +test("username and passkey login, if passkey enabled", async ({user, page}) => { + // Given passkey is enabled on the organization of the user + // Given the user has only passkey enabled as authentication + + // enter username + // passkey popup is directly shown + // user verifies passkey + // user is redirected to app +}); + +test("username and passkey login, multiple auth methods", async ({user, page}) => { + // Given passkey and password is enabled on the organization of the user + // Given the user has password and passkey registered + + // enter username + // passkey popup is directly shown + // user aborts passkey authentication + // user switches to password authentication + // user enters password + // user is redirected to app +}); diff --git a/acceptance/tests/username-password-otp_email.spec.ts b/acceptance/tests/username-password-otp_email.spec.ts new file mode 100644 index 00000000000..43749cb203e --- /dev/null +++ b/acceptance/tests/username-password-otp_email.spec.ts @@ -0,0 +1,86 @@ +import {test as base} from "@playwright/test"; +import {OtpType, PasswordUserWithOTP} from './user'; +import path from 'path'; +import dotenv from 'dotenv'; +import {loginScreenExpect, loginWithPassword} from "./login"; +import {startSink} from "./otp"; + +// Read from ".env" file. +dotenv.config({path: path.resolve(__dirname, '.env.local')}); + +const test = base.extend<{ user: PasswordUserWithOTP }>({ + user: async ({page}, use) => { + const user = new PasswordUserWithOTP({ + email: "otp_sms@example.com", + firstName: "first", + lastName: "last", + password: "Password1!", + organization: "", + type: OtpType.email, + }); + + await user.ensure(page); + await use(user); + }, +}); + + +test("username, password and email otp login, enter code manually", async ({user, page}) => { + // Given email otp is enabled on the organizaiton of the user + // Given the user has only email otp configured as second factor + + // User enters username + // User enters password + // User receives an email with a verification code + // User enters the code into the ui + // User is redirected to the app (default redirect url) +}); + + +test("username, password and email otp login, click link in email", async ({user, page}) => { + // Given email otp is enabled on the organizaiton of the user + // Given the user has only email otp configured as second factor + + // User enters username + // User enters password + // User receives an email with a verification code + // User clicks link in the email + // User is redirected to the app (default redirect url) +}); + +test("username, password and email otp login, resend code", async ({user, page}) => { + // Given email otp is enabled on the organizaiton of the user + // Given the user has only email otp configured as second factor + + // User enters username + // User enters password + // User receives an email with a verification code + // User clicks resend code + // User receives a new email with a verification code + // User enters the new code in the ui + // User is redirected to the app (default redirect url) +}); + +test("username, password and email otp login, wrong code", async ({user, page}) => { + // Given email otp is enabled on the organizaiton of the user + // Given the user has only email otp configured as second factor + + // User enters username + // User enters password + // User receives an email with a verification code + // User enters a wrond code + // Error message - "Invalid code" is shown +}); + +test("username, password and email otp login, multiple mfa options", async ({user, page}) => { + // Given email otp and sms otp is enabled on the organizaiton of the user + // Given the user has email and sms otp configured as second factor + + // User enters username + // User enters password + // User receives an email with a verification code + // User clicks button to use sms otp as second factor + // User receives an sms with a verification code + // User enters code in ui + // User is redirected to the app (default redirect url) +}); diff --git a/acceptance/tests/username-password-otp_sms.spec.ts b/acceptance/tests/username-password-otp_sms.spec.ts index 6d91463a2db..1f6873a4381 100644 --- a/acceptance/tests/username-password-otp_sms.spec.ts +++ b/acceptance/tests/username-password-otp_sms.spec.ts @@ -30,4 +30,38 @@ test("username, password and otp login", async ({ user, page }) => { await loginScreenExpect(page, user.getFullName()); //server.close() }); + +test("username, password and sms otp login", async ({user, page}) => { + // Given sms otp is enabled on the organizaiton of the user + // Given the user has only sms otp configured as second factor + + // User enters username + // User enters password + // User receives an sms with a verification code + // User enters the code into the ui + // User is redirected to the app (default redirect url) +}); + +test("username, password and sms otp login, resend code", async ({user, page}) => { + // Given sms otp is enabled on the organizaiton of the user + // Given the user has only sms otp configured as second factor + + // User enters username + // User enters password + // User receives an sms with a verification code + // User clicks resend code + // User receives a new sms with a verification code + // User is redirected to the app (default redirect url) +}); + +test("username, password and sms otp login, wrong code", async ({user, page}) => { + // Given sms otp is enabled on the organizaiton of the user + // Given the user has only sms otp configured as second factor + + // User enters username + // User enters password + // User receives an sms with a verification code + // User enters a wrond code + // Error message - "Invalid code" is shown +}); */ diff --git a/acceptance/tests/username-password-totp.spec.ts b/acceptance/tests/username-password-totp.spec.ts new file mode 100644 index 00000000000..85ea828e08b --- /dev/null +++ b/acceptance/tests/username-password-totp.spec.ts @@ -0,0 +1,63 @@ +import {test as base} from "@playwright/test"; +import {OtpType, PasswordUserWithOTP} from './user'; +import path from 'path'; +import dotenv from 'dotenv'; +import {loginScreenExpect, loginWithPassword} from "./login"; +import {startSink} from "./otp"; + +// Read from ".env" file. +dotenv.config({path: path.resolve(__dirname, '.env.local')}); + +const test = base.extend<{ user: PasswordUserWithOTP }>({ + user: async ({page}, use) => { + const user = new PasswordUserWithOTP({ + email: "otp_sms@example.com", + firstName: "first", + lastName: "last", + password: "Password1!", + organization: "", + type: OtpType.sms, + }); + + await user.ensure(page); + await use(user); + }, +}); + +test("username, password and totp login", async ({user, page}) => { + // Given totp is enabled on the organizaiton of the user + // Given the user has only totp configured as second factor + + // User enters username + // User enters password + // Screen for entering the code is shown directly + // User enters the code into the ui + // User is redirected to the app (default redirect url) +}); + + +test("username, password and totp otp login, wrong code", async ({user, page}) => { + // Given totp is enabled on the organizaiton of the user + // Given the user has only totp configured as second factor + + // User enters username + // User enters password + // Screen for entering the code is shown directly + // User enters a wrond code + // Error message - "Invalid code" is shown +}); + + +test("username, password and totp login, multiple mfa options", async ({user, page}) => { + // Given totp and email otp is enabled on the organizaiton of the user + // Given the user has totp and email otp configured as second factor + + // User enters username + // User enters password + // Screen for entering the code is shown directly + // Button to switch to email otp is shown + // User clicks button to use email otp instead + // User receives an email with a verification code + // User enters code in ui + // User is redirected to the app (default redirect url) +}); diff --git a/acceptance/tests/username-password-u2f.spec.ts b/acceptance/tests/username-password-u2f.spec.ts new file mode 100644 index 00000000000..0f87175ad0d --- /dev/null +++ b/acceptance/tests/username-password-u2f.spec.ts @@ -0,0 +1,52 @@ +import {test as base} from "@playwright/test"; +import {OtpType, PasswordUserWithOTP} from './user'; +import path from 'path'; +import dotenv from 'dotenv'; +import {loginScreenExpect, loginWithPassword} from "./login"; +import {startSink} from "./otp"; + +// Read from ".env" file. +dotenv.config({path: path.resolve(__dirname, '.env.local')}); + +const test = base.extend<{ user: PasswordUserWithOTP }>({ + user: async ({page}, use) => { + const user = new PasswordUserWithOTP({ + email: "otp_sms@example.com", + firstName: "first", + lastName: "last", + password: "Password1!", + organization: "", + type: OtpType.sms, + }); + + await user.ensure(page); + await use(user); + }, +}); + + +test("username, password and u2f login", async ({user, page}) => { + // Given u2f is enabled on the organizaiton of the user + // Given the user has only u2f configured as second factor + + // User enters username + // User enters password + // Popup for u2f is directly opened + // User verifies u2f + // User is redirected to the app (default redirect url) +}); + + +test("username, password and u2f login, multiple mfa options", async ({user, page}) => { + // Given u2f and semailms otp is enabled on the organizaiton of the user + // Given the user has u2f and email otp configured as second factor + + // User enters username + // User enters password + // Popup for u2f is directly opened + // User aborts u2f verification + // User clicks button to use email otp as second factor + // User receives an email with a verification code + // User enters code in ui + // User is redirected to the app (default redirect url) +}); diff --git a/acceptance/tests/username-password.spec.ts b/acceptance/tests/username-password.spec.ts index 1bf7f17422c..40b8246a281 100644 --- a/acceptance/tests/username-password.spec.ts +++ b/acceptance/tests/username-password.spec.ts @@ -43,3 +43,112 @@ test("username and password login, wrong password", async ({ user, page }) => { await password(page, "wrong"); await passwordScreenExpect(page, "wrong"); }); + +test("username and password login, wrong username, ignore unknown usernames", async ({user, page}) => { + // Given user doesn't exist but ignore unknown usernames setting is set to true + // Given username password login is enabled on the users organization + + // enter login name + // enter password + // redirect to loginname page --> error message username or password wrong +}); + +test("username and password login, initial password change", async ({user, page}) => { + // Given user is created and has changePassword set to true + // Given username password login is enabled on the users organization + + // enter login name + // enter password + // create new password +}); + + +test("username and password login, reset password hidden", async ({user, page}) => { + // Given the organization has enabled "Password reset hidden" in the login policy + // Given username password login is enabled on the users organization + + // enter login name + // password reset link should not be shown on password screen +}); + +test("username and password login, reset password - enter code manually", async ({user, page}) => { + // Given user has forgotten password and clicks the forgot password button + // Given username password login is enabled on the users organization + + // enter login name + // click password forgotten + // enter code from email + // user is redirected to app (default redirect url) +}); + +test("username and password login, reset password - click link", async ({user, page}) => { + // Given user has forgotten password and clicks the forgot password button, and then the link in the email + // Given username password login is enabled on the users organization + + // enter login name + // click password forgotten + // click link in email + // set new password + // redirect to app (default redirect url) +}); + +test("username and password login, reset password, resend code", async ({user, page}) => { + // Given user has forgotten password and clicks the forgot password button and then resend code + // Given username password login is enabled on the users organization + + // enter login name + // click password forgotten + // click resend code + // enter code from second email + // user is redirected to app (default redirect url) +}); + +test("email login enabled", async ({user, page}) => { + // Given user with the username "testuser", email test@zitadel.com and phone number 0711111111 exists + // Given no other user with the same email address exists + + // enter email address "test@zitadel.com " in login screen + // user will get to password screen +}); + +test("email login disabled", async ({user, page}) => { + // Given user with the username "testuser", email test@zitadel.com and phone number 0711111111 exists + // Given no other user with the same email address exists + + // enter email address "test@zitadel.com" in login screen + // user will see error message "user not found" +}); + +test("email login enabled - multiple users", async ({user, page}) => { + // Given user with the username "testuser", email test@zitadel.com and phone number 0711111111 exists + // Given a second user with the username "testuser2", email test@zitadel.com and phone number 0711111111 exists + + // enter email address "test@zitadel.com" in login screen + // user will see error message "user not found" +}); + + +test("phone login enabled", async ({user, page}) => { + // Given user with the username "testuser", email test@zitadel.com and phone number 0711111111 exists + // Given no other user with the same phon number exists + + // enter phone number "0711111111" in login screen + // user will get to password screen +}); + +test("phone login disabled", async ({user, page}) => { + // Given user with the username "testuser", email test@zitadel.com and phone number 0711111111 exists + // Given no other user with the same phone number exists + + // enter phone number "0711111111" in login screen + // user will see error message "user not found" +}); + +test("phone login enabled - multiple users", async ({user, page}) => { + // Given user with the username "testuser", email test@zitadel.com and phone number 0711111111 exists + // Given a second user with the username "testuser2", email test@zitadel.com and phone number 0711111111 exists + + // enter phone number "0711111111" in login screen + // user will see error message "user not found" +}); +