From b27c1fbae95b746d5ba43f5e3fb794e7628de53a Mon Sep 17 00:00:00 2001 From: Amir Zarrinkafsh Date: Wed, 27 May 2020 21:55:44 +1000 Subject: [PATCH] [CI] Add PathPrefix integration test suite (#1052) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a suite for testing the PathPrefix feature implemented earlier to serve authelia under a multi-purpose domain. Co-authored-by: Clément Michaud --- cmd/authelia-suites/main.go | 23 +++++++ internal/server/server.go | 4 +- internal/suites/PathPrefix/.env | 1 + internal/suites/PathPrefix/configuration.yml | 48 ++++++++++++++ internal/suites/PathPrefix/docker-compose.yml | 7 ++ internal/suites/PathPrefix/users.yml | 29 +++++++++ internal/suites/action_login.go | 2 +- internal/suites/action_logout.go | 2 +- internal/suites/action_visit.go | 2 +- internal/suites/const.go | 8 ++- .../authelia/docker-compose.backend.dev.yml | 2 +- .../authelia/docker-compose.backend.dist.yml | 2 +- .../authelia/docker-compose.frontend.dev.yml | 4 +- .../authelia/docker-compose.frontend.dist.yml | 2 +- .../compose/httpbin/docker-compose.yml | 6 +- .../compose/nginx/backend/docker-compose.yml | 8 +-- .../compose/traefik2/docker-compose.yml | 6 +- .../suites/scenario_reset_password_test.go | 6 +- .../suites/scenario_user_preferences_test.go | 2 +- .../suites/suite_high_availability_test.go | 2 +- internal/suites/suite_one_factor_only_test.go | 2 +- internal/suites/suite_pathprefix.go | 64 +++++++++++++++++++ internal/suites/suite_pathprefix_test.go | 35 ++++++++++ internal/suites/suite_standalone_test.go | 10 +-- internal/suites/utils.go | 10 +++ 25 files changed, 254 insertions(+), 33 deletions(-) create mode 100644 internal/suites/PathPrefix/.env create mode 100644 internal/suites/PathPrefix/configuration.yml create mode 100644 internal/suites/PathPrefix/docker-compose.yml create mode 100644 internal/suites/PathPrefix/users.yml create mode 100644 internal/suites/suite_pathprefix.go create mode 100644 internal/suites/suite_pathprefix_test.go create mode 100644 internal/suites/utils.go diff --git a/cmd/authelia-suites/main.go b/cmd/authelia-suites/main.go index 5e64e5a20..26515777b 100644 --- a/cmd/authelia-suites/main.go +++ b/cmd/authelia-suites/main.go @@ -1,9 +1,11 @@ package main import ( + "bufio" "io/ioutil" "os" "path/filepath" + "strings" "github.com/otiai10/copy" log "github.com/sirupsen/logrus" @@ -87,6 +89,27 @@ func setupSuite(cmd *cobra.Command, args []string) { log.Fatal(err) } + suiteEnv := suiteResourcePath + "/.env" + + _, err = os.Stat(suiteEnv) + if err == nil { + file, err := os.Open(suiteEnv) + if err != nil { + log.Fatal(err) + } + + env := bufio.NewScanner(file) + + for env.Scan() { + v := strings.Split(env.Text(), "=") + + err := os.Setenv(v[0], v[1]) + if err != nil { + log.Fatal(err) + } + } + } + suiteTmpDirectory := tmpDirectory + suiteName if exist { diff --git a/internal/server/server.go b/internal/server/server.go index 43cff8140..cee96144f 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -131,10 +131,10 @@ func StartServer(configuration schema.Configuration, providers middlewares.Provi addrPattern := fmt.Sprintf("%s:%d", configuration.Host, configuration.Port) if configuration.TLSCert != "" && configuration.TLSKey != "" { - logging.Logger().Infof("Authelia is listening for TLS connections on %s", addrPattern) + logging.Logger().Infof("Authelia is listening for TLS connections on %s%s", addrPattern, configuration.Server.Path) logging.Logger().Fatal(server.ListenAndServeTLS(addrPattern, configuration.TLSCert, configuration.TLSKey)) } else { - logging.Logger().Infof("Authelia is listening for non-TLS connections on %s", addrPattern) + logging.Logger().Infof("Authelia is listening for non-TLS connections on %s%s", addrPattern, configuration.Server.Path) logging.Logger().Fatal(server.ListenAndServe(addrPattern)) } } diff --git a/internal/suites/PathPrefix/.env b/internal/suites/PathPrefix/.env new file mode 100644 index 000000000..633bb338d --- /dev/null +++ b/internal/suites/PathPrefix/.env @@ -0,0 +1 @@ +PathPrefix=/auth \ No newline at end of file diff --git a/internal/suites/PathPrefix/configuration.yml b/internal/suites/PathPrefix/configuration.yml new file mode 100644 index 000000000..3e1888d04 --- /dev/null +++ b/internal/suites/PathPrefix/configuration.yml @@ -0,0 +1,48 @@ +############################################################### +# Authelia minimal configuration # +############################################################### + +port: 9091 +tls_cert: /var/lib/authelia/ssl/cert.pem +tls_key: /var/lib/authelia/ssl/key.pem + +server: + path: auth + +log_level: debug + +jwt_secret: unsecure_secret + +authentication_backend: + file: + path: /var/lib/authelia/users.yml + +session: + secret: unsecure_session_secret + domain: example.com + expiration: 3600 # 1 hour + inactivity: 300 # 5 minutes + remember_me_duration: 1y + +storage: + local: + path: /var/lib/authelia/db.sqlite + +access_control: + default_policy: bypass + rules: + - domain: "public.example.com" + policy: bypass + - domain: "admin.example.com" + policy: two_factor + - domain: "secure.example.com" + policy: two_factor + - domain: "singlefactor.example.com" + policy: one_factor + +notifier: + smtp: + host: smtp + port: 1025 + sender: admin@example.com + disable_require_tls: true \ No newline at end of file diff --git a/internal/suites/PathPrefix/docker-compose.yml b/internal/suites/PathPrefix/docker-compose.yml new file mode 100644 index 000000000..2d2c7d294 --- /dev/null +++ b/internal/suites/PathPrefix/docker-compose.yml @@ -0,0 +1,7 @@ +version: '3' +services: + authelia-backend: + volumes: + - './PathPrefix/configuration.yml:/etc/authelia/configuration.yml:ro' + - './PathPrefix/users.yml:/var/lib/authelia/users.yml' + - './common/ssl:/var/lib/authelia/ssl:ro' \ No newline at end of file diff --git a/internal/suites/PathPrefix/users.yml b/internal/suites/PathPrefix/users.yml new file mode 100644 index 000000000..4f1a7e4e8 --- /dev/null +++ b/internal/suites/PathPrefix/users.yml @@ -0,0 +1,29 @@ +############################################################### +# Users Database # +############################################################### + +# This file can be used if you do not have an LDAP set up. + +# List of users +users: + john: + password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/" + email: john.doe@authelia.com + groups: + - admins + - dev + + harry: + password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/" + email: harry.potter@authelia.com + groups: [] + + bob: + password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/" + email: bob.dylan@authelia.com + groups: + - dev + + james: + password: "$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/" + email: james.dean@authelia.com \ No newline at end of file diff --git a/internal/suites/action_login.go b/internal/suites/action_login.go index 399363ad4..64ead3a43 100644 --- a/internal/suites/action_login.go +++ b/internal/suites/action_login.go @@ -49,7 +49,7 @@ func (wds *WebDriverSession) doLoginTwoFactor(ctx context.Context, t *testing.T, func (wds *WebDriverSession) doLoginAndRegisterTOTP(ctx context.Context, t *testing.T, username, password string, keepMeLoggedIn bool) string { wds.doLoginOneFactor(ctx, t, username, password, keepMeLoggedIn, "") secret := wds.doRegisterTOTP(ctx, t) - wds.doVisit(t, LoginBaseURL) + wds.doVisit(t, GetLoginBaseURL()) wds.verifyIsSecondFactorPage(ctx, t) return secret diff --git a/internal/suites/action_logout.go b/internal/suites/action_logout.go index daedab38a..cbac88c4b 100644 --- a/internal/suites/action_logout.go +++ b/internal/suites/action_logout.go @@ -7,6 +7,6 @@ import ( ) func (wds *WebDriverSession) doLogout(ctx context.Context, t *testing.T) { - wds.doVisit(t, fmt.Sprintf("%s%s", LoginBaseURL, "/logout")) + wds.doVisit(t, fmt.Sprintf("%s%s", GetLoginBaseURL(), "/logout")) wds.verifyIsFirstFactorPage(ctx, t) } diff --git a/internal/suites/action_visit.go b/internal/suites/action_visit.go index 56edca00b..62c473205 100644 --- a/internal/suites/action_visit.go +++ b/internal/suites/action_visit.go @@ -24,5 +24,5 @@ func (wds *WebDriverSession) doVisitLoginPage(ctx context.Context, t *testing.T, suffix = fmt.Sprintf("?rd=%s", targetURL) } - wds.doVisitAndVerifyOneFactorStep(ctx, t, fmt.Sprintf("%s/%s", LoginBaseURL, suffix)) + wds.doVisitAndVerifyOneFactorStep(ctx, t, fmt.Sprintf("%s/%s", GetLoginBaseURL(), suffix)) } diff --git a/internal/suites/const.go b/internal/suites/const.go index b86fea89f..f65694cd5 100644 --- a/internal/suites/const.go +++ b/internal/suites/const.go @@ -1,10 +1,16 @@ package suites -import "fmt" +import ( + "fmt" + "os" +) // BaseDomain the base domain. var BaseDomain = "example.com:8080" +// PathPrefix the prefix/url_base of the login portal. +var PathPrefix = os.Getenv("PathPrefix") + // LoginBaseURL the base URL of the login portal. var LoginBaseURL = fmt.Sprintf("https://login.%s", BaseDomain) diff --git a/internal/suites/example/compose/authelia/docker-compose.backend.dev.yml b/internal/suites/example/compose/authelia/docker-compose.backend.dev.yml index a9781dd74..10316235f 100644 --- a/internal/suites/example/compose/authelia/docker-compose.backend.dev.yml +++ b/internal/suites/example/compose/authelia/docker-compose.backend.dev.yml @@ -18,7 +18,7 @@ services: - 'traefik.frontend.rule=Host:login.example.com;PathPrefix:/api' - 'traefik.protocol=https' # Traefik 2.x - - 'traefik.http.routers.authelia_backend.rule=Host(`login.example.com`) && PathPrefix(`/api`)' + - 'traefik.http.routers.authelia_backend.rule=Host(`login.example.com`) && PathPrefix(`/api`) || Host(`login.example.com`) && PathPrefix(`${PathPrefix}/api`)' - 'traefik.http.routers.authelia_backend.entrypoints=https' - 'traefik.http.routers.authelia_backend.tls=true' - 'traefik.http.services.authelia_backend.loadbalancer.server.scheme=https' diff --git a/internal/suites/example/compose/authelia/docker-compose.backend.dist.yml b/internal/suites/example/compose/authelia/docker-compose.backend.dist.yml index 2e992567e..754183f04 100644 --- a/internal/suites/example/compose/authelia/docker-compose.backend.dist.yml +++ b/internal/suites/example/compose/authelia/docker-compose.backend.dist.yml @@ -7,7 +7,7 @@ services: - 'traefik.frontend.rule=Host:login.example.com;PathPrefix:/api' - 'traefik.protocol=https' # Traefik 2.x - - 'traefik.http.routers.authelia_backend.rule=Host(`login.example.com`) && PathPrefix(`/api`)' + - 'traefik.http.routers.authelia_backend.rule=Host(`login.example.com`) && PathPrefix(`/api`) || Host(`login.example.com`) && PathPrefix(`${PathPrefix}/api`)' - 'traefik.http.routers.authelia_backend.entrypoints=https' - 'traefik.http.routers.authelia_backend.tls=true' - 'traefik.http.services.authelia_backend.loadbalancer.server.scheme=https' diff --git a/internal/suites/example/compose/authelia/docker-compose.frontend.dev.yml b/internal/suites/example/compose/authelia/docker-compose.frontend.dev.yml index 11f7f8175..40d69a53d 100644 --- a/internal/suites/example/compose/authelia/docker-compose.frontend.dev.yml +++ b/internal/suites/example/compose/authelia/docker-compose.frontend.dev.yml @@ -17,8 +17,10 @@ services: # Traefik 1.x - 'traefik.frontend.rule=Host:login.example.com' # Traefik 2.x - - 'traefik.http.routers.authelia_frontend.rule=Host(`login.example.com`)' + - 'traefik.http.routers.authelia_frontend.rule=Host(`login.example.com`) || Host(`login.example.com`) && PathPrefix(`${PathPrefix}`)' - 'traefik.http.routers.authelia_frontend.entrypoints=https' - 'traefik.http.routers.authelia_frontend.tls=true' + environment: + - PUBLIC_URL=${PathPrefix} networks: - authelianet diff --git a/internal/suites/example/compose/authelia/docker-compose.frontend.dist.yml b/internal/suites/example/compose/authelia/docker-compose.frontend.dist.yml index e439689a1..0dd433fe4 100644 --- a/internal/suites/example/compose/authelia/docker-compose.frontend.dist.yml +++ b/internal/suites/example/compose/authelia/docker-compose.frontend.dist.yml @@ -8,7 +8,7 @@ services: # Traefik 1.x - 'traefik.frontend.rule=Host:login.example.com' # Traefik 2.x - - 'traefik.http.routers.authelia_frontend.rule=Host(`login.example.com`)' + - 'traefik.http.routers.authelia_frontend.rule=Host(`login.example.com`) || Host(`login.example.com`) && PathPrefix(`${PathPrefix}`)' - 'traefik.http.routers.authelia_frontend.entrypoints=https' - 'traefik.http.routers.authelia_frontend.tls=true' - 'traefik.http.services.authelia_frontend.loadbalancer.server.port=3000' diff --git a/internal/suites/example/compose/httpbin/docker-compose.yml b/internal/suites/example/compose/httpbin/docker-compose.yml index 1f64ca3b7..c3ec9d893 100644 --- a/internal/suites/example/compose/httpbin/docker-compose.yml +++ b/internal/suites/example/compose/httpbin/docker-compose.yml @@ -16,8 +16,4 @@ services: - 'traefik.http.routers.httpbin.rule=Host(`public.example.com`) && Path(`/headers`)' - 'traefik.http.routers.httpbin.priority=150' - 'traefik.http.routers.httpbin.tls=true' - - 'traefik.http.routers.httpbin.middlewares=authelia' - - 'traefik.http.middlewares.authelia.forwardauth.address=https://authelia-backend:9091/api/verify?rd=https://login.example.com:8080/' - - 'traefik.http.middlewares.authelia.forwardauth.tls.insecureSkipVerify=true' - - 'traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true' - - 'traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User, Remote-Groups' + - 'traefik.http.routers.httpbin.middlewares=authelia@docker' diff --git a/internal/suites/example/compose/nginx/backend/docker-compose.yml b/internal/suites/example/compose/nginx/backend/docker-compose.yml index 49af4cacb..325c1b790 100644 --- a/internal/suites/example/compose/nginx/backend/docker-compose.yml +++ b/internal/suites/example/compose/nginx/backend/docker-compose.yml @@ -4,18 +4,14 @@ services: image: nginx:alpine labels: - 'traefik.frontend.rule=Host:home.example.com,public.example.com,secure.example.com,admin.example.com,singlefactor.example.com' # Traefik 1.x - - 'traefik.frontend.auth.forward.address=https://authelia-backend:9091/api/verify?rd=https://login.example.com:8080/' # Traefik 1.x + - 'traefik.frontend.auth.forward.address=https://authelia-backend:9091/api/verify?rd=https://login.example.com:8080' # Traefik 1.x - 'traefik.frontend.auth.forward.tls.insecureSkipVerify=true' # Traefik 1.x - 'traefik.frontend.auth.forward.trustForwardHeader=true' # Traefik 1.x - 'traefik.frontend.auth.forward.authResponseHeaders=Remote-User,Remote-Groups' # Traefik 1.x - 'traefik.http.routers.protectedapps.rule=Host(`home.example.com`, `public.example.com`, `secure.example.com`, `admin.example.com`, `singlefactor.example.com`)' # Traefik 2.x - 'traefik.http.routers.protectedapps.entrypoints=https' # Traefik 2.x - 'traefik.http.routers.protectedapps.tls=true' # Traefik 2.x - - 'traefik.http.routers.protectedapps.middlewares=authelia' # Traefik 2.x - - 'traefik.http.middlewares.authelia.forwardauth.address=https://authelia-backend:9091/api/verify?rd=https://login.example.com:8080/' # Traefik 2.x - - 'traefik.http.middlewares.authelia.forwardauth.tls.insecureSkipVerify=true' # Traefik 2.x - - 'traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true' # Traefik 2.x - - 'traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User, Remote-Groups' # Traefik 2.x + - 'traefik.http.routers.protectedapps.middlewares=authelia@docker' # Traefik 2.x volumes: - ./example/compose/nginx/backend/html:/usr/share/nginx/html - ./example/compose/nginx/backend/nginx.conf:/etc/nginx/nginx.conf diff --git a/internal/suites/example/compose/traefik2/docker-compose.yml b/internal/suites/example/compose/traefik2/docker-compose.yml index 027dc74f3..85662a9de 100644 --- a/internal/suites/example/compose/traefik2/docker-compose.yml +++ b/internal/suites/example/compose/traefik2/docker-compose.yml @@ -1,7 +1,7 @@ version: '3' services: traefik: - image: traefik:v2.1.2 + image: traefik:v2.2.1 volumes: - '/var/run/docker.sock:/var/run/docker.sock' labels: @@ -9,6 +9,10 @@ services: - 'traefik.http.routers.api.entrypoints=https' - 'traefik.http.routers.api.service=api@internal' - 'traefik.http.routers.api.tls=true' + - 'traefik.http.middlewares.authelia.forwardauth.address=https://authelia-backend:9091${PathPrefix}/api/verify?rd=https://login.example.com:8080${PathPrefix}' # Traefik 2.x + - 'traefik.http.middlewares.authelia.forwardauth.tls.insecureSkipVerify=true' # Traefik 2.x + - 'traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true' # Traefik 2.x + - 'traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User, Remote-Groups' # Traefik 2.x command: - '--api' - '--providers.docker=true' diff --git a/internal/suites/scenario_reset_password_test.go b/internal/suites/scenario_reset_password_test.go index 5beea6891..ed66633a9 100644 --- a/internal/suites/scenario_reset_password_test.go +++ b/internal/suites/scenario_reset_password_test.go @@ -48,7 +48,7 @@ func (s *ResetPasswordScenario) TestShouldResetPassword() { ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) defer cancel() - s.doVisit(s.T(), LoginBaseURL) + s.doVisit(s.T(), GetLoginBaseURL()) s.verifyIsFirstFactorPage(ctx, s.T()) // Reset the password to abc @@ -72,7 +72,7 @@ func (s *ResetPasswordScenario) TestShouldMakeAttackerThinkPasswordResetIsInitia ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) defer cancel() - s.doVisit(s.T(), LoginBaseURL) + s.doVisit(s.T(), GetLoginBaseURL()) s.verifyIsFirstFactorPage(ctx, s.T()) // Try to initiate a password reset of an nonexistent user. @@ -86,7 +86,7 @@ func (s *ResetPasswordScenario) TestShouldLetUserNoticeThereIsAPasswordMismatch( ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) defer cancel() - s.doVisit(s.T(), LoginBaseURL) + s.doVisit(s.T(), GetLoginBaseURL()) s.verifyIsFirstFactorPage(ctx, s.T()) s.doInitiatePasswordReset(ctx, s.T(), "john") diff --git a/internal/suites/scenario_user_preferences_test.go b/internal/suites/scenario_user_preferences_test.go index 322a0eec1..3863260c8 100644 --- a/internal/suites/scenario_user_preferences_test.go +++ b/internal/suites/scenario_user_preferences_test.go @@ -63,7 +63,7 @@ func (s *UserPreferencesScenario) TestShouldRememberLastUsed2FAMethod() { s.verifyIsHome(ctx, s.T()) // Then go back to portal. - s.doVisit(s.T(), LoginBaseURL) + s.doVisit(s.T(), GetLoginBaseURL()) s.verifyIsSecondFactorPage(ctx, s.T()) // And check the latest method is still used. s.WaitElementLocatedByID(ctx, s.T(), "push-notification-method") diff --git a/internal/suites/suite_high_availability_test.go b/internal/suites/suite_high_availability_test.go index a87dbc8d1..54da51eee 100644 --- a/internal/suites/suite_high_availability_test.go +++ b/internal/suites/suite_high_availability_test.go @@ -79,7 +79,7 @@ func (s *HighAvailabilityWebDriverSuite) TestShouldKeepSessionAfterAutheliaResta s.verifyIsHome(ctx, s.T()) // Verify the user is still authenticated - s.doVisit(s.T(), LoginBaseURL) + s.doVisit(s.T(), GetLoginBaseURL()) s.verifyIsSecondFactorPage(ctx, s.T()) // Then logout and login again to check the secret is still there diff --git a/internal/suites/suite_one_factor_only_test.go b/internal/suites/suite_one_factor_only_test.go index ffc0881f6..5c6b8bcb3 100644 --- a/internal/suites/suite_one_factor_only_test.go +++ b/internal/suites/suite_one_factor_only_test.go @@ -71,7 +71,7 @@ func (s *OneFactorOnlyWebSuite) TestShouldDisplayAuthenticatedView() { s.doLoginOneFactor(ctx, s.T(), "john", "password", false, "http://unsafe.local") s.verifyURLIs(ctx, s.T(), HomeBaseURL+"/") - s.doVisit(s.T(), LoginBaseURL) + s.doVisit(s.T(), GetLoginBaseURL()) s.verifyIsAuthenticatedPage(ctx, s.T()) } diff --git a/internal/suites/suite_pathprefix.go b/internal/suites/suite_pathprefix.go new file mode 100644 index 000000000..cd639f1af --- /dev/null +++ b/internal/suites/suite_pathprefix.go @@ -0,0 +1,64 @@ +package suites + +import ( + "fmt" + "time" +) + +var pathPrefixSuiteName = "PathPrefix" + +func init() { + dockerEnvironment := NewDockerEnvironment([]string{ + "internal/suites/docker-compose.yml", + "internal/suites/PathPrefix/docker-compose.yml", + "internal/suites/example/compose/authelia/docker-compose.backend.{}.yml", + "internal/suites/example/compose/authelia/docker-compose.frontend.{}.yml", + "internal/suites/example/compose/nginx/backend/docker-compose.yml", + "internal/suites/example/compose/traefik2/docker-compose.yml", + "internal/suites/example/compose/smtp/docker-compose.yml", + "internal/suites/example/compose/httpbin/docker-compose.yml", + }) + + setup := func(suitePath string) error { + err := dockerEnvironment.Up() + + if err != nil { + return err + } + + return waitUntilAutheliaIsReady(dockerEnvironment) + } + + displayAutheliaLogs := func() error { + backendLogs, err := dockerEnvironment.Logs("authelia-backend", nil) + if err != nil { + return err + } + + fmt.Println(backendLogs) + + frontendLogs, err := dockerEnvironment.Logs("authelia-frontend", nil) + if err != nil { + return err + } + + fmt.Println(frontendLogs) + + return nil + } + + teardown := func(suitePath string) error { + err := dockerEnvironment.Down() + return err + } + + GlobalRegistry.Register(pathPrefixSuiteName, Suite{ + SetUp: setup, + SetUpTimeout: 5 * time.Minute, + OnSetupTimeout: displayAutheliaLogs, + OnError: displayAutheliaLogs, + TestTimeout: 2 * time.Minute, + TearDown: teardown, + TearDownTimeout: 2 * time.Minute, + }) +} diff --git a/internal/suites/suite_pathprefix_test.go b/internal/suites/suite_pathprefix_test.go new file mode 100644 index 000000000..21492f167 --- /dev/null +++ b/internal/suites/suite_pathprefix_test.go @@ -0,0 +1,35 @@ +package suites + +import ( + "testing" + + "github.com/stretchr/testify/suite" +) + +type PathPrefixSuite struct { + *SeleniumSuite +} + +func NewPathPrefixSuite() *PathPrefixSuite { + return &PathPrefixSuite{SeleniumSuite: new(SeleniumSuite)} +} + +func (s *PathPrefixSuite) TestOneFactorScenario() { + suite.Run(s.T(), NewOneFactorScenario()) +} + +func (s *PathPrefixSuite) TestTwoFactorScenario() { + suite.Run(s.T(), NewTwoFactorScenario()) +} + +func (s *PathPrefixSuite) TestCustomHeaders() { + suite.Run(s.T(), NewCustomHeadersScenario()) +} + +func (s *PathPrefixSuite) TestResetPasswordScenario() { + suite.Run(s.T(), NewResetPasswordScenario()) +} + +func TestPathPrefixSuite(t *testing.T) { + suite.Run(t, NewPathPrefixSuite()) +} diff --git a/internal/suites/suite_standalone_test.go b/internal/suites/suite_standalone_test.go index ad945460c..af8dc0c97 100644 --- a/internal/suites/suite_standalone_test.go +++ b/internal/suites/suite_standalone_test.go @@ -62,7 +62,7 @@ func (s *StandaloneWebDriverSuite) TestShouldLetUserKnowHeIsAlreadyAuthenticated s.verifyIsHome(ctx, s.T()) // Visit the login page and wait for redirection to 2FA page with success icon displayed. - s.doVisit(s.T(), LoginBaseURL) + s.doVisit(s.T(), GetLoginBaseURL()) s.verifyIsAuthenticatedPage(ctx, s.T()) } @@ -121,7 +121,7 @@ func (s *StandaloneSuite) TestShouldVerifyAPIVerifyUnauthorize() { // Standard case using Kubernetes. func (s *StandaloneSuite) TestShouldVerifyAPIVerifyRedirectFromXOriginalURL() { - req, err := http.NewRequest("GET", fmt.Sprintf("%s/api/verify?rd=%s", AutheliaBaseURL, LoginBaseURL), nil) + req, err := http.NewRequest("GET", fmt.Sprintf("%s/api/verify?rd=%s", AutheliaBaseURL, GetLoginBaseURL()), nil) s.Assert().NoError(err) req.Header.Set("X-Forwarded-Proto", "https") req.Header.Set("X-Original-URL", AdminBaseURL) @@ -134,11 +134,11 @@ func (s *StandaloneSuite) TestShouldVerifyAPIVerifyRedirectFromXOriginalURL() { s.Assert().NoError(err) urlEncodedAdminURL := url.QueryEscape(AdminBaseURL) - s.Assert().Equal(fmt.Sprintf("Found. Redirecting to %s?rd=%s", LoginBaseURL, urlEncodedAdminURL), string(body)) + s.Assert().Equal(fmt.Sprintf("Found. Redirecting to %s?rd=%s", GetLoginBaseURL(), urlEncodedAdminURL), string(body)) } func (s *StandaloneSuite) TestShouldVerifyAPIVerifyRedirectFromXOriginalHostURI() { - req, err := http.NewRequest("GET", fmt.Sprintf("%s/api/verify?rd=%s", AutheliaBaseURL, LoginBaseURL), nil) + req, err := http.NewRequest("GET", fmt.Sprintf("%s/api/verify?rd=%s", AutheliaBaseURL, GetLoginBaseURL()), nil) s.Assert().NoError(err) req.Header.Set("X-Forwarded-Proto", "https") req.Header.Set("X-Forwarded-Host", "secure.example.com:8080") @@ -152,7 +152,7 @@ func (s *StandaloneSuite) TestShouldVerifyAPIVerifyRedirectFromXOriginalHostURI( s.Assert().NoError(err) urlEncodedAdminURL := url.QueryEscape(SecureBaseURL + "/") - s.Assert().Equal(fmt.Sprintf("Found. Redirecting to %s?rd=%s", LoginBaseURL, urlEncodedAdminURL), string(body)) + s.Assert().Equal(fmt.Sprintf("Found. Redirecting to %s?rd=%s", GetLoginBaseURL(), urlEncodedAdminURL), string(body)) } func (s *StandaloneSuite) TestStandaloneWebDriverScenario() { diff --git a/internal/suites/utils.go b/internal/suites/utils.go new file mode 100644 index 000000000..951ab296e --- /dev/null +++ b/internal/suites/utils.go @@ -0,0 +1,10 @@ +package suites + +// GetLoginBaseURL returns the URL of the login portal and the path prefix if specified. +func GetLoginBaseURL() string { + if PathPrefix != "" { + return LoginBaseURL + PathPrefix + } + + return LoginBaseURL +}