diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a8f673c2e8..ac7d909589 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -50,9 +50,19 @@ jobs: console_cache_path: ${{ needs.console.outputs.cache_path }} version: ${{ needs.version.outputs.version }} - core-test: + core-unit-test: needs: core - uses: ./.github/workflows/core-test.yml + uses: ./.github/workflows/core-unit-test.yml + with: + go_version: "1.22" + core_cache_key: ${{ needs.core.outputs.cache_key }} + core_cache_path: ${{ needs.core.outputs.cache_path }} + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + core-integration-test: + needs: core + uses: ./.github/workflows/core-integration-test.yml with: go_version: "1.22" core_cache_key: ${{ needs.core.outputs.cache_key }} @@ -93,7 +103,7 @@ jobs: issues: write pull-requests: write needs: - [version, core-test, lint, container, e2e] + [version, core-unit-test, core-integration-test, lint, container, e2e] if: ${{ github.event_name == 'workflow_dispatch' }} secrets: GCR_JSON_KEY_BASE64: ${{ secrets.GCR_JSON_KEY_BASE64 }} diff --git a/.github/workflows/core-test.yml b/.github/workflows/core-integration-test.yml similarity index 95% rename from .github/workflows/core-test.yml rename to .github/workflows/core-integration-test.yml index 4d8d978b60..b790db01d7 100644 --- a/.github/workflows/core-test.yml +++ b/.github/workflows/core-integration-test.yml @@ -18,11 +18,8 @@ on: jobs: postgres: - runs-on: ubuntu-latest - # TODO: use runner group as soon as integration tests run in parallel - # Currently it only consumes time and adds no value - # runs-on: - # group: zitadel-public + runs-on: + group: zitadel-public services: postgres: image: postgres diff --git a/.github/workflows/core-unit-test.yml b/.github/workflows/core-unit-test.yml new file mode 100644 index 0000000000..0b1467ff5d --- /dev/null +++ b/.github/workflows/core-unit-test.yml @@ -0,0 +1,76 @@ +name: Unit test core + +on: + workflow_call: + inputs: + go_version: + required: true + type: string + core_cache_key: + required: true + type: string + core_cache_path: + required: true + type: string + crdb_version: + required: false + type: string + secrets: + CODECOV_TOKEN: + required: true + +jobs: + test: + runs-on: + group: zitadel-public + steps: + - + uses: actions/checkout@v3 + - + uses: actions/setup-go@v5 + with: + go-version: ${{ inputs.go_version }} + - + uses: actions/cache/restore@v4 + timeout-minutes: 1 + name: restore core + id: restore-core + with: + path: ${{ inputs.core_cache_path }} + key: ${{ inputs.core_cache_key }} + fail-on-cache-miss: true + - + id: go-cache-path + name: set cache path + run: echo "GO_CACHE_PATH=$(go env GOCACHE)" >> $GITHUB_OUTPUT + - + uses: actions/cache/restore@v4 + id: cache + timeout-minutes: 1 + continue-on-error: true + name: restore previous results + with: + key: unit-test-${{ inputs.core_cache_key }} + restore-keys: | + unit-test-core- + path: ${{ steps.go-cache-path.outputs.GO_CACHE_PATH }} + - + name: test + if: ${{ steps.cache.outputs.cache-hit != 'true' }} + run: make core_unit_test + - + name: publish coverage + uses: codecov/codecov-action@v4.3.0 + with: + file: profile.cov + name: core-unit-tests + flags: core-unit-tests + token: ${{ secrets.CODECOV_TOKEN }} + - + uses: actions/cache/save@v4 + name: cache results + if: ${{ steps.cache.outputs.cache-hit != 'true' }} + with: + key: unit-test-${{ inputs.core_cache_key }} + path: ${{ steps.go-cache-path.outputs.GO_CACHE_PATH }} + \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4d58908786..e56ca307d1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -205,16 +205,50 @@ make core_unit_test #### Run Local Integration Tests -To test the database-connected gRPC API, run PostgreSQL and CockroachDB, set up a ZITADEL instance and run the tests including integration tests: +Integration tests are run as gRPC clients against a running ZITADEL server binary. +The server binary is typically [build with coverage enabled](https://go.dev/doc/build-cover). +It is also possible to run a ZITADEL sever in a debugger and run the integrations tests like that. In order to run the server, a database is required. + +The database flavor can **optionally** be set in the environment to `cockroach` or `postgres`. The default is `postgres`. ```bash -export INTEGRATION_DB_FLAVOR="cockroach" ZITADEL_MASTERKEY="MasterkeyNeedsToHave32Characters" -docker compose -f internal/integration/config/docker-compose.yaml up --pull always --wait ${INTEGRATION_DB_FLAVOR} -make core_integration_test -docker compose -f internal/integration/config/docker-compose.yaml down +export INTEGRATION_DB_FLAVOR="cockroach" ``` -Repeat the above with `INTEGRATION_DB_FLAVOR="postgres"`. +In order to prepare the local system, the following will bring up the database, builds a coverage binary, initializes the database and starts the sever. + +```bash +make core_integration_db_up core_integration_server_start +``` + +When this job is finished, you can run individual package integration test through your IDE or command-line. The actual integration test clients reside in the `integration_test` subdirectory of the package they aim to test. Integration test files use the `integration` build tag, in order to be excluded from regular unit tests. +Because of the server-client split, Go is usually unaware of changes in server code and tends to cache test results. Pas `-count 1` to disable test caching. + +Example command to run a single package integration test: + +```bash +go test -count 1 -tags integration ./internal/api/grpc/management/integration_test +``` + +To run all available integration tests: + +```bash +make core_integration_test_packages +``` + +When you change any ZITADEL server code, be sure to rebuild and restart the server before the next test run. + +```bash +make core_integration_server_stop core_integration_server_start +``` + +To cleanup after testing (deletes the database!): + +```bash +make core_integration_server_stop core_integration_db_down +``` + +The test binary has the race detector enabled. `core_core_integration_server_stop` checks for any race logs reported by Go and will print them along a `66` exit code when found. Note that the actual race condition may have happened anywhere during the server lifetime, including start, stop or serving gRPC requests during tests. #### Run Local End-to-End Tests diff --git a/Makefile b/Makefile index 8ef48623f6..56788e9f34 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,12 @@ VERSION ?= development-$(now) COMMIT_SHA ?= $(shell git rev-parse HEAD) ZITADEL_IMAGE ?= zitadel:local +GOCOVERDIR = tmp/coverage +INTEGRATION_DB_FLAVOR ?= postgres +ZITADEL_MASTERKEY ?= MasterkeyNeedsToHave32Characters + +export GOCOVERDIR INTEGRATION_DB_FLAVOR ZITADEL_MASTERKEY + .PHONY: compile compile: core_build console_build compile_pipeline @@ -99,25 +105,56 @@ clean: $(RM) -r .artifacts/grpc $(RM) $(gen_authopt_path) $(RM) $(gen_zitadel_path) + $(RM) -r tmp/ .PHONY: core_unit_test core_unit_test: - go test -race -coverprofile=profile.cov ./... + go test -race -coverprofile=profile.cov -coverpkg=./internal/... ./... + +.PHONY: core_integration_db_up +core_integration_db_up: + docker compose -f internal/integration/config/docker-compose.yaml up --pull always --wait $${INTEGRATION_DB_FLAVOR} + +.PHONY: core_integration_db_down +core_integration_db_down: + docker compose -f internal/integration/config/docker-compose.yaml down .PHONY: core_integration_setup core_integration_setup: - go build -o zitadel main.go - ./zitadel init --config internal/integration/config/zitadel.yaml --config internal/integration/config/${INTEGRATION_DB_FLAVOR}.yaml - ./zitadel setup --masterkeyFromEnv --init-projections --config internal/integration/config/zitadel.yaml --config internal/integration/config/${INTEGRATION_DB_FLAVOR}.yaml --steps internal/integration/config/zitadel.yaml --steps internal/integration/config/${INTEGRATION_DB_FLAVOR}.yaml - $(RM) zitadel + go build -cover -race -tags integration -o zitadel.test main.go + mkdir -p $${GOCOVERDIR} + GORACE="halt_on_error=1" ./zitadel.test init --config internal/integration/config/zitadel.yaml --config internal/integration/config/${INTEGRATION_DB_FLAVOR}.yaml + GORACE="halt_on_error=1" ./zitadel.test setup --masterkeyFromEnv --init-projections --config internal/integration/config/zitadel.yaml --config internal/integration/config/${INTEGRATION_DB_FLAVOR}.yaml --steps internal/integration/config/steps.yaml + +.PHONY: core_integration_server_start +core_integration_server_start: core_integration_setup + GORACE="log_path=tmp/race.log" \ + ./zitadel.test start --masterkeyFromEnv --config internal/integration/config/zitadel.yaml --config internal/integration/config/${INTEGRATION_DB_FLAVOR}.yaml \ + > tmp/zitadel.log 2>&1 \ + & printf $$! > tmp/zitadel.pid + +.PHONY: core_integration_test_packages +core_integration_test_packages: + go test -count 1 -tags integration -timeout 30m $$(go list -tags integration ./... | grep "integration_test") + +.PHONY: core_integration_server_stop +core_integration_server_stop: + pid=$$(cat tmp/zitadel.pid); \ + $(RM) tmp/zitadel.pid; \ + kill $$pid; \ + if [ -s tmp/race.log.$$pid ]; then \ + cat tmp/race.log.$$pid; \ + exit 66; \ + fi + +.PHONY: core_integration_reports +core_integration_reports: + go tool covdata textfmt -i=tmp/coverage -pkg=github.com/zitadel/zitadel/internal/...,github.com/zitadel/zitadel/cmd/... -o profile.cov + $(RM) -r tmp/coverage + cat tmp/zitadel.log .PHONY: core_integration_test -core_integration_test: core_integration_setup - go test -tags=integration -race -p 1 -coverprofile=profile.cov -coverpkg=./internal/...,./cmd/... ./... - -.PHONY: core_integration_test_fast -core_integration_test_fast: core_integration_setup - go test -tags=integration -p 1 ./... +core_integration_test: core_integration_server_start core_integration_test_packages core_integration_server_stop core_integration_reports .PHONY: console_lint console_lint: diff --git a/cmd/start/start.go b/cmd/start/start.go index 47bc33ca42..594e16776b 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -79,6 +79,7 @@ import ( new_es "github.com/zitadel/zitadel/internal/eventstore/v3" "github.com/zitadel/zitadel/internal/i18n" "github.com/zitadel/zitadel/internal/id" + "github.com/zitadel/zitadel/internal/integration/sink" "github.com/zitadel/zitadel/internal/logstore" "github.com/zitadel/zitadel/internal/logstore/emitters/access" "github.com/zitadel/zitadel/internal/logstore/emitters/execution" @@ -138,6 +139,10 @@ type Server struct { func startZitadel(ctx context.Context, config *Config, masterKey string, server chan<- *Server) error { showBasicInformation(config) + // sink Server is stubbed out in production builds, see function's godoc. + closeSink := sink.StartServer() + defer closeSink() + i18n.MustLoadSupportedLanguagesFromDir() queryDBClient, err := database.Connect(config.Database, false, dialect.DBPurposeQuery) diff --git a/go.mod b/go.mod index 61d1d711d1..0137251400 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/envoyproxy/protoc-gen-validate v1.0.4 github.com/fatih/color v1.17.0 github.com/gabriel-vasile/mimetype v1.4.4 + github.com/go-chi/chi/v5 v5.1.0 github.com/go-jose/go-jose/v4 v4.0.4 github.com/go-ldap/ldap/v3 v3.4.8 github.com/go-webauthn/webauthn v0.10.2 @@ -30,6 +31,7 @@ require ( github.com/gorilla/mux v1.8.1 github.com/gorilla/schema v1.4.1 github.com/gorilla/securecookie v1.1.2 + github.com/gorilla/websocket v1.4.1 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 @@ -95,7 +97,6 @@ require ( github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.0 // indirect github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect github.com/crewjam/httperr v0.2.0 // indirect - github.com/go-chi/chi/v5 v5.1.0 // indirect github.com/go-ini/ini v1.67.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect diff --git a/go.sum b/go.sum index 82ef92c3a7..de6c80d513 100644 --- a/go.sum +++ b/go.sum @@ -346,6 +346,7 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= diff --git a/internal/api/grpc/admin/iam_member_integration_test.go b/internal/api/grpc/admin/integration_test/iam_member_test.go similarity index 82% rename from internal/api/grpc/admin/iam_member_integration_test.go rename to internal/api/grpc/admin/integration_test/iam_member_test.go index 06a8acb914..c65ede3d26 100644 --- a/internal/api/grpc/admin/iam_member_integration_test.go +++ b/internal/api/grpc/admin/integration_test/iam_member_test.go @@ -5,6 +5,7 @@ package admin_test import ( "context" "testing" + "time" "github.com/brianvoe/gofakeit/v6" "github.com/stretchr/testify/assert" @@ -33,7 +34,7 @@ func TestServer_ListIAMMemberRoles(t *testing.T) { } func TestServer_ListIAMMembers(t *testing.T) { - user := Tester.CreateHumanUserVerified(AdminCTX, Tester.Organisation.ID, gofakeit.Email()) + user := Instance.CreateHumanUserVerified(AdminCTX, Instance.DefaultOrg.Id, gofakeit.Email()) _, err := Client.AddIAMMember(AdminCTX, &admin_pb.AddIAMMemberRequest{ UserId: user.GetUserId(), Roles: iamRoles, @@ -52,7 +53,7 @@ func TestServer_ListIAMMembers(t *testing.T) { { name: "permission error", args: args{ - ctx: Tester.WithAuthorization(CTX, integration.OrgOwner), + ctx: Instance.WithAuthorization(CTX, integration.UserTypeOrgOwner), req: &admin_pb.ListIAMMembersRequest{ Query: &object.ListQuery{}, Queries: []*member.SearchQuery{{ @@ -91,26 +92,29 @@ func TestServer_ListIAMMembers(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := Client.ListIAMMembers(tt.args.ctx, tt.args.req) - if tt.wantErr { - assert.Error(t, err) - return - } - require.NoError(t, err) - wantResult := tt.want.GetResult() - gotResult := got.GetResult() + assert.EventuallyWithT(t, func(ct *assert.CollectT) { + got, err := Client.ListIAMMembers(tt.args.ctx, tt.args.req) + if tt.wantErr { + assert.Error(ct, err) + return + } + require.NoError(ct, err) + wantResult := tt.want.GetResult() + gotResult := got.GetResult() - require.Len(t, gotResult, len(wantResult)) - for i, want := range wantResult { - assert.Equal(t, want.GetUserId(), gotResult[i].GetUserId()) - assert.ElementsMatch(t, want.GetRoles(), gotResult[i].GetRoles()) - } + if assert.Len(ct, gotResult, len(wantResult)) { + for i, want := range wantResult { + assert.Equal(ct, want.GetUserId(), gotResult[i].GetUserId()) + assert.ElementsMatch(ct, want.GetRoles(), gotResult[i].GetRoles()) + } + } + }, time.Minute, time.Second) }) } } func TestServer_AddIAMMember(t *testing.T) { - user := Tester.CreateHumanUserVerified(AdminCTX, Tester.Organisation.ID, gofakeit.Email()) + user := Instance.CreateHumanUserVerified(AdminCTX, Instance.DefaultOrg.Id, gofakeit.Email()) type args struct { ctx context.Context req *admin_pb.AddIAMMemberRequest @@ -124,7 +128,7 @@ func TestServer_AddIAMMember(t *testing.T) { { name: "permission error", args: args{ - ctx: Tester.WithAuthorization(CTX, integration.OrgOwner), + ctx: Instance.WithAuthorization(CTX, integration.UserTypeOrgOwner), req: &admin_pb.AddIAMMemberRequest{ UserId: user.GetUserId(), Roles: iamRoles, @@ -143,7 +147,7 @@ func TestServer_AddIAMMember(t *testing.T) { }, want: &admin_pb.AddIAMMemberResponse{ Details: &object.ObjectDetails{ - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), }, }, }, @@ -184,7 +188,7 @@ func TestServer_AddIAMMember(t *testing.T) { } func TestServer_UpdateIAMMember(t *testing.T) { - user := Tester.CreateHumanUserVerified(AdminCTX, Tester.Organisation.ID, gofakeit.Email()) + user := Instance.CreateHumanUserVerified(AdminCTX, Instance.DefaultOrg.Id, gofakeit.Email()) _, err := Client.AddIAMMember(AdminCTX, &admin_pb.AddIAMMemberRequest{ UserId: user.GetUserId(), Roles: []string{"IAM_OWNER"}, @@ -204,7 +208,7 @@ func TestServer_UpdateIAMMember(t *testing.T) { { name: "permission error", args: args{ - ctx: Tester.WithAuthorization(CTX, integration.OrgOwner), + ctx: Instance.WithAuthorization(CTX, integration.UserTypeOrgOwner), req: &admin_pb.UpdateIAMMemberRequest{ UserId: user.GetUserId(), Roles: iamRoles, @@ -223,7 +227,7 @@ func TestServer_UpdateIAMMember(t *testing.T) { }, want: &admin_pb.UpdateIAMMemberResponse{ Details: &object.ObjectDetails{ - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), ChangeDate: timestamppb.Now(), }, }, @@ -265,7 +269,7 @@ func TestServer_UpdateIAMMember(t *testing.T) { } func TestServer_RemoveIAMMember(t *testing.T) { - user := Tester.CreateHumanUserVerified(AdminCTX, Tester.Organisation.ID, gofakeit.Email()) + user := Instance.CreateHumanUserVerified(AdminCTX, Instance.DefaultOrg.Id, gofakeit.Email()) _, err := Client.AddIAMMember(AdminCTX, &admin_pb.AddIAMMemberRequest{ UserId: user.GetUserId(), Roles: []string{"IAM_OWNER"}, @@ -285,7 +289,7 @@ func TestServer_RemoveIAMMember(t *testing.T) { { name: "permission error", args: args{ - ctx: Tester.WithAuthorization(CTX, integration.OrgOwner), + ctx: Instance.WithAuthorization(CTX, integration.UserTypeOrgOwner), req: &admin_pb.RemoveIAMMemberRequest{ UserId: user.GetUserId(), }, @@ -302,7 +306,7 @@ func TestServer_RemoveIAMMember(t *testing.T) { }, want: &admin_pb.RemoveIAMMemberResponse{ Details: &object.ObjectDetails{ - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), ChangeDate: timestamppb.Now(), }, }, diff --git a/internal/api/grpc/admin/iam_settings_integration_test.go b/internal/api/grpc/admin/integration_test/iam_settings_test.go similarity index 79% rename from internal/api/grpc/admin/iam_settings_integration_test.go rename to internal/api/grpc/admin/integration_test/iam_settings_test.go index 6d39abb747..2787f94755 100644 --- a/internal/api/grpc/admin/iam_settings_integration_test.go +++ b/internal/api/grpc/admin/integration_test/iam_settings_test.go @@ -17,21 +17,17 @@ import ( ) func TestServer_GetSecurityPolicy(t *testing.T) { - _, err := Client.SetSecurityPolicy(AdminCTX, &admin_pb.SetSecurityPolicyRequest{ + t.Parallel() + + instance := integration.NewInstance(CTX) + adminCtx := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + + _, err := instance.Client.Admin.SetSecurityPolicy(adminCtx, &admin_pb.SetSecurityPolicyRequest{ EnableIframeEmbedding: true, AllowedOrigins: []string{"foo.com", "bar.com"}, EnableImpersonation: true, }) require.NoError(t, err) - t.Cleanup(func() { - _, err := Client.SetSecurityPolicy(AdminCTX, &admin_pb.SetSecurityPolicyRequest{ - EnableIframeEmbedding: false, - AllowedOrigins: []string{}, - EnableImpersonation: false, - }) - require.NoError(t, err) - }) - tests := []struct { name string ctx context.Context @@ -40,12 +36,12 @@ func TestServer_GetSecurityPolicy(t *testing.T) { }{ { name: "permission error", - ctx: Tester.WithAuthorization(CTX, integration.OrgOwner), + ctx: instance.WithAuthorization(CTX, integration.UserTypeOrgOwner), wantErr: true, }, { name: "success", - ctx: AdminCTX, + ctx: adminCtx, want: &admin_pb.GetSecurityPolicyResponse{ Policy: &settings.SecurityPolicy{ EnableIframeEmbedding: true, @@ -57,7 +53,7 @@ func TestServer_GetSecurityPolicy(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - resp, err := Client.GetSecurityPolicy(tt.ctx, &admin_pb.GetSecurityPolicyRequest{}) + resp, err := instance.Client.Admin.GetSecurityPolicy(tt.ctx, &admin_pb.GetSecurityPolicyRequest{}) if tt.wantErr { assert.Error(t, err) return @@ -72,6 +68,11 @@ func TestServer_GetSecurityPolicy(t *testing.T) { } func TestServer_SetSecurityPolicy(t *testing.T) { + t.Parallel() + + instance := integration.NewInstance(CTX) + adminCtx := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + type args struct { ctx context.Context req *admin_pb.SetSecurityPolicyRequest @@ -85,7 +86,7 @@ func TestServer_SetSecurityPolicy(t *testing.T) { { name: "permission error", args: args{ - ctx: Tester.WithAuthorization(CTX, integration.OrgOwner), + ctx: instance.WithAuthorization(CTX, integration.UserTypeOrgOwner), req: &admin_pb.SetSecurityPolicyRequest{ EnableIframeEmbedding: true, AllowedOrigins: []string{"foo.com", "bar.com"}, @@ -97,7 +98,7 @@ func TestServer_SetSecurityPolicy(t *testing.T) { { name: "success allowed origins", args: args{ - ctx: AdminCTX, + ctx: adminCtx, req: &admin_pb.SetSecurityPolicyRequest{ AllowedOrigins: []string{"foo.com", "bar.com"}, }, @@ -105,14 +106,14 @@ func TestServer_SetSecurityPolicy(t *testing.T) { want: &admin_pb.SetSecurityPolicyResponse{ Details: &object.ObjectDetails{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: instance.ID(), }, }, }, { name: "success iframe embedding", args: args{ - ctx: AdminCTX, + ctx: adminCtx, req: &admin_pb.SetSecurityPolicyRequest{ EnableIframeEmbedding: true, }, @@ -120,14 +121,14 @@ func TestServer_SetSecurityPolicy(t *testing.T) { want: &admin_pb.SetSecurityPolicyResponse{ Details: &object.ObjectDetails{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: instance.ID(), }, }, }, { name: "success impersonation", args: args{ - ctx: AdminCTX, + ctx: adminCtx, req: &admin_pb.SetSecurityPolicyRequest{ EnableImpersonation: true, }, @@ -135,14 +136,14 @@ func TestServer_SetSecurityPolicy(t *testing.T) { want: &admin_pb.SetSecurityPolicyResponse{ Details: &object.ObjectDetails{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: instance.ID(), }, }, }, { name: "success all", args: args{ - ctx: AdminCTX, + ctx: adminCtx, req: &admin_pb.SetSecurityPolicyRequest{ EnableIframeEmbedding: true, AllowedOrigins: []string{"foo.com", "bar.com"}, @@ -152,14 +153,14 @@ func TestServer_SetSecurityPolicy(t *testing.T) { want: &admin_pb.SetSecurityPolicyResponse{ Details: &object.ObjectDetails{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: instance.ID(), }, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := Client.SetSecurityPolicy(tt.args.ctx, tt.args.req) + got, err := instance.Client.Admin.SetSecurityPolicy(tt.args.ctx, tt.args.req) if tt.wantErr { assert.Error(t, err) return diff --git a/internal/api/grpc/admin/import_integration_test.go b/internal/api/grpc/admin/integration_test/import_test.go similarity index 100% rename from internal/api/grpc/admin/import_integration_test.go rename to internal/api/grpc/admin/integration_test/import_test.go diff --git a/internal/api/grpc/admin/information_integration_test.go b/internal/api/grpc/admin/integration_test/information_test.go similarity index 81% rename from internal/api/grpc/admin/information_integration_test.go rename to internal/api/grpc/admin/integration_test/information_test.go index 7c324fc27a..9072bc80eb 100644 --- a/internal/api/grpc/admin/information_integration_test.go +++ b/internal/api/grpc/admin/integration_test/information_test.go @@ -15,6 +15,6 @@ import ( func TestServer_Healthz(t *testing.T) { ctx, cancel := context.WithTimeout(AdminCTX, time.Minute) defer cancel() - _, err := Tester.Client.Admin.Healthz(ctx, &admin.HealthzRequest{}) + _, err := Instance.Client.Admin.Healthz(ctx, &admin.HealthzRequest{}) require.NoError(t, err) } diff --git a/internal/api/grpc/admin/restrictions_integration_allow_public_org_registrations_test.go b/internal/api/grpc/admin/integration_test/restrictions_allow_public_org_registrations_test.go similarity index 64% rename from internal/api/grpc/admin/restrictions_integration_allow_public_org_registrations_test.go rename to internal/api/grpc/admin/integration_test/restrictions_allow_public_org_registrations_test.go index 5b29de19bb..3663fec4dd 100644 --- a/internal/api/grpc/admin/restrictions_integration_allow_public_org_registrations_test.go +++ b/internal/api/grpc/admin/integration_test/restrictions_allow_public_org_registrations_test.go @@ -10,20 +10,20 @@ import ( "net/http/cookiejar" "net/url" "testing" - "time" "github.com/muhlemmer/gu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/pkg/grpc/admin" ) func TestServer_Restrictions_DisallowPublicOrgRegistration(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - domain, _, _, iamOwnerCtx := Tester.UseIsolatedInstance(t, ctx, SystemCTX) - regOrgUrl, err := url.Parse("http://" + domain + ":8080/ui/login/register/org") + t.Parallel() + + instance := integration.NewInstance(CTX) + regOrgUrl, err := url.Parse("http://" + instance.Domain + ":8080/ui/login/register/org") require.NoError(t, err) // The CSRF cookie must be sent with every request. // We can simulate a browser session using a cookie jar. @@ -31,36 +31,38 @@ func TestServer_Restrictions_DisallowPublicOrgRegistration(t *testing.T) { require.NoError(t, err) browserSession := &http.Client{Jar: jar} var csrfToken string - t.Run("public org registration is allowed by default", func(*testing.T) { - csrfToken = awaitPubOrgRegAllowed(t, iamOwnerCtx, browserSession, regOrgUrl) + iamOwnerCtx := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + + t.Run("public org registration is allowed by default", func(tt *testing.T) { + csrfToken = awaitPubOrgRegAllowed(tt, iamOwnerCtx, instance.Client, browserSession, regOrgUrl) }) - t.Run("disallowing public org registration disables the endpoints", func(*testing.T) { - _, err = Tester.Client.Admin.SetRestrictions(iamOwnerCtx, &admin.SetRestrictionsRequest{DisallowPublicOrgRegistration: gu.Ptr(true)}) - require.NoError(t, err) - awaitPubOrgRegDisallowed(t, iamOwnerCtx, browserSession, regOrgUrl, csrfToken) + t.Run("disallowing public org registration disables the endpoints", func(tt *testing.T) { + _, err = instance.Client.Admin.SetRestrictions(iamOwnerCtx, &admin.SetRestrictionsRequest{DisallowPublicOrgRegistration: gu.Ptr(true)}) + require.NoError(tt, err) + awaitPubOrgRegDisallowed(tt, iamOwnerCtx, instance.Client, browserSession, regOrgUrl, csrfToken) }) - t.Run("allowing public org registration again re-enables the endpoints", func(*testing.T) { - _, err = Tester.Client.Admin.SetRestrictions(iamOwnerCtx, &admin.SetRestrictionsRequest{DisallowPublicOrgRegistration: gu.Ptr(false)}) - require.NoError(t, err) - awaitPubOrgRegAllowed(t, iamOwnerCtx, browserSession, regOrgUrl) + t.Run("allowing public org registration again re-enables the endpoints", func(tt *testing.T) { + _, err = instance.Client.Admin.SetRestrictions(iamOwnerCtx, &admin.SetRestrictionsRequest{DisallowPublicOrgRegistration: gu.Ptr(false)}) + require.NoError(tt, err) + awaitPubOrgRegAllowed(tt, iamOwnerCtx, instance.Client, browserSession, regOrgUrl) }) } // awaitPubOrgRegAllowed doesn't accept a CSRF token, as we expected it to always produce a new one -func awaitPubOrgRegAllowed(t *testing.T, ctx context.Context, client *http.Client, parsedURL *url.URL) string { +func awaitPubOrgRegAllowed(t *testing.T, ctx context.Context, cc *integration.Client, client *http.Client, parsedURL *url.URL) string { csrfToken := awaitGetSSRGetResponse(t, ctx, client, parsedURL, http.StatusOK) awaitPostFormResponse(t, ctx, client, parsedURL, http.StatusOK, csrfToken) - restrictions, err := Tester.Client.Admin.GetRestrictions(ctx, &admin.GetRestrictionsRequest{}) + restrictions, err := cc.Admin.GetRestrictions(ctx, &admin.GetRestrictionsRequest{}) require.NoError(t, err) require.False(t, restrictions.DisallowPublicOrgRegistration) return csrfToken } // awaitPubOrgRegDisallowed accepts an old CSRF token, as we don't expect to get a CSRF token from the GET request anymore -func awaitPubOrgRegDisallowed(t *testing.T, ctx context.Context, client *http.Client, parsedURL *url.URL, reuseOldCSRFToken string) { +func awaitPubOrgRegDisallowed(t *testing.T, ctx context.Context, cc *integration.Client, client *http.Client, parsedURL *url.URL, reuseOldCSRFToken string) { awaitGetSSRGetResponse(t, ctx, client, parsedURL, http.StatusNotFound) awaitPostFormResponse(t, ctx, client, parsedURL, http.StatusConflict, reuseOldCSRFToken) - restrictions, err := Tester.Client.Admin.GetRestrictions(ctx, &admin.GetRestrictionsRequest{}) + restrictions, err := cc.Admin.GetRestrictions(ctx, &admin.GetRestrictionsRequest{}) require.NoError(t, err) require.True(t, restrictions.DisallowPublicOrgRegistration) } @@ -70,9 +72,9 @@ func awaitGetSSRGetResponse(t *testing.T, ctx context.Context, client *http.Clie var csrfToken []byte await(t, ctx, func(tt *assert.CollectT) { resp, err := client.Get(parsedURL.String()) - require.NoError(t, err) + require.NoError(tt, err) body, err := io.ReadAll(resp.Body) - require.NoError(t, err) + require.NoError(tt, err) searchField := ` 0", assert.Greater, zeroCounts) }, "wait for seeded event assertions to pass") - produceEvents(iamOwnerCtx, t, userID, appID, projectID, projectGrantID) - addedCount := requireEventually(t, iamOwnerCtx, userID, projectID, appID, projectGrantID, func(c assert.TestingT, counts *eventCounts) { + produceEvents(iamOwnerCtx, t, isoInstance.Client, userID, appID, projectID, projectGrantID) + addedCount := requireEventually(t, iamOwnerCtx, isoInstance.Client, userID, projectID, appID, projectGrantID, func(c assert.TestingT, counts *eventCounts) { counts.assertAll(t, c, "added events are > seeded events", assert.Greater, seededCount) }, "wait for added event assertions to pass") - _, err := Tester.Client.System.SetLimits(SystemCTX, &system.SetLimitsRequest{ - InstanceId: instanceID, + _, err := integration.SystemClient().SetLimits(CTX, &system.SetLimitsRequest{ + InstanceId: isoInstance.ID(), AuditLogRetention: durationpb.New(time.Now().Sub(beforeTime)), }) require.NoError(t, err) var limitedCounts *eventCounts - requireEventually(t, iamOwnerCtx, userID, projectID, appID, projectGrantID, func(c assert.TestingT, counts *eventCounts) { + requireEventually(t, iamOwnerCtx, isoInstance.Client, userID, projectID, appID, projectGrantID, func(c assert.TestingT, counts *eventCounts) { counts.assertAll(t, c, "limited events < added events", assert.Less, addedCount) counts.assertAll(t, c, "limited events > 0", assert.Greater, zeroCounts) limitedCounts = counts }, "wait for limited event assertions to pass") - listedEvents, err := Tester.Client.Admin.ListEvents(iamOwnerCtx, &admin.ListEventsRequest{CreationDateFilter: &admin.ListEventsRequest_From{ + listedEvents, err := isoInstance.Client.Admin.ListEvents(iamOwnerCtx, &admin.ListEventsRequest{CreationDateFilter: &admin.ListEventsRequest_From{ From: farPast, }}) require.NoError(t, err) assert.LessOrEqual(t, len(listedEvents.GetEvents()), limitedCounts.all, "ListEvents with from query older than retention doesn't return more events") - listedEvents, err = Tester.Client.Admin.ListEvents(iamOwnerCtx, &admin.ListEventsRequest{CreationDateFilter: &admin.ListEventsRequest_Range{Range: &admin.ListEventsRequestCreationDateRange{ + listedEvents, err = isoInstance.Client.Admin.ListEvents(iamOwnerCtx, &admin.ListEventsRequest{CreationDateFilter: &admin.ListEventsRequest_Range{Range: &admin.ListEventsRequestCreationDateRange{ Since: farPast, }}}) require.NoError(t, err) assert.LessOrEqual(t, len(listedEvents.GetEvents()), limitedCounts.all, "ListEvents with since query older than retention doesn't return more events") - _, err = Tester.Client.System.ResetLimits(SystemCTX, &system.ResetLimitsRequest{ - InstanceId: instanceID, + _, err = integration.SystemClient().ResetLimits(CTX, &system.ResetLimitsRequest{ + InstanceId: isoInstance.ID(), }) require.NoError(t, err) - requireEventually(t, iamOwnerCtx, userID, projectID, appID, projectGrantID, func(c assert.TestingT, counts *eventCounts) { + requireEventually(t, iamOwnerCtx, isoInstance.Client, userID, projectID, appID, projectGrantID, func(c assert.TestingT, counts *eventCounts) { counts.assertAll(t, c, "with reset limit, added events are > seeded events", assert.Greater, seededCount) }, "wait for reset event assertions to pass") } @@ -66,6 +70,7 @@ func TestServer_Limits_AuditLogRetention(t *testing.T) { func requireEventually( t *testing.T, ctx context.Context, + cc *integration.Client, userID, projectID, appID, projectGrantID string, assertCounts func(assert.TestingT, *eventCounts), msg string, @@ -75,7 +80,7 @@ func requireEventually( countCtx, cancel := context.WithTimeout(ctx, countTimeout) defer cancel() require.EventuallyWithT(t, func(c *assert.CollectT) { - counts = countEvents(countCtx, t, userID, projectID, appID, projectGrantID) + counts = countEvents(countCtx, c, cc, userID, projectID, appID, projectGrantID) assertCounts(c, counts) }, assertTimeout, time.Second, msg) return counts @@ -91,68 +96,68 @@ func randomString(resourceType string, n int) string { return "test" + resourceType + "-" + string(b) } -func seedObjects(ctx context.Context, t *testing.T) (string, string, string, string) { +func seedObjects(ctx context.Context, t *testing.T, cc *integration.Client) (string, string, string, string) { t.Helper() - project, err := Tester.Client.Mgmt.AddProject(ctx, &management.AddProjectRequest{ + project, err := cc.Mgmt.AddProject(ctx, &management.AddProjectRequest{ Name: randomString("project", 5), }) require.NoError(t, err) - app, err := Tester.Client.Mgmt.AddOIDCApp(ctx, &management.AddOIDCAppRequest{ + app, err := cc.Mgmt.AddOIDCApp(ctx, &management.AddOIDCAppRequest{ Name: randomString("app", 5), ProjectId: project.GetId(), }) - org, err := Tester.Client.Mgmt.AddOrg(ctx, &management.AddOrgRequest{ + org, err := cc.Mgmt.AddOrg(ctx, &management.AddOrgRequest{ Name: randomString("org", 5), }) require.NoError(t, err) role := randomString("role", 5) require.NoError(t, err) - _, err = Tester.Client.Mgmt.AddProjectRole(ctx, &management.AddProjectRoleRequest{ + _, err = cc.Mgmt.AddProjectRole(ctx, &management.AddProjectRoleRequest{ ProjectId: project.GetId(), RoleKey: role, DisplayName: role, }) require.NoError(t, err) - projectGrant, err := Tester.Client.Mgmt.AddProjectGrant(ctx, &management.AddProjectGrantRequest{ + projectGrant, err := cc.Mgmt.AddProjectGrant(ctx, &management.AddProjectGrantRequest{ ProjectId: project.GetId(), GrantedOrgId: org.GetId(), RoleKeys: []string{role}, }) require.NoError(t, err) - user, err := Tester.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) + user, err := cc.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) require.NoError(t, err) userID := user.GetUser().GetId() - requireUserEvent(ctx, t, userID) + requireUserEvent(ctx, t, cc, userID) return userID, project.GetId(), app.GetAppId(), projectGrant.GetGrantId() } -func produceEvents(ctx context.Context, t *testing.T, machineID, appID, projectID, grantID string) { +func produceEvents(ctx context.Context, t *testing.T, cc *integration.Client, machineID, appID, projectID, grantID string) { t.Helper() - _, err := Tester.Client.Mgmt.UpdateOrg(ctx, &management.UpdateOrgRequest{ + _, err := cc.Mgmt.UpdateOrg(ctx, &management.UpdateOrgRequest{ Name: randomString("org", 5), }) require.NoError(t, err) - _, err = Tester.Client.Mgmt.UpdateProject(ctx, &management.UpdateProjectRequest{ + _, err = cc.Mgmt.UpdateProject(ctx, &management.UpdateProjectRequest{ Id: projectID, Name: randomString("project", 5), }) require.NoError(t, err) - _, err = Tester.Client.Mgmt.UpdateApp(ctx, &management.UpdateAppRequest{ + _, err = cc.Mgmt.UpdateApp(ctx, &management.UpdateAppRequest{ AppId: appID, ProjectId: projectID, Name: randomString("app", 5), }) require.NoError(t, err) - requireUserEvent(ctx, t, machineID) - _, err = Tester.Client.Mgmt.UpdateProjectGrant(ctx, &management.UpdateProjectGrantRequest{ + requireUserEvent(ctx, t, cc, machineID) + _, err = cc.Mgmt.UpdateProjectGrant(ctx, &management.UpdateProjectGrantRequest{ ProjectId: projectID, GrantId: grantID, }) require.NoError(t, err) } -func requireUserEvent(ctx context.Context, t *testing.T, machineID string) { - _, err := Tester.Client.Mgmt.UpdateMachine(ctx, &management.UpdateMachineRequest{ +func requireUserEvent(ctx context.Context, t *testing.T, cc *integration.Client, machineID string) { + _, err := cc.Mgmt.UpdateMachine(ctx, &management.UpdateMachineRequest{ UserId: machineID, Name: randomString("machine", 5), }) @@ -175,51 +180,50 @@ func (e *eventCounts) assertAll(t *testing.T, c assert.TestingT, name string, co }) } -func countEvents(ctx context.Context, t *testing.T, userID, projectID, appID, grantID string) *eventCounts { - t.Helper() +func countEvents(ctx context.Context, t assert.TestingT, cc *integration.Client, userID, projectID, appID, grantID string) *eventCounts { counts := new(eventCounts) var wg sync.WaitGroup wg.Add(7) go func() { defer wg.Done() - result, err := Tester.Client.Admin.ListEvents(ctx, &admin.ListEventsRequest{}) - require.NoError(t, err) + result, err := cc.Admin.ListEvents(ctx, &admin.ListEventsRequest{}) + assert.NoError(t, err) counts.all = len(result.GetEvents()) }() go func() { defer wg.Done() - result, err := Tester.Client.Auth.ListMyUserChanges(ctx, &auth.ListMyUserChangesRequest{}) - require.NoError(t, err) + result, err := cc.Auth.ListMyUserChanges(ctx, &auth.ListMyUserChangesRequest{}) + assert.NoError(t, err) counts.myUser = len(result.GetResult()) }() go func() { defer wg.Done() - result, err := Tester.Client.Mgmt.ListUserChanges(ctx, &management.ListUserChangesRequest{UserId: userID}) - require.NoError(t, err) + result, err := cc.Mgmt.ListUserChanges(ctx, &management.ListUserChangesRequest{UserId: userID}) + assert.NoError(t, err) counts.aUser = len(result.GetResult()) }() go func() { defer wg.Done() - result, err := Tester.Client.Mgmt.ListAppChanges(ctx, &management.ListAppChangesRequest{ProjectId: projectID, AppId: appID}) - require.NoError(t, err) + result, err := cc.Mgmt.ListAppChanges(ctx, &management.ListAppChangesRequest{ProjectId: projectID, AppId: appID}) + assert.NoError(t, err) counts.app = len(result.GetResult()) }() go func() { defer wg.Done() - result, err := Tester.Client.Mgmt.ListOrgChanges(ctx, &management.ListOrgChangesRequest{}) - require.NoError(t, err) + result, err := cc.Mgmt.ListOrgChanges(ctx, &management.ListOrgChangesRequest{}) + assert.NoError(t, err) counts.org = len(result.GetResult()) }() go func() { defer wg.Done() - result, err := Tester.Client.Mgmt.ListProjectChanges(ctx, &management.ListProjectChangesRequest{ProjectId: projectID}) - require.NoError(t, err) + result, err := cc.Mgmt.ListProjectChanges(ctx, &management.ListProjectChangesRequest{ProjectId: projectID}) + assert.NoError(t, err) counts.project = len(result.GetResult()) }() go func() { defer wg.Done() - result, err := Tester.Client.Mgmt.ListProjectGrantChanges(ctx, &management.ListProjectGrantChangesRequest{ProjectId: projectID, GrantId: grantID}) - require.NoError(t, err) + result, err := cc.Mgmt.ListProjectGrantChanges(ctx, &management.ListProjectGrantChangesRequest{ProjectId: projectID, GrantId: grantID}) + assert.NoError(t, err) counts.grant = len(result.GetResult()) }() wg.Wait() diff --git a/internal/api/grpc/system/limits_integration_block_test.go b/internal/api/grpc/system/integration_test/limits_block_test.go similarity index 79% rename from internal/api/grpc/system/limits_integration_block_test.go rename to internal/api/grpc/system/integration_test/limits_block_test.go index 68426dd05e..b8d17a1167 100644 --- a/internal/api/grpc/system/limits_integration_block_test.go +++ b/internal/api/grpc/system/integration_test/limits_block_test.go @@ -20,41 +20,35 @@ import ( "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/durationpb" - "github.com/zitadel/zitadel/internal/api/authz" - "github.com/zitadel/zitadel/internal/query" + "github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/pkg/grpc/admin" "github.com/zitadel/zitadel/pkg/grpc/system" ) func TestServer_Limits_Block(t *testing.T) { - domain, instanceID, _, iamOwnerCtx := Tester.UseIsolatedInstance(t, CTX, SystemCTX) + t.Parallel() + + isoInstance := integration.NewInstance(CTX) + iamOwnerCtx := isoInstance.WithAuthorization(CTX, integration.UserTypeIAMOwner) tests := []*test{ - publicAPIBlockingTest(domain), + publicAPIBlockingTest(isoInstance.Domain), { name: "mutating API", testGrpc: func(tt assert.TestingT, expectBlocked bool) { randomGrpcIdpName := randomString("idp-grpc", 5) - _, err := Tester.Client.Admin.AddGitHubProvider(iamOwnerCtx, &admin.AddGitHubProviderRequest{ + _, err := isoInstance.Client.Admin.AddGitHubProvider(iamOwnerCtx, &admin.AddGitHubProviderRequest{ Name: randomGrpcIdpName, ClientId: "client-id", ClientSecret: "client-secret", }) assertGrpcError(tt, err, expectBlocked) - //nolint:contextcheck - idpExists := idpExistsCondition(tt, instanceID, randomGrpcIdpName) - if expectBlocked { - // We ensure that the idp really is not created - assert.Neverf(tt, idpExists, 5*time.Second, 1*time.Second, "idp should never be created") - } else { - assert.Eventuallyf(tt, idpExists, 5*time.Second, 1*time.Second, "idp should be created") - } }, testHttp: func(tt assert.TestingT) (*http.Request, error, func(assert.TestingT, *http.Response, bool)) { randomHttpIdpName := randomString("idp-http", 5) req, err := http.NewRequestWithContext( CTX, "POST", - fmt.Sprintf("http://%s/admin/v1/idps/github", net.JoinHostPort(domain, "8080")), + fmt.Sprintf("http://%s/admin/v1/idps/github", net.JoinHostPort(isoInstance.Domain, "8080")), strings.NewReader(`{ "name": "`+randomHttpIdpName+`", "clientId": "client-id", @@ -64,7 +58,7 @@ func TestServer_Limits_Block(t *testing.T) { if err != nil { return nil, err, nil } - req.Header.Set("Authorization", Tester.BearerToken(iamOwnerCtx)) + req.Header.Set("Authorization", isoInstance.BearerToken(iamOwnerCtx)) return req, nil, func(ttt assert.TestingT, response *http.Response, expectBlocked bool) { assertLimitResponse(ttt, response, expectBlocked) assertSetLimitingCookie(ttt, response, expectBlocked) @@ -76,7 +70,7 @@ func TestServer_Limits_Block(t *testing.T) { req, err := http.NewRequestWithContext( CTX, "GET", - fmt.Sprintf("http://%s/.well-known/openid-configuration", net.JoinHostPort(domain, "8080")), + fmt.Sprintf("http://%s/.well-known/openid-configuration", net.JoinHostPort(isoInstance.Domain, "8080")), nil, ) return req, err, func(ttt assert.TestingT, response *http.Response, expectBlocked bool) { @@ -90,7 +84,7 @@ func TestServer_Limits_Block(t *testing.T) { req, err := http.NewRequestWithContext( CTX, "GET", - fmt.Sprintf("http://%s/ui/login/login/externalidp/callback", net.JoinHostPort(domain, "8080")), + fmt.Sprintf("http://%s/ui/login/login/externalidp/callback", net.JoinHostPort(isoInstance.Domain, "8080")), nil, ) return req, err, func(ttt assert.TestingT, response *http.Response, expectBlocked bool) { @@ -109,7 +103,7 @@ func TestServer_Limits_Block(t *testing.T) { req, err := http.NewRequestWithContext( CTX, "GET", - fmt.Sprintf("http://%s/ui/console/", net.JoinHostPort(domain, "8080")), + fmt.Sprintf("http://%s/ui/console/", net.JoinHostPort(isoInstance.Domain, "8080")), nil, ) return req, err, func(ttt assert.TestingT, response *http.Response, expectBlocked bool) { @@ -125,7 +119,7 @@ func TestServer_Limits_Block(t *testing.T) { req, err := http.NewRequestWithContext( CTX, "GET", - fmt.Sprintf("http://%s/ui/console/assets/environment.json", net.JoinHostPort(domain, "8080")), + fmt.Sprintf("http://%s/ui/console/assets/environment.json", net.JoinHostPort(isoInstance.Domain, "8080")), nil, ) return req, err, func(ttt assert.TestingT, response *http.Response, expectBlocked bool) { @@ -142,14 +136,14 @@ func TestServer_Limits_Block(t *testing.T) { } }, }} - _, err := Tester.Client.System.SetLimits(SystemCTX, &system.SetLimitsRequest{ - InstanceId: instanceID, + _, err := integration.SystemClient().SetLimits(CTX, &system.SetLimitsRequest{ + InstanceId: isoInstance.ID(), Block: gu.Ptr(true), }) require.NoError(t, err) // The following call ensures that an undefined bool is not deserialized to false - _, err = Tester.Client.System.SetLimits(SystemCTX, &system.SetLimitsRequest{ - InstanceId: instanceID, + _, err = integration.SystemClient().SetLimits(CTX, &system.SetLimitsRequest{ + InstanceId: isoInstance.ID(), AuditLogRetention: durationpb.New(time.Hour), }) require.NoError(t, err) @@ -160,8 +154,8 @@ func TestServer_Limits_Block(t *testing.T) { testBlockingAPI(t, tt, true, isFirst) }) } - _, err = Tester.Client.System.SetLimits(SystemCTX, &system.SetLimitsRequest{ - InstanceId: instanceID, + _, err = integration.SystemClient().SetLimits(CTX, &system.SetLimitsRequest{ + InstanceId: isoInstance.ID(), Block: gu.Ptr(false), }) require.NoError(t, err) @@ -183,7 +177,7 @@ type test struct { func testBlockingAPI(t *testing.T, tt *test, expectBlocked bool, isFirst bool) { req, err, assertResponse := tt.testHttp(t) require.NoError(t, err) - testHTTP := func(tt assert.TestingT) { + testHTTP := func(t require.TestingT) { resp, err := (&http.Client{ // Don't follow redirects CheckRedirect: func(req *http.Request, via []*http.Request) error { @@ -200,7 +194,7 @@ func testBlockingAPI(t *testing.T, tt *test, expectBlocked bool, isFirst bool) { // limits are eventually consistent, so we need to wait for the blocking to be set on the first test assert.EventuallyWithT(t, func(c *assert.CollectT) { testHTTP(c) - }, 15*time.Second, time.Second, "wait for blocking to be set") + }, time.Minute, time.Second, "wait for blocking to be set") } else { testHTTP(t) } @@ -249,7 +243,7 @@ func assertSetLimitingCookie(t assert.TestingT, response *http.Response, expectS return } } - assert.FailNow(t, "cookie not found") + assert.Fail(t, "cookie not found") } func assertGrpcError(t assert.TestingT, err error, expectBlocked bool) { @@ -268,20 +262,3 @@ func assertLimitResponse(t assert.TestingT, response *http.Response, expectBlock assert.GreaterOrEqual(t, response.StatusCode, 200) assert.Less(t, response.StatusCode, 300) } - -func idpExistsCondition(t assert.TestingT, instanceID, idpName string) func() bool { - return func() bool { - nameQuery, err := query.NewIDPTemplateNameSearchQuery(query.TextEquals, idpName) - assert.NoError(t, err) - instanceQuery, err := query.NewIDPTemplateResourceOwnerSearchQuery(instanceID) - assert.NoError(t, err) - idps, err := Tester.Queries.IDPTemplates(authz.WithInstanceID(CTX, instanceID), &query.IDPTemplateSearchQueries{ - Queries: []query.SearchQuery{ - instanceQuery, - nameQuery, - }, - }, false) - assert.NoError(t, err) - return len(idps.Templates) > 0 - } -} diff --git a/internal/api/grpc/system/limits_integration_bulk_test.go b/internal/api/grpc/system/integration_test/limits_bulk_test.go similarity index 95% rename from internal/api/grpc/system/limits_integration_bulk_test.go rename to internal/api/grpc/system/integration_test/limits_bulk_test.go index 0cdb37f5c3..b81c5c68ff 100644 --- a/internal/api/grpc/system/limits_integration_bulk_test.go +++ b/internal/api/grpc/system/integration_test/limits_bulk_test.go @@ -18,7 +18,7 @@ func TestServer_Limits_Bulk(t *testing.T) { instances := make([]*instance, len) for i := 0; i < len; i++ { domain := integration.RandString(5) + ".integration.localhost" - resp, err := Tester.Client.System.CreateInstance(SystemCTX, &system.CreateInstanceRequest{ + resp, err := integration.SystemClient().CreateInstance(CTX, &system.CreateInstanceRequest{ InstanceName: "testinstance", CustomDomain: domain, Owner: &system.CreateInstanceRequest_Machine_{ @@ -31,7 +31,7 @@ func TestServer_Limits_Bulk(t *testing.T) { require.NoError(t, err) instances[i] = &instance{domain, resp.GetInstanceId()} } - resp, err := Tester.Client.System.BulkSetLimits(SystemCTX, &system.BulkSetLimitsRequest{ + resp, err := integration.SystemClient().BulkSetLimits(CTX, &system.BulkSetLimitsRequest{ Limits: []*system.SetLimitsRequest{{ InstanceId: instances[0].id, Block: gu.Ptr(true), diff --git a/internal/api/grpc/system/quotas_enabled/quota_integration_test.go b/internal/api/grpc/system/integration_test/quotas_enabled/quota_test.go similarity index 61% rename from internal/api/grpc/system/quotas_enabled/quota_integration_test.go rename to internal/api/grpc/system/integration_test/quotas_enabled/quota_test.go index 225b4a2daa..09c42eeb97 100644 --- a/internal/api/grpc/system/quotas_enabled/quota_integration_test.go +++ b/internal/api/grpc/system/integration_test/quotas_enabled/quota_test.go @@ -14,21 +14,25 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" "github.com/zitadel/zitadel/internal/integration" + "github.com/zitadel/zitadel/internal/integration/sink" "github.com/zitadel/zitadel/internal/repository/quota" "github.com/zitadel/zitadel/pkg/grpc/admin" quota_pb "github.com/zitadel/zitadel/pkg/grpc/quota" "github.com/zitadel/zitadel/pkg/grpc/system" ) -var callURL = "http://localhost:" + integration.PortQuotaServer +var callURL = sink.CallURL(sink.ChannelQuota) func TestServer_QuotaNotification_Limit(t *testing.T) { + instance := integration.NewInstance(CTX) + iamCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + amount := 10 percent := 50 percentAmount := amount * percent / 100 - _, err := Tester.Client.System.SetQuota(SystemCTX, &system.SetQuotaRequest{ - InstanceId: Tester.Instance.InstanceID(), + _, err := integration.SystemClient().SetQuota(CTX, &system.SetQuotaRequest{ + InstanceId: instance.Instance.Id, Unit: quota_pb.Unit_UNIT_REQUESTS_ALL_AUTHENTICATED, From: timestamppb.Now(), ResetInterval: durationpb.New(time.Minute * 5), @@ -49,30 +53,35 @@ func TestServer_QuotaNotification_Limit(t *testing.T) { }) require.NoError(t, err) + sub := sink.Subscribe(CTX, sink.ChannelQuota) + defer sub.Close() + for i := 0; i < percentAmount; i++ { - _, err := Tester.Client.Admin.GetDefaultOrg(IAMOwnerCTX, &admin.GetDefaultOrgRequest{}) + _, err := instance.Client.Admin.GetDefaultOrg(iamCTX, &admin.GetDefaultOrgRequest{}) require.NoErrorf(t, err, "error in %d call of %d", i, percentAmount) } - awaitNotification(t, Tester.QuotaNotificationChan, quota.RequestsAllAuthenticated, percent) + awaitNotification(t, sub, quota.RequestsAllAuthenticated, percent) for i := 0; i < (amount - percentAmount); i++ { - _, err := Tester.Client.Admin.GetDefaultOrg(IAMOwnerCTX, &admin.GetDefaultOrgRequest{}) + _, err := instance.Client.Admin.GetDefaultOrg(iamCTX, &admin.GetDefaultOrgRequest{}) require.NoErrorf(t, err, "error in %d call of %d", i, percentAmount) } - awaitNotification(t, Tester.QuotaNotificationChan, quota.RequestsAllAuthenticated, 100) + awaitNotification(t, sub, quota.RequestsAllAuthenticated, 100) - _, limitErr := Tester.Client.Admin.GetDefaultOrg(IAMOwnerCTX, &admin.GetDefaultOrgRequest{}) + _, limitErr := instance.Client.Admin.GetDefaultOrg(iamCTX, &admin.GetDefaultOrgRequest{}) require.Error(t, limitErr) } func TestServer_QuotaNotification_NoLimit(t *testing.T) { - _, instanceID, _, IAMOwnerCTX := Tester.UseIsolatedInstance(t, CTX, SystemCTX) + instance := integration.NewInstance(CTX) + iamCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + amount := 10 percent := 50 percentAmount := amount * percent / 100 - _, err := Tester.Client.System.SetQuota(SystemCTX, &system.SetQuotaRequest{ - InstanceId: instanceID, + _, err := integration.SystemClient().SetQuota(CTX, &system.SetQuotaRequest{ + InstanceId: instance.Instance.Id, Unit: quota_pb.Unit_UNIT_REQUESTS_ALL_AUTHENTICATED, From: timestamppb.Now(), ResetInterval: durationpb.New(time.Minute * 5), @@ -93,34 +102,39 @@ func TestServer_QuotaNotification_NoLimit(t *testing.T) { }) require.NoError(t, err) + sub := sink.Subscribe(CTX, sink.ChannelQuota) + defer sub.Close() + for i := 0; i < percentAmount; i++ { - _, err := Tester.Client.Admin.GetDefaultOrg(IAMOwnerCTX, &admin.GetDefaultOrgRequest{}) + _, err := instance.Client.Admin.GetDefaultOrg(iamCTX, &admin.GetDefaultOrgRequest{}) require.NoErrorf(t, err, "error in %d call of %d", i, percentAmount) } - awaitNotification(t, Tester.QuotaNotificationChan, quota.RequestsAllAuthenticated, percent) + awaitNotification(t, sub, quota.RequestsAllAuthenticated, percent) for i := 0; i < (amount - percentAmount); i++ { - _, err := Tester.Client.Admin.GetDefaultOrg(IAMOwnerCTX, &admin.GetDefaultOrgRequest{}) + _, err := instance.Client.Admin.GetDefaultOrg(iamCTX, &admin.GetDefaultOrgRequest{}) require.NoErrorf(t, err, "error in %d call of %d", i, percentAmount) } - awaitNotification(t, Tester.QuotaNotificationChan, quota.RequestsAllAuthenticated, 100) + awaitNotification(t, sub, quota.RequestsAllAuthenticated, 100) for i := 0; i < amount; i++ { - _, err := Tester.Client.Admin.GetDefaultOrg(IAMOwnerCTX, &admin.GetDefaultOrgRequest{}) + _, err := instance.Client.Admin.GetDefaultOrg(iamCTX, &admin.GetDefaultOrgRequest{}) require.NoErrorf(t, err, "error in %d call of %d", i, percentAmount) } - awaitNotification(t, Tester.QuotaNotificationChan, quota.RequestsAllAuthenticated, 200) + awaitNotification(t, sub, quota.RequestsAllAuthenticated, 200) - _, limitErr := Tester.Client.Admin.GetDefaultOrg(IAMOwnerCTX, &admin.GetDefaultOrgRequest{}) + _, limitErr := instance.Client.Admin.GetDefaultOrg(iamCTX, &admin.GetDefaultOrgRequest{}) require.NoError(t, limitErr) } -func awaitNotification(t *testing.T, bodies chan []byte, unit quota.Unit, percent int) { +func awaitNotification(t *testing.T, sub *sink.Subscription, unit quota.Unit, percent int) { for { select { - case body := <-bodies: + case req, ok := <-sub.Recv(): + require.True(t, ok, "channel closed") + plain := new(bytes.Buffer) - if err := json.Indent(plain, body, "", " "); err != nil { + if err := json.Indent(plain, req.Body, "", " "); err != nil { t.Fatal(err) } t.Log("received notificationDueEvent", plain.String()) @@ -132,7 +146,7 @@ func awaitNotification(t *testing.T, bodies chan []byte, unit quota.Unit, percen Threshold uint16 `json:"threshold"` Usage uint64 `json:"usage"` }{} - if err := json.Unmarshal(body, &event); err != nil { + if err := json.Unmarshal(req.Body, &event); err != nil { t.Error(err) } if event.ID == "" { @@ -148,10 +162,10 @@ func awaitNotification(t *testing.T, bodies chan []byte, unit quota.Unit, percen } func TestServer_AddAndRemoveQuota(t *testing.T) { - _, instanceID, _, _ := Tester.UseIsolatedInstance(t, CTX, SystemCTX) + instance := integration.NewInstance(CTX) - got, err := Tester.Client.System.SetQuota(SystemCTX, &system.SetQuotaRequest{ - InstanceId: instanceID, + got, err := integration.SystemClient().SetQuota(CTX, &system.SetQuotaRequest{ + InstanceId: instance.Instance.Id, Unit: quota_pb.Unit_UNIT_REQUESTS_ALL_AUTHENTICATED, From: timestamppb.Now(), ResetInterval: durationpb.New(time.Minute), @@ -166,10 +180,10 @@ func TestServer_AddAndRemoveQuota(t *testing.T) { }, }) require.NoError(t, err) - require.Equal(t, got.Details.ResourceOwner, instanceID) + require.Equal(t, got.Details.ResourceOwner, instance.Instance.Id) - gotAlreadyExisting, errAlreadyExisting := Tester.Client.System.SetQuota(SystemCTX, &system.SetQuotaRequest{ - InstanceId: instanceID, + gotAlreadyExisting, errAlreadyExisting := integration.SystemClient().SetQuota(CTX, &system.SetQuotaRequest{ + InstanceId: instance.Instance.Id, Unit: quota_pb.Unit_UNIT_REQUESTS_ALL_AUTHENTICATED, From: timestamppb.Now(), ResetInterval: durationpb.New(time.Minute), @@ -184,17 +198,17 @@ func TestServer_AddAndRemoveQuota(t *testing.T) { }, }) require.Nil(t, errAlreadyExisting) - require.Equal(t, gotAlreadyExisting.Details.ResourceOwner, instanceID) + require.Equal(t, gotAlreadyExisting.Details.ResourceOwner, instance.Instance.Id) - gotRemove, errRemove := Tester.Client.System.RemoveQuota(SystemCTX, &system.RemoveQuotaRequest{ - InstanceId: instanceID, + gotRemove, errRemove := integration.SystemClient().RemoveQuota(CTX, &system.RemoveQuotaRequest{ + InstanceId: instance.Instance.Id, Unit: quota_pb.Unit_UNIT_REQUESTS_ALL_AUTHENTICATED, }) require.NoError(t, errRemove) - require.Equal(t, gotRemove.Details.ResourceOwner, instanceID) + require.Equal(t, gotRemove.Details.ResourceOwner, instance.Instance.Id) - gotRemoveAlready, errRemoveAlready := Tester.Client.System.RemoveQuota(SystemCTX, &system.RemoveQuotaRequest{ - InstanceId: instanceID, + gotRemoveAlready, errRemoveAlready := integration.SystemClient().RemoveQuota(CTX, &system.RemoveQuotaRequest{ + InstanceId: instance.Instance.Id, Unit: quota_pb.Unit_UNIT_REQUESTS_ALL_AUTHENTICATED, }) require.Error(t, errRemoveAlready) diff --git a/internal/api/grpc/system/integration_test/quotas_enabled/server_test.go b/internal/api/grpc/system/integration_test/quotas_enabled/server_test.go new file mode 100644 index 0000000000..0780575dd6 --- /dev/null +++ b/internal/api/grpc/system/integration_test/quotas_enabled/server_test.go @@ -0,0 +1,23 @@ +//go:build integration + +package quotas_enabled_test + +import ( + "context" + "os" + "testing" + "time" +) + +var ( + CTX context.Context +) + +func TestMain(m *testing.M) { + os.Exit(func() int { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute) + defer cancel() + CTX = ctx + return m.Run() + }()) +} diff --git a/internal/api/grpc/system/integration_test/server_test.go b/internal/api/grpc/system/integration_test/server_test.go new file mode 100644 index 0000000000..f21ec5a9de --- /dev/null +++ b/internal/api/grpc/system/integration_test/server_test.go @@ -0,0 +1,24 @@ +//go:build integration + +package system_test + +import ( + "context" + "os" + "testing" + "time" +) + +var ( + CTX context.Context +) + +func TestMain(m *testing.M) { + os.Exit(func() int { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute) + defer cancel() + + CTX = ctx + return m.Run() + }()) +} diff --git a/internal/api/grpc/system/quotas_enabled/server_integration_test.go b/internal/api/grpc/system/quotas_enabled/server_integration_test.go deleted file mode 100644 index c552049e44..0000000000 --- a/internal/api/grpc/system/quotas_enabled/server_integration_test.go +++ /dev/null @@ -1,37 +0,0 @@ -//go:build integration - -package quotas_enabled_test - -import ( - "context" - "os" - "testing" - "time" - - "github.com/zitadel/zitadel/internal/integration" -) - -var ( - CTX context.Context - SystemCTX context.Context - IAMOwnerCTX context.Context - Tester *integration.Tester -) - -func TestMain(m *testing.M) { - os.Exit(func() int { - ctx, _, cancel := integration.Contexts(5 * time.Minute) - defer cancel() - CTX = ctx - - Tester = integration.NewTester(ctx, ` -Quotas: - Access: - Enabled: true -`) - defer Tester.Done() - SystemCTX = Tester.WithAuthorization(ctx, integration.SystemUser) - IAMOwnerCTX = Tester.WithAuthorization(ctx, integration.IAMOwner) - return m.Run() - }()) -} diff --git a/internal/api/grpc/system/server_integration_test.go b/internal/api/grpc/system/server_integration_test.go deleted file mode 100644 index f36972993f..0000000000 --- a/internal/api/grpc/system/server_integration_test.go +++ /dev/null @@ -1,32 +0,0 @@ -//go:build integration - -package system_test - -import ( - "context" - "os" - "testing" - "time" - - "github.com/zitadel/zitadel/internal/integration" -) - -var ( - CTX context.Context - SystemCTX context.Context - Tester *integration.Tester -) - -func TestMain(m *testing.M) { - os.Exit(func() int { - ctx, _, cancel := integration.Contexts(5 * time.Minute) - defer cancel() - CTX = ctx - - Tester = integration.NewTester(ctx) - defer Tester.Done() - - SystemCTX = Tester.WithAuthorization(ctx, integration.SystemUser) - return m.Run() - }()) -} diff --git a/internal/api/grpc/user/v2/email_integration_test.go b/internal/api/grpc/user/v2/integration_test/email_test.go similarity index 90% rename from internal/api/grpc/user/v2/email_integration_test.go rename to internal/api/grpc/user/v2/integration_test/email_test.go index 2264934f25..c15e2c0bf3 100644 --- a/internal/api/grpc/user/v2/email_integration_test.go +++ b/internal/api/grpc/user/v2/integration_test/email_test.go @@ -12,14 +12,13 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/protobuf/types/known/timestamppb" + "github.com/zitadel/zitadel/internal/integration" object "github.com/zitadel/zitadel/pkg/grpc/object/v2" user "github.com/zitadel/zitadel/pkg/grpc/user/v2" - - "github.com/zitadel/zitadel/internal/integration" ) func TestServer_SetEmail(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() tests := []struct { name string @@ -45,7 +44,7 @@ func TestServer_SetEmail(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -64,7 +63,7 @@ func TestServer_SetEmail(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -94,7 +93,7 @@ func TestServer_SetEmail(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, VerificationCode: gu.Ptr("xxx"), }, @@ -112,7 +111,7 @@ func TestServer_SetEmail(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -145,8 +144,8 @@ func TestServer_SetEmail(t *testing.T) { } func TestServer_ResendEmailCode(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - verifiedUserID := Tester.CreateHumanUserVerified(CTX, Tester.Organisation.ID, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() + verifiedUserID := Instance.CreateHumanUserVerified(CTX, Instance.DefaultOrg.Id, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId() tests := []struct { name string @@ -177,7 +176,7 @@ func TestServer_ResendEmailCode(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -195,7 +194,7 @@ func TestServer_ResendEmailCode(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -223,7 +222,7 @@ func TestServer_ResendEmailCode(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, VerificationCode: gu.Ptr("xxx"), }, @@ -246,7 +245,7 @@ func TestServer_ResendEmailCode(t *testing.T) { } func TestServer_VerifyEmail(t *testing.T) { - userResp := Tester.CreateHumanUser(CTX) + userResp := Instance.CreateHumanUser(CTX) tests := []struct { name string req *user.VerifyEmailRequest @@ -279,7 +278,7 @@ func TestServer_VerifyEmail(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, diff --git a/internal/api/grpc/user/v2/idp_link_integration_test.go b/internal/api/grpc/user/v2/integration_test/idp_link_test.go similarity index 67% rename from internal/api/grpc/user/v2/idp_link_integration_test.go rename to internal/api/grpc/user/v2/integration_test/idp_link_test.go index 99658b3024..2daa42b91a 100644 --- a/internal/api/grpc/user/v2/idp_link_integration_test.go +++ b/internal/api/grpc/user/v2/integration_test/idp_link_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "google.golang.org/grpc/metadata" "google.golang.org/protobuf/types/known/timestamppb" "github.com/zitadel/zitadel/internal/integration" @@ -18,7 +19,7 @@ import ( ) func TestServer_AddIDPLink(t *testing.T) { - idpID := Tester.AddGenericOAuthProvider(t, CTX) + idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id) type args struct { ctx context.Context req *user.AddIDPLinkRequest @@ -36,7 +37,7 @@ func TestServer_AddIDPLink(t *testing.T) { &user.AddIDPLinkRequest{ UserId: "userID", IdpLink: &user.IDPLink{ - IdpId: idpID, + IdpId: idpResp.Id, UserId: "userID", UserName: "username", }, @@ -50,7 +51,7 @@ func TestServer_AddIDPLink(t *testing.T) { args: args{ CTX, &user.AddIDPLinkRequest{ - UserId: Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, + UserId: Instance.Users.Get(integration.UserTypeOrgOwner).ID, IdpLink: &user.IDPLink{ IdpId: "idpID", UserId: "userID", @@ -66,9 +67,9 @@ func TestServer_AddIDPLink(t *testing.T) { args: args{ CTX, &user.AddIDPLinkRequest{ - UserId: Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, + UserId: Instance.Users.Get(integration.UserTypeOrgOwner).ID, IdpLink: &user.IDPLink{ - IdpId: idpID, + IdpId: idpResp.Id, UserId: "userID", UserName: "username", }, @@ -77,7 +78,7 @@ func TestServer_AddIDPLink(t *testing.T) { want: &user.AddIDPLinkResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, wantErr: false, @@ -98,19 +99,24 @@ func TestServer_AddIDPLink(t *testing.T) { } func TestServer_ListIDPLinks(t *testing.T) { - orgResp := Tester.CreateOrganization(IamCTX, fmt.Sprintf("ListIDPLinks%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) + orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListIDPLinks%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) - instanceIdpID := Tester.AddGenericOAuthProvider(t, IamCTX) - userInstanceResp := Tester.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listidplinks.com", time.Now().UnixNano())) - Tester.CreateUserIDPlink(IamCTX, userInstanceResp.GetUserId(), "external_instance", instanceIdpID, "externalUsername_instance") + instanceIdpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id) + userInstanceResp := Instance.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listidplinks.com", time.Now().UnixNano())) + _, err := Instance.CreateUserIDPlink(IamCTX, userInstanceResp.GetUserId(), "external_instance", instanceIdpResp.Id, "externalUsername_instance") + require.NoError(t, err) - orgIdpID := Tester.AddOrgGenericOAuthProvider(t, IamCTX, orgResp.OrganizationId) - userOrgResp := Tester.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listidplinks.com", time.Now().UnixNano())) - Tester.CreateUserIDPlink(IamCTX, userOrgResp.GetUserId(), "external_org", orgIdpID, "externalUsername_org") + ctxOrg := metadata.AppendToOutgoingContext(IamCTX, "x-zitadel-orgid", orgResp.GetOrganizationId()) + orgIdpResp := Instance.AddOrgGenericOAuthProvider(ctxOrg, orgResp.OrganizationId) + userOrgResp := Instance.CreateHumanUserVerified(ctxOrg, orgResp.OrganizationId, fmt.Sprintf("%d@listidplinks.com", time.Now().UnixNano())) + _, err = Instance.CreateUserIDPlink(ctxOrg, userOrgResp.GetUserId(), "external_org", orgIdpResp.Id, "externalUsername_org") + require.NoError(t, err) - userMultipleResp := Tester.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listidplinks.com", time.Now().UnixNano())) - Tester.CreateUserIDPlink(IamCTX, userMultipleResp.GetUserId(), "external_multi", instanceIdpID, "externalUsername_multi") - Tester.CreateUserIDPlink(IamCTX, userMultipleResp.GetUserId(), "external_multi", orgIdpID, "externalUsername_multi") + userMultipleResp := Instance.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listidplinks.com", time.Now().UnixNano())) + _, err = Instance.CreateUserIDPlink(IamCTX, userMultipleResp.GetUserId(), "external_multi", instanceIdpResp.Id, "externalUsername_multi") + require.NoError(t, err) + _, err = Instance.CreateUserIDPlink(ctxOrg, userMultipleResp.GetUserId(), "external_multi", orgIdpResp.Id, "externalUsername_multi") + require.NoError(t, err) type args struct { ctx context.Context @@ -167,7 +173,7 @@ func TestServer_ListIDPLinks(t *testing.T) { }, Result: []*user.IDPLink{ { - IdpId: orgIdpID, + IdpId: orgIdpResp.Id, UserId: "external_org", UserName: "externalUsername_org", }, @@ -189,7 +195,7 @@ func TestServer_ListIDPLinks(t *testing.T) { }, Result: []*user.IDPLink{ { - IdpId: instanceIdpID, + IdpId: instanceIdpResp.Id, UserId: "external_instance", UserName: "externalUsername_instance", }, @@ -211,12 +217,12 @@ func TestServer_ListIDPLinks(t *testing.T) { }, Result: []*user.IDPLink{ { - IdpId: instanceIdpID, + IdpId: instanceIdpResp.Id, UserId: "external_multi", UserName: "externalUsername_multi", }, { - IdpId: orgIdpID, + IdpId: orgIdpResp.Id, UserId: "external_multi", UserName: "externalUsername_multi", }, @@ -252,17 +258,20 @@ func TestServer_ListIDPLinks(t *testing.T) { } func TestServer_RemoveIDPLink(t *testing.T) { - orgResp := Tester.CreateOrganization(IamCTX, fmt.Sprintf("ListIDPLinks%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) + orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListIDPLinks%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) - instanceIdpID := Tester.AddGenericOAuthProvider(t, IamCTX) - userInstanceResp := Tester.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listidplinks.com", time.Now().UnixNano())) - Tester.CreateUserIDPlink(IamCTX, userInstanceResp.GetUserId(), "external_instance", instanceIdpID, "externalUsername_instance") + instanceIdpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id) + userInstanceResp := Instance.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listidplinks.com", time.Now().UnixNano())) + _, err := Instance.CreateUserIDPlink(IamCTX, userInstanceResp.GetUserId(), "external_instance", instanceIdpResp.Id, "externalUsername_instance") + require.NoError(t, err) - orgIdpID := Tester.AddOrgGenericOAuthProvider(t, IamCTX, orgResp.OrganizationId) - userOrgResp := Tester.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listidplinks.com", time.Now().UnixNano())) - Tester.CreateUserIDPlink(IamCTX, userOrgResp.GetUserId(), "external_org", orgIdpID, "externalUsername_org") + ctxOrg := metadata.AppendToOutgoingContext(IamCTX, "x-zitadel-orgid", orgResp.GetOrganizationId()) + orgIdpResp := Instance.AddOrgGenericOAuthProvider(ctxOrg, orgResp.OrganizationId) + userOrgResp := Instance.CreateHumanUserVerified(ctxOrg, orgResp.OrganizationId, fmt.Sprintf("%d@listidplinks.com", time.Now().UnixNano())) + _, err = Instance.CreateUserIDPlink(ctxOrg, userOrgResp.GetUserId(), "external_org", orgIdpResp.Id, "externalUsername_org") + require.NoError(t, err) - userNoLinkResp := Tester.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listidplinks.com", time.Now().UnixNano())) + userNoLinkResp := Instance.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listidplinks.com", time.Now().UnixNano())) type args struct { ctx context.Context @@ -280,7 +289,7 @@ func TestServer_RemoveIDPLink(t *testing.T) { UserCTX, &user.RemoveIDPLinkRequest{ UserId: userOrgResp.GetUserId(), - IdpId: orgIdpID, + IdpId: orgIdpResp.Id, LinkedUserId: "external_org", }, }, @@ -292,7 +301,7 @@ func TestServer_RemoveIDPLink(t *testing.T) { CTX, &user.RemoveIDPLinkRequest{ UserId: userOrgResp.GetUserId(), - IdpId: orgIdpID, + IdpId: orgIdpResp.Id, LinkedUserId: "external_org", }, }, @@ -304,7 +313,7 @@ func TestServer_RemoveIDPLink(t *testing.T) { IamCTX, &user.RemoveIDPLinkRequest{ UserId: userOrgResp.GetUserId(), - IdpId: orgIdpID, + IdpId: orgIdpResp.Id, LinkedUserId: "external_org", }, }, @@ -321,7 +330,7 @@ func TestServer_RemoveIDPLink(t *testing.T) { IamCTX, &user.RemoveIDPLinkRequest{ UserId: userInstanceResp.GetUserId(), - IdpId: instanceIdpID, + IdpId: instanceIdpResp.Id, LinkedUserId: "external_instance", }, }, diff --git a/internal/api/grpc/user/v2/otp_integration_test.go b/internal/api/grpc/user/v2/integration_test/otp_test.go similarity index 59% rename from internal/api/grpc/user/v2/otp_integration_test.go rename to internal/api/grpc/user/v2/integration_test/otp_test.go index 52b30fbd38..ae7c040427 100644 --- a/internal/api/grpc/user/v2/otp_integration_test.go +++ b/internal/api/grpc/user/v2/integration_test/otp_test.go @@ -9,32 +9,31 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/protobuf/types/known/timestamppb" + "github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/pkg/grpc/object/v2" "github.com/zitadel/zitadel/pkg/grpc/user/v2" - - "github.com/zitadel/zitadel/internal/integration" ) func TestServer_AddOTPSMS(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) + userID := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) - otherUser := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, otherUser) - _, sessionTokenOtherUser, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, otherUser) + otherUser := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, otherUser) + _, sessionTokenOtherUser, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, otherUser) - userVerified := Tester.CreateHumanUser(CTX) - _, err := Tester.Client.UserV2.VerifyPhone(CTX, &user.VerifyPhoneRequest{ + userVerified := Instance.CreateHumanUser(CTX) + _, err := Instance.Client.UserV2.VerifyPhone(CTX, &user.VerifyPhoneRequest{ UserId: userVerified.GetUserId(), VerificationCode: userVerified.GetPhoneCode(), }) require.NoError(t, err) - Tester.RegisterUserPasskey(CTX, userVerified.GetUserId()) - _, sessionTokenVerified, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) + Instance.RegisterUserPasskey(CTX, userVerified.GetUserId()) + _, sessionTokenVerified, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) - userVerified2 := Tester.CreateHumanUser(CTX) - _, err = Tester.Client.UserV2.VerifyPhone(CTX, &user.VerifyPhoneRequest{ + userVerified2 := Instance.CreateHumanUser(CTX) + _, err = Instance.Client.UserV2.VerifyPhone(CTX, &user.VerifyPhoneRequest{ UserId: userVerified2.GetUserId(), VerificationCode: userVerified2.GetPhoneCode(), }) @@ -61,7 +60,7 @@ func TestServer_AddOTPSMS(t *testing.T) { { name: "user mismatch", args: args{ - ctx: Tester.WithAuthorizationToken(context.Background(), sessionTokenOtherUser), + ctx: integration.WithAuthorizationToken(context.Background(), sessionTokenOtherUser), req: &user.AddOTPSMSRequest{ UserId: userID, }, @@ -71,7 +70,7 @@ func TestServer_AddOTPSMS(t *testing.T) { { name: "phone not verified", args: args{ - ctx: Tester.WithAuthorizationToken(context.Background(), sessionToken), + ctx: integration.WithAuthorizationToken(context.Background(), sessionToken), req: &user.AddOTPSMSRequest{ UserId: userID, }, @@ -81,14 +80,14 @@ func TestServer_AddOTPSMS(t *testing.T) { { name: "add success", args: args{ - ctx: Tester.WithAuthorizationToken(context.Background(), sessionTokenVerified), + ctx: integration.WithAuthorizationToken(context.Background(), sessionTokenVerified), req: &user.AddOTPSMSRequest{ UserId: userVerified.GetUserId(), }, }, want: &user.AddOTPSMSResponse{ Details: &object.Details{ - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -102,7 +101,7 @@ func TestServer_AddOTPSMS(t *testing.T) { }, want: &user.AddOTPSMSResponse{ Details: &object.Details{ - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -122,20 +121,20 @@ func TestServer_AddOTPSMS(t *testing.T) { } func TestServer_RemoveOTPSMS(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) + userID := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) - userVerified := Tester.CreateHumanUser(CTX) - Tester.RegisterUserPasskey(CTX, userVerified.GetUserId()) - _, sessionTokenVerified, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) - userVerifiedCtx := Tester.WithAuthorizationToken(context.Background(), sessionTokenVerified) - _, err := Tester.Client.UserV2.VerifyPhone(userVerifiedCtx, &user.VerifyPhoneRequest{ + userVerified := Instance.CreateHumanUser(CTX) + Instance.RegisterUserPasskey(CTX, userVerified.GetUserId()) + _, sessionTokenVerified, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) + userVerifiedCtx := integration.WithAuthorizationToken(context.Background(), sessionTokenVerified) + _, err := Instance.Client.UserV2.VerifyPhone(userVerifiedCtx, &user.VerifyPhoneRequest{ UserId: userVerified.GetUserId(), VerificationCode: userVerified.GetPhoneCode(), }) require.NoError(t, err) - _, err = Tester.Client.UserV2.AddOTPSMS(userVerifiedCtx, &user.AddOTPSMSRequest{UserId: userVerified.GetUserId()}) + _, err = Instance.Client.UserV2.AddOTPSMS(userVerifiedCtx, &user.AddOTPSMSRequest{UserId: userVerified.GetUserId()}) require.NoError(t, err) type args struct { @@ -151,7 +150,7 @@ func TestServer_RemoveOTPSMS(t *testing.T) { { name: "not added", args: args{ - ctx: Tester.WithAuthorizationToken(context.Background(), sessionToken), + ctx: integration.WithAuthorizationToken(context.Background(), sessionToken), req: &user.RemoveOTPSMSRequest{ UserId: userID, }, @@ -168,7 +167,7 @@ func TestServer_RemoveOTPSMS(t *testing.T) { }, want: &user.RemoveOTPSMSResponse{ Details: &object.Details{ - ResourceOwner: Tester.Organisation.ResourceOwner, + ResourceOwner: Instance.DefaultOrg.Details.ResourceOwner, }, }, }, @@ -188,25 +187,25 @@ func TestServer_RemoveOTPSMS(t *testing.T) { } func TestServer_AddOTPEmail(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) + userID := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) - otherUser := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, otherUser) - _, sessionTokenOtherUser, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, otherUser) + otherUser := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, otherUser) + _, sessionTokenOtherUser, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, otherUser) - userVerified := Tester.CreateHumanUser(CTX) - _, err := Tester.Client.UserV2.VerifyEmail(CTX, &user.VerifyEmailRequest{ + userVerified := Instance.CreateHumanUser(CTX) + _, err := Instance.Client.UserV2.VerifyEmail(CTX, &user.VerifyEmailRequest{ UserId: userVerified.GetUserId(), VerificationCode: userVerified.GetEmailCode(), }) require.NoError(t, err) - Tester.RegisterUserPasskey(CTX, userVerified.GetUserId()) - _, sessionTokenVerified, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) + Instance.RegisterUserPasskey(CTX, userVerified.GetUserId()) + _, sessionTokenVerified, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) - userVerified2 := Tester.CreateHumanUser(CTX) - _, err = Tester.Client.UserV2.VerifyEmail(CTX, &user.VerifyEmailRequest{ + userVerified2 := Instance.CreateHumanUser(CTX) + _, err = Instance.Client.UserV2.VerifyEmail(CTX, &user.VerifyEmailRequest{ UserId: userVerified2.GetUserId(), VerificationCode: userVerified2.GetEmailCode(), }) @@ -233,7 +232,7 @@ func TestServer_AddOTPEmail(t *testing.T) { { name: "user mismatch", args: args{ - ctx: Tester.WithAuthorizationToken(context.Background(), sessionTokenOtherUser), + ctx: integration.WithAuthorizationToken(context.Background(), sessionTokenOtherUser), req: &user.AddOTPEmailRequest{ UserId: userID, }, @@ -243,7 +242,7 @@ func TestServer_AddOTPEmail(t *testing.T) { { name: "email not verified", args: args{ - ctx: Tester.WithAuthorizationToken(context.Background(), sessionToken), + ctx: integration.WithAuthorizationToken(context.Background(), sessionToken), req: &user.AddOTPEmailRequest{ UserId: userID, }, @@ -253,7 +252,7 @@ func TestServer_AddOTPEmail(t *testing.T) { { name: "add success", args: args{ - ctx: Tester.WithAuthorizationToken(context.Background(), sessionTokenVerified), + ctx: integration.WithAuthorizationToken(context.Background(), sessionTokenVerified), req: &user.AddOTPEmailRequest{ UserId: userVerified.GetUserId(), }, @@ -261,7 +260,7 @@ func TestServer_AddOTPEmail(t *testing.T) { want: &user.AddOTPEmailResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -276,7 +275,7 @@ func TestServer_AddOTPEmail(t *testing.T) { want: &user.AddOTPEmailResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -296,20 +295,20 @@ func TestServer_AddOTPEmail(t *testing.T) { } func TestServer_RemoveOTPEmail(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) + userID := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) - userVerified := Tester.CreateHumanUser(CTX) - Tester.RegisterUserPasskey(CTX, userVerified.GetUserId()) - _, sessionTokenVerified, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) - userVerifiedCtx := Tester.WithAuthorizationToken(context.Background(), sessionTokenVerified) - _, err := Tester.Client.UserV2.VerifyEmail(userVerifiedCtx, &user.VerifyEmailRequest{ + userVerified := Instance.CreateHumanUser(CTX) + Instance.RegisterUserPasskey(CTX, userVerified.GetUserId()) + _, sessionTokenVerified, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) + userVerifiedCtx := integration.WithAuthorizationToken(context.Background(), sessionTokenVerified) + _, err := Instance.Client.UserV2.VerifyEmail(userVerifiedCtx, &user.VerifyEmailRequest{ UserId: userVerified.GetUserId(), VerificationCode: userVerified.GetEmailCode(), }) require.NoError(t, err) - _, err = Tester.Client.UserV2.AddOTPEmail(userVerifiedCtx, &user.AddOTPEmailRequest{UserId: userVerified.GetUserId()}) + _, err = Instance.Client.UserV2.AddOTPEmail(userVerifiedCtx, &user.AddOTPEmailRequest{UserId: userVerified.GetUserId()}) require.NoError(t, err) type args struct { @@ -325,7 +324,7 @@ func TestServer_RemoveOTPEmail(t *testing.T) { { name: "not added", args: args{ - ctx: Tester.WithAuthorizationToken(context.Background(), sessionToken), + ctx: integration.WithAuthorizationToken(context.Background(), sessionToken), req: &user.RemoveOTPEmailRequest{ UserId: userID, }, @@ -343,7 +342,7 @@ func TestServer_RemoveOTPEmail(t *testing.T) { want: &user.RemoveOTPEmailResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ResourceOwner, + ResourceOwner: Instance.DefaultOrg.Details.ResourceOwner, }, }, }, diff --git a/internal/api/grpc/user/v2/passkey_integration_test.go b/internal/api/grpc/user/v2/integration_test/passkey_test.go similarity index 92% rename from internal/api/grpc/user/v2/passkey_integration_test.go rename to internal/api/grpc/user/v2/integration_test/passkey_test.go index 12d3a6622b..6041e5e409 100644 --- a/internal/api/grpc/user/v2/passkey_integration_test.go +++ b/internal/api/grpc/user/v2/integration_test/passkey_test.go @@ -13,14 +13,13 @@ import ( "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" + "github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/pkg/grpc/object/v2" "github.com/zitadel/zitadel/pkg/grpc/user/v2" - - "github.com/zitadel/zitadel/internal/integration" ) func TestServer_RegisterPasskey(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() reg, err := Client.CreatePasskeyRegistrationLink(CTX, &user.CreatePasskeyRegistrationLinkRequest{ UserId: userID, Medium: &user.CreatePasskeyRegistrationLinkRequest_ReturnCode{}, @@ -28,8 +27,8 @@ func TestServer_RegisterPasskey(t *testing.T) { require.NoError(t, err) // We also need a user session - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) type args struct { ctx context.Context @@ -62,7 +61,7 @@ func TestServer_RegisterPasskey(t *testing.T) { want: &user.RegisterPasskeyResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -106,7 +105,7 @@ func TestServer_RegisterPasskey(t *testing.T) { { name: "user setting its own passkey", args: args{ - ctx: Tester.WithAuthorizationToken(CTX, sessionToken), + ctx: integration.WithAuthorizationToken(CTX, sessionToken), req: &user.RegisterPasskeyRequest{ UserId: userID, }, @@ -114,7 +113,7 @@ func TestServer_RegisterPasskey(t *testing.T) { want: &user.RegisterPasskeyResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -132,7 +131,7 @@ func TestServer_RegisterPasskey(t *testing.T) { if tt.want != nil { assert.NotEmpty(t, got.GetPasskeyId()) assert.NotEmpty(t, got.GetPublicKeyCredentialCreationOptions()) - _, err = Tester.WebAuthN.CreateAttestationResponse(got.GetPublicKeyCredentialCreationOptions()) + _, err = Instance.WebAuthN.CreateAttestationResponse(got.GetPublicKeyCredentialCreationOptions()) require.NoError(t, err) } }) @@ -142,7 +141,7 @@ func TestServer_RegisterPasskey(t *testing.T) { func TestServer_VerifyPasskeyRegistration(t *testing.T) { userID, pkr := userWithPasskeyRegistered(t) - attestationResponse, err := Tester.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) + attestationResponse, err := Instance.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) require.NoError(t, err) type args struct { @@ -181,7 +180,7 @@ func TestServer_VerifyPasskeyRegistration(t *testing.T) { want: &user.VerifyPasskeyRegistrationResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -216,7 +215,7 @@ func TestServer_VerifyPasskeyRegistration(t *testing.T) { } func TestServer_CreatePasskeyRegistrationLink(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() type args struct { ctx context.Context @@ -248,7 +247,7 @@ func TestServer_CreatePasskeyRegistrationLink(t *testing.T) { want: &user.CreatePasskeyRegistrationLinkResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -268,7 +267,7 @@ func TestServer_CreatePasskeyRegistrationLink(t *testing.T) { want: &user.CreatePasskeyRegistrationLinkResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -284,7 +283,7 @@ func TestServer_CreatePasskeyRegistrationLink(t *testing.T) { want: &user.CreatePasskeyRegistrationLinkResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, wantCode: true, @@ -309,7 +308,7 @@ func TestServer_CreatePasskeyRegistrationLink(t *testing.T) { } func userWithPasskeyRegistered(t *testing.T) (string, *user.RegisterPasskeyResponse) { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() return userID, passkeyRegister(t, userID) } @@ -335,7 +334,7 @@ func passkeyRegister(t *testing.T, userID string) *user.RegisterPasskeyResponse } func passkeyVerify(t *testing.T, userID string, pkr *user.RegisterPasskeyResponse) string { - attestationResponse, err := Tester.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) + attestationResponse, err := Instance.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) require.NoError(t, err) _, err = Client.VerifyPasskeyRegistration(CTX, &user.VerifyPasskeyRegistrationRequest{ @@ -349,7 +348,7 @@ func passkeyVerify(t *testing.T, userID string, pkr *user.RegisterPasskeyRespons } func TestServer_RemovePasskey(t *testing.T) { - userIDWithout := Tester.CreateHumanUser(CTX).GetUserId() + userIDWithout := Instance.CreateHumanUser(CTX).GetUserId() userIDRegistered, pkrRegistered := userWithPasskeyRegistered(t) userIDVerified, passkeyIDVerified := userWithPasskeyVerified(t) userIDVerifiedPermission, passkeyIDVerifiedPermission := userWithPasskeyVerified(t) @@ -396,7 +395,7 @@ func TestServer_RemovePasskey(t *testing.T) { want: &user.RemovePasskeyResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -423,7 +422,7 @@ func TestServer_RemovePasskey(t *testing.T) { want: &user.RemovePasskeyResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -454,7 +453,7 @@ func TestServer_RemovePasskey(t *testing.T) { } func TestServer_ListPasskeys(t *testing.T) { - userIDWithout := Tester.CreateHumanUser(CTX).GetUserId() + userIDWithout := Instance.CreateHumanUser(CTX).GetUserId() userIDRegistered, _ := userWithPasskeyRegistered(t) userIDVerified, passkeyIDVerified := userWithPasskeyVerified(t) diff --git a/internal/api/grpc/user/v2/password_integration_test.go b/internal/api/grpc/user/v2/integration_test/password_test.go similarity index 91% rename from internal/api/grpc/user/v2/password_integration_test.go rename to internal/api/grpc/user/v2/integration_test/password_test.go index f97d0467d7..a316b40df5 100644 --- a/internal/api/grpc/user/v2/password_integration_test.go +++ b/internal/api/grpc/user/v2/integration_test/password_test.go @@ -11,14 +11,13 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/protobuf/types/known/timestamppb" + "github.com/zitadel/zitadel/internal/integration" object "github.com/zitadel/zitadel/pkg/grpc/object/v2" user "github.com/zitadel/zitadel/pkg/grpc/user/v2" - - "github.com/zitadel/zitadel/internal/integration" ) func TestServer_RequestPasswordReset(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() tests := []struct { name string @@ -35,7 +34,7 @@ func TestServer_RequestPasswordReset(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -54,7 +53,7 @@ func TestServer_RequestPasswordReset(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -82,7 +81,7 @@ func TestServer_RequestPasswordReset(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, VerificationCode: gu.Ptr("xxx"), }, @@ -130,7 +129,7 @@ func TestServer_SetPassword(t *testing.T) { { name: "set successful", prepare: func(request *user.SetPasswordRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID return nil }, @@ -145,14 +144,14 @@ func TestServer_SetPassword(t *testing.T) { want: &user.SetPasswordResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, { name: "change successful", prepare: func(request *user.SetPasswordRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID _, err := Client.SetPassword(CTX, &user.SetPasswordRequest{ UserId: userID, @@ -176,14 +175,14 @@ func TestServer_SetPassword(t *testing.T) { want: &user.SetPasswordResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, { name: "set with code successful", prepare: func(request *user.SetPasswordRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID resp, err := Client.PasswordReset(CTX, &user.PasswordResetRequest{ UserId: userID, @@ -210,7 +209,7 @@ func TestServer_SetPassword(t *testing.T) { want: &user.SetPasswordResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, diff --git a/internal/api/grpc/user/v2/phone_integration_test.go b/internal/api/grpc/user/v2/integration_test/phone_test.go similarity index 87% rename from internal/api/grpc/user/v2/phone_integration_test.go rename to internal/api/grpc/user/v2/integration_test/phone_test.go index ab88268ee1..456b77231d 100644 --- a/internal/api/grpc/user/v2/phone_integration_test.go +++ b/internal/api/grpc/user/v2/integration_test/phone_test.go @@ -13,14 +13,13 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/protobuf/types/known/timestamppb" + "github.com/zitadel/zitadel/internal/integration" object "github.com/zitadel/zitadel/pkg/grpc/object/v2" user "github.com/zitadel/zitadel/pkg/grpc/user/v2" - - "github.com/zitadel/zitadel/internal/integration" ) func TestServer_SetPhone(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() tests := []struct { name string @@ -38,7 +37,7 @@ func TestServer_SetPhone(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -55,7 +54,7 @@ func TestServer_SetPhone(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -72,7 +71,7 @@ func TestServer_SetPhone(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, VerificationCode: gu.Ptr("xxx"), }, @@ -90,7 +89,7 @@ func TestServer_SetPhone(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -123,8 +122,8 @@ func TestServer_SetPhone(t *testing.T) { } func TestServer_ResendPhoneCode(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - verifiedUserID := Tester.CreateHumanUserVerified(CTX, Tester.Organisation.ID, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() + verifiedUserID := Instance.CreateHumanUserVerified(CTX, Instance.DefaultOrg.Id, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId() tests := []struct { name string @@ -158,7 +157,7 @@ func TestServer_ResendPhoneCode(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -174,7 +173,7 @@ func TestServer_ResendPhoneCode(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, VerificationCode: gu.Ptr("xxx"), }, @@ -197,7 +196,7 @@ func TestServer_ResendPhoneCode(t *testing.T) { } func TestServer_VerifyPhone(t *testing.T) { - userResp := Tester.CreateHumanUser(CTX) + userResp := Instance.CreateHumanUser(CTX) tests := []struct { name string req *user.VerifyPhoneRequest @@ -230,7 +229,7 @@ func TestServer_VerifyPhone(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -249,13 +248,13 @@ func TestServer_VerifyPhone(t *testing.T) { } func TestServer_RemovePhone(t *testing.T) { - userResp := Tester.CreateHumanUser(CTX) - failResp := Tester.CreateHumanUserNoPhone(CTX) - otherUser := Tester.CreateHumanUser(CTX).GetUserId() - doubleRemoveUser := Tester.CreateHumanUser(CTX) + userResp := Instance.CreateHumanUser(CTX) + failResp := Instance.CreateHumanUserNoPhone(CTX) + otherUser := Instance.CreateHumanUser(CTX).GetUserId() + doubleRemoveUser := Instance.CreateHumanUser(CTX) - Tester.RegisterUserPasskey(CTX, otherUser) - _, sessionTokenOtherUser, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, otherUser) + Instance.RegisterUserPasskey(CTX, otherUser) + _, sessionTokenOtherUser, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, otherUser) tests := []struct { name string @@ -275,7 +274,7 @@ func TestServer_RemovePhone(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, dep: func(ctx context.Context, userID string) (*user.RemovePhoneResponse, error) { @@ -317,7 +316,7 @@ func TestServer_RemovePhone(t *testing.T) { }, { name: "other user, no permission", - ctx: Tester.WithAuthorizationToken(CTX, sessionTokenOtherUser), + ctx: integration.WithAuthorizationToken(CTX, sessionTokenOtherUser), req: &user.RemovePhoneRequest{ UserId: userResp.GetUserId(), }, diff --git a/internal/api/grpc/user/v2/query_integration_test.go b/internal/api/grpc/user/v2/integration_test/query_test.go similarity index 93% rename from internal/api/grpc/user/v2/query_integration_test.go rename to internal/api/grpc/user/v2/integration_test/query_test.go index 7509a9d430..5d0835d9ae 100644 --- a/internal/api/grpc/user/v2/query_integration_test.go +++ b/internal/api/grpc/user/v2/integration_test/query_test.go @@ -13,14 +13,13 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/protobuf/types/known/timestamppb" + "github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/pkg/grpc/object/v2" "github.com/zitadel/zitadel/pkg/grpc/user/v2" - - "github.com/zitadel/zitadel/internal/integration" ) func TestServer_GetUserByID(t *testing.T) { - orgResp := Tester.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) + orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) type args struct { ctx context.Context req *user.GetUserByIDRequest @@ -64,7 +63,7 @@ func TestServer_GetUserByID(t *testing.T) { IamCTX, &user.GetUserByIDRequest{}, func(ctx context.Context, username string, request *user.GetUserByIDRequest) (*userAttr, error) { - resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) + resp := Instance.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) request.UserId = resp.GetUserId() return &userAttr{resp.GetUserId(), username, nil, resp.GetDetails()}, nil }, @@ -108,9 +107,9 @@ func TestServer_GetUserByID(t *testing.T) { IamCTX, &user.GetUserByIDRequest{}, func(ctx context.Context, username string, request *user.GetUserByIDRequest) (*userAttr, error) { - resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) + resp := Instance.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) request.UserId = resp.GetUserId() - details := Tester.SetUserPassword(ctx, resp.GetUserId(), integration.UserPassword, true) + details := Instance.SetUserPassword(ctx, resp.GetUserId(), integration.UserPassword, true) return &userAttr{resp.GetUserId(), username, details.GetChangeDate(), resp.GetDetails()}, nil }, }, @@ -181,7 +180,7 @@ func TestServer_GetUserByID(t *testing.T) { } } assert.Equal(ttt, tt.want.User, got.User) - integration.AssertDetails(t, tt.want, got) + integration.AssertDetails(ttt, tt.want, got) }, retryDuration, time.Second) }) } @@ -190,7 +189,7 @@ func TestServer_GetUserByID(t *testing.T) { func TestServer_GetUserByID_Permission(t *testing.T) { timeNow := time.Now().UTC() newOrgOwnerEmail := fmt.Sprintf("%d@permission.get.com", timeNow.UnixNano()) - newOrg := Tester.CreateOrganization(IamCTX, fmt.Sprintf("GetHuman%d", time.Now().UnixNano()), newOrgOwnerEmail) + newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetHuman%d", time.Now().UnixNano()), newOrgOwnerEmail) newUserID := newOrg.CreatedAdmins[0].GetUserId() type args struct { ctx context.Context @@ -330,8 +329,8 @@ type userAttr struct { } func TestServer_ListUsers(t *testing.T) { - orgResp := Tester.CreateOrganization(IamCTX, fmt.Sprintf("ListUsersOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) - userResp := Tester.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listusers.com", time.Now().UnixNano())) + orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListUsersOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) + userResp := Instance.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listusers.com", time.Now().UnixNano())) type args struct { ctx context.Context count int @@ -378,7 +377,7 @@ func TestServer_ListUsers(t *testing.T) { infos := make([]userAttr, len(usernames)) userIDs := make([]string, len(usernames)) for i, username := range usernames { - resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) + resp := Instance.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) userIDs[i] = resp.GetUserId() infos[i] = userAttr{resp.GetUserId(), username, nil, resp.GetDetails()} } @@ -432,9 +431,9 @@ func TestServer_ListUsers(t *testing.T) { infos := make([]userAttr, len(usernames)) userIDs := make([]string, len(usernames)) for i, username := range usernames { - resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) + resp := Instance.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) userIDs[i] = resp.GetUserId() - details := Tester.SetUserPassword(ctx, resp.GetUserId(), integration.UserPassword, true) + details := Instance.SetUserPassword(ctx, resp.GetUserId(), integration.UserPassword, true) infos[i] = userAttr{resp.GetUserId(), username, details.GetChangeDate(), resp.GetDetails()} } request.Queries = append(request.Queries, InUserIDsQuery(userIDs)) @@ -489,7 +488,7 @@ func TestServer_ListUsers(t *testing.T) { infos := make([]userAttr, len(usernames)) userIDs := make([]string, len(usernames)) for i, username := range usernames { - resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) + resp := Instance.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) userIDs[i] = resp.GetUserId() infos[i] = userAttr{resp.GetUserId(), username, nil, resp.GetDetails()} } @@ -585,7 +584,7 @@ func TestServer_ListUsers(t *testing.T) { infos := make([]userAttr, len(usernames)) userIDs := make([]string, len(usernames)) for i, username := range usernames { - resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) + resp := Instance.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) userIDs[i] = resp.GetUserId() infos[i] = userAttr{resp.GetUserId(), username, nil, resp.GetDetails()} request.Queries = append(request.Queries, UsernameQuery(username)) @@ -638,7 +637,7 @@ func TestServer_ListUsers(t *testing.T) { func(ctx context.Context, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) { infos := make([]userAttr, len(usernames)) for i, username := range usernames { - resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) + resp := Instance.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) infos[i] = userAttr{resp.GetUserId(), username, nil, resp.GetDetails()} } request.Queries = append(request.Queries, InUserEmailsQuery(usernames)) @@ -690,7 +689,7 @@ func TestServer_ListUsers(t *testing.T) { func(ctx context.Context, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) { infos := make([]userAttr, len(usernames)) for i, username := range usernames { - resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) + resp := Instance.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) infos[i] = userAttr{resp.GetUserId(), username, nil, resp.GetDetails()} } request.Queries = append(request.Queries, InUserEmailsQuery(usernames)) @@ -801,11 +800,11 @@ func TestServer_ListUsers(t *testing.T) { 3, &user.ListUsersRequest{}, func(ctx context.Context, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) { - orgResp := Tester.CreateOrganization(ctx, fmt.Sprintf("ListUsersResourceowner%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) + orgResp := Instance.CreateOrganization(ctx, fmt.Sprintf("ListUsersResourceowner%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) infos := make([]userAttr, len(usernames)) for i, username := range usernames { - resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) + resp := Instance.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) infos[i] = userAttr{resp.GetUserId(), username, nil, resp.GetDetails()} } request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId)) @@ -935,7 +934,7 @@ func TestServer_ListUsers(t *testing.T) { for i := range tt.want.Result { assert.Contains(ttt, got.Result, tt.want.Result[i]) } - integration.AssertListDetails(t, tt.want, got) + integration.AssertListDetails(ttt, tt.want, got) }, retryDuration, time.Millisecond*100, "timeout waiting for expected user result") }) } diff --git a/internal/api/grpc/user/v2/totp_integration_test.go b/internal/api/grpc/user/v2/integration_test/totp_test.go similarity index 72% rename from internal/api/grpc/user/v2/totp_integration_test.go rename to internal/api/grpc/user/v2/integration_test/totp_test.go index 474aed95b8..e65756c1c1 100644 --- a/internal/api/grpc/user/v2/totp_integration_test.go +++ b/internal/api/grpc/user/v2/integration_test/totp_test.go @@ -12,22 +12,21 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/protobuf/types/known/timestamppb" + "github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/pkg/grpc/object/v2" "github.com/zitadel/zitadel/pkg/grpc/user/v2" - - "github.com/zitadel/zitadel/internal/integration" ) func TestServer_RegisterTOTP(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) - ctx := Tester.WithAuthorizationToken(CTX, sessionToken) + userID := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) + ctx := integration.WithAuthorizationToken(CTX, sessionToken) - otherUser := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, otherUser) - _, sessionTokenOtherUser, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, otherUser) - ctxOtherUser := Tester.WithAuthorizationToken(CTX, sessionTokenOtherUser) + otherUser := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, otherUser) + _, sessionTokenOtherUser, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, otherUser) + ctxOtherUser := integration.WithAuthorizationToken(CTX, sessionTokenOtherUser) type args struct { ctx context.Context @@ -68,7 +67,7 @@ func TestServer_RegisterTOTP(t *testing.T) { want: &user.RegisterTOTPResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -83,7 +82,7 @@ func TestServer_RegisterTOTP(t *testing.T) { want: &user.RegisterTOTPResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -105,10 +104,10 @@ func TestServer_RegisterTOTP(t *testing.T) { } func TestServer_VerifyTOTPRegistration(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) - ctx := Tester.WithAuthorizationToken(CTX, sessionToken) + userID := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) + ctx := integration.WithAuthorizationToken(CTX, sessionToken) reg, err := Client.RegisterTOTP(ctx, &user.RegisterTOTPRequest{ UserId: userID, @@ -117,10 +116,10 @@ func TestServer_VerifyTOTPRegistration(t *testing.T) { code, err := totp.GenerateCode(reg.Secret, time.Now()) require.NoError(t, err) - otherUser := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, otherUser) - _, sessionTokenOtherUser, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, otherUser) - ctxOtherUser := Tester.WithAuthorizationToken(CTX, sessionTokenOtherUser) + otherUser := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, otherUser) + _, sessionTokenOtherUser, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, otherUser) + ctxOtherUser := integration.WithAuthorizationToken(CTX, sessionTokenOtherUser) regOtherUser, err := Client.RegisterTOTP(CTX, &user.RegisterTOTPRequest{ UserId: otherUser, @@ -172,7 +171,7 @@ func TestServer_VerifyTOTPRegistration(t *testing.T) { want: &user.VerifyTOTPRegistrationResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ResourceOwner, + ResourceOwner: Instance.DefaultOrg.Details.ResourceOwner, }, }, }, @@ -188,7 +187,7 @@ func TestServer_VerifyTOTPRegistration(t *testing.T) { want: &user.VerifyTOTPRegistrationResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ResourceOwner, + ResourceOwner: Instance.DefaultOrg.Details.ResourceOwner, }, }, }, @@ -208,15 +207,15 @@ func TestServer_VerifyTOTPRegistration(t *testing.T) { } func TestServer_RemoveTOTP(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) + userID := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) - userVerified := Tester.CreateHumanUser(CTX) - Tester.RegisterUserPasskey(CTX, userVerified.GetUserId()) - _, sessionTokenVerified, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) - userVerifiedCtx := Tester.WithAuthorizationToken(context.Background(), sessionTokenVerified) - _, err := Tester.Client.UserV2.VerifyPhone(userVerifiedCtx, &user.VerifyPhoneRequest{ + userVerified := Instance.CreateHumanUser(CTX) + Instance.RegisterUserPasskey(CTX, userVerified.GetUserId()) + _, sessionTokenVerified, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) + userVerifiedCtx := integration.WithAuthorizationToken(context.Background(), sessionTokenVerified) + _, err := Instance.Client.UserV2.VerifyPhone(userVerifiedCtx, &user.VerifyPhoneRequest{ UserId: userVerified.GetUserId(), VerificationCode: userVerified.GetPhoneCode(), }) @@ -248,7 +247,7 @@ func TestServer_RemoveTOTP(t *testing.T) { { name: "not added", args: args{ - ctx: Tester.WithAuthorizationToken(context.Background(), sessionToken), + ctx: integration.WithAuthorizationToken(context.Background(), sessionToken), req: &user.RemoveTOTPRequest{ UserId: userID, }, @@ -265,7 +264,7 @@ func TestServer_RemoveTOTP(t *testing.T) { }, want: &user.RemoveTOTPResponse{ Details: &object.Details{ - ResourceOwner: Tester.Organisation.ResourceOwner, + ResourceOwner: Instance.DefaultOrg.Details.ResourceOwner, }, }, }, diff --git a/internal/api/grpc/user/v2/u2f_integration_test.go b/internal/api/grpc/user/v2/integration_test/u2f_test.go similarity index 82% rename from internal/api/grpc/user/v2/u2f_integration_test.go rename to internal/api/grpc/user/v2/integration_test/u2f_test.go index c4d4c33071..b8af753f85 100644 --- a/internal/api/grpc/user/v2/u2f_integration_test.go +++ b/internal/api/grpc/user/v2/integration_test/u2f_test.go @@ -11,21 +11,20 @@ import ( "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" + "github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/pkg/grpc/object/v2" "github.com/zitadel/zitadel/pkg/grpc/user/v2" - - "github.com/zitadel/zitadel/internal/integration" ) func TestServer_RegisterU2F(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - otherUser := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() + otherUser := Instance.CreateHumanUser(CTX).GetUserId() // We also need a user session - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) - Tester.RegisterUserPasskey(CTX, otherUser) - _, sessionTokenOtherUser, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, otherUser) + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) + Instance.RegisterUserPasskey(CTX, otherUser) + _, sessionTokenOtherUser, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, otherUser) type args struct { ctx context.Context @@ -56,14 +55,14 @@ func TestServer_RegisterU2F(t *testing.T) { want: &user.RegisterU2FResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, { name: "other user, no permission", args: args{ - ctx: Tester.WithAuthorizationToken(CTX, sessionTokenOtherUser), + ctx: integration.WithAuthorizationToken(CTX, sessionTokenOtherUser), req: &user.RegisterU2FRequest{ UserId: userID, }, @@ -73,7 +72,7 @@ func TestServer_RegisterU2F(t *testing.T) { { name: "user setting its own passkey", args: args{ - ctx: Tester.WithAuthorizationToken(CTX, sessionToken), + ctx: integration.WithAuthorizationToken(CTX, sessionToken), req: &user.RegisterU2FRequest{ UserId: userID, }, @@ -81,7 +80,7 @@ func TestServer_RegisterU2F(t *testing.T) { want: &user.RegisterU2FResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -99,7 +98,7 @@ func TestServer_RegisterU2F(t *testing.T) { if tt.want != nil { assert.NotEmpty(t, got.GetU2FId()) assert.NotEmpty(t, got.GetPublicKeyCredentialCreationOptions()) - _, err = Tester.WebAuthN.CreateAttestationResponse(got.GetPublicKeyCredentialCreationOptions()) + _, err = Instance.WebAuthN.CreateAttestationResponse(got.GetPublicKeyCredentialCreationOptions()) require.NoError(t, err) } }) @@ -109,7 +108,7 @@ func TestServer_RegisterU2F(t *testing.T) { func TestServer_VerifyU2FRegistration(t *testing.T) { ctx, userID, pkr := ctxFromNewUserWithRegisteredU2F(t) - attestationResponse, err := Tester.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) + attestationResponse, err := Instance.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) require.NoError(t, err) type args struct { @@ -147,7 +146,7 @@ func TestServer_VerifyU2FRegistration(t *testing.T) { want: &user.VerifyU2FRegistrationResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -182,10 +181,10 @@ func TestServer_VerifyU2FRegistration(t *testing.T) { } func ctxFromNewUserWithRegisteredU2F(t *testing.T) (context.Context, string, *user.RegisterU2FResponse) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) - ctx := Tester.WithAuthorizationToken(CTX, sessionToken) + userID := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) + ctx := integration.WithAuthorizationToken(CTX, sessionToken) pkr, err := Client.RegisterU2F(ctx, &user.RegisterU2FRequest{ UserId: userID, @@ -198,7 +197,7 @@ func ctxFromNewUserWithRegisteredU2F(t *testing.T) (context.Context, string, *us func ctxFromNewUserWithVerifiedU2F(t *testing.T) (context.Context, string, string) { ctx, userID, pkr := ctxFromNewUserWithRegisteredU2F(t) - attestationResponse, err := Tester.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) + attestationResponse, err := Instance.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) require.NoError(t, err) _, err = Client.VerifyU2FRegistration(ctx, &user.VerifyU2FRegistrationRequest{ @@ -212,7 +211,7 @@ func ctxFromNewUserWithVerifiedU2F(t *testing.T) (context.Context, string, strin } func TestServer_RemoveU2F(t *testing.T) { - userIDWithout := Tester.CreateHumanUser(CTX).GetUserId() + userIDWithout := Instance.CreateHumanUser(CTX).GetUserId() ctxRegistered, userIDRegistered, pkrRegistered := ctxFromNewUserWithRegisteredU2F(t) _, userIDVerified, u2fVerified := ctxFromNewUserWithVerifiedU2F(t) _, userIDVerifiedPermission, u2fVerifiedPermission := ctxFromNewUserWithVerifiedU2F(t) @@ -259,7 +258,7 @@ func TestServer_RemoveU2F(t *testing.T) { want: &user.RemoveU2FResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -286,7 +285,7 @@ func TestServer_RemoveU2F(t *testing.T) { want: &user.RemoveU2FResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, diff --git a/internal/api/grpc/user/v2/user_integration_test.go b/internal/api/grpc/user/v2/integration_test/user_test.go similarity index 88% rename from internal/api/grpc/user/v2/user_integration_test.go rename to internal/api/grpc/user/v2/integration_test/user_test.go index e762c10181..cab073c616 100644 --- a/internal/api/grpc/user/v2/user_integration_test.go +++ b/internal/api/grpc/user/v2/integration_test/user_test.go @@ -15,16 +15,13 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" - "github.com/zitadel/zitadel/pkg/grpc/object/v2" - "github.com/zitadel/zitadel/pkg/grpc/user/v2" - - "github.com/zitadel/zitadel/internal/api/grpc" "github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/pkg/grpc/idp" mgmt "github.com/zitadel/zitadel/pkg/grpc/management" + "github.com/zitadel/zitadel/pkg/grpc/object/v2" + "github.com/zitadel/zitadel/pkg/grpc/user/v2" ) var ( @@ -32,30 +29,28 @@ var ( IamCTX context.Context UserCTX context.Context SystemCTX context.Context - ErrCTX context.Context - Tester *integration.Tester + Instance *integration.Instance Client user.UserServiceClient ) func TestMain(m *testing.M) { os.Exit(func() int { - ctx, errCtx, cancel := integration.Contexts(time.Hour) + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute) defer cancel() - Tester = integration.NewTester(ctx) - defer Tester.Done() + Instance = integration.NewInstance(ctx) - UserCTX = Tester.WithAuthorization(ctx, integration.Login) - IamCTX = Tester.WithAuthorization(ctx, integration.IAMOwner) - SystemCTX = Tester.WithAuthorization(ctx, integration.SystemUser) - CTX, ErrCTX = Tester.WithAuthorization(ctx, integration.OrgOwner), errCtx - Client = Tester.Client.UserV2 + UserCTX = Instance.WithAuthorization(ctx, integration.UserTypeLogin) + IamCTX = Instance.WithAuthorization(ctx, integration.UserTypeIAMOwner) + SystemCTX = integration.WithSystemAuthorization(ctx) + CTX = Instance.WithAuthorization(ctx, integration.UserTypeOrgOwner) + Client = Instance.Client.UserV2 return m.Run() }()) } func TestServer_AddHumanUser(t *testing.T) { - idpID := Tester.AddGenericOAuthProvider(t, CTX) + idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id) type args struct { ctx context.Context req *user.AddHumanUserRequest @@ -73,7 +68,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -103,7 +98,7 @@ func TestServer_AddHumanUser(t *testing.T) { want: &user.AddHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -114,7 +109,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -147,7 +142,7 @@ func TestServer_AddHumanUser(t *testing.T) { want: &user.AddHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, EmailCode: gu.Ptr("something"), }, @@ -159,7 +154,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -194,7 +189,7 @@ func TestServer_AddHumanUser(t *testing.T) { want: &user.AddHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -205,7 +200,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -240,7 +235,7 @@ func TestServer_AddHumanUser(t *testing.T) { want: &user.AddHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, PhoneCode: gu.Ptr("something"), }, @@ -252,7 +247,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -293,7 +288,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Email: &user.SetHumanEmail{ @@ -324,7 +319,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -358,7 +353,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -405,7 +400,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -436,7 +431,7 @@ func TestServer_AddHumanUser(t *testing.T) { }, IdpLinks: []*user.IDPLink{ { - IdpId: idpID, + IdpId: idpResp.Id, UserId: "userID", UserName: "username", }, @@ -446,7 +441,7 @@ func TestServer_AddHumanUser(t *testing.T) { want: &user.AddHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -457,7 +452,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -492,7 +487,7 @@ func TestServer_AddHumanUser(t *testing.T) { want: &user.AddHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -503,7 +498,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -537,7 +532,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -565,7 +560,7 @@ func TestServer_AddHumanUser(t *testing.T) { want: &user.AddHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -576,7 +571,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -637,7 +632,7 @@ func TestServer_AddHumanUser(t *testing.T) { func TestServer_AddHumanUser_Permission(t *testing.T) { newOrgOwnerEmail := fmt.Sprintf("%d@permission.com", time.Now().UnixNano()) - newOrg := Tester.CreateOrganization(IamCTX, fmt.Sprintf("AddHuman%d", time.Now().UnixNano()), newOrgOwnerEmail) + newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("AddHuman%d", time.Now().UnixNano()), newOrgOwnerEmail) type args struct { ctx context.Context req *user.AddHumanUserRequest @@ -857,7 +852,7 @@ func TestServer_UpdateHumanUser(t *testing.T) { { name: "change username, ok", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID return nil }, @@ -870,14 +865,14 @@ func TestServer_UpdateHumanUser(t *testing.T) { want: &user.UpdateHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, { name: "change profile, ok", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID return nil }, @@ -897,14 +892,14 @@ func TestServer_UpdateHumanUser(t *testing.T) { want: &user.UpdateHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, { name: "change email, ok", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID return nil }, @@ -920,14 +915,14 @@ func TestServer_UpdateHumanUser(t *testing.T) { want: &user.UpdateHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, { name: "change email, code, ok", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID return nil }, @@ -943,7 +938,7 @@ func TestServer_UpdateHumanUser(t *testing.T) { want: &user.UpdateHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, EmailCode: gu.Ptr("something"), }, @@ -951,7 +946,7 @@ func TestServer_UpdateHumanUser(t *testing.T) { { name: "change phone, ok", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID return nil }, @@ -967,14 +962,14 @@ func TestServer_UpdateHumanUser(t *testing.T) { want: &user.UpdateHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, { name: "change phone, code, ok", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID return nil }, @@ -990,7 +985,7 @@ func TestServer_UpdateHumanUser(t *testing.T) { want: &user.UpdateHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, PhoneCode: gu.Ptr("something"), }, @@ -998,7 +993,7 @@ func TestServer_UpdateHumanUser(t *testing.T) { { name: "change password, code, ok", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID resp, err := Client.PasswordReset(CTX, &user.PasswordResetRequest{ UserId: userID, @@ -1030,14 +1025,14 @@ func TestServer_UpdateHumanUser(t *testing.T) { want: &user.UpdateHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, { name: "change hashed password, code, ok", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID resp, err := Client.PasswordReset(CTX, &user.PasswordResetRequest{ UserId: userID, @@ -1068,14 +1063,14 @@ func TestServer_UpdateHumanUser(t *testing.T) { want: &user.UpdateHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, { name: "change hashed password, code, not supported", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID resp, err := Client.PasswordReset(CTX, &user.PasswordResetRequest{ UserId: userID, @@ -1110,7 +1105,7 @@ func TestServer_UpdateHumanUser(t *testing.T) { { name: "change password, old password, ok", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID resp, err := Client.PasswordReset(CTX, &user.PasswordResetRequest{ @@ -1157,7 +1152,7 @@ func TestServer_UpdateHumanUser(t *testing.T) { want: &user.UpdateHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1186,7 +1181,7 @@ func TestServer_UpdateHumanUser(t *testing.T) { func TestServer_UpdateHumanUser_Permission(t *testing.T) { newOrgOwnerEmail := fmt.Sprintf("%d@permission.update.com", time.Now().UnixNano()) - newOrg := Tester.CreateOrganization(IamCTX, fmt.Sprintf("UpdateHuman%d", time.Now().UnixNano()), newOrgOwnerEmail) + newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("UpdateHuman%d", time.Now().UnixNano()), newOrgOwnerEmail) newUserID := newOrg.CreatedAdmins[0].GetUserId() type args struct { ctx context.Context @@ -1296,7 +1291,7 @@ func TestServer_LockUser(t *testing.T) { CTX, &user.LockUserRequest{}, func(request *user.LockUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() return nil }, @@ -1304,7 +1299,7 @@ func TestServer_LockUser(t *testing.T) { want: &user.LockUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1314,7 +1309,7 @@ func TestServer_LockUser(t *testing.T) { CTX, &user.LockUserRequest{}, func(request *user.LockUserRequest) error { - resp := Tester.CreateMachineUser(CTX) + resp := Instance.CreateMachineUser(CTX) request.UserId = resp.GetUserId() return nil }, @@ -1322,7 +1317,7 @@ func TestServer_LockUser(t *testing.T) { want: &user.LockUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1332,7 +1327,7 @@ func TestServer_LockUser(t *testing.T) { CTX, &user.LockUserRequest{}, func(request *user.LockUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() _, err := Client.LockUser(CTX, &user.LockUserRequest{ UserId: resp.GetUserId(), @@ -1348,7 +1343,7 @@ func TestServer_LockUser(t *testing.T) { CTX, &user.LockUserRequest{}, func(request *user.LockUserRequest) error { - resp := Tester.CreateMachineUser(CTX) + resp := Instance.CreateMachineUser(CTX) request.UserId = resp.GetUserId() _, err := Client.LockUser(CTX, &user.LockUserRequest{ UserId: resp.GetUserId(), @@ -1404,7 +1399,7 @@ func TestServer_UnLockUser(t *testing.T) { ctx: CTX, req: &user.UnlockUserRequest{}, prepare: func(request *user.UnlockUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() return nil }, @@ -1417,7 +1412,7 @@ func TestServer_UnLockUser(t *testing.T) { ctx: CTX, req: &user.UnlockUserRequest{}, prepare: func(request *user.UnlockUserRequest) error { - resp := Tester.CreateMachineUser(CTX) + resp := Instance.CreateMachineUser(CTX) request.UserId = resp.GetUserId() return nil }, @@ -1430,7 +1425,7 @@ func TestServer_UnLockUser(t *testing.T) { ctx: CTX, req: &user.UnlockUserRequest{}, prepare: func(request *user.UnlockUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() _, err := Client.LockUser(CTX, &user.LockUserRequest{ UserId: resp.GetUserId(), @@ -1441,7 +1436,7 @@ func TestServer_UnLockUser(t *testing.T) { want: &user.UnlockUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1451,7 +1446,7 @@ func TestServer_UnLockUser(t *testing.T) { ctx: CTX, req: &user.UnlockUserRequest{}, prepare: func(request *user.UnlockUserRequest) error { - resp := Tester.CreateMachineUser(CTX) + resp := Instance.CreateMachineUser(CTX) request.UserId = resp.GetUserId() _, err := Client.LockUser(CTX, &user.LockUserRequest{ UserId: resp.GetUserId(), @@ -1462,7 +1457,7 @@ func TestServer_UnLockUser(t *testing.T) { want: &user.UnlockUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1512,7 +1507,7 @@ func TestServer_DeactivateUser(t *testing.T) { CTX, &user.DeactivateUserRequest{}, func(request *user.DeactivateUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() return nil }, @@ -1520,7 +1515,7 @@ func TestServer_DeactivateUser(t *testing.T) { want: &user.DeactivateUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1530,7 +1525,7 @@ func TestServer_DeactivateUser(t *testing.T) { CTX, &user.DeactivateUserRequest{}, func(request *user.DeactivateUserRequest) error { - resp := Tester.CreateMachineUser(CTX) + resp := Instance.CreateMachineUser(CTX) request.UserId = resp.GetUserId() return nil }, @@ -1538,7 +1533,7 @@ func TestServer_DeactivateUser(t *testing.T) { want: &user.DeactivateUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1548,7 +1543,7 @@ func TestServer_DeactivateUser(t *testing.T) { CTX, &user.DeactivateUserRequest{}, func(request *user.DeactivateUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() _, err := Client.DeactivateUser(CTX, &user.DeactivateUserRequest{ UserId: resp.GetUserId(), @@ -1564,7 +1559,7 @@ func TestServer_DeactivateUser(t *testing.T) { CTX, &user.DeactivateUserRequest{}, func(request *user.DeactivateUserRequest) error { - resp := Tester.CreateMachineUser(CTX) + resp := Instance.CreateMachineUser(CTX) request.UserId = resp.GetUserId() _, err := Client.DeactivateUser(CTX, &user.DeactivateUserRequest{ UserId: resp.GetUserId(), @@ -1620,7 +1615,7 @@ func TestServer_ReactivateUser(t *testing.T) { ctx: CTX, req: &user.ReactivateUserRequest{}, prepare: func(request *user.ReactivateUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() return nil }, @@ -1633,7 +1628,7 @@ func TestServer_ReactivateUser(t *testing.T) { ctx: CTX, req: &user.ReactivateUserRequest{}, prepare: func(request *user.ReactivateUserRequest) error { - resp := Tester.CreateMachineUser(CTX) + resp := Instance.CreateMachineUser(CTX) request.UserId = resp.GetUserId() return nil }, @@ -1646,7 +1641,7 @@ func TestServer_ReactivateUser(t *testing.T) { ctx: CTX, req: &user.ReactivateUserRequest{}, prepare: func(request *user.ReactivateUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() _, err := Client.DeactivateUser(CTX, &user.DeactivateUserRequest{ UserId: resp.GetUserId(), @@ -1657,7 +1652,7 @@ func TestServer_ReactivateUser(t *testing.T) { want: &user.ReactivateUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1667,7 +1662,7 @@ func TestServer_ReactivateUser(t *testing.T) { ctx: CTX, req: &user.ReactivateUserRequest{}, prepare: func(request *user.ReactivateUserRequest) error { - resp := Tester.CreateMachineUser(CTX) + resp := Instance.CreateMachineUser(CTX) request.UserId = resp.GetUserId() _, err := Client.DeactivateUser(CTX, &user.DeactivateUserRequest{ UserId: resp.GetUserId(), @@ -1678,7 +1673,7 @@ func TestServer_ReactivateUser(t *testing.T) { want: &user.ReactivateUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1700,7 +1695,7 @@ func TestServer_ReactivateUser(t *testing.T) { } func TestServer_DeleteUser(t *testing.T) { - projectResp, err := Tester.CreateProject(CTX) + projectResp, err := Instance.CreateProject(CTX) require.NoError(t, err) type args struct { ctx context.Context @@ -1730,7 +1725,7 @@ func TestServer_DeleteUser(t *testing.T) { ctx: CTX, req: &user.DeleteUserRequest{}, prepare: func(request *user.DeleteUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() return err }, @@ -1738,7 +1733,7 @@ func TestServer_DeleteUser(t *testing.T) { want: &user.DeleteUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1748,7 +1743,7 @@ func TestServer_DeleteUser(t *testing.T) { ctx: CTX, req: &user.DeleteUserRequest{}, prepare: func(request *user.DeleteUserRequest) error { - resp := Tester.CreateMachineUser(CTX) + resp := Instance.CreateMachineUser(CTX) request.UserId = resp.GetUserId() return err }, @@ -1756,7 +1751,7 @@ func TestServer_DeleteUser(t *testing.T) { want: &user.DeleteUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1766,18 +1761,18 @@ func TestServer_DeleteUser(t *testing.T) { ctx: CTX, req: &user.DeleteUserRequest{}, prepare: func(request *user.DeleteUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() - Tester.CreateProjectUserGrant(t, CTX, projectResp.GetId(), request.UserId) - Tester.CreateProjectMembership(t, CTX, projectResp.GetId(), request.UserId) - Tester.CreateOrgMembership(t, CTX, request.UserId) + Instance.CreateProjectUserGrant(t, CTX, projectResp.GetId(), request.UserId) + Instance.CreateProjectMembership(t, CTX, projectResp.GetId(), request.UserId) + Instance.CreateOrgMembership(t, CTX, request.UserId) return err }, }, want: &user.DeleteUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1799,13 +1794,13 @@ func TestServer_DeleteUser(t *testing.T) { } func TestServer_StartIdentityProviderIntent(t *testing.T) { - idpID := Tester.AddGenericOAuthProvider(t, CTX) - orgIdpID := Tester.AddOrgGenericOAuthProvider(t, CTX, Tester.Organisation.ID) - orgResp := Tester.CreateOrganization(IamCTX, fmt.Sprintf("NotDefaultOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) - notDefaultOrgIdpID := Tester.AddOrgGenericOAuthProvider(t, CTX, orgResp.OrganizationId) - samlIdpID := Tester.AddSAMLProvider(t, CTX) - samlRedirectIdpID := Tester.AddSAMLRedirectProvider(t, CTX, "") - samlPostIdpID := Tester.AddSAMLPostProvider(t, CTX) + idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id) + orgIdpResp := Instance.AddOrgGenericOAuthProvider(CTX, Instance.DefaultOrg.Id) + orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("NotDefaultOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) + notDefaultOrgIdpResp := Instance.AddOrgGenericOAuthProvider(IamCTX, orgResp.OrganizationId) + samlIdpID := Instance.AddSAMLProvider(IamCTX) + samlRedirectIdpID := Instance.AddSAMLRedirectProvider(IamCTX, "") + samlPostIdpID := Instance.AddSAMLPostProvider(IamCTX) type args struct { ctx context.Context req *user.StartIdentityProviderIntentRequest @@ -1828,7 +1823,7 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { args: args{ CTX, &user.StartIdentityProviderIntentRequest{ - IdpId: idpID, + IdpId: idpResp.Id, }, }, wantErr: true, @@ -1838,7 +1833,7 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { args: args{ CTX, &user.StartIdentityProviderIntentRequest{ - IdpId: idpID, + IdpId: idpResp.Id, Content: &user.StartIdentityProviderIntentRequest_Urls{ Urls: &user.RedirectURLs{ SuccessUrl: "https://example.com/success", @@ -1850,13 +1845,13 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { want: want{ details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), }, url: "https://example.com/oauth/v2/authorize", parametersEqual: map[string]string{ "client_id": "clientID", "prompt": "select_account", - "redirect_uri": "http://" + Tester.Config.ExternalDomain + ":8080/idps/callback", + "redirect_uri": "http://" + Instance.Domain + ":8080/idps/callback", "response_type": "code", "scope": "openid profile email", }, @@ -1869,7 +1864,7 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { args: args{ CTX, &user.StartIdentityProviderIntentRequest{ - IdpId: orgIdpID, + IdpId: orgIdpResp.Id, Content: &user.StartIdentityProviderIntentRequest_Urls{ Urls: &user.RedirectURLs{ SuccessUrl: "https://example.com/success", @@ -1881,13 +1876,13 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { want: want{ details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), }, url: "https://example.com/oauth/v2/authorize", parametersEqual: map[string]string{ "client_id": "clientID", "prompt": "select_account", - "redirect_uri": "http://" + Tester.Config.ExternalDomain + ":8080/idps/callback", + "redirect_uri": "http://" + Instance.Domain + ":8080/idps/callback", "response_type": "code", "scope": "openid profile email", }, @@ -1900,7 +1895,7 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { args: args{ CTX, &user.StartIdentityProviderIntentRequest{ - IdpId: notDefaultOrgIdpID, + IdpId: notDefaultOrgIdpResp.Id, Content: &user.StartIdentityProviderIntentRequest_Urls{ Urls: &user.RedirectURLs{ SuccessUrl: "https://example.com/success", @@ -1912,13 +1907,13 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { want: want{ details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), }, url: "https://example.com/oauth/v2/authorize", parametersEqual: map[string]string{ "client_id": "clientID", "prompt": "select_account", - "redirect_uri": "http://" + Tester.Config.ExternalDomain + ":8080/idps/callback", + "redirect_uri": "http://" + Instance.Domain + ":8080/idps/callback", "response_type": "code", "scope": "openid profile email", }, @@ -1931,7 +1926,7 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { args: args{ CTX, &user.StartIdentityProviderIntentRequest{ - IdpId: orgIdpID, + IdpId: orgIdpResp.Id, Content: &user.StartIdentityProviderIntentRequest_Urls{ Urls: &user.RedirectURLs{ SuccessUrl: "https://example.com/success", @@ -1943,13 +1938,13 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { want: want{ details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), }, url: "https://example.com/oauth/v2/authorize", parametersEqual: map[string]string{ "client_id": "clientID", "prompt": "select_account", - "redirect_uri": "http://" + Tester.Config.ExternalDomain + ":8080/idps/callback", + "redirect_uri": "http://" + Instance.Domain + ":8080/idps/callback", "response_type": "code", "scope": "openid profile email", }, @@ -1974,9 +1969,9 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { want: want{ details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), }, - url: "http://" + Tester.Config.ExternalDomain + ":8000/sso", + url: "http://" + Instance.Domain + ":8000/sso", parametersExisting: []string{"RelayState", "SAMLRequest"}, }, wantErr: false, @@ -1998,9 +1993,9 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { want: want{ details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), }, - url: "http://" + Tester.Config.ExternalDomain + ":8000/sso", + url: "http://" + Instance.Domain + ":8000/sso", parametersExisting: []string{"RelayState", "SAMLRequest"}, }, wantErr: false, @@ -2022,7 +2017,7 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { want: want{ details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), }, postForm: true, }, @@ -2061,14 +2056,15 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { } } +/* func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { - idpID := Tester.AddGenericOAuthProvider(t, CTX) - intentID := Tester.CreateIntent(t, CTX, idpID) - successfulID, token, changeDate, sequence := Tester.CreateSuccessfulOAuthIntent(t, CTX, idpID, "", "id") - successfulWithUserID, withUsertoken, withUserchangeDate, withUsersequence := Tester.CreateSuccessfulOAuthIntent(t, CTX, idpID, "user", "id") - ldapSuccessfulID, ldapToken, ldapChangeDate, ldapSequence := Tester.CreateSuccessfulLDAPIntent(t, CTX, idpID, "", "id") - ldapSuccessfulWithUserID, ldapWithUserToken, ldapWithUserChangeDate, ldapWithUserSequence := Tester.CreateSuccessfulLDAPIntent(t, CTX, idpID, "user", "id") - samlSuccessfulID, samlToken, samlChangeDate, samlSequence := Tester.CreateSuccessfulSAMLIntent(t, CTX, idpID, "", "id") + idpID := Instance.AddGenericOAuthProvider(t, CTX) + intentID := Instance.CreateIntent(t, CTX, idpID) + successfulID, token, changeDate, sequence := Instance.CreateSuccessfulOAuthIntent(t, CTX, idpID, "", "id") + successfulWithUserID, withUsertoken, withUserchangeDate, withUsersequence := Instance.CreateSuccessfulOAuthIntent(t, CTX, idpID, "user", "id") + ldapSuccessfulID, ldapToken, ldapChangeDate, ldapSequence := Instance.CreateSuccessfulLDAPIntent(t, CTX, idpID, "", "id") + ldapSuccessfulWithUserID, ldapWithUserToken, ldapWithUserChangeDate, ldapWithUserSequence := Instance.CreateSuccessfulLDAPIntent(t, CTX, idpID, "user", "id") + samlSuccessfulID, samlToken, samlChangeDate, samlSequence := Instance.CreateSuccessfulSAMLIntent(t, CTX, idpID, "", "id") type args struct { ctx context.Context req *user.RetrieveIdentityProviderIntentRequest @@ -2113,7 +2109,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { want: &user.RetrieveIdentityProviderIntentResponse{ Details: &object.Details{ ChangeDate: timestamppb.New(changeDate), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), Sequence: sequence, }, IdpInformation: &user.IDPInformation{ @@ -2150,7 +2146,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { want: &user.RetrieveIdentityProviderIntentResponse{ Details: &object.Details{ ChangeDate: timestamppb.New(withUserchangeDate), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), Sequence: withUsersequence, }, UserId: "user", @@ -2188,7 +2184,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { want: &user.RetrieveIdentityProviderIntentResponse{ Details: &object.Details{ ChangeDate: timestamppb.New(ldapChangeDate), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), Sequence: ldapSequence, }, IdpInformation: &user.IDPInformation{ @@ -2233,7 +2229,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { want: &user.RetrieveIdentityProviderIntentResponse{ Details: &object.Details{ ChangeDate: timestamppb.New(ldapWithUserChangeDate), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), Sequence: ldapWithUserSequence, }, UserId: "user", @@ -2279,7 +2275,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { want: &user.RetrieveIdentityProviderIntentResponse{ Details: &object.Details{ ChangeDate: timestamppb.New(samlChangeDate), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), Sequence: samlSequence, }, IdpInformation: &user.IDPInformation{ @@ -2319,40 +2315,41 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { }) } } +*/ func TestServer_ListAuthenticationMethodTypes(t *testing.T) { - userIDWithoutAuth := Tester.CreateHumanUser(CTX).GetUserId() + userIDWithoutAuth := Instance.CreateHumanUser(CTX).GetUserId() - userIDWithPasskey := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userIDWithPasskey) + userIDWithPasskey := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userIDWithPasskey) - userMultipleAuth := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userMultipleAuth) - provider, err := Tester.Client.Mgmt.AddGenericOIDCProvider(CTX, &mgmt.AddGenericOIDCProviderRequest{ + userMultipleAuth := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userMultipleAuth) + provider, err := Instance.Client.Mgmt.AddGenericOIDCProvider(CTX, &mgmt.AddGenericOIDCProviderRequest{ Name: "ListAuthenticationMethodTypes", Issuer: "https://example.com", ClientId: "client_id", ClientSecret: "client_secret", }) require.NoError(t, err) - _, err = Tester.Client.Mgmt.AddCustomLoginPolicy(CTX, &mgmt.AddCustomLoginPolicyRequest{}) + _, err = Instance.Client.Mgmt.AddCustomLoginPolicy(CTX, &mgmt.AddCustomLoginPolicyRequest{}) require.Condition(t, func() bool { code := status.Convert(err).Code() return code == codes.AlreadyExists || code == codes.OK }) - _, err = Tester.Client.Mgmt.AddIDPToLoginPolicy(CTX, &mgmt.AddIDPToLoginPolicyRequest{ + _, err = Instance.Client.Mgmt.AddIDPToLoginPolicy(CTX, &mgmt.AddIDPToLoginPolicyRequest{ IdpId: provider.GetId(), OwnerType: idp.IDPOwnerType_IDP_OWNER_TYPE_ORG, }) require.NoError(t, err) - idpLink, err := Tester.Client.UserV2.AddIDPLink(CTX, &user.AddIDPLinkRequest{UserId: userMultipleAuth, IdpLink: &user.IDPLink{ + idpLink, err := Instance.Client.UserV2.AddIDPLink(CTX, &user.AddIDPLinkRequest{UserId: userMultipleAuth, IdpLink: &user.IDPLink{ IdpId: provider.GetId(), UserId: "external-id", UserName: "displayName", }}) require.NoError(t, err) // This should not remove the user IDP links - _, err = Tester.Client.Mgmt.RemoveIDPFromLoginPolicy(CTX, &mgmt.RemoveIDPFromLoginPolicyRequest{ + _, err = Instance.Client.Mgmt.RemoveIDPFromLoginPolicy(CTX, &mgmt.RemoveIDPFromLoginPolicyRequest{ IdpId: provider.GetId(), }) require.NoError(t, err) diff --git a/internal/api/grpc/user/v2beta/email_integration_test.go b/internal/api/grpc/user/v2beta/integration_test/email_test.go similarity index 90% rename from internal/api/grpc/user/v2beta/email_integration_test.go rename to internal/api/grpc/user/v2beta/integration_test/email_test.go index 4034a5e7da..71d411fdbb 100644 --- a/internal/api/grpc/user/v2beta/email_integration_test.go +++ b/internal/api/grpc/user/v2beta/integration_test/email_test.go @@ -18,7 +18,7 @@ import ( ) func TestServer_SetEmail(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() tests := []struct { name string @@ -44,7 +44,7 @@ func TestServer_SetEmail(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -63,7 +63,7 @@ func TestServer_SetEmail(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -93,7 +93,7 @@ func TestServer_SetEmail(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, VerificationCode: gu.Ptr("xxx"), }, @@ -111,7 +111,7 @@ func TestServer_SetEmail(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -144,8 +144,8 @@ func TestServer_SetEmail(t *testing.T) { } func TestServer_ResendEmailCode(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - verifiedUserID := Tester.CreateHumanUserVerified(CTX, Tester.Organisation.ID, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() + verifiedUserID := Instance.CreateHumanUserVerified(CTX, Instance.DefaultOrg.Id, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId() tests := []struct { name string @@ -176,7 +176,7 @@ func TestServer_ResendEmailCode(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -194,7 +194,7 @@ func TestServer_ResendEmailCode(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -222,7 +222,7 @@ func TestServer_ResendEmailCode(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, VerificationCode: gu.Ptr("xxx"), }, @@ -245,7 +245,7 @@ func TestServer_ResendEmailCode(t *testing.T) { } func TestServer_VerifyEmail(t *testing.T) { - userResp := Tester.CreateHumanUser(CTX) + userResp := Instance.CreateHumanUser(CTX) tests := []struct { name string req *user.VerifyEmailRequest @@ -278,7 +278,7 @@ func TestServer_VerifyEmail(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, diff --git a/internal/api/grpc/user/v2beta/otp_integration_test.go b/internal/api/grpc/user/v2beta/integration_test/otp_test.go similarity index 66% rename from internal/api/grpc/user/v2beta/otp_integration_test.go rename to internal/api/grpc/user/v2beta/integration_test/otp_test.go index a6d671c645..6d6e2eff3e 100644 --- a/internal/api/grpc/user/v2beta/otp_integration_test.go +++ b/internal/api/grpc/user/v2beta/integration_test/otp_test.go @@ -15,24 +15,24 @@ import ( ) func TestServer_AddOTPSMS(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) + userID := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) - otherUser := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, otherUser) - _, sessionTokenOtherUser, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, otherUser) + otherUser := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, otherUser) + _, sessionTokenOtherUser, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, otherUser) - userVerified := Tester.CreateHumanUser(CTX) + userVerified := Instance.CreateHumanUser(CTX) _, err := Client.VerifyPhone(CTX, &user.VerifyPhoneRequest{ UserId: userVerified.GetUserId(), VerificationCode: userVerified.GetPhoneCode(), }) require.NoError(t, err) - Tester.RegisterUserPasskey(CTX, userVerified.GetUserId()) - _, sessionTokenVerified, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) + Instance.RegisterUserPasskey(CTX, userVerified.GetUserId()) + _, sessionTokenVerified, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) - userVerified2 := Tester.CreateHumanUser(CTX) + userVerified2 := Instance.CreateHumanUser(CTX) _, err = Client.VerifyPhone(CTX, &user.VerifyPhoneRequest{ UserId: userVerified2.GetUserId(), VerificationCode: userVerified2.GetPhoneCode(), @@ -60,7 +60,7 @@ func TestServer_AddOTPSMS(t *testing.T) { { name: "user mismatch", args: args{ - ctx: Tester.WithAuthorizationToken(context.Background(), sessionTokenOtherUser), + ctx: integration.WithAuthorizationToken(context.Background(), sessionTokenOtherUser), req: &user.AddOTPSMSRequest{ UserId: userID, }, @@ -70,7 +70,7 @@ func TestServer_AddOTPSMS(t *testing.T) { { name: "phone not verified", args: args{ - ctx: Tester.WithAuthorizationToken(context.Background(), sessionToken), + ctx: integration.WithAuthorizationToken(context.Background(), sessionToken), req: &user.AddOTPSMSRequest{ UserId: userID, }, @@ -80,14 +80,14 @@ func TestServer_AddOTPSMS(t *testing.T) { { name: "add success", args: args{ - ctx: Tester.WithAuthorizationToken(context.Background(), sessionTokenVerified), + ctx: integration.WithAuthorizationToken(context.Background(), sessionTokenVerified), req: &user.AddOTPSMSRequest{ UserId: userVerified.GetUserId(), }, }, want: &user.AddOTPSMSResponse{ Details: &object.Details{ - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -101,7 +101,7 @@ func TestServer_AddOTPSMS(t *testing.T) { }, want: &user.AddOTPSMSResponse{ Details: &object.Details{ - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -121,14 +121,14 @@ func TestServer_AddOTPSMS(t *testing.T) { } func TestServer_RemoveOTPSMS(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) + userID := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) - userVerified := Tester.CreateHumanUser(CTX) - Tester.RegisterUserPasskey(CTX, userVerified.GetUserId()) - _, sessionTokenVerified, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) - userVerifiedCtx := Tester.WithAuthorizationToken(context.Background(), sessionTokenVerified) + userVerified := Instance.CreateHumanUser(CTX) + Instance.RegisterUserPasskey(CTX, userVerified.GetUserId()) + _, sessionTokenVerified, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) + userVerifiedCtx := integration.WithAuthorizationToken(context.Background(), sessionTokenVerified) _, err := Client.VerifyPhone(userVerifiedCtx, &user.VerifyPhoneRequest{ UserId: userVerified.GetUserId(), VerificationCode: userVerified.GetPhoneCode(), @@ -150,7 +150,7 @@ func TestServer_RemoveOTPSMS(t *testing.T) { { name: "not added", args: args{ - ctx: Tester.WithAuthorizationToken(context.Background(), sessionToken), + ctx: integration.WithAuthorizationToken(context.Background(), sessionToken), req: &user.RemoveOTPSMSRequest{ UserId: userID, }, @@ -167,7 +167,7 @@ func TestServer_RemoveOTPSMS(t *testing.T) { }, want: &user.RemoveOTPSMSResponse{ Details: &object.Details{ - ResourceOwner: Tester.Organisation.ResourceOwner, + ResourceOwner: Instance.DefaultOrg.Details.ResourceOwner, }, }, }, @@ -187,24 +187,24 @@ func TestServer_RemoveOTPSMS(t *testing.T) { } func TestServer_AddOTPEmail(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) + userID := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) - otherUser := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, otherUser) - _, sessionTokenOtherUser, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, otherUser) + otherUser := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, otherUser) + _, sessionTokenOtherUser, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, otherUser) - userVerified := Tester.CreateHumanUser(CTX) + userVerified := Instance.CreateHumanUser(CTX) _, err := Client.VerifyEmail(CTX, &user.VerifyEmailRequest{ UserId: userVerified.GetUserId(), VerificationCode: userVerified.GetEmailCode(), }) require.NoError(t, err) - Tester.RegisterUserPasskey(CTX, userVerified.GetUserId()) - _, sessionTokenVerified, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) + Instance.RegisterUserPasskey(CTX, userVerified.GetUserId()) + _, sessionTokenVerified, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) - userVerified2 := Tester.CreateHumanUser(CTX) + userVerified2 := Instance.CreateHumanUser(CTX) _, err = Client.VerifyEmail(CTX, &user.VerifyEmailRequest{ UserId: userVerified2.GetUserId(), VerificationCode: userVerified2.GetEmailCode(), @@ -232,7 +232,7 @@ func TestServer_AddOTPEmail(t *testing.T) { { name: "user mismatch", args: args{ - ctx: Tester.WithAuthorizationToken(context.Background(), sessionTokenOtherUser), + ctx: integration.WithAuthorizationToken(context.Background(), sessionTokenOtherUser), req: &user.AddOTPEmailRequest{ UserId: userID, }, @@ -242,7 +242,7 @@ func TestServer_AddOTPEmail(t *testing.T) { { name: "email not verified", args: args{ - ctx: Tester.WithAuthorizationToken(context.Background(), sessionToken), + ctx: integration.WithAuthorizationToken(context.Background(), sessionToken), req: &user.AddOTPEmailRequest{ UserId: userID, }, @@ -252,7 +252,7 @@ func TestServer_AddOTPEmail(t *testing.T) { { name: "add success", args: args{ - ctx: Tester.WithAuthorizationToken(context.Background(), sessionTokenVerified), + ctx: integration.WithAuthorizationToken(context.Background(), sessionTokenVerified), req: &user.AddOTPEmailRequest{ UserId: userVerified.GetUserId(), }, @@ -260,7 +260,7 @@ func TestServer_AddOTPEmail(t *testing.T) { want: &user.AddOTPEmailResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -275,7 +275,7 @@ func TestServer_AddOTPEmail(t *testing.T) { want: &user.AddOTPEmailResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -295,14 +295,14 @@ func TestServer_AddOTPEmail(t *testing.T) { } func TestServer_RemoveOTPEmail(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) + userID := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) - userVerified := Tester.CreateHumanUser(CTX) - Tester.RegisterUserPasskey(CTX, userVerified.GetUserId()) - _, sessionTokenVerified, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) - userVerifiedCtx := Tester.WithAuthorizationToken(context.Background(), sessionTokenVerified) + userVerified := Instance.CreateHumanUser(CTX) + Instance.RegisterUserPasskey(CTX, userVerified.GetUserId()) + _, sessionTokenVerified, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) + userVerifiedCtx := integration.WithAuthorizationToken(context.Background(), sessionTokenVerified) _, err := Client.VerifyEmail(userVerifiedCtx, &user.VerifyEmailRequest{ UserId: userVerified.GetUserId(), VerificationCode: userVerified.GetEmailCode(), @@ -324,7 +324,7 @@ func TestServer_RemoveOTPEmail(t *testing.T) { { name: "not added", args: args{ - ctx: Tester.WithAuthorizationToken(context.Background(), sessionToken), + ctx: integration.WithAuthorizationToken(context.Background(), sessionToken), req: &user.RemoveOTPEmailRequest{ UserId: userID, }, @@ -342,7 +342,7 @@ func TestServer_RemoveOTPEmail(t *testing.T) { want: &user.RemoveOTPEmailResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ResourceOwner, + ResourceOwner: Instance.DefaultOrg.Details.ResourceOwner, }, }, }, diff --git a/internal/api/grpc/user/v2beta/passkey_integration_test.go b/internal/api/grpc/user/v2beta/integration_test/passkey_test.go similarity index 89% rename from internal/api/grpc/user/v2beta/passkey_integration_test.go rename to internal/api/grpc/user/v2beta/integration_test/passkey_test.go index 230a744a64..acca01885c 100644 --- a/internal/api/grpc/user/v2beta/passkey_integration_test.go +++ b/internal/api/grpc/user/v2beta/integration_test/passkey_test.go @@ -18,7 +18,7 @@ import ( ) func TestServer_RegisterPasskey(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() reg, err := Client.CreatePasskeyRegistrationLink(CTX, &user.CreatePasskeyRegistrationLinkRequest{ UserId: userID, Medium: &user.CreatePasskeyRegistrationLinkRequest_ReturnCode{}, @@ -26,8 +26,8 @@ func TestServer_RegisterPasskey(t *testing.T) { require.NoError(t, err) // We also need a user session - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) type args struct { ctx context.Context @@ -60,7 +60,7 @@ func TestServer_RegisterPasskey(t *testing.T) { want: &user.RegisterPasskeyResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -104,7 +104,7 @@ func TestServer_RegisterPasskey(t *testing.T) { { name: "user setting its own passkey", args: args{ - ctx: Tester.WithAuthorizationToken(CTX, sessionToken), + ctx: integration.WithAuthorizationToken(CTX, sessionToken), req: &user.RegisterPasskeyRequest{ UserId: userID, }, @@ -112,7 +112,7 @@ func TestServer_RegisterPasskey(t *testing.T) { want: &user.RegisterPasskeyResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -130,7 +130,7 @@ func TestServer_RegisterPasskey(t *testing.T) { if tt.want != nil { assert.NotEmpty(t, got.GetPasskeyId()) assert.NotEmpty(t, got.GetPublicKeyCredentialCreationOptions()) - _, err = Tester.WebAuthN.CreateAttestationResponse(got.GetPublicKeyCredentialCreationOptions()) + _, err = Instance.WebAuthN.CreateAttestationResponse(got.GetPublicKeyCredentialCreationOptions()) require.NoError(t, err) } }) @@ -138,7 +138,7 @@ func TestServer_RegisterPasskey(t *testing.T) { } func TestServer_VerifyPasskeyRegistration(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() reg, err := Client.CreatePasskeyRegistrationLink(CTX, &user.CreatePasskeyRegistrationLinkRequest{ UserId: userID, Medium: &user.CreatePasskeyRegistrationLinkRequest_ReturnCode{}, @@ -152,7 +152,7 @@ func TestServer_VerifyPasskeyRegistration(t *testing.T) { require.NotEmpty(t, pkr.GetPasskeyId()) require.NotEmpty(t, pkr.GetPublicKeyCredentialCreationOptions()) - attestationResponse, err := Tester.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) + attestationResponse, err := Instance.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) require.NoError(t, err) type args struct { @@ -191,7 +191,7 @@ func TestServer_VerifyPasskeyRegistration(t *testing.T) { want: &user.VerifyPasskeyRegistrationResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -226,7 +226,7 @@ func TestServer_VerifyPasskeyRegistration(t *testing.T) { } func TestServer_CreatePasskeyRegistrationLink(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() type args struct { ctx context.Context @@ -258,7 +258,7 @@ func TestServer_CreatePasskeyRegistrationLink(t *testing.T) { want: &user.CreatePasskeyRegistrationLinkResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -278,7 +278,7 @@ func TestServer_CreatePasskeyRegistrationLink(t *testing.T) { want: &user.CreatePasskeyRegistrationLinkResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -294,7 +294,7 @@ func TestServer_CreatePasskeyRegistrationLink(t *testing.T) { want: &user.CreatePasskeyRegistrationLinkResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, wantCode: true, diff --git a/internal/api/grpc/user/v2beta/password_integration_test.go b/internal/api/grpc/user/v2beta/integration_test/password_test.go similarity index 91% rename from internal/api/grpc/user/v2beta/password_integration_test.go rename to internal/api/grpc/user/v2beta/integration_test/password_test.go index 03b18a5fa7..7dd71edbba 100644 --- a/internal/api/grpc/user/v2beta/password_integration_test.go +++ b/internal/api/grpc/user/v2beta/integration_test/password_test.go @@ -17,7 +17,7 @@ import ( ) func TestServer_RequestPasswordReset(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() tests := []struct { name string @@ -34,7 +34,7 @@ func TestServer_RequestPasswordReset(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -53,7 +53,7 @@ func TestServer_RequestPasswordReset(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -81,7 +81,7 @@ func TestServer_RequestPasswordReset(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, VerificationCode: gu.Ptr("xxx"), }, @@ -129,7 +129,7 @@ func TestServer_SetPassword(t *testing.T) { { name: "set successful", prepare: func(request *user.SetPasswordRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID return nil }, @@ -144,14 +144,14 @@ func TestServer_SetPassword(t *testing.T) { want: &user.SetPasswordResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, { name: "change successful", prepare: func(request *user.SetPasswordRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID _, err := Client.SetPassword(CTX, &user.SetPasswordRequest{ UserId: userID, @@ -175,14 +175,14 @@ func TestServer_SetPassword(t *testing.T) { want: &user.SetPasswordResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, { name: "set with code successful", prepare: func(request *user.SetPasswordRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID resp, err := Client.PasswordReset(CTX, &user.PasswordResetRequest{ UserId: userID, @@ -209,7 +209,7 @@ func TestServer_SetPassword(t *testing.T) { want: &user.SetPasswordResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, diff --git a/internal/api/grpc/user/v2beta/phone_integration_test.go b/internal/api/grpc/user/v2beta/integration_test/phone_test.go similarity index 87% rename from internal/api/grpc/user/v2beta/phone_integration_test.go rename to internal/api/grpc/user/v2beta/integration_test/phone_test.go index 692f7af5f7..baa7b0f895 100644 --- a/internal/api/grpc/user/v2beta/phone_integration_test.go +++ b/internal/api/grpc/user/v2beta/integration_test/phone_test.go @@ -19,7 +19,7 @@ import ( ) func TestServer_SetPhone(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() tests := []struct { name string @@ -37,7 +37,7 @@ func TestServer_SetPhone(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -54,7 +54,7 @@ func TestServer_SetPhone(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -71,7 +71,7 @@ func TestServer_SetPhone(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, VerificationCode: gu.Ptr("xxx"), }, @@ -89,7 +89,7 @@ func TestServer_SetPhone(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -122,8 +122,8 @@ func TestServer_SetPhone(t *testing.T) { } func TestServer_ResendPhoneCode(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - verifiedUserID := Tester.CreateHumanUserVerified(CTX, Tester.Organisation.ID, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() + verifiedUserID := Instance.CreateHumanUserVerified(CTX, Instance.DefaultOrg.Id, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId() tests := []struct { name string @@ -157,7 +157,7 @@ func TestServer_ResendPhoneCode(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -173,7 +173,7 @@ func TestServer_ResendPhoneCode(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, VerificationCode: gu.Ptr("xxx"), }, @@ -196,7 +196,7 @@ func TestServer_ResendPhoneCode(t *testing.T) { } func TestServer_VerifyPhone(t *testing.T) { - userResp := Tester.CreateHumanUser(CTX) + userResp := Instance.CreateHumanUser(CTX) tests := []struct { name string req *user.VerifyPhoneRequest @@ -229,7 +229,7 @@ func TestServer_VerifyPhone(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -248,13 +248,13 @@ func TestServer_VerifyPhone(t *testing.T) { } func TestServer_RemovePhone(t *testing.T) { - userResp := Tester.CreateHumanUser(CTX) - failResp := Tester.CreateHumanUserNoPhone(CTX) - otherUser := Tester.CreateHumanUser(CTX).GetUserId() - doubleRemoveUser := Tester.CreateHumanUser(CTX) + userResp := Instance.CreateHumanUser(CTX) + failResp := Instance.CreateHumanUserNoPhone(CTX) + otherUser := Instance.CreateHumanUser(CTX).GetUserId() + doubleRemoveUser := Instance.CreateHumanUser(CTX) - Tester.RegisterUserPasskey(CTX, otherUser) - _, sessionTokenOtherUser, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, otherUser) + Instance.RegisterUserPasskey(CTX, otherUser) + _, sessionTokenOtherUser, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, otherUser) tests := []struct { name string @@ -274,7 +274,7 @@ func TestServer_RemovePhone(t *testing.T) { Details: &object.Details{ Sequence: 1, ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, dep: func(ctx context.Context, userID string) (*user.RemovePhoneResponse, error) { @@ -316,7 +316,7 @@ func TestServer_RemovePhone(t *testing.T) { }, { name: "other user, no permission", - ctx: Tester.WithAuthorizationToken(CTX, sessionTokenOtherUser), + ctx: integration.WithAuthorizationToken(CTX, sessionTokenOtherUser), req: &user.RemovePhoneRequest{ UserId: userResp.GetUserId(), }, diff --git a/internal/api/grpc/user/v2beta/query_integration_test.go b/internal/api/grpc/user/v2beta/integration_test/query_test.go similarity index 94% rename from internal/api/grpc/user/v2beta/query_integration_test.go rename to internal/api/grpc/user/v2beta/integration_test/query_test.go index 1b375e4091..f78a54d049 100644 --- a/internal/api/grpc/user/v2beta/query_integration_test.go +++ b/internal/api/grpc/user/v2beta/integration_test/query_test.go @@ -28,7 +28,7 @@ func detailsV2ToV2beta(obj *object.Details) *object_v2beta.Details { } func TestServer_GetUserByID(t *testing.T) { - orgResp := Tester.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) + orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) type args struct { ctx context.Context req *user.GetUserByIDRequest @@ -72,7 +72,7 @@ func TestServer_GetUserByID(t *testing.T) { IamCTX, &user.GetUserByIDRequest{}, func(ctx context.Context, username string, request *user.GetUserByIDRequest) (*userAttr, error) { - resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) + resp := Instance.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) request.UserId = resp.GetUserId() return &userAttr{resp.GetUserId(), username, nil, resp.GetDetails()}, nil }, @@ -116,9 +116,9 @@ func TestServer_GetUserByID(t *testing.T) { IamCTX, &user.GetUserByIDRequest{}, func(ctx context.Context, username string, request *user.GetUserByIDRequest) (*userAttr, error) { - resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) + resp := Instance.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) request.UserId = resp.GetUserId() - details := Tester.SetUserPassword(ctx, resp.GetUserId(), integration.UserPassword, true) + details := Instance.SetUserPassword(ctx, resp.GetUserId(), integration.UserPassword, true) return &userAttr{resp.GetUserId(), username, details.GetChangeDate(), resp.GetDetails()}, nil }, }, @@ -198,7 +198,7 @@ func TestServer_GetUserByID(t *testing.T) { func TestServer_GetUserByID_Permission(t *testing.T) { timeNow := time.Now().UTC() newOrgOwnerEmail := fmt.Sprintf("%d@permission.get.com", timeNow.UnixNano()) - newOrg := Tester.CreateOrganization(IamCTX, fmt.Sprintf("GetHuman%d", time.Now().UnixNano()), newOrgOwnerEmail) + newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetHuman%d", time.Now().UnixNano()), newOrgOwnerEmail) newUserID := newOrg.CreatedAdmins[0].GetUserId() type args struct { ctx context.Context @@ -338,8 +338,8 @@ type userAttr struct { } func TestServer_ListUsers(t *testing.T) { - orgResp := Tester.CreateOrganization(IamCTX, fmt.Sprintf("ListUsersOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) - userResp := Tester.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listusers.com", time.Now().UnixNano())) + orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListUsersOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) + userResp := Instance.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listusers.com", time.Now().UnixNano())) type args struct { ctx context.Context count int @@ -386,7 +386,7 @@ func TestServer_ListUsers(t *testing.T) { infos := make([]userAttr, len(usernames)) userIDs := make([]string, len(usernames)) for i, username := range usernames { - resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) + resp := Instance.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) userIDs[i] = resp.GetUserId() infos[i] = userAttr{resp.GetUserId(), username, nil, resp.GetDetails()} } @@ -440,9 +440,9 @@ func TestServer_ListUsers(t *testing.T) { infos := make([]userAttr, len(usernames)) userIDs := make([]string, len(usernames)) for i, username := range usernames { - resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) + resp := Instance.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) userIDs[i] = resp.GetUserId() - details := Tester.SetUserPassword(ctx, resp.GetUserId(), integration.UserPassword, true) + details := Instance.SetUserPassword(ctx, resp.GetUserId(), integration.UserPassword, true) infos[i] = userAttr{resp.GetUserId(), username, details.GetChangeDate(), resp.GetDetails()} } request.Queries = append(request.Queries, InUserIDsQuery(userIDs)) @@ -497,7 +497,7 @@ func TestServer_ListUsers(t *testing.T) { infos := make([]userAttr, len(usernames)) userIDs := make([]string, len(usernames)) for i, username := range usernames { - resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) + resp := Instance.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) userIDs[i] = resp.GetUserId() infos[i] = userAttr{resp.GetUserId(), username, nil, resp.GetDetails()} } @@ -593,7 +593,7 @@ func TestServer_ListUsers(t *testing.T) { infos := make([]userAttr, len(usernames)) userIDs := make([]string, len(usernames)) for i, username := range usernames { - resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) + resp := Instance.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) userIDs[i] = resp.GetUserId() infos[i] = userAttr{resp.GetUserId(), username, nil, resp.GetDetails()} request.Queries = append(request.Queries, UsernameQuery(username)) @@ -646,7 +646,7 @@ func TestServer_ListUsers(t *testing.T) { func(ctx context.Context, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) { infos := make([]userAttr, len(usernames)) for i, username := range usernames { - resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) + resp := Instance.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) infos[i] = userAttr{resp.GetUserId(), username, nil, resp.GetDetails()} } request.Queries = append(request.Queries, InUserEmailsQuery(usernames)) @@ -698,7 +698,7 @@ func TestServer_ListUsers(t *testing.T) { func(ctx context.Context, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) { infos := make([]userAttr, len(usernames)) for i, username := range usernames { - resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) + resp := Instance.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) infos[i] = userAttr{resp.GetUserId(), username, nil, resp.GetDetails()} } request.Queries = append(request.Queries, InUserEmailsQuery(usernames)) @@ -809,11 +809,11 @@ func TestServer_ListUsers(t *testing.T) { 3, &user.ListUsersRequest{}, func(ctx context.Context, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) { - orgResp := Tester.CreateOrganization(ctx, fmt.Sprintf("ListUsersResourceowner%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) + orgResp := Instance.CreateOrganization(ctx, fmt.Sprintf("ListUsersResourceowner%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) infos := make([]userAttr, len(usernames)) for i, username := range usernames { - resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) + resp := Instance.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) infos[i] = userAttr{resp.GetUserId(), username, nil, resp.GetDetails()} } request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId)) diff --git a/internal/api/grpc/user/v2beta/totp_integration_test.go b/internal/api/grpc/user/v2beta/integration_test/totp_test.go similarity index 70% rename from internal/api/grpc/user/v2beta/totp_integration_test.go rename to internal/api/grpc/user/v2beta/integration_test/totp_test.go index 47b2952afd..4afe5e1f31 100644 --- a/internal/api/grpc/user/v2beta/totp_integration_test.go +++ b/internal/api/grpc/user/v2beta/integration_test/totp_test.go @@ -18,15 +18,15 @@ import ( ) func TestServer_RegisterTOTP(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) - ctx := Tester.WithAuthorizationToken(CTX, sessionToken) + userID := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) + ctx := integration.WithAuthorizationToken(CTX, sessionToken) - otherUser := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, otherUser) - _, sessionTokenOtherUser, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, otherUser) - ctxOtherUser := Tester.WithAuthorizationToken(CTX, sessionTokenOtherUser) + otherUser := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, otherUser) + _, sessionTokenOtherUser, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, otherUser) + ctxOtherUser := integration.WithAuthorizationToken(CTX, sessionTokenOtherUser) type args struct { ctx context.Context @@ -67,7 +67,7 @@ func TestServer_RegisterTOTP(t *testing.T) { want: &user.RegisterTOTPResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -82,7 +82,7 @@ func TestServer_RegisterTOTP(t *testing.T) { want: &user.RegisterTOTPResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -104,22 +104,27 @@ func TestServer_RegisterTOTP(t *testing.T) { } func TestServer_VerifyTOTPRegistration(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) - ctx := Tester.WithAuthorizationToken(CTX, sessionToken) + userID := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) + ctx := integration.WithAuthorizationToken(CTX, sessionToken) + + var reg *user.RegisterTOTPResponse + assert.EventuallyWithT(t, func(ct *assert.CollectT) { + var err error + reg, err = Client.RegisterTOTP(ctx, &user.RegisterTOTPRequest{ + UserId: userID, + }) + assert.NoError(ct, err) + }, time.Minute, time.Second/10) - reg, err := Client.RegisterTOTP(ctx, &user.RegisterTOTPRequest{ - UserId: userID, - }) - require.NoError(t, err) code, err := totp.GenerateCode(reg.Secret, time.Now()) require.NoError(t, err) - otherUser := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, otherUser) - _, sessionTokenOtherUser, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, otherUser) - ctxOtherUser := Tester.WithAuthorizationToken(CTX, sessionTokenOtherUser) + otherUser := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, otherUser) + _, sessionTokenOtherUser, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, otherUser) + ctxOtherUser := integration.WithAuthorizationToken(CTX, sessionTokenOtherUser) regOtherUser, err := Client.RegisterTOTP(CTX, &user.RegisterTOTPRequest{ UserId: otherUser, @@ -171,7 +176,7 @@ func TestServer_VerifyTOTPRegistration(t *testing.T) { want: &user.VerifyTOTPRegistrationResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ResourceOwner, + ResourceOwner: Instance.DefaultOrg.Details.ResourceOwner, }, }, }, @@ -187,7 +192,7 @@ func TestServer_VerifyTOTPRegistration(t *testing.T) { want: &user.VerifyTOTPRegistrationResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ResourceOwner, + ResourceOwner: Instance.DefaultOrg.Details.ResourceOwner, }, }, }, @@ -207,14 +212,14 @@ func TestServer_VerifyTOTPRegistration(t *testing.T) { } func TestServer_RemoveTOTP(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) + userID := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) - userVerified := Tester.CreateHumanUser(CTX) - Tester.RegisterUserPasskey(CTX, userVerified.GetUserId()) - _, sessionTokenVerified, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) - userVerifiedCtx := Tester.WithAuthorizationToken(context.Background(), sessionTokenVerified) + userVerified := Instance.CreateHumanUser(CTX) + Instance.RegisterUserPasskey(CTX, userVerified.GetUserId()) + _, sessionTokenVerified, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userVerified.GetUserId()) + userVerifiedCtx := integration.WithAuthorizationToken(context.Background(), sessionTokenVerified) _, err := Client.VerifyPhone(userVerifiedCtx, &user.VerifyPhoneRequest{ UserId: userVerified.GetUserId(), VerificationCode: userVerified.GetPhoneCode(), @@ -247,7 +252,7 @@ func TestServer_RemoveTOTP(t *testing.T) { { name: "not added", args: args{ - ctx: Tester.WithAuthorizationToken(context.Background(), sessionToken), + ctx: integration.WithAuthorizationToken(context.Background(), sessionToken), req: &user.RemoveTOTPRequest{ UserId: userID, }, @@ -264,7 +269,7 @@ func TestServer_RemoveTOTP(t *testing.T) { }, want: &user.RemoveTOTPResponse{ Details: &object.Details{ - ResourceOwner: Tester.Organisation.ResourceOwner, + ResourceOwner: Instance.DefaultOrg.Details.ResourceOwner, }, }, }, diff --git a/internal/api/grpc/user/v2beta/u2f_integration_test.go b/internal/api/grpc/user/v2beta/integration_test/u2f_test.go similarity index 76% rename from internal/api/grpc/user/v2beta/u2f_integration_test.go rename to internal/api/grpc/user/v2beta/integration_test/u2f_test.go index 3b7fbd293c..6e47cbbb99 100644 --- a/internal/api/grpc/user/v2beta/u2f_integration_test.go +++ b/internal/api/grpc/user/v2beta/integration_test/u2f_test.go @@ -17,14 +17,14 @@ import ( ) func TestServer_RegisterU2F(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - otherUser := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() + otherUser := Instance.CreateHumanUser(CTX).GetUserId() // We also need a user session - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) - Tester.RegisterUserPasskey(CTX, otherUser) - _, sessionTokenOtherUser, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, otherUser) + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) + Instance.RegisterUserPasskey(CTX, otherUser) + _, sessionTokenOtherUser, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, otherUser) type args struct { ctx context.Context @@ -55,14 +55,14 @@ func TestServer_RegisterU2F(t *testing.T) { want: &user.RegisterU2FResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, { name: "other user, no permission", args: args{ - ctx: Tester.WithAuthorizationToken(CTX, sessionTokenOtherUser), + ctx: integration.WithAuthorizationToken(CTX, sessionTokenOtherUser), req: &user.RegisterU2FRequest{ UserId: userID, }, @@ -72,7 +72,7 @@ func TestServer_RegisterU2F(t *testing.T) { { name: "user setting its own passkey", args: args{ - ctx: Tester.WithAuthorizationToken(CTX, sessionToken), + ctx: integration.WithAuthorizationToken(CTX, sessionToken), req: &user.RegisterU2FRequest{ UserId: userID, }, @@ -80,7 +80,7 @@ func TestServer_RegisterU2F(t *testing.T) { want: &user.RegisterU2FResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -98,7 +98,7 @@ func TestServer_RegisterU2F(t *testing.T) { if tt.want != nil { assert.NotEmpty(t, got.GetU2FId()) assert.NotEmpty(t, got.GetPublicKeyCredentialCreationOptions()) - _, err = Tester.WebAuthN.CreateAttestationResponse(got.GetPublicKeyCredentialCreationOptions()) + _, err = Instance.WebAuthN.CreateAttestationResponse(got.GetPublicKeyCredentialCreationOptions()) require.NoError(t, err) } }) @@ -106,10 +106,10 @@ func TestServer_RegisterU2F(t *testing.T) { } func TestServer_VerifyU2FRegistration(t *testing.T) { - userID := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userID) - _, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTX, userID) - ctx := Tester.WithAuthorizationToken(CTX, sessionToken) + userID := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userID) + _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) + ctx := integration.WithAuthorizationToken(CTX, sessionToken) pkr, err := Client.RegisterU2F(ctx, &user.RegisterU2FRequest{ UserId: userID, @@ -117,7 +117,7 @@ func TestServer_VerifyU2FRegistration(t *testing.T) { require.NoError(t, err) require.NotEmpty(t, pkr.GetPublicKeyCredentialCreationOptions()) - attestationResponse, err := Tester.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) + attestationResponse, err := Instance.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) require.NoError(t, err) type args struct { @@ -155,7 +155,7 @@ func TestServer_VerifyU2FRegistration(t *testing.T) { want: &user.VerifyU2FRegistrationResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, diff --git a/internal/api/grpc/user/v2beta/user_integration_test.go b/internal/api/grpc/user/v2beta/integration_test/user_test.go similarity index 88% rename from internal/api/grpc/user/v2beta/user_integration_test.go rename to internal/api/grpc/user/v2beta/integration_test/user_test.go index d808e46c5f..bf93b67c93 100644 --- a/internal/api/grpc/user/v2beta/user_integration_test.go +++ b/internal/api/grpc/user/v2beta/integration_test/user_test.go @@ -15,10 +15,8 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" - "github.com/zitadel/zitadel/internal/api/grpc" "github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/pkg/grpc/idp" mgmt "github.com/zitadel/zitadel/pkg/grpc/management" @@ -31,30 +29,28 @@ var ( IamCTX context.Context UserCTX context.Context SystemCTX context.Context - ErrCTX context.Context - Tester *integration.Tester + Instance *integration.Instance Client user.UserServiceClient ) func TestMain(m *testing.M) { os.Exit(func() int { - ctx, errCtx, cancel := integration.Contexts(time.Hour) + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute) defer cancel() - Tester = integration.NewTester(ctx) - defer Tester.Done() + Instance = integration.NewInstance(ctx) - UserCTX = Tester.WithAuthorization(ctx, integration.Login) - IamCTX = Tester.WithAuthorization(ctx, integration.IAMOwner) - SystemCTX = Tester.WithAuthorization(ctx, integration.SystemUser) - CTX, ErrCTX = Tester.WithAuthorization(ctx, integration.OrgOwner), errCtx - Client = Tester.Client.UserV2beta + UserCTX = Instance.WithAuthorization(ctx, integration.UserTypeLogin) + IamCTX = Instance.WithAuthorization(ctx, integration.UserTypeIAMOwner) + SystemCTX = integration.WithSystemAuthorization(ctx) + CTX = Instance.WithAuthorization(ctx, integration.UserTypeOrgOwner) + Client = Instance.Client.UserV2beta return m.Run() }()) } func TestServer_AddHumanUser(t *testing.T) { - idpID := Tester.AddGenericOAuthProvider(t, CTX) + idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id) type args struct { ctx context.Context req *user.AddHumanUserRequest @@ -72,7 +68,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -102,7 +98,7 @@ func TestServer_AddHumanUser(t *testing.T) { want: &user.AddHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -113,7 +109,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -146,7 +142,7 @@ func TestServer_AddHumanUser(t *testing.T) { want: &user.AddHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, EmailCode: gu.Ptr("something"), }, @@ -158,7 +154,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -193,7 +189,7 @@ func TestServer_AddHumanUser(t *testing.T) { want: &user.AddHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -204,7 +200,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -239,7 +235,7 @@ func TestServer_AddHumanUser(t *testing.T) { want: &user.AddHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, PhoneCode: gu.Ptr("something"), }, @@ -251,7 +247,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -292,7 +288,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Email: &user.SetHumanEmail{ @@ -323,7 +319,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -357,7 +353,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -404,7 +400,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -435,7 +431,7 @@ func TestServer_AddHumanUser(t *testing.T) { }, IdpLinks: []*user.IDPLink{ { - IdpId: idpID, + IdpId: idpResp.Id, UserId: "userID", UserName: "username", }, @@ -445,7 +441,7 @@ func TestServer_AddHumanUser(t *testing.T) { want: &user.AddHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -456,7 +452,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -491,7 +487,7 @@ func TestServer_AddHumanUser(t *testing.T) { want: &user.AddHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -502,7 +498,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -536,7 +532,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -564,7 +560,7 @@ func TestServer_AddHumanUser(t *testing.T) { want: &user.AddHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -575,7 +571,7 @@ func TestServer_AddHumanUser(t *testing.T) { &user.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: Tester.Organisation.ID, + OrgId: Instance.DefaultOrg.Id, }, }, Profile: &user.SetHumanProfile{ @@ -636,7 +632,7 @@ func TestServer_AddHumanUser(t *testing.T) { func TestServer_AddHumanUser_Permission(t *testing.T) { newOrgOwnerEmail := fmt.Sprintf("%d@permission.com", time.Now().UnixNano()) - newOrg := Tester.CreateOrganization(IamCTX, fmt.Sprintf("AddHuman%d", time.Now().UnixNano()), newOrgOwnerEmail) + newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("AddHuman%d", time.Now().UnixNano()), newOrgOwnerEmail) type args struct { ctx context.Context req *user.AddHumanUserRequest @@ -856,7 +852,7 @@ func TestServer_UpdateHumanUser(t *testing.T) { { name: "change username, ok", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID return nil }, @@ -869,14 +865,14 @@ func TestServer_UpdateHumanUser(t *testing.T) { want: &user.UpdateHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, { name: "change profile, ok", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID return nil }, @@ -896,14 +892,14 @@ func TestServer_UpdateHumanUser(t *testing.T) { want: &user.UpdateHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, { name: "change email, ok", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID return nil }, @@ -919,14 +915,14 @@ func TestServer_UpdateHumanUser(t *testing.T) { want: &user.UpdateHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, { name: "change email, code, ok", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID return nil }, @@ -942,7 +938,7 @@ func TestServer_UpdateHumanUser(t *testing.T) { want: &user.UpdateHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, EmailCode: gu.Ptr("something"), }, @@ -950,7 +946,7 @@ func TestServer_UpdateHumanUser(t *testing.T) { { name: "change phone, ok", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID return nil }, @@ -966,14 +962,14 @@ func TestServer_UpdateHumanUser(t *testing.T) { want: &user.UpdateHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, { name: "change phone, code, ok", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID return nil }, @@ -989,7 +985,7 @@ func TestServer_UpdateHumanUser(t *testing.T) { want: &user.UpdateHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, PhoneCode: gu.Ptr("something"), }, @@ -997,7 +993,7 @@ func TestServer_UpdateHumanUser(t *testing.T) { { name: "change password, code, ok", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID resp, err := Client.PasswordReset(CTX, &user.PasswordResetRequest{ UserId: userID, @@ -1029,14 +1025,14 @@ func TestServer_UpdateHumanUser(t *testing.T) { want: &user.UpdateHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, { name: "change hashed password, code, ok", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID resp, err := Client.PasswordReset(CTX, &user.PasswordResetRequest{ UserId: userID, @@ -1067,14 +1063,14 @@ func TestServer_UpdateHumanUser(t *testing.T) { want: &user.UpdateHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, { name: "change hashed password, code, not supported", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID resp, err := Client.PasswordReset(CTX, &user.PasswordResetRequest{ UserId: userID, @@ -1109,7 +1105,7 @@ func TestServer_UpdateHumanUser(t *testing.T) { { name: "change password, old password, ok", prepare: func(request *user.UpdateHumanUserRequest) error { - userID := Tester.CreateHumanUser(CTX).GetUserId() + userID := Instance.CreateHumanUser(CTX).GetUserId() request.UserId = userID resp, err := Client.PasswordReset(CTX, &user.PasswordResetRequest{ @@ -1156,7 +1152,7 @@ func TestServer_UpdateHumanUser(t *testing.T) { want: &user.UpdateHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1185,7 +1181,7 @@ func TestServer_UpdateHumanUser(t *testing.T) { func TestServer_UpdateHumanUser_Permission(t *testing.T) { newOrgOwnerEmail := fmt.Sprintf("%d@permission.update.com", time.Now().UnixNano()) - newOrg := Tester.CreateOrganization(IamCTX, fmt.Sprintf("UpdateHuman%d", time.Now().UnixNano()), newOrgOwnerEmail) + newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("UpdateHuman%d", time.Now().UnixNano()), newOrgOwnerEmail) newUserID := newOrg.CreatedAdmins[0].GetUserId() type args struct { ctx context.Context @@ -1295,7 +1291,7 @@ func TestServer_LockUser(t *testing.T) { CTX, &user.LockUserRequest{}, func(request *user.LockUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() return nil }, @@ -1303,7 +1299,7 @@ func TestServer_LockUser(t *testing.T) { want: &user.LockUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1313,7 +1309,7 @@ func TestServer_LockUser(t *testing.T) { CTX, &user.LockUserRequest{}, func(request *user.LockUserRequest) error { - resp := Tester.CreateMachineUser(CTX) + resp := Instance.CreateMachineUser(CTX) request.UserId = resp.GetUserId() return nil }, @@ -1321,7 +1317,7 @@ func TestServer_LockUser(t *testing.T) { want: &user.LockUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1331,7 +1327,7 @@ func TestServer_LockUser(t *testing.T) { CTX, &user.LockUserRequest{}, func(request *user.LockUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() _, err := Client.LockUser(CTX, &user.LockUserRequest{ UserId: resp.GetUserId(), @@ -1347,7 +1343,7 @@ func TestServer_LockUser(t *testing.T) { CTX, &user.LockUserRequest{}, func(request *user.LockUserRequest) error { - resp := Tester.CreateMachineUser(CTX) + resp := Instance.CreateMachineUser(CTX) request.UserId = resp.GetUserId() _, err := Client.LockUser(CTX, &user.LockUserRequest{ UserId: resp.GetUserId(), @@ -1403,7 +1399,7 @@ func TestServer_UnLockUser(t *testing.T) { ctx: CTX, req: &user.UnlockUserRequest{}, prepare: func(request *user.UnlockUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() return nil }, @@ -1416,7 +1412,7 @@ func TestServer_UnLockUser(t *testing.T) { ctx: CTX, req: &user.UnlockUserRequest{}, prepare: func(request *user.UnlockUserRequest) error { - resp := Tester.CreateMachineUser(CTX) + resp := Instance.CreateMachineUser(CTX) request.UserId = resp.GetUserId() return nil }, @@ -1429,7 +1425,7 @@ func TestServer_UnLockUser(t *testing.T) { ctx: CTX, req: &user.UnlockUserRequest{}, prepare: func(request *user.UnlockUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() _, err := Client.LockUser(CTX, &user.LockUserRequest{ UserId: resp.GetUserId(), @@ -1440,7 +1436,7 @@ func TestServer_UnLockUser(t *testing.T) { want: &user.UnlockUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1450,7 +1446,7 @@ func TestServer_UnLockUser(t *testing.T) { ctx: CTX, req: &user.UnlockUserRequest{}, prepare: func(request *user.UnlockUserRequest) error { - resp := Tester.CreateMachineUser(CTX) + resp := Instance.CreateMachineUser(CTX) request.UserId = resp.GetUserId() _, err := Client.LockUser(CTX, &user.LockUserRequest{ UserId: resp.GetUserId(), @@ -1461,7 +1457,7 @@ func TestServer_UnLockUser(t *testing.T) { want: &user.UnlockUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1511,7 +1507,7 @@ func TestServer_DeactivateUser(t *testing.T) { CTX, &user.DeactivateUserRequest{}, func(request *user.DeactivateUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() return nil }, @@ -1519,7 +1515,7 @@ func TestServer_DeactivateUser(t *testing.T) { want: &user.DeactivateUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1529,7 +1525,7 @@ func TestServer_DeactivateUser(t *testing.T) { CTX, &user.DeactivateUserRequest{}, func(request *user.DeactivateUserRequest) error { - resp := Tester.CreateMachineUser(CTX) + resp := Instance.CreateMachineUser(CTX) request.UserId = resp.GetUserId() return nil }, @@ -1537,7 +1533,7 @@ func TestServer_DeactivateUser(t *testing.T) { want: &user.DeactivateUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1547,7 +1543,7 @@ func TestServer_DeactivateUser(t *testing.T) { CTX, &user.DeactivateUserRequest{}, func(request *user.DeactivateUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() _, err := Client.DeactivateUser(CTX, &user.DeactivateUserRequest{ UserId: resp.GetUserId(), @@ -1563,7 +1559,7 @@ func TestServer_DeactivateUser(t *testing.T) { CTX, &user.DeactivateUserRequest{}, func(request *user.DeactivateUserRequest) error { - resp := Tester.CreateMachineUser(CTX) + resp := Instance.CreateMachineUser(CTX) request.UserId = resp.GetUserId() _, err := Client.DeactivateUser(CTX, &user.DeactivateUserRequest{ UserId: resp.GetUserId(), @@ -1619,7 +1615,7 @@ func TestServer_ReactivateUser(t *testing.T) { ctx: CTX, req: &user.ReactivateUserRequest{}, prepare: func(request *user.ReactivateUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() return nil }, @@ -1632,7 +1628,7 @@ func TestServer_ReactivateUser(t *testing.T) { ctx: CTX, req: &user.ReactivateUserRequest{}, prepare: func(request *user.ReactivateUserRequest) error { - resp := Tester.CreateMachineUser(CTX) + resp := Instance.CreateMachineUser(CTX) request.UserId = resp.GetUserId() return nil }, @@ -1645,7 +1641,7 @@ func TestServer_ReactivateUser(t *testing.T) { ctx: CTX, req: &user.ReactivateUserRequest{}, prepare: func(request *user.ReactivateUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() _, err := Client.DeactivateUser(CTX, &user.DeactivateUserRequest{ UserId: resp.GetUserId(), @@ -1656,7 +1652,7 @@ func TestServer_ReactivateUser(t *testing.T) { want: &user.ReactivateUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1666,7 +1662,7 @@ func TestServer_ReactivateUser(t *testing.T) { ctx: CTX, req: &user.ReactivateUserRequest{}, prepare: func(request *user.ReactivateUserRequest) error { - resp := Tester.CreateMachineUser(CTX) + resp := Instance.CreateMachineUser(CTX) request.UserId = resp.GetUserId() _, err := Client.DeactivateUser(CTX, &user.DeactivateUserRequest{ UserId: resp.GetUserId(), @@ -1677,7 +1673,7 @@ func TestServer_ReactivateUser(t *testing.T) { want: &user.ReactivateUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1699,7 +1695,7 @@ func TestServer_ReactivateUser(t *testing.T) { } func TestServer_DeleteUser(t *testing.T) { - projectResp, err := Tester.CreateProject(CTX) + projectResp, err := Instance.CreateProject(CTX) require.NoError(t, err) type args struct { ctx context.Context @@ -1729,7 +1725,7 @@ func TestServer_DeleteUser(t *testing.T) { ctx: CTX, req: &user.DeleteUserRequest{}, prepare: func(request *user.DeleteUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() return err }, @@ -1737,7 +1733,7 @@ func TestServer_DeleteUser(t *testing.T) { want: &user.DeleteUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1747,7 +1743,7 @@ func TestServer_DeleteUser(t *testing.T) { ctx: CTX, req: &user.DeleteUserRequest{}, prepare: func(request *user.DeleteUserRequest) error { - resp := Tester.CreateMachineUser(CTX) + resp := Instance.CreateMachineUser(CTX) request.UserId = resp.GetUserId() return err }, @@ -1755,7 +1751,7 @@ func TestServer_DeleteUser(t *testing.T) { want: &user.DeleteUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1765,18 +1761,18 @@ func TestServer_DeleteUser(t *testing.T) { ctx: CTX, req: &user.DeleteUserRequest{}, prepare: func(request *user.DeleteUserRequest) error { - resp := Tester.CreateHumanUser(CTX) + resp := Instance.CreateHumanUser(CTX) request.UserId = resp.GetUserId() - Tester.CreateProjectUserGrant(t, CTX, projectResp.GetId(), request.UserId) - Tester.CreateProjectMembership(t, CTX, projectResp.GetId(), request.UserId) - Tester.CreateOrgMembership(t, CTX, request.UserId) + Instance.CreateProjectUserGrant(t, CTX, projectResp.GetId(), request.UserId) + Instance.CreateProjectMembership(t, CTX, projectResp.GetId(), request.UserId) + Instance.CreateOrgMembership(t, CTX, request.UserId) return err }, }, want: &user.DeleteUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, }, @@ -1798,7 +1794,7 @@ func TestServer_DeleteUser(t *testing.T) { } func TestServer_AddIDPLink(t *testing.T) { - idpID := Tester.AddGenericOAuthProvider(t, CTX) + idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id) type args struct { ctx context.Context req *user.AddIDPLinkRequest @@ -1816,7 +1812,7 @@ func TestServer_AddIDPLink(t *testing.T) { &user.AddIDPLinkRequest{ UserId: "userID", IdpLink: &user.IDPLink{ - IdpId: idpID, + IdpId: idpResp.Id, UserId: "userID", UserName: "username", }, @@ -1830,7 +1826,7 @@ func TestServer_AddIDPLink(t *testing.T) { args: args{ CTX, &user.AddIDPLinkRequest{ - UserId: Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, + UserId: Instance.Users.Get(integration.UserTypeOrgOwner).ID, IdpLink: &user.IDPLink{ IdpId: "idpID", UserId: "userID", @@ -1846,9 +1842,9 @@ func TestServer_AddIDPLink(t *testing.T) { args: args{ CTX, &user.AddIDPLinkRequest{ - UserId: Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, + UserId: Instance.Users.Get(integration.UserTypeOrgOwner).ID, IdpLink: &user.IDPLink{ - IdpId: idpID, + IdpId: idpResp.Id, UserId: "userID", UserName: "username", }, @@ -1857,7 +1853,7 @@ func TestServer_AddIDPLink(t *testing.T) { want: &user.AddIDPLinkResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Organisation.ID, + ResourceOwner: Instance.DefaultOrg.Id, }, }, wantErr: false, @@ -1878,13 +1874,13 @@ func TestServer_AddIDPLink(t *testing.T) { } func TestServer_StartIdentityProviderIntent(t *testing.T) { - idpID := Tester.AddGenericOAuthProvider(t, CTX) - orgIdpID := Tester.AddOrgGenericOAuthProvider(t, CTX, Tester.Organisation.ID) - orgResp := Tester.CreateOrganization(IamCTX, fmt.Sprintf("NotDefaultOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) - notDefaultOrgIdpID := Tester.AddOrgGenericOAuthProvider(t, CTX, orgResp.OrganizationId) - samlIdpID := Tester.AddSAMLProvider(t, CTX) - samlRedirectIdpID := Tester.AddSAMLRedirectProvider(t, CTX, "") - samlPostIdpID := Tester.AddSAMLPostProvider(t, CTX) + idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id) + orgIdpID := Instance.AddOrgGenericOAuthProvider(CTX, Instance.DefaultOrg.Id) + orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("NotDefaultOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) + notDefaultOrgIdpID := Instance.AddOrgGenericOAuthProvider(IamCTX, orgResp.OrganizationId) + samlIdpID := Instance.AddSAMLProvider(IamCTX) + samlRedirectIdpID := Instance.AddSAMLRedirectProvider(IamCTX, "") + samlPostIdpID := Instance.AddSAMLPostProvider(IamCTX) type args struct { ctx context.Context req *user.StartIdentityProviderIntentRequest @@ -1907,7 +1903,7 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { args: args{ CTX, &user.StartIdentityProviderIntentRequest{ - IdpId: idpID, + IdpId: idpResp.Id, }, }, wantErr: true, @@ -1917,7 +1913,7 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { args: args{ CTX, &user.StartIdentityProviderIntentRequest{ - IdpId: idpID, + IdpId: idpResp.Id, Content: &user.StartIdentityProviderIntentRequest_Urls{ Urls: &user.RedirectURLs{ SuccessUrl: "https://example.com/success", @@ -1929,13 +1925,13 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { want: want{ details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), }, url: "https://example.com/oauth/v2/authorize", parametersEqual: map[string]string{ "client_id": "clientID", "prompt": "select_account", - "redirect_uri": "http://" + Tester.Config.ExternalDomain + ":8080/idps/callback", + "redirect_uri": "http://" + Instance.Domain + ":8080/idps/callback", "response_type": "code", "scope": "openid profile email", }, @@ -1948,7 +1944,7 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { args: args{ CTX, &user.StartIdentityProviderIntentRequest{ - IdpId: orgIdpID, + IdpId: orgIdpID.Id, Content: &user.StartIdentityProviderIntentRequest_Urls{ Urls: &user.RedirectURLs{ SuccessUrl: "https://example.com/success", @@ -1960,13 +1956,13 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { want: want{ details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), }, url: "https://example.com/oauth/v2/authorize", parametersEqual: map[string]string{ "client_id": "clientID", "prompt": "select_account", - "redirect_uri": "http://" + Tester.Config.ExternalDomain + ":8080/idps/callback", + "redirect_uri": "http://" + Instance.Domain + ":8080/idps/callback", "response_type": "code", "scope": "openid profile email", }, @@ -1979,7 +1975,7 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { args: args{ CTX, &user.StartIdentityProviderIntentRequest{ - IdpId: notDefaultOrgIdpID, + IdpId: notDefaultOrgIdpID.Id, Content: &user.StartIdentityProviderIntentRequest_Urls{ Urls: &user.RedirectURLs{ SuccessUrl: "https://example.com/success", @@ -1991,13 +1987,13 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { want: want{ details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), }, url: "https://example.com/oauth/v2/authorize", parametersEqual: map[string]string{ "client_id": "clientID", "prompt": "select_account", - "redirect_uri": "http://" + Tester.Config.ExternalDomain + ":8080/idps/callback", + "redirect_uri": "http://" + Instance.Domain + ":8080/idps/callback", "response_type": "code", "scope": "openid profile email", }, @@ -2010,7 +2006,7 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { args: args{ CTX, &user.StartIdentityProviderIntentRequest{ - IdpId: orgIdpID, + IdpId: orgIdpID.Id, Content: &user.StartIdentityProviderIntentRequest_Urls{ Urls: &user.RedirectURLs{ SuccessUrl: "https://example.com/success", @@ -2022,13 +2018,13 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { want: want{ details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), }, url: "https://example.com/oauth/v2/authorize", parametersEqual: map[string]string{ "client_id": "clientID", "prompt": "select_account", - "redirect_uri": "http://" + Tester.Config.ExternalDomain + ":8080/idps/callback", + "redirect_uri": "http://" + Instance.Domain + ":8080/idps/callback", "response_type": "code", "scope": "openid profile email", }, @@ -2053,9 +2049,9 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { want: want{ details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), }, - url: "http://" + Tester.Config.ExternalDomain + ":8000/sso", + url: "http://" + Instance.Domain + ":8000/sso", parametersExisting: []string{"RelayState", "SAMLRequest"}, }, wantErr: false, @@ -2077,9 +2073,9 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { want: want{ details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), }, - url: "http://" + Tester.Config.ExternalDomain + ":8000/sso", + url: "http://" + Instance.Domain + ":8000/sso", parametersExisting: []string{"RelayState", "SAMLRequest"}, }, wantErr: false, @@ -2101,7 +2097,7 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { want: want{ details: &object.Details{ ChangeDate: timestamppb.Now(), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), }, postForm: true, }, @@ -2140,14 +2136,15 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) { } } +/* func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { - idpID := Tester.AddGenericOAuthProvider(t, CTX) - intentID := Tester.CreateIntent(t, CTX, idpID) - successfulID, token, changeDate, sequence := Tester.CreateSuccessfulOAuthIntent(t, CTX, idpID, "", "id") - successfulWithUserID, withUsertoken, withUserchangeDate, withUsersequence := Tester.CreateSuccessfulOAuthIntent(t, CTX, idpID, "user", "id") - ldapSuccessfulID, ldapToken, ldapChangeDate, ldapSequence := Tester.CreateSuccessfulLDAPIntent(t, CTX, idpID, "", "id") - ldapSuccessfulWithUserID, ldapWithUserToken, ldapWithUserChangeDate, ldapWithUserSequence := Tester.CreateSuccessfulLDAPIntent(t, CTX, idpID, "user", "id") - samlSuccessfulID, samlToken, samlChangeDate, samlSequence := Tester.CreateSuccessfulSAMLIntent(t, CTX, idpID, "", "id") + idpID := Instance.AddGenericOAuthProvider(t, CTX) + intentID := Instance.CreateIntent(t, CTX, idpID) + successfulID, token, changeDate, sequence := Instance.CreateSuccessfulOAuthIntent(t, CTX, idpID.Id, "", "id") + successfulWithUserID, withUsertoken, withUserchangeDate, withUsersequence := Instance.CreateSuccessfulOAuthIntent(t, CTX, idpID.Id, "user", "id") + ldapSuccessfulID, ldapToken, ldapChangeDate, ldapSequence := Instance.CreateSuccessfulLDAPIntent(t, CTX, idpID.Id, "", "id") + ldapSuccessfulWithUserID, ldapWithUserToken, ldapWithUserChangeDate, ldapWithUserSequence := Instance.CreateSuccessfulLDAPIntent(t, CTX, idpID.Id, "user", "id") + samlSuccessfulID, samlToken, samlChangeDate, samlSequence := Instance.CreateSuccessfulSAMLIntent(t, CTX, idpID.Id, "", "id") type args struct { ctx context.Context req *user.RetrieveIdentityProviderIntentRequest @@ -2192,7 +2189,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { want: &user.RetrieveIdentityProviderIntentResponse{ Details: &object.Details{ ChangeDate: timestamppb.New(changeDate), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), Sequence: sequence, }, IdpInformation: &user.IDPInformation{ @@ -2202,7 +2199,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { IdToken: gu.Ptr("idToken"), }, }, - IdpId: idpID, + IdpId: idpID.Id, UserId: "id", UserName: "username", RawInformation: func() *structpb.Struct { @@ -2229,7 +2226,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { want: &user.RetrieveIdentityProviderIntentResponse{ Details: &object.Details{ ChangeDate: timestamppb.New(withUserchangeDate), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), Sequence: withUsersequence, }, UserId: "user", @@ -2240,7 +2237,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { IdToken: gu.Ptr("idToken"), }, }, - IdpId: idpID, + IdpId: idpID.Id, UserId: "id", UserName: "username", RawInformation: func() *structpb.Struct { @@ -2267,7 +2264,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { want: &user.RetrieveIdentityProviderIntentResponse{ Details: &object.Details{ ChangeDate: timestamppb.New(ldapChangeDate), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), Sequence: ldapSequence, }, IdpInformation: &user.IDPInformation{ @@ -2284,7 +2281,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { }(), }, }, - IdpId: idpID, + IdpId: idpID.Id, UserId: "id", UserName: "username", RawInformation: func() *structpb.Struct { @@ -2312,7 +2309,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { want: &user.RetrieveIdentityProviderIntentResponse{ Details: &object.Details{ ChangeDate: timestamppb.New(ldapWithUserChangeDate), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), Sequence: ldapWithUserSequence, }, UserId: "user", @@ -2330,7 +2327,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { }(), }, }, - IdpId: idpID, + IdpId: idpID.Id, UserId: "id", UserName: "username", RawInformation: func() *structpb.Struct { @@ -2358,7 +2355,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { want: &user.RetrieveIdentityProviderIntentResponse{ Details: &object.Details{ ChangeDate: timestamppb.New(samlChangeDate), - ResourceOwner: Tester.Instance.InstanceID(), + ResourceOwner: Instance.ID(), Sequence: samlSequence, }, IdpInformation: &user.IDPInformation{ @@ -2367,7 +2364,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { Assertion: []byte(""), }, }, - IdpId: idpID, + IdpId: idpID.Id, UserId: "id", UserName: "", RawInformation: func() *structpb.Struct { @@ -2398,28 +2395,29 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { }) } } +*/ func TestServer_ListAuthenticationMethodTypes(t *testing.T) { - userIDWithoutAuth := Tester.CreateHumanUser(CTX).GetUserId() + userIDWithoutAuth := Instance.CreateHumanUser(CTX).GetUserId() - userIDWithPasskey := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userIDWithPasskey) + userIDWithPasskey := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userIDWithPasskey) - userMultipleAuth := Tester.CreateHumanUser(CTX).GetUserId() - Tester.RegisterUserPasskey(CTX, userMultipleAuth) - provider, err := Tester.Client.Mgmt.AddGenericOIDCProvider(CTX, &mgmt.AddGenericOIDCProviderRequest{ + userMultipleAuth := Instance.CreateHumanUser(CTX).GetUserId() + Instance.RegisterUserPasskey(CTX, userMultipleAuth) + provider, err := Instance.Client.Mgmt.AddGenericOIDCProvider(CTX, &mgmt.AddGenericOIDCProviderRequest{ Name: "ListAuthenticationMethodTypes", Issuer: "https://example.com", ClientId: "client_id", ClientSecret: "client_secret", }) require.NoError(t, err) - _, err = Tester.Client.Mgmt.AddCustomLoginPolicy(CTX, &mgmt.AddCustomLoginPolicyRequest{}) + _, err = Instance.Client.Mgmt.AddCustomLoginPolicy(CTX, &mgmt.AddCustomLoginPolicyRequest{}) require.Condition(t, func() bool { code := status.Convert(err).Code() return code == codes.AlreadyExists || code == codes.OK }) - _, err = Tester.Client.Mgmt.AddIDPToLoginPolicy(CTX, &mgmt.AddIDPToLoginPolicyRequest{ + _, err = Instance.Client.Mgmt.AddIDPToLoginPolicy(CTX, &mgmt.AddIDPToLoginPolicyRequest{ IdpId: provider.GetId(), OwnerType: idp.IDPOwnerType_IDP_OWNER_TYPE_ORG, }) @@ -2431,7 +2429,7 @@ func TestServer_ListAuthenticationMethodTypes(t *testing.T) { }}) require.NoError(t, err) // This should not remove the user IDP links - _, err = Tester.Client.Mgmt.RemoveIDPFromLoginPolicy(CTX, &mgmt.RemoveIDPFromLoginPolicyRequest{ + _, err = Instance.Client.Mgmt.RemoveIDPFromLoginPolicy(CTX, &mgmt.RemoveIDPFromLoginPolicyRequest{ IdpId: provider.GetId(), }) require.NoError(t, err) diff --git a/internal/api/idp/idp_integration_test.go b/internal/api/idp/integration_test/idp_test.go similarity index 90% rename from internal/api/idp/idp_integration_test.go rename to internal/api/idp/integration_test/idp_test.go index 51d9bbfeea..609b98262b 100644 --- a/internal/api/idp/idp_integration_test.go +++ b/internal/api/idp/integration_test/idp_test.go @@ -31,29 +31,27 @@ import ( ) var ( - CTX context.Context - ErrCTX context.Context - Tester *integration.Tester - Client user.UserServiceClient + CTX context.Context + Instance *integration.Instance + Client user.UserServiceClient ) func TestMain(m *testing.M) { os.Exit(func() int { - ctx, errCtx, cancel := integration.Contexts(time.Hour) + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute) defer cancel() - Tester = integration.NewTester(ctx) - defer Tester.Done() + Instance = integration.NewInstance(ctx) - CTX, ErrCTX = Tester.WithAuthorization(ctx, integration.OrgOwner), errCtx - Client = Tester.Client.UserV2 + CTX = Instance.WithAuthorization(ctx, integration.UserTypeIAMOwner) + Client = Instance.Client.UserV2 return m.Run() }()) } func TestServer_SAMLCertificate(t *testing.T) { - samlRedirectIdpID := Tester.AddSAMLRedirectProvider(t, CTX, "") - oauthIdpID := Tester.AddGenericOAuthProvider(t, CTX) + samlRedirectIdpID := Instance.AddSAMLRedirectProvider(CTX, "") + oauthIdpResp := Instance.AddGenericOAuthProvider(CTX, Instance.DefaultOrg.Id) type args struct { ctx context.Context @@ -76,7 +74,7 @@ func TestServer_SAMLCertificate(t *testing.T) { name: "saml certificate, invalid idp type", args: args{ ctx: CTX, - idpID: oauthIdpID, + idpID: oauthIdpResp.Id, }, want: http.StatusBadRequest, }, @@ -91,7 +89,7 @@ func TestServer_SAMLCertificate(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - certificateURL := http_util.BuildOrigin(Tester.Host(), Tester.Server.Config.ExternalSecure) + "/idps/" + tt.args.idpID + "/saml/certificate" + certificateURL := http_util.BuildOrigin(Instance.Host(), Instance.Config.Secure) + "/idps/" + tt.args.idpID + "/saml/certificate" resp, err := http.Get(certificateURL) assert.NoError(t, err) assert.Equal(t, tt.want, resp.StatusCode) @@ -109,8 +107,8 @@ func TestServer_SAMLCertificate(t *testing.T) { } func TestServer_SAMLMetadata(t *testing.T) { - samlRedirectIdpID := Tester.AddSAMLRedirectProvider(t, CTX, "") - oauthIdpID := Tester.AddGenericOAuthProvider(t, CTX) + samlRedirectIdpID := Instance.AddSAMLRedirectProvider(CTX, "") + oauthIdpResp := Instance.AddGenericOAuthProvider(CTX, Instance.DefaultOrg.Id) type args struct { ctx context.Context @@ -133,7 +131,7 @@ func TestServer_SAMLMetadata(t *testing.T) { name: "saml metadata, invalid idp type", args: args{ ctx: CTX, - idpID: oauthIdpID, + idpID: oauthIdpResp.Id, }, want: http.StatusBadRequest, }, @@ -148,7 +146,7 @@ func TestServer_SAMLMetadata(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - metadataURL := http_util.BuildOrigin(Tester.Host(), Tester.Server.Config.ExternalSecure) + "/idps/" + tt.args.idpID + "/saml/metadata" + metadataURL := http_util.BuildOrigin(Instance.Host(), Instance.Config.Secure) + "/idps/" + tt.args.idpID + "/saml/metadata" resp, err := http.Get(metadataURL) assert.NoError(t, err) assert.Equal(t, tt.want, resp.StatusCode) @@ -166,13 +164,13 @@ func TestServer_SAMLMetadata(t *testing.T) { } func TestServer_SAMLACS(t *testing.T) { - userHuman := Tester.CreateHumanUser(CTX) - samlRedirectIdpID := Tester.AddSAMLRedirectProvider(t, CTX, "urn:oid:0.9.2342.19200300.100.1.1") // the username is set in urn:oid:0.9.2342.19200300.100.1.1 + userHuman := Instance.CreateHumanUser(CTX) + samlRedirectIdpID := Instance.AddSAMLRedirectProvider(CTX, "urn:oid:0.9.2342.19200300.100.1.1") // the username is set in urn:oid:0.9.2342.19200300.100.1.1 externalUserID := "test1" linkedExternalUserID := "test2" - Tester.CreateUserIDPlink(CTX, userHuman.UserId, linkedExternalUserID, samlRedirectIdpID, linkedExternalUserID) + Instance.CreateUserIDPlink(CTX, userHuman.UserId, linkedExternalUserID, samlRedirectIdpID, linkedExternalUserID) idp, err := getIDP( - http_util.BuildOrigin(Tester.Host(), Tester.Server.Config.ExternalSecure), + http_util.BuildOrigin(Instance.Host(), Instance.Config.Secure), []string{samlRedirectIdpID}, externalUserID, linkedExternalUserID, @@ -328,7 +326,7 @@ func TestServer_SAMLACS(t *testing.T) { if tt.args.intentID != "" { relayState = tt.args.intentID } - callbackURL := http_util.BuildOrigin(Tester.Host(), Tester.Server.Config.ExternalSecure) + "/idps/" + tt.args.idpID + "/saml/acs" + callbackURL := http_util.BuildOrigin(Instance.Host(), Instance.Config.Secure) + "/idps/" + tt.args.idpID + "/saml/acs" response := createResponse(t, idp, samlRequest, tt.args.nameID, tt.args.nameIDFormat, tt.args.username) //test purposes, use defined response if tt.args.response != "" { diff --git a/internal/api/oidc/auth_request_integration_test.go b/internal/api/oidc/integration_test/auth_request_test.go similarity index 68% rename from internal/api/oidc/auth_request_integration_test.go rename to internal/api/oidc/integration_test/auth_request_test.go index faa5126676..bd9142a3f6 100644 --- a/internal/api/oidc/auth_request_integration_test.go +++ b/internal/api/oidc/integration_test/auth_request_test.go @@ -28,17 +28,21 @@ var ( ) func TestOPStorage_CreateAuthRequest(t *testing.T) { - clientID, _ := createClient(t) + t.Parallel() - id := createAuthRequest(t, clientID, redirectURI) + clientID, _ := createClient(t, Instance) + + id := createAuthRequest(t, Instance, clientID, redirectURI) require.Contains(t, id, command.IDPrefixV2) } func TestOPStorage_CreateAccessToken_code(t *testing.T) { - clientID, _ := createClient(t) - authRequestID := createAuthRequest(t, clientID, redirectURI) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + t.Parallel() + + clientID, _ := createClient(t, Instance) + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI) + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -51,13 +55,13 @@ func TestOPStorage_CreateAccessToken_code(t *testing.T) { // test code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, false) assertIDTokenClaims(t, tokens.IDTokenClaims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) // callback on a succeeded request must fail - linkResp, err = Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + linkResp, err = Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -69,15 +73,17 @@ func TestOPStorage_CreateAccessToken_code(t *testing.T) { require.Error(t, err) // exchange with a used code must fail - _, err = exchangeTokens(t, clientID, code, redirectURI) + _, err = exchangeTokens(t, Instance, clientID, code, redirectURI) require.Error(t, err) } func TestOPStorage_CreateAccessToken_implicit(t *testing.T) { + t.Parallel() + clientID := createImplicitClient(t) authRequestID := createAuthRequestImplicit(t, clientID, redirectURIImplicit) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -104,14 +110,14 @@ func TestOPStorage_CreateAccessToken_implicit(t *testing.T) { assert.Equal(t, "state", values.Get("state")) // check id_token / claims - provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURIImplicit) + provider, err := Instance.CreateRelyingParty(CTX, clientID, redirectURIImplicit) require.NoError(t, err) claims, err := rp.VerifyTokens[*oidc.IDTokenClaims](context.Background(), accessToken, idToken, provider.IDTokenVerifier()) require.NoError(t, err) assertIDTokenClaims(t, claims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) // callback on a succeeded request must fail - linkResp, err = Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + linkResp, err = Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -124,10 +130,12 @@ func TestOPStorage_CreateAccessToken_implicit(t *testing.T) { } func TestOPStorage_CreateAccessAndRefreshTokens_code(t *testing.T) { - clientID, _ := createClient(t) - authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + t.Parallel() + + clientID, _ := createClient(t, Instance) + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -140,19 +148,21 @@ func TestOPStorage_CreateAccessAndRefreshTokens_code(t *testing.T) { // test code exchange (expect refresh token to be returned) code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, true) assertIDTokenClaims(t, tokens.IDTokenClaims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) } func TestOPStorage_CreateAccessAndRefreshTokens_refresh(t *testing.T) { - clientID, _ := createClient(t) - provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) + t.Parallel() + + clientID, _ := createClient(t, Instance) + provider, err := Instance.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) - authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -165,7 +175,7 @@ func TestOPStorage_CreateAccessAndRefreshTokens_refresh(t *testing.T) { // code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, true) assertIDTokenClaims(t, tokens.IDTokenClaims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) @@ -183,12 +193,14 @@ func TestOPStorage_CreateAccessAndRefreshTokens_refresh(t *testing.T) { } func TestOPStorage_RevokeToken_access_token(t *testing.T) { - clientID, _ := createClient(t) - provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) + t.Parallel() + + clientID, _ := createClient(t, Instance) + provider, err := Instance.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) - authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -201,7 +213,7 @@ func TestOPStorage_RevokeToken_access_token(t *testing.T) { // code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, true) assertIDTokenClaims(t, tokens.IDTokenClaims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) @@ -226,12 +238,14 @@ func TestOPStorage_RevokeToken_access_token(t *testing.T) { } func TestOPStorage_RevokeToken_access_token_invalid_token_hint_type(t *testing.T) { - clientID, _ := createClient(t) - provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) + t.Parallel() + + clientID, _ := createClient(t, Instance) + provider, err := Instance.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) - authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -244,7 +258,7 @@ func TestOPStorage_RevokeToken_access_token_invalid_token_hint_type(t *testing.T // code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, true) assertIDTokenClaims(t, tokens.IDTokenClaims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) @@ -263,12 +277,14 @@ func TestOPStorage_RevokeToken_access_token_invalid_token_hint_type(t *testing.T } func TestOPStorage_RevokeToken_refresh_token(t *testing.T) { - clientID, _ := createClient(t) - provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) + t.Parallel() + + clientID, _ := createClient(t, Instance) + provider, err := Instance.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) - authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -281,7 +297,7 @@ func TestOPStorage_RevokeToken_refresh_token(t *testing.T) { // code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, true) assertIDTokenClaims(t, tokens.IDTokenClaims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) @@ -306,12 +322,14 @@ func TestOPStorage_RevokeToken_refresh_token(t *testing.T) { } func TestOPStorage_RevokeToken_refresh_token_invalid_token_type_hint(t *testing.T) { - clientID, _ := createClient(t) - provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) + t.Parallel() + + clientID, _ := createClient(t, Instance) + provider, err := Instance.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) - authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -324,7 +342,7 @@ func TestOPStorage_RevokeToken_refresh_token_invalid_token_type_hint(t *testing. // code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, true) assertIDTokenClaims(t, tokens.IDTokenClaims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) @@ -343,10 +361,12 @@ func TestOPStorage_RevokeToken_refresh_token_invalid_token_type_hint(t *testing. } func TestOPStorage_RevokeToken_invalid_client(t *testing.T) { - clientID, _ := createClient(t) - authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + t.Parallel() + + clientID, _ := createClient(t, Instance) + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -359,26 +379,28 @@ func TestOPStorage_RevokeToken_invalid_client(t *testing.T) { // code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, true) assertIDTokenClaims(t, tokens.IDTokenClaims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) // simulate second client (not part of the audience) trying to revoke the token - otherClientID, _ := createClient(t) - provider, err := Tester.CreateRelyingParty(CTX, otherClientID, redirectURI) + otherClientID, _ := createClient(t, Instance) + provider, err := Instance.CreateRelyingParty(CTX, otherClientID, redirectURI) require.NoError(t, err) err = rp.RevokeToken(CTX, provider, tokens.AccessToken, "") require.Error(t, err) } func TestOPStorage_TerminateSession(t *testing.T) { - clientID, _ := createClient(t) - provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) + t.Parallel() + + clientID, _ := createClient(t, Instance) + provider, err := Instance.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) - authRequestID := createAuthRequest(t, clientID, redirectURI) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI) + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -391,7 +413,7 @@ func TestOPStorage_TerminateSession(t *testing.T) { // test code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, false) assertIDTokenClaims(t, tokens.IDTokenClaims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) @@ -410,12 +432,14 @@ func TestOPStorage_TerminateSession(t *testing.T) { } func TestOPStorage_TerminateSession_refresh_grant(t *testing.T) { - clientID, _ := createClient(t) - provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) + t.Parallel() + + clientID, _ := createClient(t, Instance) + provider, err := Instance.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) - authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -428,7 +452,7 @@ func TestOPStorage_TerminateSession_refresh_grant(t *testing.T) { // test code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, true) assertIDTokenClaims(t, tokens.IDTokenClaims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) @@ -454,12 +478,14 @@ func TestOPStorage_TerminateSession_refresh_grant(t *testing.T) { } func TestOPStorage_TerminateSession_empty_id_token_hint(t *testing.T) { - clientID, _ := createClient(t) - provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) + t.Parallel() + + clientID, _ := createClient(t, Instance) + provider, err := Instance.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) - authRequestID := createAuthRequest(t, clientID, redirectURI) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI) + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -472,21 +498,21 @@ func TestOPStorage_TerminateSession_empty_id_token_hint(t *testing.T) { // test code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, false) assertIDTokenClaims(t, tokens.IDTokenClaims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) postLogoutRedirect, err := rp.EndSession(CTX, provider, "", logoutRedirectURI, "state") require.NoError(t, err) - assert.Equal(t, http_utils.BuildOrigin(Tester.Host(), Tester.Config.ExternalSecure)+Tester.Config.OIDC.DefaultLogoutURLV2+logoutRedirectURI+"?state=state", postLogoutRedirect.String()) + assert.Equal(t, http_utils.BuildOrigin(Instance.Host(), Instance.Config.Secure)+Instance.Config.LogoutURLV2+logoutRedirectURI+"?state=state", postLogoutRedirect.String()) // userinfo must not fail until login UI terminated session _, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) require.NoError(t, err) // simulate termination by login UI - _, err = Tester.Client.SessionV2.DeleteSession(CTXLOGIN, &session.DeleteSessionRequest{ + _, err = Instance.Client.SessionV2.DeleteSession(CTXLOGIN, &session.DeleteSessionRequest{ SessionId: sessionID, SessionToken: gu.Ptr(sessionToken), }) @@ -497,15 +523,15 @@ func TestOPStorage_TerminateSession_empty_id_token_hint(t *testing.T) { require.Error(t, err) } -func exchangeTokens(t testing.TB, clientID, code, redirectURI string) (*oidc.Tokens[*oidc.IDTokenClaims], error) { - provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) +func exchangeTokens(t testing.TB, instance *integration.Instance, clientID, code, redirectURI string) (*oidc.Tokens[*oidc.IDTokenClaims], error) { + provider, err := instance.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) return rp.CodeExchange[*oidc.IDTokenClaims](context.Background(), code, provider, rp.WithCodeVerifier(integration.CodeVerifier)) } func refreshTokens(t testing.TB, clientID, refreshToken string) (*oidc.Tokens[*oidc.IDTokenClaims], error) { - provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) + provider, err := Instance.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) return rp.RefreshTokens[*oidc.IDTokenClaims](CTX, provider, refreshToken, "", "") diff --git a/internal/api/oidc/client_integration_test.go b/internal/api/oidc/integration_test/client_test.go similarity index 81% rename from internal/api/oidc/client_integration_test.go rename to internal/api/oidc/integration_test/client_test.go index 9ff0b104d9..7e9f15ffac 100644 --- a/internal/api/oidc/client_integration_test.go +++ b/internal/api/oidc/integration_test/client_test.go @@ -24,9 +24,11 @@ import ( ) func TestServer_Introspect(t *testing.T) { - project, err := Tester.CreateProject(CTX) + t.Parallel() + + project, err := Instance.CreateProject(CTX) require.NoError(t, err) - app, err := Tester.CreateOIDCNativeClient(CTX, redirectURI, logoutRedirectURI, project.GetId(), false) + app, err := Instance.CreateOIDCNativeClient(CTX, redirectURI, logoutRedirectURI, project.GetId(), false) require.NoError(t, err) wantAudience := []string{app.GetClientId(), project.GetId()} @@ -39,16 +41,16 @@ func TestServer_Introspect(t *testing.T) { { name: "client assertion", api: func(t *testing.T) (string, rs.ResourceServer) { - api, err := Tester.CreateAPIClientJWT(CTX, project.GetId()) + api, err := Instance.CreateAPIClientJWT(CTX, project.GetId()) require.NoError(t, err) - keyResp, err := Tester.Client.Mgmt.AddAppKey(CTX, &management.AddAppKeyRequest{ + keyResp, err := Instance.Client.Mgmt.AddAppKey(CTX, &management.AddAppKeyRequest{ ProjectId: project.GetId(), AppId: api.GetAppId(), Type: authn.KeyType_KEY_TYPE_JSON, ExpirationDate: nil, }) require.NoError(t, err) - resourceServer, err := Tester.CreateResourceServerJWTProfile(CTX, keyResp.GetKeyDetails()) + resourceServer, err := Instance.CreateResourceServerJWTProfile(CTX, keyResp.GetKeyDetails()) require.NoError(t, err) return api.GetClientId(), resourceServer }, @@ -56,9 +58,9 @@ func TestServer_Introspect(t *testing.T) { { name: "client credentials", api: func(t *testing.T) (string, rs.ResourceServer) { - api, err := Tester.CreateAPIClientBasic(CTX, project.GetId()) + api, err := Instance.CreateAPIClientBasic(CTX, project.GetId()) require.NoError(t, err) - resourceServer, err := Tester.CreateResourceServerClientCredentials(CTX, api.GetClientId(), api.GetClientSecret()) + resourceServer, err := Instance.CreateResourceServerClientCredentials(CTX, api.GetClientId(), api.GetClientSecret()) require.NoError(t, err) return api.GetClientId(), resourceServer }, @@ -66,9 +68,9 @@ func TestServer_Introspect(t *testing.T) { { name: "client invalid id, error", api: func(t *testing.T) (string, rs.ResourceServer) { - api, err := Tester.CreateAPIClientBasic(CTX, project.GetId()) + api, err := Instance.CreateAPIClientBasic(CTX, project.GetId()) require.NoError(t, err) - resourceServer, err := Tester.CreateResourceServerClientCredentials(CTX, "xxxxx", api.GetClientSecret()) + resourceServer, err := Instance.CreateResourceServerClientCredentials(CTX, "xxxxx", api.GetClientSecret()) require.NoError(t, err) return api.GetClientId(), resourceServer }, @@ -77,9 +79,9 @@ func TestServer_Introspect(t *testing.T) { { name: "client invalid secret, error", api: func(t *testing.T) (string, rs.ResourceServer) { - api, err := Tester.CreateAPIClientBasic(CTX, project.GetId()) + api, err := Instance.CreateAPIClientBasic(CTX, project.GetId()) require.NoError(t, err) - resourceServer, err := Tester.CreateResourceServerClientCredentials(CTX, api.GetClientId(), "xxxxx") + resourceServer, err := Instance.CreateResourceServerClientCredentials(CTX, api.GetClientId(), "xxxxx") require.NoError(t, err) return api.GetClientId(), resourceServer }, @@ -88,9 +90,9 @@ func TestServer_Introspect(t *testing.T) { { name: "client credentials on jwt client, error", api: func(t *testing.T) (string, rs.ResourceServer) { - api, err := Tester.CreateAPIClientJWT(CTX, project.GetId()) + api, err := Instance.CreateAPIClientJWT(CTX, project.GetId()) require.NoError(t, err) - resourceServer, err := Tester.CreateResourceServerClientCredentials(CTX, api.GetClientId(), "xxxxx") + resourceServer, err := Instance.CreateResourceServerClientCredentials(CTX, api.GetClientId(), "xxxxx") require.NoError(t, err) return api.GetClientId(), resourceServer }, @@ -104,9 +106,9 @@ func TestServer_Introspect(t *testing.T) { wantAudience = append(wantAudience, apiID) scope := []string{oidc.ScopeOpenID, oidc.ScopeProfile, oidc.ScopeEmail, oidc.ScopeOfflineAccess, oidc_api.ScopeResourceOwner} - authRequestID := createAuthRequest(t, app.GetClientId(), redirectURI, scope...) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + authRequestID := createAuthRequest(t, Instance, app.GetClientId(), redirectURI, scope...) + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -119,7 +121,7 @@ func TestServer_Introspect(t *testing.T) { // code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, app.GetClientId(), code, redirectURI) + tokens, err := exchangeTokens(t, Instance, app.GetClientId(), code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, true) assertIDTokenClaims(t, tokens.IDTokenClaims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) @@ -133,7 +135,7 @@ func TestServer_Introspect(t *testing.T) { require.NoError(t, err) assertIntrospection(t, introspection, - Tester.OIDCIssuer(), app.GetClientId(), + Instance.OIDCIssuer(), app.GetClientId(), scope, wantAudience, tokens.Expiry, tokens.Expiry.Add(-12*time.Hour)) }) @@ -141,9 +143,11 @@ func TestServer_Introspect(t *testing.T) { } func TestServer_Introspect_invalid_auth_invalid_token(t *testing.T) { + t.Parallel() + // ensure that when an invalid authentication and token is sent, the authentication error is returned // https://github.com/zitadel/zitadel/pull/8133 - resourceServer, err := Tester.CreateResourceServerClientCredentials(CTX, "xxxxx", "xxxxx") + resourceServer, err := Instance.CreateResourceServerClientCredentials(CTX, "xxxxx", "xxxxx") require.NoError(t, err) _, err = rs.Introspect[*oidc.IntrospectionResponse](context.Background(), resourceServer, "xxxxx") require.Error(t, err) @@ -187,17 +191,19 @@ func assertIntrospection( // TestServer_VerifyClient tests verification by running code flow tests // with clients that have different authentication methods. func TestServer_VerifyClient(t *testing.T) { - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - project, err := Tester.CreateProject(CTX) + t.Parallel() + + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + project, err := Instance.CreateProject(CTX) require.NoError(t, err) - inactiveClient, err := Tester.CreateOIDCInactivateClient(CTX, redirectURI, logoutRedirectURI, project.GetId()) + inactiveClient, err := Instance.CreateOIDCInactivateClient(CTX, redirectURI, logoutRedirectURI, project.GetId()) require.NoError(t, err) - nativeClient, err := Tester.CreateOIDCNativeClient(CTX, redirectURI, logoutRedirectURI, project.GetId(), false) + nativeClient, err := Instance.CreateOIDCNativeClient(CTX, redirectURI, logoutRedirectURI, project.GetId(), false) require.NoError(t, err) - basicWebClient, err := Tester.CreateOIDCWebClientBasic(CTX, redirectURI, logoutRedirectURI, project.GetId()) + basicWebClient, err := Instance.CreateOIDCWebClientBasic(CTX, redirectURI, logoutRedirectURI, project.GetId()) require.NoError(t, err) - jwtWebClient, keyData, err := Tester.CreateOIDCWebClientJWT(CTX, redirectURI, logoutRedirectURI, project.GetId()) + jwtWebClient, keyData, err := Instance.CreateOIDCWebClientJWT(CTX, redirectURI, logoutRedirectURI, project.GetId()) require.NoError(t, err) type clientDetails struct { @@ -295,9 +301,9 @@ func TestServer_VerifyClient(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - authRequestID, err := Tester.CreateOIDCAuthRequest(CTX, tt.client.authReqClientID, Tester.Users[integration.FirstInstanceUsersKey][integration.Login].ID, redirectURI, oidc.ScopeOpenID) + authRequestID, err := Instance.CreateOIDCAuthRequest(CTX, tt.client.authReqClientID, Instance.Users.Get(integration.UserTypeLogin).ID, redirectURI, oidc.ScopeOpenID) require.NoError(t, err) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -313,7 +319,7 @@ func TestServer_VerifyClient(t *testing.T) { if tt.client.keyData != nil { options = append(options, rp.WithJWTProfile(rp.SignerFromKeyFile(tt.client.keyData))) } - provider, err := rp.NewRelyingPartyOIDC(CTX, Tester.OIDCIssuer(), tt.client.clientID, tt.client.clientSecret, redirectURI, []string{oidc.ScopeOpenID}, options...) + provider, err := rp.NewRelyingPartyOIDC(CTX, Instance.OIDCIssuer(), tt.client.clientID, tt.client.clientSecret, redirectURI, []string{oidc.ScopeOpenID}, options...) require.NoError(t, err) // test code exchange diff --git a/internal/api/oidc/keys_integration_test.go b/internal/api/oidc/integration_test/keys_test.go similarity index 66% rename from internal/api/oidc/keys_integration_test.go rename to internal/api/oidc/integration_test/keys_test.go index a78e4fc1b8..e8160017a5 100644 --- a/internal/api/oidc/keys_integration_test.go +++ b/internal/api/oidc/integration_test/keys_test.go @@ -18,17 +18,23 @@ import ( http_util "github.com/zitadel/zitadel/internal/api/http" "github.com/zitadel/zitadel/internal/crypto" + "github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/pkg/grpc/feature/v2" oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2" ) func TestServer_Keys(t *testing.T) { - // TODO: isolated instance + t.Parallel() - clientID, _ := createClient(t) - authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess, zitadelAudienceScope) - sessionID, sessionToken, _, _ := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + instance := integration.NewInstance(CTX) + ctxLogin := instance.WithAuthorization(CTX, integration.UserTypeLogin) + + clientID, _ := createClient(t, instance) + authRequestID := createAuthRequest(t, instance, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess, zitadelAudienceScope) + + instance.RegisterUserPasskey(instance.WithAuthorization(CTX, integration.UserTypeOrgOwner), instance.AdminUserID) + sessionID, sessionToken, _, _ := instance.CreateVerifiedWebAuthNSession(t, ctxLogin, instance.AdminUserID) + linkResp, err := instance.Client.OIDCv2.CreateCallback(ctxLogin, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -41,10 +47,10 @@ func TestServer_Keys(t *testing.T) { // code exchange so we are sure there is 1 legacy key pair. code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - _, err = exchangeTokens(t, clientID, code, redirectURI) + _, err = exchangeTokens(t, instance, clientID, code, redirectURI) require.NoError(t, err) - issuer := http_util.BuildHTTP(Tester.Config.ExternalDomain, Tester.Config.Port, Tester.Config.ExternalSecure) + issuer := http_util.BuildHTTP(instance.Domain, instance.Config.Port, instance.Config.Secure) discovery, err := client.Discover(CTX, issuer, http.DefaultClient) require.NoError(t, err) @@ -66,7 +72,7 @@ func TestServer_Keys(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ensureWebKeyFeature(t, tt.webKeyFeature) + ensureWebKeyFeature(t, instance, tt.webKeyFeature) assert.EventuallyWithT(t, func(ttt *assert.CollectT) { resp, err := http.Get(discovery.JwksURI) @@ -100,14 +106,16 @@ func TestServer_Keys(t *testing.T) { } } -func ensureWebKeyFeature(t *testing.T, set bool) { - _, err := Tester.Client.FeatureV2.SetInstanceFeatures(CTXIAM, &feature.SetInstanceFeaturesRequest{ +func ensureWebKeyFeature(t *testing.T, instance *integration.Instance, set bool) { + ctxIam := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + + _, err := instance.Client.FeatureV2.SetInstanceFeatures(ctxIam, &feature.SetInstanceFeaturesRequest{ WebKey: proto.Bool(set), }) require.NoError(t, err) t.Cleanup(func() { - _, err := Tester.Client.FeatureV2.SetInstanceFeatures(CTXIAM, &feature.SetInstanceFeaturesRequest{ + _, err := instance.Client.FeatureV2.SetInstanceFeatures(ctxIam, &feature.SetInstanceFeaturesRequest{ WebKey: proto.Bool(false), }) require.NoError(t, err) diff --git a/internal/api/oidc/oidc_integration_test.go b/internal/api/oidc/integration_test/oidc_test.go similarity index 59% rename from internal/api/oidc/oidc_integration_test.go rename to internal/api/oidc/integration_test/oidc_test.go index 1f7f615809..016745cf56 100644 --- a/internal/api/oidc/oidc_integration_test.go +++ b/internal/api/oidc/integration_test/oidc_test.go @@ -28,7 +28,7 @@ var ( CTX context.Context CTXLOGIN context.Context CTXIAM context.Context - Tester *integration.Tester + Instance *integration.Instance User *user.AddHumanUserResponse ) @@ -41,27 +41,26 @@ const ( func TestMain(m *testing.M) { os.Exit(func() int { - ctx, _, cancel := integration.Contexts(10 * time.Minute) + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute) defer cancel() - Tester = integration.NewTester(ctx) - defer Tester.Done() + Instance = integration.NewInstance(ctx) - CTX = Tester.WithAuthorization(ctx, integration.OrgOwner) - User = Tester.CreateHumanUser(CTX) - Tester.SetUserPassword(CTX, User.GetUserId(), integration.UserPassword, false) - Tester.RegisterUserPasskey(CTX, User.GetUserId()) - CTXLOGIN = Tester.WithAuthorization(ctx, integration.Login) - CTXIAM = Tester.WithAuthorization(ctx, integration.IAMOwner) + CTX = Instance.WithAuthorization(ctx, integration.UserTypeOrgOwner) + User = Instance.CreateHumanUser(CTX) + Instance.SetUserPassword(CTX, User.GetUserId(), integration.UserPassword, false) + Instance.RegisterUserPasskey(CTX, User.GetUserId()) + CTXLOGIN = Instance.WithAuthorization(ctx, integration.UserTypeLogin) + CTXIAM = Instance.WithAuthorization(ctx, integration.UserTypeIAMOwner) return m.Run() }()) } func Test_ZITADEL_API_missing_audience_scope(t *testing.T) { - clientID, _ := createClient(t) - authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + clientID, _ := createClient(t, Instance) + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI, oidc.ScopeOpenID) + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -74,22 +73,22 @@ func Test_ZITADEL_API_missing_audience_scope(t *testing.T) { // code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, false) assertIDTokenClaims(t, tokens.IDTokenClaims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) ctx := metadata.AppendToOutgoingContext(context.Background(), "Authorization", fmt.Sprintf("%s %s", tokens.TokenType, tokens.AccessToken)) - myUserResp, err := Tester.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) + myUserResp, err := Instance.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) require.Error(t, err) require.Nil(t, myUserResp) } func Test_ZITADEL_API_missing_authentication(t *testing.T) { - clientID, _ := createClient(t) - authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, zitadelAudienceScope) - createResp, err := Tester.Client.SessionV2.CreateSession(CTX, &session.CreateSessionRequest{ + clientID, _ := createClient(t, Instance) + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI, oidc.ScopeOpenID, zitadelAudienceScope) + createResp, err := Instance.Client.SessionV2.CreateSession(CTX, &session.CreateSessionRequest{ Checks: &session.Checks{ User: &session.CheckUser{ Search: &session.CheckUser_UserId{UserId: User.GetUserId()}, @@ -97,7 +96,7 @@ func Test_ZITADEL_API_missing_authentication(t *testing.T) { }, }) require.NoError(t, err) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -110,24 +109,24 @@ func Test_ZITADEL_API_missing_authentication(t *testing.T) { // code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) ctx := metadata.AppendToOutgoingContext(context.Background(), "Authorization", fmt.Sprintf("%s %s", tokens.TokenType, tokens.AccessToken)) - myUserResp, err := Tester.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) + myUserResp, err := Instance.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) require.Error(t, err) require.Nil(t, myUserResp) } func Test_ZITADEL_API_missing_mfa_policy(t *testing.T) { - clientID, _ := createClient(t) - org := Tester.CreateOrganization(CTXIAM, fmt.Sprintf("ZITADEL_API_MISSING_MFA_%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) + clientID, _ := createClient(t, Instance) + org := Instance.CreateOrganization(CTXIAM, fmt.Sprintf("ZITADEL_API_MISSING_MFA_%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) userID := org.CreatedAdmins[0].GetUserId() - Tester.SetUserPassword(CTXIAM, userID, integration.UserPassword, false) - authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, zitadelAudienceScope) - sessionID, sessionToken, startTime, changeTime := Tester.CreatePasswordSession(t, CTXLOGIN, userID, integration.UserPassword) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + Instance.SetUserPassword(CTXIAM, userID, integration.UserPassword, false) + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI, oidc.ScopeOpenID, zitadelAudienceScope) + sessionID, sessionToken, startTime, changeTime := Instance.CreatePasswordSession(t, CTXLOGIN, userID, integration.UserPassword) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -140,20 +139,20 @@ func Test_ZITADEL_API_missing_mfa_policy(t *testing.T) { // code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertIDTokenClaims(t, tokens.IDTokenClaims, userID, armPassword, startTime, changeTime, sessionID) ctx := metadata.AppendToOutgoingContext(context.Background(), "Authorization", fmt.Sprintf("%s %s", tokens.TokenType, tokens.AccessToken)) // pre check if request would succeed - myUserResp, err := Tester.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) + myUserResp, err := Instance.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) require.NoError(t, err) require.Equal(t, userID, myUserResp.GetUser().GetId()) // require MFA ctxOrg := metadata.AppendToOutgoingContext(CTXIAM, "x-zitadel-orgid", org.GetOrganizationId()) - _, err = Tester.Client.Mgmt.AddCustomLoginPolicy(ctxOrg, &mgmt.AddCustomLoginPolicyRequest{ + _, err = Instance.Client.Mgmt.AddCustomLoginPolicy(ctxOrg, &mgmt.AddCustomLoginPolicyRequest{ ForceMfa: true, }) require.NoError(t, err) @@ -164,23 +163,23 @@ func Test_ZITADEL_API_missing_mfa_policy(t *testing.T) { retryDuration = time.Until(ctxDeadline) } require.EventuallyWithT(t, func(ttt *assert.CollectT) { - got, getErr := Tester.Client.Mgmt.GetLoginPolicy(ctxOrg, &mgmt.GetLoginPolicyRequest{}) + got, getErr := Instance.Client.Mgmt.GetLoginPolicy(ctxOrg, &mgmt.GetLoginPolicyRequest{}) assert.NoError(ttt, getErr) assert.False(ttt, got.GetPolicy().IsDefault) }, retryDuration, time.Millisecond*100, "timeout waiting for login policy") // now it must fail - myUserResp, err = Tester.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) + myUserResp, err = Instance.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) require.Error(t, err) require.Nil(t, myUserResp) } func Test_ZITADEL_API_success(t *testing.T) { - clientID, _ := createClient(t) - authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, zitadelAudienceScope) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + clientID, _ := createClient(t, Instance) + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI, oidc.ScopeOpenID, zitadelAudienceScope) + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -193,28 +192,28 @@ func Test_ZITADEL_API_success(t *testing.T) { // code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, false) assertIDTokenClaims(t, tokens.IDTokenClaims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) ctx := metadata.AppendToOutgoingContext(context.Background(), "Authorization", fmt.Sprintf("%s %s", tokens.TokenType, tokens.AccessToken)) - myUserResp, err := Tester.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) + myUserResp, err := Instance.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) require.NoError(t, err) require.Equal(t, User.GetUserId(), myUserResp.GetUser().GetId()) } func Test_ZITADEL_API_glob_redirects(t *testing.T) { const redirectURI = "https://my-org-1yfnjl2xj-my-app.vercel.app/api/auth/callback/zitadel" - clientID, _ := createClientWithOpts(t, clientOpts{ + clientID, _ := createClientWithOpts(t, Instance, clientOpts{ redirectURI: "https://my-org-*-my-app.vercel.app/api/auth/callback/zitadel", logoutURI: "https://my-org-*-my-app.vercel.app/", devMode: true, }) - authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, zitadelAudienceScope) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI, oidc.ScopeOpenID, zitadelAudienceScope) + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -227,23 +226,23 @@ func Test_ZITADEL_API_glob_redirects(t *testing.T) { // code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, false) assertIDTokenClaims(t, tokens.IDTokenClaims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) ctx := metadata.AppendToOutgoingContext(context.Background(), "Authorization", fmt.Sprintf("%s %s", tokens.TokenType, tokens.AccessToken)) - myUserResp, err := Tester.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) + myUserResp, err := Instance.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) require.NoError(t, err) require.Equal(t, User.GetUserId(), myUserResp.GetUser().GetId()) } func Test_ZITADEL_API_inactive_access_token(t *testing.T) { - clientID, _ := createClient(t) - authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess, zitadelAudienceScope) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + clientID, _ := createClient(t, Instance) + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess, zitadelAudienceScope) + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -256,14 +255,14 @@ func Test_ZITADEL_API_inactive_access_token(t *testing.T) { // code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, true) assertIDTokenClaims(t, tokens.IDTokenClaims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) // make sure token works ctx := metadata.AppendToOutgoingContext(context.Background(), "Authorization", fmt.Sprintf("%s %s", tokens.TokenType, tokens.AccessToken)) - myUserResp, err := Tester.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) + myUserResp, err := Instance.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) require.NoError(t, err) require.Equal(t, User.GetUserId(), myUserResp.GetUser().GetId()) @@ -274,18 +273,18 @@ func Test_ZITADEL_API_inactive_access_token(t *testing.T) { // use invalidated token ctx = metadata.AppendToOutgoingContext(context.Background(), "Authorization", fmt.Sprintf("%s %s", tokens.TokenType, tokens.AccessToken)) - myUserResp, err = Tester.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) + myUserResp, err = Instance.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) require.Error(t, err) require.Nil(t, myUserResp) } func Test_ZITADEL_API_terminated_session(t *testing.T) { - clientID, _ := createClient(t) - provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) + clientID, _ := createClient(t, Instance) + provider, err := Instance.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) - authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess, zitadelAudienceScope) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess, zitadelAudienceScope) + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -298,14 +297,14 @@ func Test_ZITADEL_API_terminated_session(t *testing.T) { // code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, true) assertIDTokenClaims(t, tokens.IDTokenClaims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) // make sure token works ctx := metadata.AppendToOutgoingContext(context.Background(), "Authorization", fmt.Sprintf("%s %s", tokens.TokenType, tokens.AccessToken)) - myUserResp, err := Tester.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) + myUserResp, err := Instance.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) require.NoError(t, err) require.Equal(t, User.GetUserId(), myUserResp.GetUser().GetId()) @@ -316,13 +315,13 @@ func Test_ZITADEL_API_terminated_session(t *testing.T) { // use token from terminated session ctx = metadata.AppendToOutgoingContext(context.Background(), "Authorization", fmt.Sprintf("%s %s", tokens.TokenType, tokens.AccessToken)) - myUserResp, err = Tester.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) + myUserResp, err = Instance.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) require.Error(t, err) require.Nil(t, myUserResp) } func Test_ZITADEL_API_terminated_session_user_disabled(t *testing.T) { - clientID, _ := createClient(t) + clientID, _ := createClient(t, Instance) tests := []struct { name string disable func(userID string) error @@ -330,32 +329,32 @@ func Test_ZITADEL_API_terminated_session_user_disabled(t *testing.T) { { name: "deactivated", disable: func(userID string) error { - _, err := Tester.Client.UserV2.DeactivateUser(CTX, &user.DeactivateUserRequest{UserId: userID}) + _, err := Instance.Client.UserV2.DeactivateUser(CTX, &user.DeactivateUserRequest{UserId: userID}) return err }, }, { name: "locked", disable: func(userID string) error { - _, err := Tester.Client.UserV2.LockUser(CTX, &user.LockUserRequest{UserId: userID}) + _, err := Instance.Client.UserV2.LockUser(CTX, &user.LockUserRequest{UserId: userID}) return err }, }, { name: "deleted", disable: func(userID string) error { - _, err := Tester.Client.UserV2.DeleteUser(CTX, &user.DeleteUserRequest{UserId: userID}) + _, err := Instance.Client.UserV2.DeleteUser(CTX, &user.DeleteUserRequest{UserId: userID}) return err }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - disabledUser := Tester.CreateHumanUser(CTX) - Tester.SetUserPassword(CTX, disabledUser.GetUserId(), integration.UserPassword, false) - authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess, zitadelAudienceScope) - sessionID, sessionToken, startTime, changeTime := Tester.CreatePasswordSession(t, CTXLOGIN, disabledUser.GetUserId(), integration.UserPassword) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + disabledUser := Instance.CreateHumanUser(CTX) + Instance.SetUserPassword(CTX, disabledUser.GetUserId(), integration.UserPassword, false) + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess, zitadelAudienceScope) + sessionID, sessionToken, startTime, changeTime := Instance.CreatePasswordSession(t, CTXLOGIN, disabledUser.GetUserId(), integration.UserPassword) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -368,14 +367,14 @@ func Test_ZITADEL_API_terminated_session_user_disabled(t *testing.T) { // code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, true) assertIDTokenClaims(t, tokens.IDTokenClaims, disabledUser.GetUserId(), armPassword, startTime, changeTime, sessionID) // make sure token works ctx := metadata.AppendToOutgoingContext(context.Background(), "Authorization", fmt.Sprintf("%s %s", tokens.TokenType, tokens.AccessToken)) - myUserResp, err := Tester.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) + myUserResp, err := Instance.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) require.NoError(t, err) require.Equal(t, disabledUser.GetUserId(), myUserResp.GetUser().GetId()) @@ -385,15 +384,15 @@ func Test_ZITADEL_API_terminated_session_user_disabled(t *testing.T) { // use token from deactivated user ctx = metadata.AppendToOutgoingContext(context.Background(), "Authorization", fmt.Sprintf("%s %s", tokens.TokenType, tokens.AccessToken)) - myUserResp, err = Tester.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) + myUserResp, err = Instance.Client.Auth.GetMyUser(ctx, &auth.GetMyUserRequest{}) require.Error(t, err) require.Nil(t, myUserResp) }) } } -func createClient(t testing.TB) (clientID, projectID string) { - return createClientWithOpts(t, clientOpts{ +func createClient(t testing.TB, instance *integration.Instance) (clientID, projectID string) { + return createClientWithOpts(t, instance, clientOpts{ redirectURI: redirectURI, logoutURI: logoutRedirectURI, devMode: false, @@ -406,28 +405,30 @@ type clientOpts struct { devMode bool } -func createClientWithOpts(t testing.TB, opts clientOpts) (clientID, projectID string) { - project, err := Tester.CreateProject(CTX) +func createClientWithOpts(t testing.TB, instance *integration.Instance, opts clientOpts) (clientID, projectID string) { + ctx := instance.WithAuthorization(CTX, integration.UserTypeOrgOwner) + + project, err := instance.CreateProject(ctx) require.NoError(t, err) - app, err := Tester.CreateOIDCNativeClient(CTX, opts.redirectURI, opts.logoutURI, project.GetId(), opts.devMode) + app, err := instance.CreateOIDCNativeClient(ctx, opts.redirectURI, opts.logoutURI, project.GetId(), opts.devMode) require.NoError(t, err) return app.GetClientId(), project.GetId() } func createImplicitClient(t testing.TB) string { - app, err := Tester.CreateOIDCImplicitFlowClient(CTX, redirectURIImplicit) + app, err := Instance.CreateOIDCImplicitFlowClient(CTX, redirectURIImplicit) require.NoError(t, err) return app.GetClientId() } -func createAuthRequest(t testing.TB, clientID, redirectURI string, scope ...string) string { - redURL, err := Tester.CreateOIDCAuthRequest(CTX, clientID, Tester.Users[integration.FirstInstanceUsersKey][integration.Login].ID, redirectURI, scope...) +func createAuthRequest(t testing.TB, instance *integration.Instance, clientID, redirectURI string, scope ...string) string { + redURL, err := instance.CreateOIDCAuthRequest(CTX, clientID, instance.Users.Get(integration.UserTypeLogin).ID, redirectURI, scope...) require.NoError(t, err) return redURL } func createAuthRequestImplicit(t testing.TB, clientID, redirectURI string, scope ...string) string { - redURL, err := Tester.CreateOIDCAuthRequestImplicit(CTX, clientID, Tester.Users[integration.FirstInstanceUsersKey][integration.Login].ID, redirectURI, scope...) + redURL, err := Instance.CreateOIDCAuthRequestImplicit(CTX, clientID, Instance.Users.Get(integration.UserTypeLogin).ID, redirectURI, scope...) require.NoError(t, err) return redURL } @@ -437,5 +438,5 @@ func assertOIDCTime(t *testing.T, actual oidc.Time, expected time.Time) { } func assertOIDCTimeRange(t *testing.T, actual oidc.Time, expectedStart, expectedEnd time.Time) { - assert.WithinRange(t, actual.AsTime(), expectedStart.Add(-1*time.Second), expectedEnd.Add(1*time.Second)) + assert.WithinRange(t, actual.AsTime(), expectedStart.Add(-10*time.Second), expectedEnd.Add(10*time.Second)) } diff --git a/internal/api/oidc/server_integration_test.go b/internal/api/oidc/integration_test/server_test.go similarity index 92% rename from internal/api/oidc/server_integration_test.go rename to internal/api/oidc/integration_test/server_test.go index 8a0c8796fa..fcf9bfb65e 100644 --- a/internal/api/oidc/server_integration_test.go +++ b/internal/api/oidc/integration_test/server_test.go @@ -18,8 +18,10 @@ import ( ) func TestServer_RefreshToken_Status(t *testing.T) { - clientID, _ := createClient(t) - provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) + t.Parallel() + + clientID, _ := createClient(t, Instance) + provider, err := Instance.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) tests := []struct { diff --git a/internal/api/oidc/token_client_credentials_integration_test.go b/internal/api/oidc/integration_test/token_client_credentials_test.go similarity index 80% rename from internal/api/oidc/token_client_credentials_integration_test.go rename to internal/api/oidc/integration_test/token_client_credentials_test.go index 21a1c4de75..5316202e31 100644 --- a/internal/api/oidc/token_client_credentials_integration_test.go +++ b/internal/api/oidc/integration_test/token_client_credentials_test.go @@ -19,7 +19,9 @@ import ( ) func TestServer_ClientCredentialsExchange(t *testing.T) { - machine, name, clientID, clientSecret, err := Tester.CreateOIDCCredentialsClient(CTX) + t.Parallel() + + machine, name, clientID, clientSecret, err := Instance.CreateOIDCCredentialsClient(CTX) require.NoError(t, err) type claims struct { @@ -57,7 +59,7 @@ func TestServer_ClientCredentialsExchange(t *testing.T) { name: "machine user without secret error", clientID: func() string { name := gofakeit.Username() - _, err := Tester.Client.Mgmt.AddMachineUser(CTX, &management.AddMachineUserRequest{ + _, err := Instance.Client.Mgmt.AddMachineUser(CTX, &management.AddMachineUserRequest{ Name: name, UserName: name, AccessTokenType: user.AccessTokenType_ACCESS_TOKEN_TYPE_JWT, @@ -99,14 +101,14 @@ func TestServer_ClientCredentialsExchange(t *testing.T) { clientSecret: clientSecret, scope: []string{ oidc.ScopeOpenID, - domain.OrgIDScope + Tester.Organisation.ID, - domain.OrgDomainPrimaryScope + Tester.Organisation.Domain, + domain.OrgIDScope + Instance.DefaultOrg.Id, + domain.OrgDomainPrimaryScope + Instance.DefaultOrg.PrimaryDomain, }, wantClaims: claims{ - resourceOwnerID: Tester.Organisation.ID, - resourceOwnerName: Tester.Organisation.Name, - resourceOwnerPrimaryDomain: Tester.Organisation.Domain, - orgDomain: Tester.Organisation.Domain, + resourceOwnerID: Instance.DefaultOrg.Id, + resourceOwnerName: Instance.DefaultOrg.Name, + resourceOwnerPrimaryDomain: Instance.DefaultOrg.PrimaryDomain, + orgDomain: Instance.DefaultOrg.PrimaryDomain, }, }, { @@ -115,10 +117,10 @@ func TestServer_ClientCredentialsExchange(t *testing.T) { clientSecret: clientSecret, scope: []string{ oidc.ScopeOpenID, - domain.OrgDomainPrimaryScope + Tester.Organisation.Domain, + domain.OrgDomainPrimaryScope + Instance.DefaultOrg.PrimaryDomain, domain.OrgDomainPrimaryScope + "foo"}, wantClaims: claims{ - orgDomain: Tester.Organisation.Domain, + orgDomain: Instance.DefaultOrg.PrimaryDomain, }, }, { @@ -126,19 +128,19 @@ func TestServer_ClientCredentialsExchange(t *testing.T) { clientID: clientID, clientSecret: clientSecret, scope: []string{oidc.ScopeOpenID, - domain.OrgIDScope + Tester.Organisation.ID, + domain.OrgIDScope + Instance.DefaultOrg.Id, domain.OrgIDScope + "foo", }, wantClaims: claims{ - resourceOwnerID: Tester.Organisation.ID, - resourceOwnerName: Tester.Organisation.Name, - resourceOwnerPrimaryDomain: Tester.Organisation.Domain, + resourceOwnerID: Instance.DefaultOrg.Id, + resourceOwnerName: Instance.DefaultOrg.Name, + resourceOwnerPrimaryDomain: Instance.DefaultOrg.PrimaryDomain, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - provider, err := rp.NewRelyingPartyOIDC(CTX, Tester.OIDCIssuer(), tt.clientID, tt.clientSecret, redirectURI, tt.scope) + provider, err := rp.NewRelyingPartyOIDC(CTX, Instance.OIDCIssuer(), tt.clientID, tt.clientSecret, redirectURI, tt.scope) require.NoError(t, err) tokens, err := rp.ClientCredentials(CTX, provider, nil) if tt.wantErr { diff --git a/internal/api/oidc/token_exchange_integration_test.go b/internal/api/oidc/integration_test/token_exchange_test.go similarity index 91% rename from internal/api/oidc/token_exchange_integration_test.go rename to internal/api/oidc/integration_test/token_exchange_test.go index b8b4b0bbfe..26c4475024 100644 --- a/internal/api/oidc/token_exchange_integration_test.go +++ b/internal/api/oidc/integration_test/token_exchange_test.go @@ -26,9 +26,9 @@ import ( ) func setTokenExchangeFeature(t *testing.T, value bool) { - iamCTX := Tester.WithAuthorization(CTX, integration.IAMOwner) + iamCTX := Instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) - _, err := Tester.Client.FeatureV2.SetInstanceFeatures(iamCTX, &feature.SetInstanceFeaturesRequest{ + _, err := Instance.Client.FeatureV2.SetInstanceFeatures(iamCTX, &feature.SetInstanceFeaturesRequest{ OidcTokenExchange: proto.Bool(value), }) require.NoError(t, err) @@ -36,19 +36,19 @@ func setTokenExchangeFeature(t *testing.T, value bool) { } func resetFeatures(t *testing.T) { - iamCTX := Tester.WithAuthorization(CTX, integration.IAMOwner) - _, err := Tester.Client.FeatureV2.ResetInstanceFeatures(iamCTX, &feature.ResetInstanceFeaturesRequest{}) + iamCTX := Instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + _, err := Instance.Client.FeatureV2.ResetInstanceFeatures(iamCTX, &feature.ResetInstanceFeaturesRequest{}) require.NoError(t, err) time.Sleep(time.Second) } func setImpersonationPolicy(t *testing.T, value bool) { - iamCTX := Tester.WithAuthorization(CTX, integration.IAMOwner) + iamCTX := Instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) - policy, err := Tester.Client.Admin.GetSecurityPolicy(iamCTX, &admin.GetSecurityPolicyRequest{}) + policy, err := Instance.Client.Admin.GetSecurityPolicy(iamCTX, &admin.GetSecurityPolicyRequest{}) require.NoError(t, err) if policy.GetPolicy().GetEnableImpersonation() != value { - _, err = Tester.Client.Admin.SetSecurityPolicy(iamCTX, &admin.SetSecurityPolicyRequest{ + _, err = Instance.Client.Admin.SetSecurityPolicy(iamCTX, &admin.SetSecurityPolicyRequest{ EnableImpersonation: value, }) require.NoError(t, err) @@ -57,8 +57,8 @@ func setImpersonationPolicy(t *testing.T, value bool) { } func createMachineUserPATWithMembership(t *testing.T, roles ...string) (userID, pat string) { - iamCTX := Tester.WithAuthorization(CTX, integration.IAMOwner) - userID, pat, err := Tester.CreateMachineUserPATWithMembership(iamCTX, roles...) + iamCTX := Instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + userID, pat, err := Instance.CreateMachineUserPATWithMembership(iamCTX, roles...) require.NoError(t, err) return userID, pat } @@ -112,16 +112,18 @@ func refreshTokenVerifier(ctx context.Context, provider rp.RelyingParty, subject } func TestServer_TokenExchange(t *testing.T) { + t.Parallel() + t.Cleanup(func() { resetFeatures(t) setImpersonationPolicy(t, false) }) - client, keyData, err := Tester.CreateOIDCTokenExchangeClient(CTX) + client, keyData, err := Instance.CreateOIDCTokenExchangeClient(CTX) require.NoError(t, err) signer, err := rp.SignerFromKeyFile(keyData)() require.NoError(t, err) - exchanger, err := tokenexchange.NewTokenExchangerJWTProfile(CTX, Tester.OIDCIssuer(), client.GetClientId(), signer) + exchanger, err := tokenexchange.NewTokenExchangerJWTProfile(CTX, Instance.OIDCIssuer(), client.GetClientId(), signer) require.NoError(t, err) time.Sleep(time.Second) @@ -137,9 +139,9 @@ func TestServer_TokenExchange(t *testing.T) { patScopes := oidc.SpaceDelimitedArray{"openid", "profile", "urn:zitadel:iam:user:metadata", "urn:zitadel:iam:user:resourceowner"} - relyingParty, err := rp.NewRelyingPartyOIDC(CTX, Tester.OIDCIssuer(), client.GetClientId(), "", "", []string{"openid"}, rp.WithJWTProfile(rp.SignerFromKeyFile(keyData))) + relyingParty, err := rp.NewRelyingPartyOIDC(CTX, Instance.OIDCIssuer(), client.GetClientId(), "", "", []string{"openid"}, rp.WithJWTProfile(rp.SignerFromKeyFile(keyData))) require.NoError(t, err) - resourceServer, err := Tester.CreateResourceServerJWTProfile(CTX, keyData) + resourceServer, err := Instance.CreateResourceServerJWTProfile(CTX, keyData) require.NoError(t, err) type settings struct { @@ -481,7 +483,7 @@ func TestServer_TokenExchange(t *testing.T) { token, err := crypto.Sign(&oidc.JWTTokenRequest{ Issuer: client.GetClientId(), Subject: User.GetUserId(), - Audience: oidc.Audience{Tester.OIDCIssuer()}, + Audience: oidc.Audience{Instance.OIDCIssuer()}, ExpiresAt: oidc.FromTime(time.Now().Add(time.Hour)), IssuedAt: oidc.FromTime(time.Now().Add(-time.Second)), }, signer) @@ -559,13 +561,13 @@ func TestServer_TokenExchange(t *testing.T) { // This test tries to call the zitadel API with an impersonated token, // which should fail. func TestImpersonation_API_Call(t *testing.T) { - client, keyData, err := Tester.CreateOIDCTokenExchangeClient(CTX) + client, keyData, err := Instance.CreateOIDCTokenExchangeClient(CTX) require.NoError(t, err) signer, err := rp.SignerFromKeyFile(keyData)() require.NoError(t, err) - exchanger, err := tokenexchange.NewTokenExchangerJWTProfile(CTX, Tester.OIDCIssuer(), client.GetClientId(), signer) + exchanger, err := tokenexchange.NewTokenExchangerJWTProfile(CTX, Instance.OIDCIssuer(), client.GetClientId(), signer) require.NoError(t, err) - resourceServer, err := Tester.CreateResourceServerJWTProfile(CTX, keyData) + resourceServer, err := Instance.CreateResourceServerJWTProfile(CTX, keyData) require.NoError(t, err) setTokenExchangeFeature(t, true) @@ -576,15 +578,15 @@ func TestImpersonation_API_Call(t *testing.T) { }) iamUserID, iamImpersonatorPAT := createMachineUserPATWithMembership(t, "IAM_ADMIN_IMPERSONATOR") - iamOwner := Tester.Users.Get(integration.FirstInstanceUsersKey, integration.IAMOwner) + iamOwner := Instance.Users.Get(integration.UserTypeIAMOwner) // impersonating the IAM owner! resp, err := tokenexchange.ExchangeToken(CTX, exchanger, iamOwner.Token, oidc.AccessTokenType, iamImpersonatorPAT, oidc.AccessTokenType, nil, nil, nil, oidc.AccessTokenType) require.NoError(t, err) accessTokenVerifier(CTX, resourceServer, iamOwner.ID, iamUserID) - impersonatedCTX := Tester.WithAuthorizationToken(CTX, resp.AccessToken) - _, err = Tester.Client.Admin.GetAllowedLanguages(impersonatedCTX, &admin.GetAllowedLanguagesRequest{}) + impersonatedCTX := integration.WithAuthorizationToken(CTX, resp.AccessToken) + _, err = Instance.Client.Admin.GetAllowedLanguages(impersonatedCTX, &admin.GetAllowedLanguagesRequest{}) status := status.Convert(err) assert.Equal(t, codes.PermissionDenied, status.Code()) assert.Equal(t, "Errors.TokenExchange.Token.NotForAPI (APP-Shi0J)", status.Message()) diff --git a/internal/api/oidc/token_jwt_profile_integration_test.go b/internal/api/oidc/integration_test/token_jwt_profile_test.go similarity index 76% rename from internal/api/oidc/token_jwt_profile_integration_test.go rename to internal/api/oidc/integration_test/token_jwt_profile_test.go index 0ad8d76da2..24fad41a2b 100644 --- a/internal/api/oidc/token_jwt_profile_integration_test.go +++ b/internal/api/oidc/integration_test/token_jwt_profile_test.go @@ -17,7 +17,9 @@ import ( ) func TestServer_JWTProfile(t *testing.T) { - user, name, keyData, err := Tester.CreateOIDCJWTProfileClient(CTX) + t.Parallel() + + user, name, keyData, err := Instance.CreateOIDCJWTProfileClient(CTX) require.NoError(t, err) type claims struct { @@ -56,14 +58,14 @@ func TestServer_JWTProfile(t *testing.T) { keyData: keyData, scope: []string{ oidc.ScopeOpenID, - domain.OrgIDScope + Tester.Organisation.ID, - domain.OrgDomainPrimaryScope + Tester.Organisation.Domain, + domain.OrgIDScope + Instance.DefaultOrg.Id, + domain.OrgDomainPrimaryScope + Instance.DefaultOrg.PrimaryDomain, }, wantClaims: claims{ - resourceOwnerID: Tester.Organisation.ID, - resourceOwnerName: Tester.Organisation.Name, - resourceOwnerPrimaryDomain: Tester.Organisation.Domain, - orgDomain: Tester.Organisation.Domain, + resourceOwnerID: Instance.DefaultOrg.Id, + resourceOwnerName: Instance.DefaultOrg.Name, + resourceOwnerPrimaryDomain: Instance.DefaultOrg.PrimaryDomain, + orgDomain: Instance.DefaultOrg.PrimaryDomain, }, }, { @@ -71,29 +73,29 @@ func TestServer_JWTProfile(t *testing.T) { keyData: keyData, scope: []string{ oidc.ScopeOpenID, - domain.OrgDomainPrimaryScope + Tester.Organisation.Domain, + domain.OrgDomainPrimaryScope + Instance.DefaultOrg.PrimaryDomain, domain.OrgDomainPrimaryScope + "foo"}, wantClaims: claims{ - orgDomain: Tester.Organisation.Domain, + orgDomain: Instance.DefaultOrg.PrimaryDomain, }, }, { name: "invalid org id filtered", keyData: keyData, scope: []string{oidc.ScopeOpenID, - domain.OrgIDScope + Tester.Organisation.ID, + domain.OrgIDScope + Instance.DefaultOrg.Id, domain.OrgIDScope + "foo", }, wantClaims: claims{ - resourceOwnerID: Tester.Organisation.ID, - resourceOwnerName: Tester.Organisation.Name, - resourceOwnerPrimaryDomain: Tester.Organisation.Domain, + resourceOwnerID: Instance.DefaultOrg.Id, + resourceOwnerName: Instance.DefaultOrg.Name, + resourceOwnerPrimaryDomain: Instance.DefaultOrg.PrimaryDomain, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - tokenSource, err := profile.NewJWTProfileTokenSourceFromKeyFileData(CTX, Tester.OIDCIssuer(), tt.keyData, tt.scope) + tokenSource, err := profile.NewJWTProfileTokenSourceFromKeyFileData(CTX, Instance.OIDCIssuer(), tt.keyData, tt.scope) require.NoError(t, err) tokens, err := tokenSource.TokenCtx(CTX) @@ -104,7 +106,7 @@ func TestServer_JWTProfile(t *testing.T) { require.NoError(t, err) require.NotNil(t, tokens) - provider, err := rp.NewRelyingPartyOIDC(CTX, Tester.OIDCIssuer(), "", "", redirectURI, tt.scope) + provider, err := rp.NewRelyingPartyOIDC(CTX, Instance.OIDCIssuer(), "", "", redirectURI, tt.scope) require.NoError(t, err) userinfo, err := rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, oidc.BearerToken, user.GetUserId(), provider) require.NoError(t, err) diff --git a/internal/api/oidc/userinfo_integration_test.go b/internal/api/oidc/integration_test/userinfo_test.go similarity index 82% rename from internal/api/oidc/userinfo_integration_test.go rename to internal/api/oidc/integration_test/userinfo_test.go index e938078078..c2ad3be3ec 100644 --- a/internal/api/oidc/userinfo_integration_test.go +++ b/internal/api/oidc/integration_test/userinfo_test.go @@ -27,9 +27,9 @@ import ( // userinfo integration test against a matrix of different feature flags. // This ensure that the response of the different implementations remains the same. func TestServer_UserInfo(t *testing.T) { - iamOwnerCTX := Tester.WithAuthorization(CTX, integration.IAMOwner) + iamOwnerCTX := Instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) t.Cleanup(func() { - _, err := Tester.Client.FeatureV2.ResetInstanceFeatures(iamOwnerCTX, &feature.ResetInstanceFeaturesRequest{}) + _, err := Instance.Client.FeatureV2.ResetInstanceFeatures(iamOwnerCTX, &feature.ResetInstanceFeaturesRequest{}) require.NoError(t, err) }) tests := []struct { @@ -67,7 +67,7 @@ func TestServer_UserInfo(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - _, err := Tester.Client.FeatureV2.SetInstanceFeatures(iamOwnerCTX, &feature.SetInstanceFeaturesRequest{ + _, err := Instance.Client.FeatureV2.SetInstanceFeatures(iamOwnerCTX, &feature.SetInstanceFeaturesRequest{ OidcLegacyIntrospection: &tt.legacy, OidcTriggerIntrospectionProjections: &tt.trigger, WebKey: &tt.webKey, @@ -86,7 +86,7 @@ func testServer_UserInfo(t *testing.T) { roleBar = "bar" ) - clientID, projectID := createClient(t) + clientID, projectID := createClient(t, Instance) addProjectRolesGrants(t, User.GetUserId(), projectID, roleFoo, roleBar) tests := []struct { @@ -133,21 +133,21 @@ func testServer_UserInfo(t *testing.T) { { name: "project role assertion", prepare: func(t *testing.T, clientID string, scope []string) *oidc.Tokens[*oidc.IDTokenClaims] { - _, err := Tester.Client.Mgmt.UpdateProject(CTX, &management.UpdateProjectRequest{ + _, err := Instance.Client.Mgmt.UpdateProject(CTX, &management.UpdateProjectRequest{ Id: projectID, Name: fmt.Sprintf("project-%d", time.Now().UnixNano()), ProjectRoleAssertion: true, }) require.NoError(t, err) t.Cleanup(func() { - _, err := Tester.Client.Mgmt.UpdateProject(CTX, &management.UpdateProjectRequest{ + _, err := Instance.Client.Mgmt.UpdateProject(CTX, &management.UpdateProjectRequest{ Id: projectID, Name: fmt.Sprintf("project-%d", time.Now().UnixNano()), ProjectRoleAssertion: false, }) require.NoError(t, err) }) - resp, err := Tester.Client.Mgmt.GetProjectByID(CTX, &management.GetProjectByIDRequest{Id: projectID}) + resp, err := Instance.Client.Mgmt.GetProjectByID(CTX, &management.GetProjectByIDRequest{Id: projectID}) require.NoError(t, err) require.True(t, resp.GetProject().GetProjectRoleAssertion(), "project role assertion") @@ -157,7 +157,7 @@ func testServer_UserInfo(t *testing.T) { assertions: []func(*testing.T, *oidc.UserInfo){ assertUserinfo, func(t *testing.T, ui *oidc.UserInfo) { - assertProjectRoleClaims(t, projectID, ui.Claims, true, []string{roleFoo, roleBar}, []string{Tester.Organisation.ID}) + assertProjectRoleClaims(t, projectID, ui.Claims, true, []string{roleFoo, roleBar}, []string{Instance.DefaultOrg.Id}) }, }, }, @@ -170,7 +170,7 @@ func testServer_UserInfo(t *testing.T) { assertions: []func(*testing.T, *oidc.UserInfo){ assertUserinfo, func(t *testing.T, ui *oidc.UserInfo) { - assertProjectRoleClaims(t, projectID, ui.Claims, true, []string{roleFoo}, []string{Tester.Organisation.ID}) + assertProjectRoleClaims(t, projectID, ui.Claims, true, []string{roleFoo}, []string{Instance.DefaultOrg.Id}) }, }, }, @@ -184,14 +184,14 @@ func testServer_UserInfo(t *testing.T) { assertions: []func(*testing.T, *oidc.UserInfo){ assertUserinfo, func(t *testing.T, ui *oidc.UserInfo) { - assertProjectRoleClaims(t, projectID, ui.Claims, true, []string{roleFoo}, []string{Tester.Organisation.ID}) + assertProjectRoleClaims(t, projectID, ui.Claims, true, []string{roleFoo}, []string{Instance.DefaultOrg.Id}) }, }, }, { name: "PAT", prepare: func(t *testing.T, clientID string, scope []string) *oidc.Tokens[*oidc.IDTokenClaims] { - user := Tester.Users.Get(integration.FirstInstanceUsersKey, integration.OrgOwner) + user := Instance.Users.Get(integration.UserTypeOrgOwner) return &oidc.Tokens[*oidc.IDTokenClaims]{ Token: &oauth2.Token{ AccessToken: user.Token, @@ -206,11 +206,8 @@ func testServer_UserInfo(t *testing.T) { }, assertions: []func(*testing.T, *oidc.UserInfo){ func(t *testing.T, ui *oidc.UserInfo) { - user := Tester.Users.Get(integration.FirstInstanceUsersKey, integration.OrgOwner) + user := Instance.Users.Get(integration.UserTypeOrgOwner) assert.Equal(t, user.ID, ui.Subject) - assert.Equal(t, user.PreferredLoginName, ui.PreferredUsername) - assert.Equal(t, user.Machine.Name, ui.Name) - assert.Equal(t, user.ResourceOwner, ui.Claims[oidc_api.ClaimResourceOwnerID]) assert.NotEmpty(t, ui.Claims[oidc_api.ClaimResourceOwnerName]) assert.NotEmpty(t, ui.Claims[oidc_api.ClaimResourceOwnerPrimaryDomain]) }, @@ -220,7 +217,7 @@ func testServer_UserInfo(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tokens := tt.prepare(t, clientID, tt.scope) - provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) + provider, err := Instance.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) userinfo, err := rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) if tt.wantErr { @@ -242,17 +239,17 @@ func TestServer_UserInfo_OrgIDRoles(t *testing.T) { roleFoo = "foo" roleBar = "bar" ) - clientID, projectID := createClient(t) + clientID, projectID := createClient(t, Instance) addProjectRolesGrants(t, User.GetUserId(), projectID, roleFoo, roleBar) grantedOrgID := addProjectOrgGrant(t, User.GetUserId(), projectID, roleFoo, roleBar) - _, err := Tester.Client.Mgmt.UpdateProject(CTX, &management.UpdateProjectRequest{ + _, err := Instance.Client.Mgmt.UpdateProject(CTX, &management.UpdateProjectRequest{ Id: projectID, Name: fmt.Sprintf("project-%d", time.Now().UnixNano()), ProjectRoleAssertion: true, }) require.NoError(t, err) - resp, err := Tester.Client.Mgmt.GetProjectByID(CTX, &management.GetProjectByIDRequest{Id: projectID}) + resp, err := Instance.Client.Mgmt.GetProjectByID(CTX, &management.GetProjectByIDRequest{Id: projectID}) require.NoError(t, err) require.True(t, resp.GetProject().GetProjectRoleAssertion(), "project role assertion") @@ -266,7 +263,7 @@ func TestServer_UserInfo_OrgIDRoles(t *testing.T) { scope: []string{ oidc.ScopeOpenID, oidc.ScopeOfflineAccess, }, - wantRoleOrgIDs: []string{Tester.Organisation.ID, grantedOrgID}, + wantRoleOrgIDs: []string{Instance.DefaultOrg.Id, grantedOrgID}, }, { name: "only granted org", @@ -279,24 +276,24 @@ func TestServer_UserInfo_OrgIDRoles(t *testing.T) { name: "only own org", scope: []string{ oidc.ScopeOpenID, oidc.ScopeOfflineAccess, - domain.OrgRoleIDScope + Tester.Organisation.ID, + domain.OrgRoleIDScope + Instance.DefaultOrg.Id, }, - wantRoleOrgIDs: []string{Tester.Organisation.ID}, + wantRoleOrgIDs: []string{Instance.DefaultOrg.Id}, }, { name: "request both orgs", scope: []string{ oidc.ScopeOpenID, oidc.ScopeOfflineAccess, - domain.OrgRoleIDScope + Tester.Organisation.ID, + domain.OrgRoleIDScope + Instance.DefaultOrg.Id, domain.OrgRoleIDScope + grantedOrgID, }, - wantRoleOrgIDs: []string{Tester.Organisation.ID, grantedOrgID}, + wantRoleOrgIDs: []string{Instance.DefaultOrg.Id, grantedOrgID}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tokens := getTokens(t, clientID, tt.scope) - provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) + provider, err := Instance.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) userinfo, err := rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) require.NoError(t, err) @@ -312,10 +309,10 @@ func TestServer_UserInfo_Issue6662(t *testing.T) { roleBar = "bar" ) - project, err := Tester.CreateProject(CTX) + project, err := Instance.CreateProject(CTX) projectID := project.GetId() require.NoError(t, err) - user, _, clientID, clientSecret, err := Tester.CreateOIDCCredentialsClient(CTX) + user, _, clientID, clientSecret, err := Instance.CreateOIDCCredentialsClient(CTX) require.NoError(t, err) addProjectRolesGrants(t, user.GetUserId(), projectID, roleFoo, roleBar) @@ -324,14 +321,14 @@ func TestServer_UserInfo_Issue6662(t *testing.T) { domain.ProjectIDScope + projectID + domain.AudSuffix, } - provider, err := rp.NewRelyingPartyOIDC(CTX, Tester.OIDCIssuer(), clientID, clientSecret, redirectURI, scope) + provider, err := rp.NewRelyingPartyOIDC(CTX, Instance.OIDCIssuer(), clientID, clientSecret, redirectURI, scope) require.NoError(t, err) tokens, err := rp.ClientCredentials(CTX, provider, nil) require.NoError(t, err) userinfo, err := rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, user.GetUserId(), provider) require.NoError(t, err) - assertProjectRoleClaims(t, projectID, userinfo.Claims, false, []string{roleFoo}, []string{Tester.Organisation.ID}) + assertProjectRoleClaims(t, projectID, userinfo.Claims, false, []string{roleFoo}, []string{Instance.DefaultOrg.Id}) } func addProjectRolesGrants(t *testing.T, userID, projectID string, roles ...string) { @@ -343,12 +340,12 @@ func addProjectRolesGrants(t *testing.T, userID, projectID string, roles ...stri DisplayName: role, } } - _, err := Tester.Client.Mgmt.BulkAddProjectRoles(CTX, &management.BulkAddProjectRolesRequest{ + _, err := Instance.Client.Mgmt.BulkAddProjectRoles(CTX, &management.BulkAddProjectRolesRequest{ ProjectId: projectID, Roles: bulkRoles, }) require.NoError(t, err) - _, err = Tester.Client.Mgmt.AddUserGrant(CTX, &management.AddUserGrantRequest{ + _, err = Instance.Client.Mgmt.AddUserGrant(CTX, &management.AddUserGrantRequest{ UserId: userID, ProjectId: projectID, RoleKeys: roles, @@ -359,8 +356,8 @@ func addProjectRolesGrants(t *testing.T, userID, projectID string, roles ...stri // addProjectOrgGrant adds a new organization which will be granted on the projectID with the specified roles. // The userID will be granted in the new organization to the project with the same roles. func addProjectOrgGrant(t *testing.T, userID, projectID string, roles ...string) (grantedOrgID string) { - grantedOrg := Tester.CreateOrganization(CTXIAM, fmt.Sprintf("ZITADEL_GRANTED_%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) - projectGrant, err := Tester.Client.Mgmt.AddProjectGrant(CTX, &management.AddProjectGrantRequest{ + grantedOrg := Instance.CreateOrganization(CTXIAM, fmt.Sprintf("ZITADEL_GRANTED_%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) + projectGrant, err := Instance.Client.Mgmt.AddProjectGrant(CTX, &management.AddProjectGrantRequest{ ProjectId: projectID, GrantedOrgId: grantedOrg.GetOrganizationId(), RoleKeys: roles, @@ -368,7 +365,7 @@ func addProjectOrgGrant(t *testing.T, userID, projectID string, roles ...string) require.NoError(t, err) ctxOrg := metadata.AppendToOutgoingContext(CTXIAM, "x-zitadel-orgid", grantedOrg.GetOrganizationId()) - _, err = Tester.Client.Mgmt.AddUserGrant(ctxOrg, &management.AddUserGrantRequest{ + _, err = Instance.Client.Mgmt.AddUserGrant(ctxOrg, &management.AddUserGrantRequest{ UserId: userID, ProjectId: projectID, ProjectGrantId: projectGrant.GetGrantId(), @@ -379,9 +376,9 @@ func addProjectOrgGrant(t *testing.T, userID, projectID string, roles ...string) } func getTokens(t *testing.T, clientID string, scope []string) *oidc.Tokens[*oidc.IDTokenClaims] { - authRequestID := createAuthRequest(t, clientID, redirectURI, scope...) - sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) - linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ + authRequestID := createAuthRequest(t, Instance, clientID, redirectURI, scope...) + sessionID, sessionToken, startTime, changeTime := Instance.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) + linkResp, err := Instance.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_pb.CreateCallbackRequest_Session{ Session: &oidc_pb.Session{ @@ -394,7 +391,7 @@ func getTokens(t *testing.T, clientID string, scope []string) *oidc.Tokens[*oidc // code exchange code := assertCodeResponse(t, linkResp.GetCallbackUrl()) - tokens, err := exchangeTokens(t, clientID, code, redirectURI) + tokens, err := exchangeTokens(t, Instance, clientID, code, redirectURI) require.NoError(t, err) assertTokens(t, tokens, true) assertIDTokenClaims(t, tokens.IDTokenClaims, User.GetUserId(), armPasskey, startTime, changeTime, sessionID) diff --git a/internal/api/oidc/server_test.go b/internal/api/oidc/server_test.go index 47f24fcdee..76d073151a 100644 --- a/internal/api/oidc/server_test.go +++ b/internal/api/oidc/server_test.go @@ -7,9 +7,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/oidc/v3/pkg/op" + "golang.org/x/text/language" + "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/feature" - "golang.org/x/text/language" ) func TestServer_createDiscoveryConfig(t *testing.T) { diff --git a/internal/command/org_idp_test.go b/internal/command/org_idp_test.go index e1fa43e879..b2b4632cf6 100644 --- a/internal/command/org_idp_test.go +++ b/internal/command/org_idp_test.go @@ -21,7 +21,7 @@ import ( "github.com/zitadel/zitadel/internal/zerrors" ) -func TestCommandSide_AddOrgGenericOAuthIDP(t *testing.T) { +func TestCommandSide_AddOrgGenericOAuthProvider(t *testing.T) { type fields struct { eventstore func(*testing.T) *eventstore.Eventstore idGenerator id.Generator diff --git a/internal/integration/assert.go b/internal/integration/assert.go index b3e63fd29e..3c5fadb373 100644 --- a/internal/integration/assert.go +++ b/internal/integration/assert.go @@ -50,7 +50,7 @@ type ResourceListDetailsMsg interface { // If the change date is populated, it is checked with a tolerance of 1 minute around Now. // // The resource owner is compared with expected. -func AssertDetails[D Details, M DetailsMsg[D]](t testing.TB, expected, actual M) { +func AssertDetails[D Details, M DetailsMsg[D]](t assert.TestingT, expected, actual M) { wantDetails, gotDetails := expected.GetDetails(), actual.GetDetails() var nilDetails D if wantDetails == nilDetails { @@ -69,7 +69,7 @@ func AssertDetails[D Details, M DetailsMsg[D]](t testing.TB, expected, actual M) assert.Equal(t, wantDetails.GetResourceOwner(), gotDetails.GetResourceOwner()) } -func AssertResourceDetails(t testing.TB, expected *resources_object.Details, actual *resources_object.Details) { +func AssertResourceDetails(t assert.TestingT, expected *resources_object.Details, actual *resources_object.Details) { if expected.GetChanged() != nil { wantChangeDate := time.Now() gotChangeDate := actual.GetChanged().AsTime() @@ -87,7 +87,7 @@ func AssertResourceDetails(t testing.TB, expected *resources_object.Details, act } } -func AssertListDetails[L ListDetails, D ListDetailsMsg[L]](t testing.TB, expected, actual D) { +func AssertListDetails[L ListDetails, D ListDetailsMsg[L]](t assert.TestingT, expected, actual D) { wantDetails, gotDetails := expected.GetDetails(), actual.GetDetails() var nilDetails L if wantDetails == nilDetails { @@ -99,11 +99,11 @@ func AssertListDetails[L ListDetails, D ListDetailsMsg[L]](t testing.TB, expecte if wantDetails.GetTimestamp() != nil { gotCD := gotDetails.GetTimestamp().AsTime() wantCD := time.Now() - assert.WithinRange(t, gotCD, wantCD.Add(-time.Minute), wantCD.Add(time.Minute)) + assert.WithinRange(t, gotCD, wantCD.Add(-10*time.Minute), wantCD.Add(time.Minute)) } } -func AssertResourceListDetails[D ResourceListDetailsMsg](t testing.TB, expected, actual D) { +func AssertResourceListDetails[D ResourceListDetailsMsg](t assert.TestingT, expected, actual D) { wantDetails, gotDetails := expected.GetDetails(), actual.GetDetails() if wantDetails == nil { assert.Nil(t, gotDetails) @@ -116,7 +116,7 @@ func AssertResourceListDetails[D ResourceListDetailsMsg](t testing.TB, expected, if wantDetails.GetTimestamp() != nil { gotCD := gotDetails.GetTimestamp().AsTime() wantCD := time.Now() - assert.WithinRange(t, gotCD, wantCD.Add(-time.Minute), wantCD.Add(time.Minute)) + assert.WithinRange(t, gotCD, wantCD.Add(-10*time.Minute), wantCD.Add(time.Minute)) } } diff --git a/internal/integration/client.go b/internal/integration/client.go index ed5f0620c4..404ec0162b 100644 --- a/internal/integration/client.go +++ b/internal/integration/client.go @@ -6,26 +6,17 @@ import ( "testing" "time" - crewjam_saml "github.com/crewjam/saml" + "github.com/brianvoe/gofakeit/v6" "github.com/muhlemmer/gu" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v3/pkg/oidc" - "golang.org/x/oauth2" - "golang.org/x/text/language" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/metadata" "google.golang.org/protobuf/types/known/durationpb" "google.golang.org/protobuf/types/known/structpb" - "github.com/zitadel/zitadel/internal/api/authz" - "github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/domain" - "github.com/zitadel/zitadel/internal/idp/providers/ldap" - openid "github.com/zitadel/zitadel/internal/idp/providers/oidc" - "github.com/zitadel/zitadel/internal/idp/providers/saml" - idp_rp "github.com/zitadel/zitadel/internal/repository/idp" "github.com/zitadel/zitadel/pkg/grpc/admin" "github.com/zitadel/zitadel/pkg/grpc/auth" "github.com/zitadel/zitadel/pkg/grpc/feature/v2" @@ -37,7 +28,7 @@ import ( object_v3alpha "github.com/zitadel/zitadel/pkg/grpc/object/v3alpha" oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2" oidc_pb_v2beta "github.com/zitadel/zitadel/pkg/grpc/oidc/v2beta" - "github.com/zitadel/zitadel/pkg/grpc/org/v2" + org "github.com/zitadel/zitadel/pkg/grpc/org/v2" org_v2beta "github.com/zitadel/zitadel/pkg/grpc/org/v2beta" action "github.com/zitadel/zitadel/pkg/grpc/resources/action/v3alpha" user_v3alpha "github.com/zitadel/zitadel/pkg/grpc/resources/user/v3alpha" @@ -47,7 +38,6 @@ import ( session_v2beta "github.com/zitadel/zitadel/pkg/grpc/session/v2beta" "github.com/zitadel/zitadel/pkg/grpc/settings/v2" settings_v2beta "github.com/zitadel/zitadel/pkg/grpc/settings/v2beta" - "github.com/zitadel/zitadel/pkg/grpc/system" user_pb "github.com/zitadel/zitadel/pkg/grpc/user" user_v2 "github.com/zitadel/zitadel/pkg/grpc/user/v2" user_v2beta "github.com/zitadel/zitadel/pkg/grpc/user/v2beta" @@ -68,7 +58,6 @@ type Client struct { OIDCv2 oidc_pb.OIDCServiceClient OrgV2beta org_v2beta.OrganizationServiceClient OrgV2 org.OrganizationServiceClient - System system.SystemServiceClient ActionV3Alpha action.ZITADELActionsClient FeatureV2beta feature_v2beta.FeatureServiceClient FeatureV2 feature.FeatureServiceClient @@ -78,8 +67,14 @@ type Client struct { UserV3Alpha user_v3alpha.ZITADELUsersClient } -func newClient(cc *grpc.ClientConn) Client { - return Client{ +func newClient(ctx context.Context, target string) (*Client, error) { + cc, err := grpc.NewClient(target, + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + if err != nil { + return nil, err + } + client := &Client{ CC: cc, Admin: admin.NewAdminServiceClient(cc), Mgmt: mgmt.NewManagementServiceClient(cc), @@ -94,7 +89,6 @@ func newClient(cc *grpc.ClientConn) Client { OIDCv2: oidc_pb.NewOIDCServiceClient(cc), OrgV2beta: org_v2beta.NewOrganizationServiceClient(cc), OrgV2: org.NewOrganizationServiceClient(cc), - System: system.NewSystemServiceClient(cc), ActionV3Alpha: action.NewZITADELActionsClient(cc), FeatureV2beta: feature_v2beta.NewFeatureServiceClient(cc), FeatureV2: feature.NewFeatureServiceClient(cc), @@ -103,60 +97,38 @@ func newClient(cc *grpc.ClientConn) Client { IDPv2: idp_pb.NewIdentityProviderServiceClient(cc), UserV3Alpha: user_v3alpha.NewZITADELUsersClient(cc), } + return client, client.pollHealth(ctx) } -func (t *Tester) UseIsolatedInstance(tt *testing.T, iamOwnerCtx, systemCtx context.Context) (primaryDomain, instanceId, adminID string, authenticatedIamOwnerCtx context.Context) { - primaryDomain = RandString(5) + ".integration.localhost" - instance, err := t.Client.System.CreateInstance(systemCtx, &system.CreateInstanceRequest{ - InstanceName: "testinstance", - CustomDomain: primaryDomain, - Owner: &system.CreateInstanceRequest_Machine_{ - Machine: &system.CreateInstanceRequest_Machine{ - UserName: "owner", - Name: "owner", - PersonalAccessToken: &system.CreateInstanceRequest_PersonalAccessToken{}, - }, - }, - }) - require.NoError(tt, err) - t.createClientConn(iamOwnerCtx, fmt.Sprintf("%s:%d", primaryDomain, t.Config.Port)) - instanceId = instance.GetInstanceId() - owner, err := t.Queries.GetUserByLoginName(authz.WithInstanceID(iamOwnerCtx, instanceId), true, "owner@"+primaryDomain) - require.NoError(tt, err) - t.Users.Set(instanceId, IAMOwner, &User{ - User: owner, - Token: instance.GetPat(), - }) - newCtx := t.WithInstanceAuthorization(iamOwnerCtx, IAMOwner, instanceId) - var adminUser *mgmt.ImportHumanUserResponse - // the following serves two purposes: - // 1. it ensures that the instance is ready to be used - // 2. it enables a normal login with the default admin user credentials - require.EventuallyWithT(tt, func(collectT *assert.CollectT) { - var importErr error - adminUser, importErr = t.Client.Mgmt.ImportHumanUser(newCtx, &mgmt.ImportHumanUserRequest{ - UserName: "zitadel-admin@zitadel.localhost", - Email: &mgmt.ImportHumanUserRequest_Email{ - Email: "zitadel-admin@zitadel.localhost", - IsEmailVerified: true, - }, - Password: "Password1!", - Profile: &mgmt.ImportHumanUserRequest_Profile{ - FirstName: "hodor", - LastName: "hodor", - NickName: "hodor", - }, - }) - assert.NoError(collectT, importErr) - }, 2*time.Minute, 100*time.Millisecond, "instance not ready") - return primaryDomain, instanceId, adminUser.GetUserId(), t.updateInstanceAndOrg(newCtx, fmt.Sprintf("%s:%d", primaryDomain, t.Config.ExternalPort)) +// pollHealth waits until a healthy status is reported. +func (c *Client) pollHealth(ctx context.Context) (err error) { + for { + err = func(ctx context.Context) error { + ctx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + + _, err := c.Admin.Healthz(ctx, &admin.HealthzRequest{}) + return err + }(ctx) + if err == nil { + return nil + } + logging.WithError(err).Debug("poll healthz") + + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(time.Second): + continue + } + } } -func (s *Tester) CreateHumanUser(ctx context.Context) *user_v2.AddHumanUserResponse { - resp, err := s.Client.UserV2.AddHumanUser(ctx, &user_v2.AddHumanUserRequest{ +func (i *Instance) CreateHumanUser(ctx context.Context) *user_v2.AddHumanUserResponse { + resp, err := i.Client.UserV2.AddHumanUser(ctx, &user_v2.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: s.Organisation.ID, + OrgId: i.DefaultOrg.GetId(), }, }, Profile: &user_v2.SetHumanProfile{ @@ -178,15 +150,15 @@ func (s *Tester) CreateHumanUser(ctx context.Context) *user_v2.AddHumanUserRespo }, }, }) - logging.OnError(err).Fatal("create human user") + logging.OnError(err).Panic("create human user") return resp } -func (s *Tester) CreateHumanUserNoPhone(ctx context.Context) *user_v2.AddHumanUserResponse { - resp, err := s.Client.UserV2.AddHumanUser(ctx, &user_v2.AddHumanUserRequest{ +func (i *Instance) CreateHumanUserNoPhone(ctx context.Context) *user_v2.AddHumanUserResponse { + resp, err := i.Client.UserV2.AddHumanUser(ctx, &user_v2.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: s.Organisation.ID, + OrgId: i.DefaultOrg.GetId(), }, }, Profile: &user_v2.SetHumanProfile{ @@ -202,15 +174,15 @@ func (s *Tester) CreateHumanUserNoPhone(ctx context.Context) *user_v2.AddHumanUs }, }, }) - logging.OnError(err).Fatal("create human user") + logging.OnError(err).Panic("create human user") return resp } -func (s *Tester) CreateHumanUserWithTOTP(ctx context.Context, secret string) *user_v2.AddHumanUserResponse { - resp, err := s.Client.UserV2.AddHumanUser(ctx, &user_v2.AddHumanUserRequest{ +func (i *Instance) CreateHumanUserWithTOTP(ctx context.Context, secret string) *user_v2.AddHumanUserResponse { + resp, err := i.Client.UserV2.AddHumanUser(ctx, &user_v2.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ - OrgId: s.Organisation.ID, + OrgId: i.DefaultOrg.GetId(), }, }, Profile: &user_v2.SetHumanProfile{ @@ -233,12 +205,12 @@ func (s *Tester) CreateHumanUserWithTOTP(ctx context.Context, secret string) *us }, TotpSecret: gu.Ptr(secret), }) - logging.OnError(err).Fatal("create human user") + logging.OnError(err).Panic("create human user") return resp } -func (s *Tester) CreateOrganization(ctx context.Context, name, adminEmail string) *org.AddOrganizationResponse { - resp, err := s.Client.OrgV2.AddOrganization(ctx, &org.AddOrganizationRequest{ +func (i *Instance) CreateOrganization(ctx context.Context, name, adminEmail string) *org.AddOrganizationResponse { + resp, err := i.Client.OrgV2.AddOrganization(ctx, &org.AddOrganizationRequest{ Name: name, Admins: []*org.AddOrganizationRequest_Admin{ { @@ -259,12 +231,12 @@ func (s *Tester) CreateOrganization(ctx context.Context, name, adminEmail string }, }, }) - logging.OnError(err).Fatal("create org") + logging.OnError(err).Panic("create org") return resp } -func (s *Tester) DeactivateOrganization(ctx context.Context, orgID string) *mgmt.DeactivateOrgResponse { - resp, err := s.Client.Mgmt.DeactivateOrg( +func (i *Instance) DeactivateOrganization(ctx context.Context, orgID string) *mgmt.DeactivateOrgResponse { + resp, err := i.Client.Mgmt.DeactivateOrg( SetOrgID(ctx, orgID), &mgmt.DeactivateOrgRequest{}, ) @@ -281,8 +253,8 @@ func SetOrgID(ctx context.Context, orgID string) context.Context { return metadata.NewOutgoingContext(ctx, md) } -func (s *Tester) CreateOrganizationWithUserID(ctx context.Context, name, userID string) *org.AddOrganizationResponse { - resp, err := s.Client.OrgV2.AddOrganization(ctx, &org.AddOrganizationRequest{ +func (i *Instance) CreateOrganizationWithUserID(ctx context.Context, name, userID string) *org.AddOrganizationResponse { + resp, err := i.Client.OrgV2.AddOrganization(ctx, &org.AddOrganizationRequest{ Name: name, Admins: []*org.AddOrganizationRequest_Admin{ { @@ -296,8 +268,8 @@ func (s *Tester) CreateOrganizationWithUserID(ctx context.Context, name, userID return resp } -func (s *Tester) CreateHumanUserVerified(ctx context.Context, org, email string) *user_v2.AddHumanUserResponse { - resp, err := s.Client.UserV2.AddHumanUser(ctx, &user_v2.AddHumanUserRequest{ +func (i *Instance) CreateHumanUserVerified(ctx context.Context, org, email string) *user_v2.AddHumanUserResponse { + resp, err := i.Client.UserV2.AddHumanUser(ctx, &user_v2.AddHumanUserRequest{ Organization: &object.Organization{ Org: &object.Organization_OrgId{ OrgId: org, @@ -323,23 +295,23 @@ func (s *Tester) CreateHumanUserVerified(ctx context.Context, org, email string) }, }, }) - logging.OnError(err).Fatal("create human user") + logging.OnError(err).Panic("create human user") return resp } -func (s *Tester) CreateMachineUser(ctx context.Context) *mgmt.AddMachineUserResponse { - resp, err := s.Client.Mgmt.AddMachineUser(ctx, &mgmt.AddMachineUserRequest{ +func (i *Instance) CreateMachineUser(ctx context.Context) *mgmt.AddMachineUserResponse { + resp, err := i.Client.Mgmt.AddMachineUser(ctx, &mgmt.AddMachineUserRequest{ UserName: fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()), Name: "Mickey", Description: "Mickey Mouse", AccessTokenType: user_pb.AccessTokenType_ACCESS_TOKEN_TYPE_BEARER, }) - logging.OnError(err).Fatal("create human user") + logging.OnError(err).Panic("create human user") return resp } -func (s *Tester) CreateUserIDPlink(ctx context.Context, userID, externalID, idpID, username string) *user_v2.AddIDPLinkResponse { - resp, err := s.Client.UserV2.AddIDPLink( +func (i *Instance) CreateUserIDPlink(ctx context.Context, userID, externalID, idpID, username string) (*user_v2.AddIDPLinkResponse, error) { + return i.Client.UserV2.AddIDPLink( ctx, &user_v2.AddIDPLinkRequest{ UserId: userID, @@ -350,67 +322,65 @@ func (s *Tester) CreateUserIDPlink(ctx context.Context, userID, externalID, idpI }, }, ) - logging.OnError(err).Fatal("create human user link") - return resp } -func (s *Tester) RegisterUserPasskey(ctx context.Context, userID string) { - reg, err := s.Client.UserV2.CreatePasskeyRegistrationLink(ctx, &user_v2.CreatePasskeyRegistrationLinkRequest{ +func (i *Instance) RegisterUserPasskey(ctx context.Context, userID string) { + reg, err := i.Client.UserV2.CreatePasskeyRegistrationLink(ctx, &user_v2.CreatePasskeyRegistrationLinkRequest{ UserId: userID, Medium: &user_v2.CreatePasskeyRegistrationLinkRequest_ReturnCode{}, }) - logging.OnError(err).Fatal("create user passkey") + logging.OnError(err).Panic("create user passkey") - pkr, err := s.Client.UserV2.RegisterPasskey(ctx, &user_v2.RegisterPasskeyRequest{ + pkr, err := i.Client.UserV2.RegisterPasskey(ctx, &user_v2.RegisterPasskeyRequest{ UserId: userID, Code: reg.GetCode(), - Domain: s.Config.ExternalDomain, + Domain: i.Domain, }) - logging.OnError(err).Fatal("create user passkey") - attestationResponse, err := s.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) - logging.OnError(err).Fatal("create user passkey") + logging.OnError(err).Panic("create user passkey") + attestationResponse, err := i.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) + logging.OnError(err).Panic("create user passkey") - _, err = s.Client.UserV2.VerifyPasskeyRegistration(ctx, &user_v2.VerifyPasskeyRegistrationRequest{ + _, err = i.Client.UserV2.VerifyPasskeyRegistration(ctx, &user_v2.VerifyPasskeyRegistrationRequest{ UserId: userID, PasskeyId: pkr.GetPasskeyId(), PublicKeyCredential: attestationResponse, PasskeyName: "nice name", }) - logging.OnError(err).Fatal("create user passkey") + logging.OnError(err).Panic("create user passkey") } -func (s *Tester) RegisterUserU2F(ctx context.Context, userID string) { - pkr, err := s.Client.UserV2.RegisterU2F(ctx, &user_v2.RegisterU2FRequest{ +func (i *Instance) RegisterUserU2F(ctx context.Context, userID string) { + pkr, err := i.Client.UserV2.RegisterU2F(ctx, &user_v2.RegisterU2FRequest{ UserId: userID, - Domain: s.Config.ExternalDomain, + Domain: i.Domain, }) - logging.OnError(err).Fatal("create user u2f") - attestationResponse, err := s.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) - logging.OnError(err).Fatal("create user u2f") + logging.OnError(err).Panic("create user u2f") + attestationResponse, err := i.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) + logging.OnError(err).Panic("create user u2f") - _, err = s.Client.UserV2.VerifyU2FRegistration(ctx, &user_v2.VerifyU2FRegistrationRequest{ + _, err = i.Client.UserV2.VerifyU2FRegistration(ctx, &user_v2.VerifyU2FRegistrationRequest{ UserId: userID, U2FId: pkr.GetU2FId(), PublicKeyCredential: attestationResponse, TokenName: "nice name", }) - logging.OnError(err).Fatal("create user u2f") + logging.OnError(err).Panic("create user u2f") } -func (s *Tester) SetUserPassword(ctx context.Context, userID, password string, changeRequired bool) *object.Details { - resp, err := s.Client.UserV2.SetPassword(ctx, &user_v2.SetPasswordRequest{ +func (i *Instance) SetUserPassword(ctx context.Context, userID, password string, changeRequired bool) *object.Details { + resp, err := i.Client.UserV2.SetPassword(ctx, &user_v2.SetPasswordRequest{ UserId: userID, NewPassword: &user_v2.Password{ Password: password, ChangeRequired: changeRequired, }, }) - logging.OnError(err).Fatal("set user password") + logging.OnError(err).Panic("set user password") return resp.GetDetails() } -func (s *Tester) AddGenericOAuthIDP(ctx context.Context, name string) *admin.AddGenericOAuthProviderResponse { - resp, err := s.Client.Admin.AddGenericOAuthProvider(ctx, &admin.AddGenericOAuthProviderRequest{ +func (i *Instance) AddGenericOAuthProvider(ctx context.Context, name string) *admin.AddGenericOAuthProviderResponse { + resp, err := i.Client.Admin.AddGenericOAuthProvider(ctx, &admin.AddGenericOAuthProviderRequest{ Name: name, ClientId: "clientID", ClientSecret: "clientSecret", @@ -427,136 +397,126 @@ func (s *Tester) AddGenericOAuthIDP(ctx context.Context, name string) *admin.Add AutoLinking: idp.AutoLinkingOption_AUTO_LINKING_OPTION_USERNAME, }, }) - logging.OnError(err).Fatal("create generic OAuth idp") - return resp -} + logging.OnError(err).Panic("create generic OAuth idp") -func (s *Tester) AddGenericOAuthProvider(t *testing.T, ctx context.Context) string { - ctx = authz.WithInstance(ctx, s.Instance) - id, _, err := s.Commands.AddInstanceGenericOAuthProvider(ctx, command.GenericOAuthProvider{ - Name: "idp", - ClientID: "clientID", - ClientSecret: "clientSecret", - AuthorizationEndpoint: "https://example.com/oauth/v2/authorize", - TokenEndpoint: "https://example.com/oauth/v2/token", - UserEndpoint: "https://api.example.com/user", - Scopes: []string{"openid", "profile", "email"}, - IDAttribute: "id", - IDPOptions: idp_rp.Options{ - IsLinkingAllowed: true, - IsCreationAllowed: true, - IsAutoCreation: true, - IsAutoUpdate: true, - }, - }) - require.NoError(t, err) - return id -} - -func (s *Tester) AddOrgGenericOAuthIDP(ctx context.Context, name string) *mgmt.AddGenericOAuthProviderResponse { - resp, err := s.Client.Mgmt.AddGenericOAuthProvider(ctx, &mgmt.AddGenericOAuthProviderRequest{ - Name: name, - ClientId: "clientID", - ClientSecret: "clientSecret", - AuthorizationEndpoint: "https://example.com/oauth/v2/authorize", - TokenEndpoint: "https://example.com/oauth/v2/token", - UserEndpoint: "https://api.example.com/user", - Scopes: []string{"openid", "profile", "email"}, - IdAttribute: "id", - ProviderOptions: &idp.Options{ - IsLinkingAllowed: true, - IsCreationAllowed: true, - IsAutoCreation: true, - IsAutoUpdate: true, - AutoLinking: idp.AutoLinkingOption_AUTO_LINKING_OPTION_USERNAME, - }, - }) - logging.OnError(err).Fatal("create generic OAuth idp") - return resp -} - -func (s *Tester) AddOrgGenericOAuthProvider(t *testing.T, ctx context.Context, orgID string) string { - ctx = authz.WithInstance(ctx, s.Instance) - id, _, err := s.Commands.AddOrgGenericOAuthProvider(ctx, orgID, - command.GenericOAuthProvider{ - Name: "idp", - ClientID: "clientID", - ClientSecret: "clientSecret", - AuthorizationEndpoint: "https://example.com/oauth/v2/authorize", - TokenEndpoint: "https://example.com/oauth/v2/token", - UserEndpoint: "https://api.example.com/user", - Scopes: []string{"openid", "profile", "email"}, - IDAttribute: "id", - IDPOptions: idp_rp.Options{ - IsLinkingAllowed: true, - IsCreationAllowed: true, - IsAutoCreation: true, - IsAutoUpdate: true, - }, + mustAwait(func() error { + _, err := i.Client.Admin.GetProviderByID(ctx, &admin.GetProviderByIDRequest{ + Id: resp.GetId(), }) - require.NoError(t, err) - return id + return err + }) + + return resp } -func (s *Tester) AddSAMLProvider(t *testing.T, ctx context.Context) string { - ctx = authz.WithInstance(ctx, s.Instance) - id, _, err := s.Server.Commands.AddInstanceSAMLProvider(ctx, command.SAMLProvider{ - Name: "saml-idp", - Metadata: []byte("\n \n \n \n \n MIIDBzCCAe+gAwIBAgIJAPr/Mrlc8EGhMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNTEyMjgxOTE5NDVaFw0yNTEyMjUxOTE5NDVaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANDoWzLos4LWxTn8Gyu2lEbl4WcelUbgLN5zYm4ron8Ahs+rvcsu2zkdD/s6jdGJI8WqJKhYK2u61ygnXgAZqC6ggtFPnBpizcDzjgND2g+aucSoUODHt67f0fQuAmupN/zp5MZysJ6IHLJnYLNpfJYk96lRz9ODnO1Mpqtr9PWxm+pz7nzq5F0vRepkgpcRxv6ufQBjlrFytccyEVdXrvFtkjXcnhVVNSR4kHuOOMS6D7pebSJ1mrCmshbD5SX1jXPBKFPAjozYX6PxqLxUx1Y4faFEf4MBBVcInyB4oURNB2s59hEEi2jq9izNE7EbEK6BY5sEhoCPl9m32zE6ljkCAwEAAaNQME4wHQYDVR0OBBYEFB9ZklC1Ork2zl56zg08ei7ss/+iMB8GA1UdIwQYMBaAFB9ZklC1Ork2zl56zg08ei7ss/+iMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAVoTSQ5pAirw8OR9FZ1bRSuTDhY9uxzl/OL7lUmsv2cMNeCB3BRZqm3mFt+cwN8GsH6f3uvNONIhgFpTGN5LEcXQz89zJEzB+qaHqmbFpHQl/sx2B8ezNgT/882H2IH00dXESEfy/+1gHg2pxjGnhRBN6el/gSaDiySIMKbilDrffuvxiCfbpPN0NRRiPJhd2ay9KuL/RxQRl1gl9cHaWiouWWba1bSBb2ZPhv2rPMUsFo98ntkGCObDX6Y1SpkqmoTbrsbGFsTG2DLxnvr4GdN1BSr0Uu/KV3adj47WkXVPeMYQti/bQmxQB8tRFhrw80qakTLUzreO96WzlBBMtY=\n \n \n \n \n \n \n MIIDBzCCAe+gAwIBAgIJAPr/Mrlc8EGhMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNTEyMjgxOTE5NDVaFw0yNTEyMjUxOTE5NDVaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANDoWzLos4LWxTn8Gyu2lEbl4WcelUbgLN5zYm4ron8Ahs+rvcsu2zkdD/s6jdGJI8WqJKhYK2u61ygnXgAZqC6ggtFPnBpizcDzjgND2g+aucSoUODHt67f0fQuAmupN/zp5MZysJ6IHLJnYLNpfJYk96lRz9ODnO1Mpqtr9PWxm+pz7nzq5F0vRepkgpcRxv6ufQBjlrFytccyEVdXrvFtkjXcnhVVNSR4kHuOOMS6D7pebSJ1mrCmshbD5SX1jXPBKFPAjozYX6PxqLxUx1Y4faFEf4MBBVcInyB4oURNB2s59hEEi2jq9izNE7EbEK6BY5sEhoCPl9m32zE6ljkCAwEAAaNQME4wHQYDVR0OBBYEFB9ZklC1Ork2zl56zg08ei7ss/+iMB8GA1UdIwQYMBaAFB9ZklC1Ork2zl56zg08ei7ss/+iMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAVoTSQ5pAirw8OR9FZ1bRSuTDhY9uxzl/OL7lUmsv2cMNeCB3BRZqm3mFt+cwN8GsH6f3uvNONIhgFpTGN5LEcXQz89zJEzB+qaHqmbFpHQl/sx2B8ezNgT/882H2IH00dXESEfy/+1gHg2pxjGnhRBN6el/gSaDiySIMKbilDrffuvxiCfbpPN0NRRiPJhd2ay9KuL/RxQRl1gl9cHaWiouWWba1bSBb2ZPhv2rPMUsFo98ntkGCObDX6Y1SpkqmoTbrsbGFsTG2DLxnvr4GdN1BSr0Uu/KV3adj47WkXVPeMYQti/bQmxQB8tRFhrw80qakTLUzreO96WzlBBMtY=\n \n \n \n \n \n \n \n urn:oasis:names:tc:SAML:2.0:nameid-format:transient\n \n \n \n"), - IDPOptions: idp_rp.Options{ +func (i *Instance) AddOrgGenericOAuthProvider(ctx context.Context, name string) *mgmt.AddGenericOAuthProviderResponse { + resp, err := i.Client.Mgmt.AddGenericOAuthProvider(ctx, &mgmt.AddGenericOAuthProviderRequest{ + Name: name, + ClientId: "clientID", + ClientSecret: "clientSecret", + AuthorizationEndpoint: "https://example.com/oauth/v2/authorize", + TokenEndpoint: "https://example.com/oauth/v2/token", + UserEndpoint: "https://api.example.com/user", + Scopes: []string{"openid", "profile", "email"}, + IdAttribute: "id", + ProviderOptions: &idp.Options{ + IsLinkingAllowed: true, + IsCreationAllowed: true, + IsAutoCreation: true, + IsAutoUpdate: true, + AutoLinking: idp.AutoLinkingOption_AUTO_LINKING_OPTION_USERNAME, + }, + }) + logging.OnError(err).Panic("create generic OAuth idp") + /* + mustAwait(func() error { + _, err := i.Client.Mgmt.GetProviderByID(ctx, &mgmt.GetProviderByIDRequest{ + Id: resp.GetId(), + }) + return err + }) + */ + return resp +} + +func (i *Instance) AddSAMLProvider(ctx context.Context) string { + resp, err := i.Client.Admin.AddSAMLProvider(ctx, &admin.AddSAMLProviderRequest{ + Name: "saml-idp", + Metadata: &admin.AddSAMLProviderRequest_MetadataXml{ + MetadataXml: []byte("\n \n \n \n \n MIIDBzCCAe+gAwIBAgIJAPr/Mrlc8EGhMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNTEyMjgxOTE5NDVaFw0yNTEyMjUxOTE5NDVaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANDoWzLos4LWxTn8Gyu2lEbl4WcelUbgLN5zYm4ron8Ahs+rvcsu2zkdD/s6jdGJI8WqJKhYK2u61ygnXgAZqC6ggtFPnBpizcDzjgND2g+aucSoUODHt67f0fQuAmupN/zp5MZysJ6IHLJnYLNpfJYk96lRz9ODnO1Mpqtr9PWxm+pz7nzq5F0vRepkgpcRxv6ufQBjlrFytccyEVdXrvFtkjXcnhVVNSR4kHuOOMS6D7pebSJ1mrCmshbD5SX1jXPBKFPAjozYX6PxqLxUx1Y4faFEf4MBBVcInyB4oURNB2s59hEEi2jq9izNE7EbEK6BY5sEhoCPl9m32zE6ljkCAwEAAaNQME4wHQYDVR0OBBYEFB9ZklC1Ork2zl56zg08ei7ss/+iMB8GA1UdIwQYMBaAFB9ZklC1Ork2zl56zg08ei7ss/+iMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAVoTSQ5pAirw8OR9FZ1bRSuTDhY9uxzl/OL7lUmsv2cMNeCB3BRZqm3mFt+cwN8GsH6f3uvNONIhgFpTGN5LEcXQz89zJEzB+qaHqmbFpHQl/sx2B8ezNgT/882H2IH00dXESEfy/+1gHg2pxjGnhRBN6el/gSaDiySIMKbilDrffuvxiCfbpPN0NRRiPJhd2ay9KuL/RxQRl1gl9cHaWiouWWba1bSBb2ZPhv2rPMUsFo98ntkGCObDX6Y1SpkqmoTbrsbGFsTG2DLxnvr4GdN1BSr0Uu/KV3adj47WkXVPeMYQti/bQmxQB8tRFhrw80qakTLUzreO96WzlBBMtY=\n \n \n \n \n \n \n MIIDBzCCAe+gAwIBAgIJAPr/Mrlc8EGhMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNTEyMjgxOTE5NDVaFw0yNTEyMjUxOTE5NDVaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANDoWzLos4LWxTn8Gyu2lEbl4WcelUbgLN5zYm4ron8Ahs+rvcsu2zkdD/s6jdGJI8WqJKhYK2u61ygnXgAZqC6ggtFPnBpizcDzjgND2g+aucSoUODHt67f0fQuAmupN/zp5MZysJ6IHLJnYLNpfJYk96lRz9ODnO1Mpqtr9PWxm+pz7nzq5F0vRepkgpcRxv6ufQBjlrFytccyEVdXrvFtkjXcnhVVNSR4kHuOOMS6D7pebSJ1mrCmshbD5SX1jXPBKFPAjozYX6PxqLxUx1Y4faFEf4MBBVcInyB4oURNB2s59hEEi2jq9izNE7EbEK6BY5sEhoCPl9m32zE6ljkCAwEAAaNQME4wHQYDVR0OBBYEFB9ZklC1Ork2zl56zg08ei7ss/+iMB8GA1UdIwQYMBaAFB9ZklC1Ork2zl56zg08ei7ss/+iMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAVoTSQ5pAirw8OR9FZ1bRSuTDhY9uxzl/OL7lUmsv2cMNeCB3BRZqm3mFt+cwN8GsH6f3uvNONIhgFpTGN5LEcXQz89zJEzB+qaHqmbFpHQl/sx2B8ezNgT/882H2IH00dXESEfy/+1gHg2pxjGnhRBN6el/gSaDiySIMKbilDrffuvxiCfbpPN0NRRiPJhd2ay9KuL/RxQRl1gl9cHaWiouWWba1bSBb2ZPhv2rPMUsFo98ntkGCObDX6Y1SpkqmoTbrsbGFsTG2DLxnvr4GdN1BSr0Uu/KV3adj47WkXVPeMYQti/bQmxQB8tRFhrw80qakTLUzreO96WzlBBMtY=\n \n \n \n \n \n \n \n urn:oasis:names:tc:SAML:2.0:nameid-format:transient\n \n \n \n"), + }, + ProviderOptions: &idp.Options{ IsLinkingAllowed: true, IsCreationAllowed: true, IsAutoCreation: true, IsAutoUpdate: true, }, }) - require.NoError(t, err) - return id + logging.OnError(err).Panic("create saml idp") + return resp.GetId() } -func (s *Tester) AddSAMLRedirectProvider(t *testing.T, ctx context.Context, transientMappingAttributeName string) string { - ctx = authz.WithInstance(ctx, s.Instance) - id, _, err := s.Server.Commands.AddInstanceSAMLProvider(ctx, command.SAMLProvider{ - Name: "saml-idp-redirect", - Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", - Metadata: []byte("\n \n \n \n \n MIIDBzCCAe+gAwIBAgIJAPr/Mrlc8EGhMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNTEyMjgxOTE5NDVaFw0yNTEyMjUxOTE5NDVaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANDoWzLos4LWxTn8Gyu2lEbl4WcelUbgLN5zYm4ron8Ahs+rvcsu2zkdD/s6jdGJI8WqJKhYK2u61ygnXgAZqC6ggtFPnBpizcDzjgND2g+aucSoUODHt67f0fQuAmupN/zp5MZysJ6IHLJnYLNpfJYk96lRz9ODnO1Mpqtr9PWxm+pz7nzq5F0vRepkgpcRxv6ufQBjlrFytccyEVdXrvFtkjXcnhVVNSR4kHuOOMS6D7pebSJ1mrCmshbD5SX1jXPBKFPAjozYX6PxqLxUx1Y4faFEf4MBBVcInyB4oURNB2s59hEEi2jq9izNE7EbEK6BY5sEhoCPl9m32zE6ljkCAwEAAaNQME4wHQYDVR0OBBYEFB9ZklC1Ork2zl56zg08ei7ss/+iMB8GA1UdIwQYMBaAFB9ZklC1Ork2zl56zg08ei7ss/+iMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAVoTSQ5pAirw8OR9FZ1bRSuTDhY9uxzl/OL7lUmsv2cMNeCB3BRZqm3mFt+cwN8GsH6f3uvNONIhgFpTGN5LEcXQz89zJEzB+qaHqmbFpHQl/sx2B8ezNgT/882H2IH00dXESEfy/+1gHg2pxjGnhRBN6el/gSaDiySIMKbilDrffuvxiCfbpPN0NRRiPJhd2ay9KuL/RxQRl1gl9cHaWiouWWba1bSBb2ZPhv2rPMUsFo98ntkGCObDX6Y1SpkqmoTbrsbGFsTG2DLxnvr4GdN1BSr0Uu/KV3adj47WkXVPeMYQti/bQmxQB8tRFhrw80qakTLUzreO96WzlBBMtY=\n \n \n \n \n \n \n MIIDBzCCAe+gAwIBAgIJAPr/Mrlc8EGhMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNTEyMjgxOTE5NDVaFw0yNTEyMjUxOTE5NDVaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANDoWzLos4LWxTn8Gyu2lEbl4WcelUbgLN5zYm4ron8Ahs+rvcsu2zkdD/s6jdGJI8WqJKhYK2u61ygnXgAZqC6ggtFPnBpizcDzjgND2g+aucSoUODHt67f0fQuAmupN/zp5MZysJ6IHLJnYLNpfJYk96lRz9ODnO1Mpqtr9PWxm+pz7nzq5F0vRepkgpcRxv6ufQBjlrFytccyEVdXrvFtkjXcnhVVNSR4kHuOOMS6D7pebSJ1mrCmshbD5SX1jXPBKFPAjozYX6PxqLxUx1Y4faFEf4MBBVcInyB4oURNB2s59hEEi2jq9izNE7EbEK6BY5sEhoCPl9m32zE6ljkCAwEAAaNQME4wHQYDVR0OBBYEFB9ZklC1Ork2zl56zg08ei7ss/+iMB8GA1UdIwQYMBaAFB9ZklC1Ork2zl56zg08ei7ss/+iMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAVoTSQ5pAirw8OR9FZ1bRSuTDhY9uxzl/OL7lUmsv2cMNeCB3BRZqm3mFt+cwN8GsH6f3uvNONIhgFpTGN5LEcXQz89zJEzB+qaHqmbFpHQl/sx2B8ezNgT/882H2IH00dXESEfy/+1gHg2pxjGnhRBN6el/gSaDiySIMKbilDrffuvxiCfbpPN0NRRiPJhd2ay9KuL/RxQRl1gl9cHaWiouWWba1bSBb2ZPhv2rPMUsFo98ntkGCObDX6Y1SpkqmoTbrsbGFsTG2DLxnvr4GdN1BSr0Uu/KV3adj47WkXVPeMYQti/bQmxQB8tRFhrw80qakTLUzreO96WzlBBMtY=\n \n \n \n \n \n \n \n urn:oasis:names:tc:SAML:2.0:nameid-format:transient\n \n \n"), - TransientMappingAttributeName: transientMappingAttributeName, - IDPOptions: idp_rp.Options{ +func (i *Instance) AddSAMLRedirectProvider(ctx context.Context, transientMappingAttributeName string) string { + resp, err := i.Client.Admin.AddSAMLProvider(ctx, &admin.AddSAMLProviderRequest{ + Name: "saml-idp-redirect", + Binding: idp.SAMLBinding_SAML_BINDING_REDIRECT, + Metadata: &admin.AddSAMLProviderRequest_MetadataXml{ + MetadataXml: []byte("\n \n \n \n \n MIIDBzCCAe+gAwIBAgIJAPr/Mrlc8EGhMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNTEyMjgxOTE5NDVaFw0yNTEyMjUxOTE5NDVaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANDoWzLos4LWxTn8Gyu2lEbl4WcelUbgLN5zYm4ron8Ahs+rvcsu2zkdD/s6jdGJI8WqJKhYK2u61ygnXgAZqC6ggtFPnBpizcDzjgND2g+aucSoUODHt67f0fQuAmupN/zp5MZysJ6IHLJnYLNpfJYk96lRz9ODnO1Mpqtr9PWxm+pz7nzq5F0vRepkgpcRxv6ufQBjlrFytccyEVdXrvFtkjXcnhVVNSR4kHuOOMS6D7pebSJ1mrCmshbD5SX1jXPBKFPAjozYX6PxqLxUx1Y4faFEf4MBBVcInyB4oURNB2s59hEEi2jq9izNE7EbEK6BY5sEhoCPl9m32zE6ljkCAwEAAaNQME4wHQYDVR0OBBYEFB9ZklC1Ork2zl56zg08ei7ss/+iMB8GA1UdIwQYMBaAFB9ZklC1Ork2zl56zg08ei7ss/+iMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAVoTSQ5pAirw8OR9FZ1bRSuTDhY9uxzl/OL7lUmsv2cMNeCB3BRZqm3mFt+cwN8GsH6f3uvNONIhgFpTGN5LEcXQz89zJEzB+qaHqmbFpHQl/sx2B8ezNgT/882H2IH00dXESEfy/+1gHg2pxjGnhRBN6el/gSaDiySIMKbilDrffuvxiCfbpPN0NRRiPJhd2ay9KuL/RxQRl1gl9cHaWiouWWba1bSBb2ZPhv2rPMUsFo98ntkGCObDX6Y1SpkqmoTbrsbGFsTG2DLxnvr4GdN1BSr0Uu/KV3adj47WkXVPeMYQti/bQmxQB8tRFhrw80qakTLUzreO96WzlBBMtY=\n \n \n \n \n \n \n MIIDBzCCAe+gAwIBAgIJAPr/Mrlc8EGhMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNTEyMjgxOTE5NDVaFw0yNTEyMjUxOTE5NDVaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANDoWzLos4LWxTn8Gyu2lEbl4WcelUbgLN5zYm4ron8Ahs+rvcsu2zkdD/s6jdGJI8WqJKhYK2u61ygnXgAZqC6ggtFPnBpizcDzjgND2g+aucSoUODHt67f0fQuAmupN/zp5MZysJ6IHLJnYLNpfJYk96lRz9ODnO1Mpqtr9PWxm+pz7nzq5F0vRepkgpcRxv6ufQBjlrFytccyEVdXrvFtkjXcnhVVNSR4kHuOOMS6D7pebSJ1mrCmshbD5SX1jXPBKFPAjozYX6PxqLxUx1Y4faFEf4MBBVcInyB4oURNB2s59hEEi2jq9izNE7EbEK6BY5sEhoCPl9m32zE6ljkCAwEAAaNQME4wHQYDVR0OBBYEFB9ZklC1Ork2zl56zg08ei7ss/+iMB8GA1UdIwQYMBaAFB9ZklC1Ork2zl56zg08ei7ss/+iMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAVoTSQ5pAirw8OR9FZ1bRSuTDhY9uxzl/OL7lUmsv2cMNeCB3BRZqm3mFt+cwN8GsH6f3uvNONIhgFpTGN5LEcXQz89zJEzB+qaHqmbFpHQl/sx2B8ezNgT/882H2IH00dXESEfy/+1gHg2pxjGnhRBN6el/gSaDiySIMKbilDrffuvxiCfbpPN0NRRiPJhd2ay9KuL/RxQRl1gl9cHaWiouWWba1bSBb2ZPhv2rPMUsFo98ntkGCObDX6Y1SpkqmoTbrsbGFsTG2DLxnvr4GdN1BSr0Uu/KV3adj47WkXVPeMYQti/bQmxQB8tRFhrw80qakTLUzreO96WzlBBMtY=\n \n \n \n \n \n \n \n urn:oasis:names:tc:SAML:2.0:nameid-format:transient\n \n \n"), + }, + TransientMappingAttributeName: &transientMappingAttributeName, + ProviderOptions: &idp.Options{ IsLinkingAllowed: true, IsCreationAllowed: true, IsAutoCreation: true, IsAutoUpdate: true, }, }) - require.NoError(t, err) - return id + logging.OnError(err).Panic("create saml idp") + return resp.GetId() } -func (s *Tester) AddSAMLPostProvider(t *testing.T, ctx context.Context) string { - ctx = authz.WithInstance(ctx, s.Instance) - id, _, err := s.Server.Commands.AddInstanceSAMLProvider(ctx, command.SAMLProvider{ - Name: "saml-idp-post", - Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", - Metadata: []byte("\n \n \n \n \n MIIDBzCCAe+gAwIBAgIJAPr/Mrlc8EGhMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNTEyMjgxOTE5NDVaFw0yNTEyMjUxOTE5NDVaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANDoWzLos4LWxTn8Gyu2lEbl4WcelUbgLN5zYm4ron8Ahs+rvcsu2zkdD/s6jdGJI8WqJKhYK2u61ygnXgAZqC6ggtFPnBpizcDzjgND2g+aucSoUODHt67f0fQuAmupN/zp5MZysJ6IHLJnYLNpfJYk96lRz9ODnO1Mpqtr9PWxm+pz7nzq5F0vRepkgpcRxv6ufQBjlrFytccyEVdXrvFtkjXcnhVVNSR4kHuOOMS6D7pebSJ1mrCmshbD5SX1jXPBKFPAjozYX6PxqLxUx1Y4faFEf4MBBVcInyB4oURNB2s59hEEi2jq9izNE7EbEK6BY5sEhoCPl9m32zE6ljkCAwEAAaNQME4wHQYDVR0OBBYEFB9ZklC1Ork2zl56zg08ei7ss/+iMB8GA1UdIwQYMBaAFB9ZklC1Ork2zl56zg08ei7ss/+iMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAVoTSQ5pAirw8OR9FZ1bRSuTDhY9uxzl/OL7lUmsv2cMNeCB3BRZqm3mFt+cwN8GsH6f3uvNONIhgFpTGN5LEcXQz89zJEzB+qaHqmbFpHQl/sx2B8ezNgT/882H2IH00dXESEfy/+1gHg2pxjGnhRBN6el/gSaDiySIMKbilDrffuvxiCfbpPN0NRRiPJhd2ay9KuL/RxQRl1gl9cHaWiouWWba1bSBb2ZPhv2rPMUsFo98ntkGCObDX6Y1SpkqmoTbrsbGFsTG2DLxnvr4GdN1BSr0Uu/KV3adj47WkXVPeMYQti/bQmxQB8tRFhrw80qakTLUzreO96WzlBBMtY=\n \n \n \n \n \n \n MIIDBzCCAe+gAwIBAgIJAPr/Mrlc8EGhMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNTEyMjgxOTE5NDVaFw0yNTEyMjUxOTE5NDVaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANDoWzLos4LWxTn8Gyu2lEbl4WcelUbgLN5zYm4ron8Ahs+rvcsu2zkdD/s6jdGJI8WqJKhYK2u61ygnXgAZqC6ggtFPnBpizcDzjgND2g+aucSoUODHt67f0fQuAmupN/zp5MZysJ6IHLJnYLNpfJYk96lRz9ODnO1Mpqtr9PWxm+pz7nzq5F0vRepkgpcRxv6ufQBjlrFytccyEVdXrvFtkjXcnhVVNSR4kHuOOMS6D7pebSJ1mrCmshbD5SX1jXPBKFPAjozYX6PxqLxUx1Y4faFEf4MBBVcInyB4oURNB2s59hEEi2jq9izNE7EbEK6BY5sEhoCPl9m32zE6ljkCAwEAAaNQME4wHQYDVR0OBBYEFB9ZklC1Ork2zl56zg08ei7ss/+iMB8GA1UdIwQYMBaAFB9ZklC1Ork2zl56zg08ei7ss/+iMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAVoTSQ5pAirw8OR9FZ1bRSuTDhY9uxzl/OL7lUmsv2cMNeCB3BRZqm3mFt+cwN8GsH6f3uvNONIhgFpTGN5LEcXQz89zJEzB+qaHqmbFpHQl/sx2B8ezNgT/882H2IH00dXESEfy/+1gHg2pxjGnhRBN6el/gSaDiySIMKbilDrffuvxiCfbpPN0NRRiPJhd2ay9KuL/RxQRl1gl9cHaWiouWWba1bSBb2ZPhv2rPMUsFo98ntkGCObDX6Y1SpkqmoTbrsbGFsTG2DLxnvr4GdN1BSr0Uu/KV3adj47WkXVPeMYQti/bQmxQB8tRFhrw80qakTLUzreO96WzlBBMtY=\n \n \n \n \n \n \n \n urn:oasis:names:tc:SAML:2.0:nameid-format:transient\n \n \n"), - IDPOptions: idp_rp.Options{ +func (i *Instance) AddSAMLPostProvider(ctx context.Context) string { + resp, err := i.Client.Admin.AddSAMLProvider(ctx, &admin.AddSAMLProviderRequest{ + Name: "saml-idp-post", + Binding: idp.SAMLBinding_SAML_BINDING_POST, + Metadata: &admin.AddSAMLProviderRequest_MetadataXml{ + MetadataXml: []byte("\n \n \n \n \n MIIDBzCCAe+gAwIBAgIJAPr/Mrlc8EGhMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNTEyMjgxOTE5NDVaFw0yNTEyMjUxOTE5NDVaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANDoWzLos4LWxTn8Gyu2lEbl4WcelUbgLN5zYm4ron8Ahs+rvcsu2zkdD/s6jdGJI8WqJKhYK2u61ygnXgAZqC6ggtFPnBpizcDzjgND2g+aucSoUODHt67f0fQuAmupN/zp5MZysJ6IHLJnYLNpfJYk96lRz9ODnO1Mpqtr9PWxm+pz7nzq5F0vRepkgpcRxv6ufQBjlrFytccyEVdXrvFtkjXcnhVVNSR4kHuOOMS6D7pebSJ1mrCmshbD5SX1jXPBKFPAjozYX6PxqLxUx1Y4faFEf4MBBVcInyB4oURNB2s59hEEi2jq9izNE7EbEK6BY5sEhoCPl9m32zE6ljkCAwEAAaNQME4wHQYDVR0OBBYEFB9ZklC1Ork2zl56zg08ei7ss/+iMB8GA1UdIwQYMBaAFB9ZklC1Ork2zl56zg08ei7ss/+iMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAVoTSQ5pAirw8OR9FZ1bRSuTDhY9uxzl/OL7lUmsv2cMNeCB3BRZqm3mFt+cwN8GsH6f3uvNONIhgFpTGN5LEcXQz89zJEzB+qaHqmbFpHQl/sx2B8ezNgT/882H2IH00dXESEfy/+1gHg2pxjGnhRBN6el/gSaDiySIMKbilDrffuvxiCfbpPN0NRRiPJhd2ay9KuL/RxQRl1gl9cHaWiouWWba1bSBb2ZPhv2rPMUsFo98ntkGCObDX6Y1SpkqmoTbrsbGFsTG2DLxnvr4GdN1BSr0Uu/KV3adj47WkXVPeMYQti/bQmxQB8tRFhrw80qakTLUzreO96WzlBBMtY=\n \n \n \n \n \n \n MIIDBzCCAe+gAwIBAgIJAPr/Mrlc8EGhMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNTEyMjgxOTE5NDVaFw0yNTEyMjUxOTE5NDVaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANDoWzLos4LWxTn8Gyu2lEbl4WcelUbgLN5zYm4ron8Ahs+rvcsu2zkdD/s6jdGJI8WqJKhYK2u61ygnXgAZqC6ggtFPnBpizcDzjgND2g+aucSoUODHt67f0fQuAmupN/zp5MZysJ6IHLJnYLNpfJYk96lRz9ODnO1Mpqtr9PWxm+pz7nzq5F0vRepkgpcRxv6ufQBjlrFytccyEVdXrvFtkjXcnhVVNSR4kHuOOMS6D7pebSJ1mrCmshbD5SX1jXPBKFPAjozYX6PxqLxUx1Y4faFEf4MBBVcInyB4oURNB2s59hEEi2jq9izNE7EbEK6BY5sEhoCPl9m32zE6ljkCAwEAAaNQME4wHQYDVR0OBBYEFB9ZklC1Ork2zl56zg08ei7ss/+iMB8GA1UdIwQYMBaAFB9ZklC1Ork2zl56zg08ei7ss/+iMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAVoTSQ5pAirw8OR9FZ1bRSuTDhY9uxzl/OL7lUmsv2cMNeCB3BRZqm3mFt+cwN8GsH6f3uvNONIhgFpTGN5LEcXQz89zJEzB+qaHqmbFpHQl/sx2B8ezNgT/882H2IH00dXESEfy/+1gHg2pxjGnhRBN6el/gSaDiySIMKbilDrffuvxiCfbpPN0NRRiPJhd2ay9KuL/RxQRl1gl9cHaWiouWWba1bSBb2ZPhv2rPMUsFo98ntkGCObDX6Y1SpkqmoTbrsbGFsTG2DLxnvr4GdN1BSr0Uu/KV3adj47WkXVPeMYQti/bQmxQB8tRFhrw80qakTLUzreO96WzlBBMtY=\n \n \n \n \n \n \n \n urn:oasis:names:tc:SAML:2.0:nameid-format:transient\n \n \n"), + }, + ProviderOptions: &idp.Options{ IsLinkingAllowed: true, IsCreationAllowed: true, IsAutoCreation: true, IsAutoUpdate: true, }, }) - require.NoError(t, err) - return id + logging.OnError(err).Panic("create saml idp") + return resp.GetId() } -func (s *Tester) CreateIntent(t *testing.T, ctx context.Context, idpID string) string { +/* +func (s *Instance) CreateIntent(t *testing.T, ctx context.Context, idpID string) string { + resp, err := i.Client.UserV2.StartIdentityProviderIntent(ctx, &user.StartIdentityProviderIntentRequest{ + IdpId: idpID, + Content: &user.StartIdentityProviderIntentRequest_Urls{ + Urls: &user.RedirectURLs{ + SuccessUrl: "https://example.com/success", + FailureUrl: "https://example.com/failure", + }, + AutoLinking: idp.AutoLinkingOption_AUTO_LINKING_OPTION_USERNAME, + }, + }) + logging.OnError(err).Fatal("create generic OAuth idp") + return resp +} + +func (i *Instance) CreateIntent(t *testing.T, ctx context.Context, idpID string) string { ctx = authz.WithInstance(context.WithoutCancel(ctx), s.Instance) writeModel, _, err := s.Commands.CreateIntent(ctx, idpID, "https://example.com/success", "https://example.com/failure", s.Instance.InstanceID()) require.NoError(t, err) return writeModel.AggregateID } -func (s *Tester) CreateSuccessfulOAuthIntent(t *testing.T, ctx context.Context, idpID, userID, idpUserID string) (string, string, time.Time, uint64) { +func (i *Instance) CreateSuccessfulOAuthIntent(t *testing.T, ctx context.Context, idpID, userID, idpUserID string) (string, string, time.Time, uint64) { ctx = authz.WithInstance(context.WithoutCancel(ctx), s.Instance) intentID := s.CreateIntent(t, ctx, idpID) writeModel, err := s.Commands.GetIntentWriteModel(ctx, intentID, s.Instance.InstanceID()) @@ -582,7 +542,7 @@ func (s *Tester) CreateSuccessfulOAuthIntent(t *testing.T, ctx context.Context, return intentID, token, writeModel.ChangeDate, writeModel.ProcessedSequence } -func (s *Tester) CreateSuccessfulLDAPIntent(t *testing.T, ctx context.Context, idpID, userID, idpUserID string) (string, string, time.Time, uint64) { +func (s *Instance) CreateSuccessfulLDAPIntent(t *testing.T, ctx context.Context, idpID, userID, idpUserID string) (string, string, time.Time, uint64) { ctx = authz.WithInstance(context.WithoutCancel(ctx), s.Instance) intentID := s.CreateIntent(t, ctx, idpID) writeModel, err := s.Commands.GetIntentWriteModel(ctx, intentID, s.Instance.InstanceID()) @@ -610,7 +570,7 @@ func (s *Tester) CreateSuccessfulLDAPIntent(t *testing.T, ctx context.Context, i return intentID, token, writeModel.ChangeDate, writeModel.ProcessedSequence } -func (s *Tester) CreateSuccessfulSAMLIntent(t *testing.T, ctx context.Context, idpID, userID, idpUserID string) (string, string, time.Time, uint64) { +func (s *Instance) CreateSuccessfulSAMLIntent(t *testing.T, ctx context.Context, idpID, userID, idpUserID string) (string, string, time.Time, uint64) { ctx = authz.WithInstance(context.WithoutCancel(ctx), s.Instance) intentID := s.CreateIntent(t, ctx, idpID) writeModel, err := s.Server.Commands.GetIntentWriteModel(ctx, intentID, s.Instance.InstanceID()) @@ -626,17 +586,18 @@ func (s *Tester) CreateSuccessfulSAMLIntent(t *testing.T, ctx context.Context, i require.NoError(t, err) return intentID, token, writeModel.ChangeDate, writeModel.ProcessedSequence } +*/ -func (s *Tester) CreateVerifiedWebAuthNSession(t *testing.T, ctx context.Context, userID string) (id, token string, start, change time.Time) { - return s.CreateVerifiedWebAuthNSessionWithLifetime(t, ctx, userID, 0) +func (i *Instance) CreateVerifiedWebAuthNSession(t *testing.T, ctx context.Context, userID string) (id, token string, start, change time.Time) { + return i.CreateVerifiedWebAuthNSessionWithLifetime(t, ctx, userID, 0) } -func (s *Tester) CreateVerifiedWebAuthNSessionWithLifetime(t *testing.T, ctx context.Context, userID string, lifetime time.Duration) (id, token string, start, change time.Time) { +func (i *Instance) CreateVerifiedWebAuthNSessionWithLifetime(t *testing.T, ctx context.Context, userID string, lifetime time.Duration) (id, token string, start, change time.Time) { var sessionLifetime *durationpb.Duration if lifetime > 0 { sessionLifetime = durationpb.New(lifetime) } - createResp, err := s.Client.SessionV2.CreateSession(ctx, &session.CreateSessionRequest{ + createResp, err := i.Client.SessionV2.CreateSession(ctx, &session.CreateSessionRequest{ Checks: &session.Checks{ User: &session.CheckUser{ Search: &session.CheckUser_UserId{UserId: userID}, @@ -644,7 +605,7 @@ func (s *Tester) CreateVerifiedWebAuthNSessionWithLifetime(t *testing.T, ctx con }, Challenges: &session.RequestChallenges{ WebAuthN: &session.RequestChallenges_WebAuthN{ - Domain: s.Config.ExternalDomain, + Domain: i.Domain, UserVerificationRequirement: session.UserVerificationRequirement_USER_VERIFICATION_REQUIREMENT_REQUIRED, }, }, @@ -652,10 +613,10 @@ func (s *Tester) CreateVerifiedWebAuthNSessionWithLifetime(t *testing.T, ctx con }) require.NoError(t, err) - assertion, err := s.WebAuthN.CreateAssertionResponse(createResp.GetChallenges().GetWebAuthN().GetPublicKeyCredentialRequestOptions(), true) + assertion, err := i.WebAuthN.CreateAssertionResponse(createResp.GetChallenges().GetWebAuthN().GetPublicKeyCredentialRequestOptions(), true) require.NoError(t, err) - updateResp, err := s.Client.SessionV2.SetSession(ctx, &session.SetSessionRequest{ + updateResp, err := i.Client.SessionV2.SetSession(ctx, &session.SetSessionRequest{ SessionId: createResp.GetSessionId(), Checks: &session.Checks{ WebAuthN: &session.CheckWebAuthN{ @@ -668,8 +629,8 @@ func (s *Tester) CreateVerifiedWebAuthNSessionWithLifetime(t *testing.T, ctx con createResp.GetDetails().GetChangeDate().AsTime(), updateResp.GetDetails().GetChangeDate().AsTime() } -func (s *Tester) CreatePasswordSession(t *testing.T, ctx context.Context, userID, password string) (id, token string, start, change time.Time) { - createResp, err := s.Client.SessionV2.CreateSession(ctx, &session.CreateSessionRequest{ +func (i *Instance) CreatePasswordSession(t *testing.T, ctx context.Context, userID, password string) (id, token string, start, change time.Time) { + createResp, err := i.Client.SessionV2.CreateSession(ctx, &session.CreateSessionRequest{ Checks: &session.Checks{ User: &session.CheckUser{ Search: &session.CheckUser_UserId{UserId: userID}, @@ -684,8 +645,8 @@ func (s *Tester) CreatePasswordSession(t *testing.T, ctx context.Context, userID createResp.GetDetails().GetChangeDate().AsTime(), createResp.GetDetails().GetChangeDate().AsTime() } -func (s *Tester) CreateProjectUserGrant(t *testing.T, ctx context.Context, projectID, userID string) string { - resp, err := s.Client.Mgmt.AddUserGrant(ctx, &mgmt.AddUserGrantRequest{ +func (i *Instance) CreateProjectUserGrant(t *testing.T, ctx context.Context, projectID, userID string) string { + resp, err := i.Client.Mgmt.AddUserGrant(ctx, &mgmt.AddUserGrantRequest{ UserId: userID, ProjectId: projectID, }) @@ -693,16 +654,16 @@ func (s *Tester) CreateProjectUserGrant(t *testing.T, ctx context.Context, proje return resp.GetUserGrantId() } -func (s *Tester) CreateOrgMembership(t *testing.T, ctx context.Context, userID string) { - _, err := s.Client.Mgmt.AddOrgMember(ctx, &mgmt.AddOrgMemberRequest{ +func (i *Instance) CreateOrgMembership(t *testing.T, ctx context.Context, userID string) { + _, err := i.Client.Mgmt.AddOrgMember(ctx, &mgmt.AddOrgMemberRequest{ UserId: userID, Roles: []string{domain.RoleOrgOwner}, }) require.NoError(t, err) } -func (s *Tester) CreateProjectMembership(t *testing.T, ctx context.Context, projectID, userID string) { - _, err := s.Client.Mgmt.AddProjectMember(ctx, &mgmt.AddProjectMemberRequest{ +func (i *Instance) CreateProjectMembership(t *testing.T, ctx context.Context, projectID, userID string) { + _, err := i.Client.Mgmt.AddProjectMember(ctx, &mgmt.AddProjectMemberRequest{ ProjectId: projectID, UserId: userID, Roles: []string{domain.RoleProjectOwner}, @@ -710,13 +671,12 @@ func (s *Tester) CreateProjectMembership(t *testing.T, ctx context.Context, proj require.NoError(t, err) } -func (s *Tester) CreateTarget(ctx context.Context, t *testing.T, name, endpoint string, ty domain.TargetType, interrupt bool) *action.CreateTargetResponse { - nameSet := fmt.Sprint(time.Now().UnixNano() + 1) - if name != "" { - nameSet = name +func (i *Instance) CreateTarget(ctx context.Context, t *testing.T, name, endpoint string, ty domain.TargetType, interrupt bool) *action.CreateTargetResponse { + if name == "" { + name = gofakeit.Name() } reqTarget := &action.Target{ - Name: nameSet, + Name: name, Endpoint: endpoint, Timeout: durationpb.New(10 * time.Second), } @@ -738,20 +698,20 @@ func (s *Tester) CreateTarget(ctx context.Context, t *testing.T, name, endpoint RestAsync: &action.SetRESTAsync{}, } } - target, err := s.Client.ActionV3Alpha.CreateTarget(ctx, &action.CreateTargetRequest{Target: reqTarget}) + target, err := i.Client.ActionV3Alpha.CreateTarget(ctx, &action.CreateTargetRequest{Target: reqTarget}) require.NoError(t, err) return target } -func (s *Tester) DeleteExecution(ctx context.Context, t *testing.T, cond *action.Condition) { - _, err := s.Client.ActionV3Alpha.SetExecution(ctx, &action.SetExecutionRequest{ +func (i *Instance) DeleteExecution(ctx context.Context, t *testing.T, cond *action.Condition) { + _, err := i.Client.ActionV3Alpha.SetExecution(ctx, &action.SetExecutionRequest{ Condition: cond, }) require.NoError(t, err) } -func (s *Tester) SetExecution(ctx context.Context, t *testing.T, cond *action.Condition, targets []*action.ExecutionTargetType) *action.SetExecutionResponse { - target, err := s.Client.ActionV3Alpha.SetExecution(ctx, &action.SetExecutionRequest{ +func (i *Instance) SetExecution(ctx context.Context, t *testing.T, cond *action.Condition, targets []*action.ExecutionTargetType) *action.SetExecutionResponse { + target, err := i.Client.ActionV3Alpha.SetExecution(ctx, &action.SetExecutionRequest{ Condition: cond, Execution: &action.Execution{ Targets: targets, @@ -761,15 +721,15 @@ func (s *Tester) SetExecution(ctx context.Context, t *testing.T, cond *action.Co return target } -func (s *Tester) CreateUserSchemaEmpty(ctx context.Context) *userschema_v3alpha.CreateUserSchemaResponse { - return s.CreateUserSchemaEmptyWithType(ctx, fmt.Sprint(time.Now().UnixNano()+1)) +func (i *Instance) CreateUserSchemaEmpty(ctx context.Context) *userschema_v3alpha.CreateUserSchemaResponse { + return i.CreateUserSchemaEmptyWithType(ctx, fmt.Sprint(time.Now().UnixNano()+1)) } -func (s *Tester) CreateUserSchema(ctx context.Context, schemaData []byte) *userschema_v3alpha.CreateUserSchemaResponse { +func (i *Instance) CreateUserSchema(ctx context.Context, schemaData []byte) *userschema_v3alpha.CreateUserSchemaResponse { userSchema := new(structpb.Struct) err := userSchema.UnmarshalJSON(schemaData) logging.OnError(err).Fatal("create userschema unmarshal") - schema, err := s.Client.UserSchemaV3.CreateUserSchema(ctx, &userschema_v3alpha.CreateUserSchemaRequest{ + schema, err := i.Client.UserSchemaV3.CreateUserSchema(ctx, &userschema_v3alpha.CreateUserSchemaRequest{ UserSchema: &userschema_v3alpha.UserSchema{ Type: fmt.Sprint(time.Now().UnixNano() + 1), DataType: &userschema_v3alpha.UserSchema_Schema{ @@ -781,7 +741,7 @@ func (s *Tester) CreateUserSchema(ctx context.Context, schemaData []byte) *users return schema } -func (s *Tester) CreateUserSchemaEmptyWithType(ctx context.Context, schemaType string) *userschema_v3alpha.CreateUserSchemaResponse { +func (i *Instance) CreateUserSchemaEmptyWithType(ctx context.Context, schemaType string) *userschema_v3alpha.CreateUserSchemaResponse { userSchema := new(structpb.Struct) err := userSchema.UnmarshalJSON([]byte(`{ "$schema": "urn:zitadel:schema:v1", @@ -789,7 +749,7 @@ func (s *Tester) CreateUserSchemaEmptyWithType(ctx context.Context, schemaType s "properties": {} }`)) logging.OnError(err).Fatal("create userschema unmarshal") - schema, err := s.Client.UserSchemaV3.CreateUserSchema(ctx, &userschema_v3alpha.CreateUserSchemaRequest{ + schema, err := i.Client.UserSchemaV3.CreateUserSchema(ctx, &userschema_v3alpha.CreateUserSchemaRequest{ UserSchema: &userschema_v3alpha.UserSchema{ Type: schemaType, DataType: &userschema_v3alpha.UserSchema_Schema{ @@ -801,11 +761,11 @@ func (s *Tester) CreateUserSchemaEmptyWithType(ctx context.Context, schemaType s return schema } -func (s *Tester) CreateSchemaUser(ctx context.Context, orgID string, schemaID string, data []byte) *user_v3alpha.CreateUserResponse { +func (i *Instance) CreateSchemaUser(ctx context.Context, orgID string, schemaID string, data []byte) *user_v3alpha.CreateUserResponse { userData := new(structpb.Struct) err := userData.UnmarshalJSON(data) logging.OnError(err).Fatal("create user unmarshal") - user, err := s.Client.UserV3Alpha.CreateUser(ctx, &user_v3alpha.CreateUserRequest{ + user, err := i.Client.UserV3Alpha.CreateUser(ctx, &user_v3alpha.CreateUserRequest{ Organization: &object_v3alpha.Organization{Property: &object_v3alpha.Organization_OrgId{OrgId: orgID}}, User: &user_v3alpha.CreateUser{ SchemaId: schemaID, diff --git a/internal/integration/config.go b/internal/integration/config.go new file mode 100644 index 0000000000..5aea740752 --- /dev/null +++ b/internal/integration/config.go @@ -0,0 +1,53 @@ +package integration + +import ( + "bytes" + _ "embed" + "os/exec" + "path/filepath" + + "github.com/zitadel/logging" + "sigs.k8s.io/yaml" +) + +type Config struct { + Log *logging.Config + Hostname string + Port uint16 + Secure bool + LoginURLV2 string + LogoutURLV2 string + WebAuthNName string +} + +var ( + //go:embed config/client.yaml + clientYAML []byte +) + +var ( + tmpDir string + loadedConfig Config +) + +// TmpDir returns the absolute path to the projects's temp directory. +func TmpDir() string { + return tmpDir +} + +func init() { + cmd := exec.Command("git", "rev-parse", "--show-toplevel") + out, err := cmd.Output() + if err != nil { + panic(err) + } + tmpDir = filepath.Join(string(bytes.TrimSpace(out)), "tmp") + + if err := yaml.Unmarshal(clientYAML, &loadedConfig); err != nil { + panic(err) + } + if err := loadedConfig.Log.SetLogger(); err != nil { + panic(err) + } + SystemToken = systemUserToken() +} diff --git a/internal/integration/config/client.yaml b/internal/integration/config/client.yaml new file mode 100644 index 0000000000..43e417d4d6 --- /dev/null +++ b/internal/integration/config/client.yaml @@ -0,0 +1,10 @@ +Log: + Level: info + Formatter: + Format: text +Hostname: localhost +Port: 8080 +Secure: false +LoginURLV2: "/login?authRequest=" +LogoutURLV2: "/logout?post_logout_redirect=" +WebAuthNName: ZITADEL diff --git a/internal/integration/config/docker-compose.yaml b/internal/integration/config/docker-compose.yaml index b7f065fad7..1749b9f0ab 100644 --- a/internal/integration/config/docker-compose.yaml +++ b/internal/integration/config/docker-compose.yaml @@ -14,7 +14,7 @@ services: - PGUSER=zitadel - POSTGRES_DB=zitadel - POSTGRES_HOST_AUTH_METHOD=trust - command: postgres -c shared_preload_libraries=pg_stat_statements -c pg_stat_statements.track=all + command: postgres -c shared_preload_libraries=pg_stat_statements -c pg_stat_statements.track=all -c shared_buffers=1GB -c work_mem=16MB -c effective_io_concurrency=100 -c wal_level=minimal -c archive_mode=off -c max_wal_senders=0 healthcheck: test: ["CMD-SHELL", "pg_isready"] interval: '10s' diff --git a/internal/integration/config/postgres.yaml b/internal/integration/config/postgres.yaml index c75187d7fb..9cabb440c0 100644 --- a/internal/integration/config/postgres.yaml +++ b/internal/integration/config/postgres.yaml @@ -1,10 +1,12 @@ Database: + EventPushConnRatio: 0.2 # 4 + ProjectionSpoolerConnRatio: 0.3 # 6 postgres: Host: localhost Port: 5432 Database: zitadel - MaxOpenConns: 15 - MaxIdleConns: 10 + MaxOpenConns: 20 + MaxIdleConns: 20 User: Username: zitadel SSL: diff --git a/internal/integration/config/steps.yaml b/internal/integration/config/steps.yaml new file mode 100644 index 0000000000..fea8441e2b --- /dev/null +++ b/internal/integration/config/steps.yaml @@ -0,0 +1,13 @@ +FirstInstance: + Skip: false + PatPath: tmp/admin-pat.txt + InstanceName: ZITADEL + DefaultLanguage: en + Org: + Name: ZITADEL + Machine: + Machine: + Username: boss + Name: boss + Pat: + ExpirationDate: 2099-01-01T00:00:00Z diff --git a/internal/integration/config/zitadel.yaml b/internal/integration/config/zitadel.yaml index d58529b7a8..68e0b43f9c 100644 --- a/internal/integration/config/zitadel.yaml +++ b/internal/integration/config/zitadel.yaml @@ -1,15 +1,19 @@ Log: - Level: debug + Level: info ExternalSecure: false TLS: Enabled: false +Quotas: + Access: + Enabled: true + Telemetry: Enabled: true Endpoints: - - http://localhost:8081 + - http://localhost:8081/milestone Headers: single-value: "single-value" multi-value: @@ -27,14 +31,15 @@ LogStore: Enabled: true Projections: - HandleActiveInstances: 60s + HandleActiveInstances: 30m + RequeueEvery: 5s + TransactionDuration: 1m Customizations: NotificationsQuotas: RequeueEvery: 1s + telemetry: HandleActiveInstances: 60s - Telemetry: - RequeueEvery: 5s - HandleActiveInstances: 60s + RequeueEvery: 1s DefaultInstance: LoginPolicy: diff --git a/internal/integration/instance.go b/internal/integration/instance.go new file mode 100644 index 0000000000..c6e0b9737c --- /dev/null +++ b/internal/integration/instance.go @@ -0,0 +1,354 @@ +// Package integration provides helpers for integration testing. +package integration + +import ( + "bytes" + "context" + _ "embed" + "errors" + "fmt" + "os" + "path/filepath" + "time" + + "github.com/brianvoe/gofakeit/v6" + "github.com/zitadel/logging" + "google.golang.org/grpc/metadata" + "google.golang.org/protobuf/proto" + + http_util "github.com/zitadel/zitadel/internal/api/http" + "github.com/zitadel/zitadel/internal/webauthn" + "github.com/zitadel/zitadel/pkg/grpc/admin" + "github.com/zitadel/zitadel/pkg/grpc/auth" + "github.com/zitadel/zitadel/pkg/grpc/instance" + "github.com/zitadel/zitadel/pkg/grpc/management" + "github.com/zitadel/zitadel/pkg/grpc/org" + "github.com/zitadel/zitadel/pkg/grpc/system" + "github.com/zitadel/zitadel/pkg/grpc/user" + user_v2 "github.com/zitadel/zitadel/pkg/grpc/user/v2" +) + +// NotEmpty can be used as placeholder, when the returned values is unknown. +// It can be used in tests to assert whether a value should be empty or not. +const NotEmpty = "not empty" + +const ( + adminPATFile = "admin-pat.txt" +) + +// UserType provides constants that give +// a short explanation with the purpose +// a service user. +// This allows to pre-create users with +// different permissions and reuse them. +type UserType int + +//go:generate enumer -type UserType -transform snake -trimprefix UserType +const ( + UserTypeUnspecified UserType = iota + UserTypeIAMOwner + UserTypeOrgOwner + UserTypeLogin +) + +const ( + UserPassword = "VeryS3cret!" +) + +const ( + PortMilestoneServer = "8081" + PortQuotaServer = "8082" +) + +// User information with a Personal Access Token. +type User struct { + ID string + Username string + Token string +} + +type UserMap map[UserType]*User + +func (m UserMap) Set(typ UserType, user *User) { + m[typ] = user +} + +func (m UserMap) Get(typ UserType) *User { + return m[typ] +} + +// Host returns the primary host of zitadel, on which the first instance is served. +// http://localhost:8080 by default +func (c *Config) Host() string { + return fmt.Sprintf("%s:%d", c.Hostname, c.Port) +} + +// Instance is a Zitadel server and client with all resources available for testing. +type Instance struct { + Config Config + Domain string + Instance *instance.InstanceDetail + DefaultOrg *org.Org + Users UserMap + AdminUserID string // First human user for password login + + Client *Client + WebAuthN *webauthn.Client +} + +// GetFirstInstance returns the default instance and org information, +// with authorized machine users. +// Using the first instance is not recommended as parallel test might +// interfere with each other. +// It is recommended to use [NewInstance] instead. +func GetFirstInstance(ctx context.Context) *Instance { + i := &Instance{ + Config: loadedConfig, + Domain: loadedConfig.Hostname, + } + token := loadInstanceOwnerPAT() + i.setClient(ctx) + i.setupInstance(ctx, token) + return i +} + +// NewInstance returns a new instance that can be used for integration tests. +// The instance contains a gRPC client connected to the domain of this instance. +// The included users are the IAM_OWNER, ORG_OWNER of the default org and +// a Login client user. +// +// The instance is isolated and is safe for parallel testing. +func NewInstance(ctx context.Context) *Instance { + primaryDomain := RandString(5) + ".integration.localhost" + + ctx = WithSystemAuthorization(ctx) + resp, err := SystemClient().CreateInstance(ctx, &system.CreateInstanceRequest{ + InstanceName: "testinstance", + CustomDomain: primaryDomain, + Owner: &system.CreateInstanceRequest_Machine_{ + Machine: &system.CreateInstanceRequest_Machine{ + UserName: "owner", + Name: "owner", + PersonalAccessToken: &system.CreateInstanceRequest_PersonalAccessToken{}, + }, + }, + }) + if err != nil { + panic(err) + } + i := &Instance{ + Config: loadedConfig, + Domain: primaryDomain, + } + i.setClient(ctx) + i.awaitFirstUser(WithAuthorizationToken(ctx, resp.GetPat())) + i.setupInstance(ctx, resp.GetPat()) + return i +} + +func (i *Instance) ID() string { + return i.Instance.GetId() +} + +func (i *Instance) awaitFirstUser(ctx context.Context) { + var allErrs []error + for { + resp, err := i.Client.UserV2.AddHumanUser(ctx, &user_v2.AddHumanUserRequest{ + Username: proto.String("zitadel-admin@zitadel.localhost"), + Profile: &user_v2.SetHumanProfile{ + GivenName: "hodor", + FamilyName: "hodor", + NickName: proto.String("hodor"), + }, + Email: &user_v2.SetHumanEmail{ + Email: "zitadel-admin@zitadel.localhost", + Verification: &user_v2.SetHumanEmail_IsVerified{ + IsVerified: true, + }, + }, + PasswordType: &user_v2.AddHumanUserRequest_Password{ + Password: &user_v2.Password{ + Password: "Password1!", + ChangeRequired: false, + }, + }, + }) + if err == nil { + i.AdminUserID = resp.GetUserId() + return + } + logging.WithError(err).Debug("await first instance user") + allErrs = append(allErrs, err) + select { + case <-ctx.Done(): + panic(errors.Join(append(allErrs, ctx.Err())...)) + case <-time.After(time.Second): + continue + } + } +} + +func (i *Instance) setupInstance(ctx context.Context, token string) { + i.Users = make(UserMap) + ctx = WithAuthorizationToken(ctx, token) + i.setInstance(ctx) + i.setOrganization(ctx) + i.createMachineUserInstanceOwner(ctx, token) + i.createMachineUserOrgOwner(ctx) + i.createLoginClient(ctx) + i.createWebAuthNClient() +} + +// Host returns the primary Domain of the instance with the port. +func (i *Instance) Host() string { + return fmt.Sprintf("%s:%d", i.Domain, i.Config.Port) +} + +func loadInstanceOwnerPAT() string { + data, err := os.ReadFile(filepath.Join(tmpDir, adminPATFile)) + if err != nil { + panic(err) + } + return string(bytes.TrimSpace(data)) +} + +func (i *Instance) createMachineUserInstanceOwner(ctx context.Context, token string) { + mustAwait(func() error { + user, err := i.Client.Auth.GetMyUser(WithAuthorizationToken(ctx, token), &auth.GetMyUserRequest{}) + if err != nil { + return err + } + i.Users.Set(UserTypeIAMOwner, &User{ + ID: user.GetUser().GetId(), + Username: user.GetUser().GetUserName(), + Token: token, + }) + return nil + }) +} + +func (i *Instance) createMachineUserOrgOwner(ctx context.Context) { + _, err := i.Client.Mgmt.AddOrgMember(ctx, &management.AddOrgMemberRequest{ + UserId: i.createMachineUser(ctx, UserTypeOrgOwner), + Roles: []string{"ORG_OWNER"}, + }) + if err != nil { + panic(err) + } +} + +func (i *Instance) createLoginClient(ctx context.Context) { + i.createMachineUser(ctx, UserTypeLogin) +} + +func (i *Instance) setClient(ctx context.Context) { + client, err := newClient(ctx, i.Host()) + if err != nil { + panic(err) + } + i.Client = client +} + +func (i *Instance) setInstance(ctx context.Context) { + mustAwait(func() error { + instance, err := i.Client.Admin.GetMyInstance(ctx, &admin.GetMyInstanceRequest{}) + i.Instance = instance.GetInstance() + return err + }) +} + +func (i *Instance) setOrganization(ctx context.Context) { + mustAwait(func() error { + resp, err := i.Client.Mgmt.GetMyOrg(ctx, &management.GetMyOrgRequest{}) + i.DefaultOrg = resp.GetOrg() + return err + }) +} + +func (i *Instance) createMachineUser(ctx context.Context, userType UserType) (userID string) { + mustAwait(func() error { + username := gofakeit.Username() + userResp, err := i.Client.Mgmt.AddMachineUser(ctx, &management.AddMachineUserRequest{ + UserName: username, + Name: username, + Description: userType.String(), + AccessTokenType: user.AccessTokenType_ACCESS_TOKEN_TYPE_JWT, + }) + if err != nil { + return err + } + userID = userResp.GetUserId() + patResp, err := i.Client.Mgmt.AddPersonalAccessToken(ctx, &management.AddPersonalAccessTokenRequest{ + UserId: userID, + }) + if err != nil { + return err + } + i.Users.Set(userType, &User{ + ID: userID, + Username: username, + Token: patResp.GetToken(), + }) + return nil + }) + return userID +} + +func (i *Instance) createWebAuthNClient() { + i.WebAuthN = webauthn.NewClient(i.Config.WebAuthNName, i.Domain, http_util.BuildOrigin(i.Host(), i.Config.Secure)) +} + +func (i *Instance) WithAuthorization(ctx context.Context, u UserType) context.Context { + return i.WithInstanceAuthorization(ctx, u) +} + +func (i *Instance) WithInstanceAuthorization(ctx context.Context, u UserType) context.Context { + return WithAuthorizationToken(ctx, i.Users.Get(u).Token) +} + +func (i *Instance) GetUserID(u UserType) string { + return i.Users.Get(u).ID +} + +func WithAuthorizationToken(ctx context.Context, token string) context.Context { + md, ok := metadata.FromOutgoingContext(ctx) + if !ok { + md = make(metadata.MD) + } + md.Set("Authorization", fmt.Sprintf("Bearer %s", token)) + return metadata.NewOutgoingContext(ctx, md) +} + +func (i *Instance) BearerToken(ctx context.Context) string { + md, ok := metadata.FromOutgoingContext(ctx) + if !ok { + return "" + } + return md.Get("Authorization")[0] +} + +func (i *Instance) WithSystemAuthorizationHTTP(u UserType) map[string]string { + return map[string]string{"Authorization": fmt.Sprintf("Bearer %s", i.Users.Get(u).Token)} +} + +func await(af func() error) error { + maxTimer := time.NewTimer(15 * time.Minute) + for { + err := af() + if err == nil { + return nil + } + select { + case <-maxTimer.C: + return err + case <-time.After(time.Second): + continue + } + } +} + +func mustAwait(af func() error) { + if err := await(af); err != nil { + panic(err) + } +} diff --git a/internal/integration/integration.go b/internal/integration/integration.go deleted file mode 100644 index 20af65993b..0000000000 --- a/internal/integration/integration.go +++ /dev/null @@ -1,449 +0,0 @@ -// Package integration provides helpers for integration testing. -package integration - -import ( - "bytes" - "context" - "database/sql" - _ "embed" - "errors" - "fmt" - "io" - "net/http" - "net/http/httptest" - "os" - "reflect" - "strings" - "sync" - "time" - - "github.com/spf13/viper" - "github.com/zitadel/logging" - "github.com/zitadel/oidc/v3/pkg/client" - "github.com/zitadel/oidc/v3/pkg/oidc" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" - "google.golang.org/grpc/metadata" - - "github.com/zitadel/zitadel/cmd" - "github.com/zitadel/zitadel/cmd/start" - "github.com/zitadel/zitadel/internal/api/authz" - http_util "github.com/zitadel/zitadel/internal/api/http" - z_oidc "github.com/zitadel/zitadel/internal/api/oidc" - "github.com/zitadel/zitadel/internal/command" - "github.com/zitadel/zitadel/internal/domain" - "github.com/zitadel/zitadel/internal/eventstore/v1/models" - "github.com/zitadel/zitadel/internal/net" - "github.com/zitadel/zitadel/internal/query" - "github.com/zitadel/zitadel/internal/webauthn" - "github.com/zitadel/zitadel/internal/zerrors" - "github.com/zitadel/zitadel/pkg/grpc/admin" -) - -var ( - //go:embed config/zitadel.yaml - zitadelYAML []byte - //go:embed config/cockroach.yaml - cockroachYAML []byte - //go:embed config/postgres.yaml - postgresYAML []byte - //go:embed config/system-user-key.pem - systemUserKey []byte -) - -// NotEmpty can be used as placeholder, when the returned values is unknown. -// It can be used in tests to assert whether a value should be empty or not. -const NotEmpty = "not empty" - -// UserType provides constants that give -// a short explinanation with the purpose -// a serverice user. -// This allows to pre-create users with -// different permissions and reuse them. -type UserType int - -//go:generate stringer -type=UserType -const ( - Unspecified UserType = iota - OrgOwner - Login - IAMOwner - SystemUser // SystemUser is a user with access to the system service. -) - -const ( - FirstInstanceUsersKey = "first" - UserPassword = "VeryS3cret!" -) - -const ( - PortMilestoneServer = "8081" - PortQuotaServer = "8082" -) - -// User information with a Personal Access Token. -type User struct { - *query.User - Token string -} - -type InstanceUserMap map[string]map[UserType]*User - -func (m InstanceUserMap) Set(instanceID string, typ UserType, user *User) { - if m[instanceID] == nil { - m[instanceID] = make(map[UserType]*User) - } - m[instanceID][typ] = user -} - -func (m InstanceUserMap) Get(instanceID string, typ UserType) *User { - if users, ok := m[instanceID]; ok { - return users[typ] - } - return nil -} - -// Tester is a Zitadel server and client with all resources available for testing. -type Tester struct { - *start.Server - - Instance authz.Instance - Organisation *query.Org - Users InstanceUserMap - - MilestoneChan chan []byte - milestoneServer *httptest.Server - QuotaNotificationChan chan []byte - quotaNotificationServer *httptest.Server - - Client Client - WebAuthN *webauthn.Client - wg sync.WaitGroup // used for shutdown -} - -const commandLine = `start --masterkeyFromEnv` - -func (s *Tester) Host() string { - return fmt.Sprintf("%s:%d", s.Config.ExternalDomain, s.Config.Port) -} - -func (s *Tester) createClientConn(ctx context.Context, target string) { - cc, err := grpc.DialContext(ctx, target, - grpc.WithBlock(), - grpc.WithTransportCredentials(insecure.NewCredentials()), - ) - if err != nil { - s.Shutdown <- os.Interrupt - s.wg.Wait() - } - logging.OnError(err).Fatal("integration tester client dial") - logging.New().WithField("target", target).Info("finished dialing grpc client conn") - - s.Client = newClient(cc) - err = s.pollHealth(ctx) - logging.OnError(err).Fatal("integration tester health") -} - -// pollHealth waits until a healthy status is reported. -// TODO: remove when we make the setup blocking on all -// projections completed. -func (s *Tester) pollHealth(ctx context.Context) (err error) { - for { - err = func(ctx context.Context) error { - ctx, cancel := context.WithTimeout(ctx, 5*time.Second) - defer cancel() - - _, err := s.Client.Admin.Healthz(ctx, &admin.HealthzRequest{}) - return err - }(ctx) - if err == nil { - return nil - } - logging.WithError(err).Info("poll healthz") - - select { - case <-ctx.Done(): - return ctx.Err() - case <-time.After(time.Second): - continue - } - } -} - -const ( - LoginUser = "loginClient" - MachineUserOrgOwner = "integrationOrgOwner" - MachineUserInstanceOwner = "integrationInstanceOwner" -) - -func (s *Tester) createMachineUserOrgOwner(ctx context.Context) { - var err error - - ctx, user := s.createMachineUser(ctx, MachineUserOrgOwner, OrgOwner) - _, err = s.Commands.AddOrgMember(ctx, user.ResourceOwner, user.ID, "ORG_OWNER") - target := new(zerrors.AlreadyExistsError) - if !errors.As(err, &target) { - logging.OnError(err).Fatal("add org member") - } -} - -func (s *Tester) createMachineUserInstanceOwner(ctx context.Context) { - var err error - - ctx, user := s.createMachineUser(ctx, MachineUserInstanceOwner, IAMOwner) - _, err = s.Commands.AddInstanceMember(ctx, user.ID, "IAM_OWNER") - target := new(zerrors.AlreadyExistsError) - if !errors.As(err, &target) { - logging.OnError(err).Fatal("add instance member") - } -} - -func (s *Tester) createLoginClient(ctx context.Context) { - s.createMachineUser(ctx, LoginUser, Login) -} - -func (s *Tester) createMachineUser(ctx context.Context, username string, userType UserType) (context.Context, *query.User) { - var err error - ctx = s.updateInstanceAndOrg(ctx, s.Host()) - usernameQuery, err := query.NewUserUsernameSearchQuery(username, query.TextEquals) - logging.OnError(err).Fatal("user query") - user, err := s.Queries.GetUser(ctx, true, usernameQuery) - if errors.Is(err, sql.ErrNoRows) { - _, err = s.Commands.AddMachine(ctx, &command.Machine{ - ObjectRoot: models.ObjectRoot{ - ResourceOwner: s.Organisation.ID, - }, - Username: username, - Name: username, - Description: "who cares?", - AccessTokenType: domain.OIDCTokenTypeJWT, - }) - logging.WithFields("username", username).OnError(err).Fatal("add machine user") - user, err = s.Queries.GetUser(ctx, true, usernameQuery) - } - logging.WithFields("username", username).OnError(err).Fatal("get user") - - scopes := []string{oidc.ScopeOpenID, oidc.ScopeProfile, z_oidc.ScopeUserMetaData, z_oidc.ScopeResourceOwner} - pat := command.NewPersonalAccessToken(user.ResourceOwner, user.ID, time.Now().Add(time.Hour), scopes, domain.UserTypeMachine) - _, err = s.Commands.AddPersonalAccessToken(ctx, pat) - logging.WithFields("username", SystemUser).OnError(err).Fatal("add pat") - s.Users.Set(FirstInstanceUsersKey, userType, &User{ - User: user, - Token: pat.Token, - }) - return ctx, user -} - -func (s *Tester) WithAuthorization(ctx context.Context, u UserType) context.Context { - return s.WithInstanceAuthorization(ctx, u, FirstInstanceUsersKey) -} - -func (s *Tester) WithInstanceAuthorization(ctx context.Context, u UserType, instanceID string) context.Context { - if u == SystemUser { - s.ensureSystemUser() - } - return s.WithAuthorizationToken(ctx, s.Users.Get(instanceID, u).Token) -} - -func (s *Tester) GetUserID(u UserType) string { - if u == SystemUser { - s.ensureSystemUser() - } - return s.Users.Get(FirstInstanceUsersKey, u).ID -} - -func (s *Tester) WithAuthorizationToken(ctx context.Context, token string) context.Context { - md, ok := metadata.FromOutgoingContext(ctx) - if !ok { - md = make(metadata.MD) - } - md.Set("Authorization", fmt.Sprintf("Bearer %s", token)) - return metadata.NewOutgoingContext(ctx, md) -} - -func (s *Tester) BearerToken(ctx context.Context) string { - md, ok := metadata.FromOutgoingContext(ctx) - if !ok { - return "" - } - return md.Get("Authorization")[0] -} - -func (s *Tester) ensureSystemUser() { - const ISSUER = "tester" - if s.Users.Get(FirstInstanceUsersKey, SystemUser) != nil { - return - } - audience := http_util.BuildOrigin(s.Host(), s.Server.Config.ExternalSecure) - signer, err := client.NewSignerFromPrivateKeyByte(systemUserKey, "") - logging.OnError(err).Fatal("system key signer") - jwt, err := client.SignedJWTProfileAssertion(ISSUER, []string{audience}, time.Hour, signer) - logging.OnError(err).Fatal("system key jwt") - s.Users.Set(FirstInstanceUsersKey, SystemUser, &User{Token: jwt}) -} - -func (s *Tester) WithSystemAuthorizationHTTP(u UserType) map[string]string { - return map[string]string{"Authorization": fmt.Sprintf("Bearer %s", s.Users.Get(FirstInstanceUsersKey, u).Token)} -} - -// Done send an interrupt signal to cleanly shutdown the server. -func (s *Tester) Done() { - err := s.Client.CC.Close() - logging.OnError(err).Error("integration tester client close") - - s.Shutdown <- os.Interrupt - s.wg.Wait() - s.milestoneServer.Close() - s.quotaNotificationServer.Close() -} - -// NewTester start a new Zitadel server by passing the default commandline. -// The server will listen on the configured port. -// The database configuration that will be used can be set by the -// INTEGRATION_DB_FLAVOR environment variable and can have the values "cockroach" -// or "postgres". Defaults to "cockroach". -// -// The default Instance and Organisation are read from the DB and system -// users are created as needed. -// -// After the server is started, a [grpc.ClientConn] will be created and -// the server is polled for it's health status. -// -// Note: the database must already be setup and initialized before -// using NewTester. See the CONTRIBUTING.md document for details. - -func NewTester(ctx context.Context, zitadelConfigYAML ...string) *Tester { - args := strings.Split(commandLine, " ") - - sc := make(chan *start.Server) - //nolint:contextcheck - cmd := cmd.New(os.Stdout, os.Stdin, args, sc) - cmd.SetArgs(args) - for _, yaml := range append([]string{string(zitadelYAML)}, zitadelConfigYAML...) { - err := viper.MergeConfig(bytes.NewBuffer([]byte(yaml))) - logging.OnError(err).Fatal() - } - var err error - flavor := os.Getenv("INTEGRATION_DB_FLAVOR") - switch flavor { - case "cockroach", "": - err = viper.MergeConfig(bytes.NewBuffer(cockroachYAML)) - case "postgres": - err = viper.MergeConfig(bytes.NewBuffer(postgresYAML)) - default: - logging.New().WithField("flavor", flavor).Fatal("unknown db flavor set in INTEGRATION_DB_FLAVOR") - } - logging.OnError(err).Fatal() - - tester := Tester{ - Users: make(InstanceUserMap), - } - tester.MilestoneChan = make(chan []byte, 100) - tester.milestoneServer, err = runMilestoneServer(ctx, tester.MilestoneChan) - logging.OnError(err).Fatal() - tester.QuotaNotificationChan = make(chan []byte, 100) - tester.quotaNotificationServer, err = runQuotaServer(ctx, tester.QuotaNotificationChan) - logging.OnError(err).Fatal() - - tester.wg.Add(1) - go func(wg *sync.WaitGroup) { - logging.OnError(cmd.Execute()).Fatal() - wg.Done() - }(&tester.wg) - - select { - case tester.Server = <-sc: - case <-ctx.Done(): - logging.OnError(ctx.Err()).Fatal("waiting for integration tester server") - } - host := tester.Host() - tester.createClientConn(ctx, host) - tester.createLoginClient(ctx) - tester.WebAuthN = webauthn.NewClient(tester.Config.WebAuthNName, tester.Config.ExternalDomain, http_util.BuildOrigin(host, tester.Config.ExternalSecure)) - tester.createMachineUserOrgOwner(ctx) - tester.createMachineUserInstanceOwner(ctx) - tester.WebAuthN = webauthn.NewClient(tester.Config.WebAuthNName, tester.Config.ExternalDomain, "https://"+tester.Host()) - return &tester -} - -func Contexts(timeout time.Duration) (ctx, errCtx context.Context, cancel context.CancelFunc) { - errCtx, cancel = context.WithCancel(context.Background()) - cancel() - ctx, cancel = context.WithTimeout(context.Background(), timeout) - return ctx, errCtx, cancel -} - -func runMilestoneServer(ctx context.Context, bodies chan []byte) (*httptest.Server, error) { - mockServer := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - body, err := io.ReadAll(r.Body) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - if r.Header.Get("single-value") != "single-value" { - http.Error(w, "single-value header not set", http.StatusInternalServerError) - return - } - if reflect.DeepEqual(r.Header.Get("multi-value"), "multi-value-1,multi-value-2") { - http.Error(w, "single-value header not set", http.StatusInternalServerError) - return - } - bodies <- body - w.WriteHeader(http.StatusOK) - })) - config := net.ListenConfig() - listener, err := config.Listen(ctx, "tcp", ":"+PortMilestoneServer) - if err != nil { - return nil, err - } - mockServer.Listener = listener - mockServer.Start() - return mockServer, nil -} - -func runQuotaServer(ctx context.Context, bodies chan []byte) (*httptest.Server, error) { - mockServer := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - body, err := io.ReadAll(r.Body) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - bodies <- body - w.WriteHeader(http.StatusOK) - })) - config := net.ListenConfig() - listener, err := config.Listen(ctx, "tcp", ":"+PortQuotaServer) - if err != nil { - return nil, err - } - mockServer.Listener = listener - mockServer.Start() - return mockServer, nil -} - -func (s *Tester) updateInstanceAndOrg(ctx context.Context, domain string) context.Context { - var err error - s.Instance, err = s.Queries.InstanceByHost(ctx, domain, "") - logging.OnError(err).Fatal("query instance") - ctx = authz.WithInstance(ctx, s.Instance) - - s.Organisation, err = s.Queries.OrgByID(ctx, true, s.Instance.DefaultOrganisationID()) - logging.OnError(err).Fatal("query organisation") - return ctx -} - -func await(af func() error) error { - maxTimer := time.NewTimer(15 * time.Minute) - for { - err := af() - if err == nil { - return nil - } - select { - case <-maxTimer.C: - return err - case <-time.After(time.Second / 10): - continue - } - } -} diff --git a/internal/integration/integration_test.go b/internal/integration/integration_test.go deleted file mode 100644 index 416602ea25..0000000000 --- a/internal/integration/integration_test.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build integration - -package integration - -import ( - "testing" - "time" -) - -func TestNewTester(t *testing.T) { - ctx, _, cancel := Contexts(time.Hour) - defer cancel() - - s := NewTester(ctx) - defer s.Done() -} diff --git a/internal/integration/oidc.go b/internal/integration/oidc.go index 1d15d25f29..9f394e2c2c 100644 --- a/internal/integration/oidc.go +++ b/internal/integration/oidc.go @@ -24,11 +24,11 @@ import ( "github.com/zitadel/zitadel/pkg/grpc/user" ) -func (s *Tester) CreateOIDCClient(ctx context.Context, redirectURI, logoutRedirectURI, projectID string, appType app.OIDCAppType, authMethod app.OIDCAuthMethodType, devMode bool, grantTypes ...app.OIDCGrantType) (*management.AddOIDCAppResponse, error) { +func (i *Instance) CreateOIDCClient(ctx context.Context, redirectURI, logoutRedirectURI, projectID string, appType app.OIDCAppType, authMethod app.OIDCAuthMethodType, devMode bool, grantTypes ...app.OIDCGrantType) (*management.AddOIDCAppResponse, error) { if len(grantTypes) == 0 { grantTypes = []app.OIDCGrantType{app.OIDCGrantType_OIDC_GRANT_TYPE_AUTHORIZATION_CODE, app.OIDCGrantType_OIDC_GRANT_TYPE_REFRESH_TOKEN} } - resp, err := s.Client.Mgmt.AddOIDCApp(ctx, &management.AddOIDCAppRequest{ + resp, err := i.Client.Mgmt.AddOIDCApp(ctx, &management.AddOIDCAppRequest{ ProjectId: projectID, Name: fmt.Sprintf("app-%d", time.Now().UnixNano()), RedirectUris: []string{redirectURI}, @@ -51,7 +51,7 @@ func (s *Tester) CreateOIDCClient(ctx context.Context, redirectURI, logoutRedire return nil, err } return resp, await(func() error { - _, err := s.Client.Mgmt.GetAppByID(ctx, &management.GetAppByIDRequest{ + _, err := i.Client.Mgmt.GetAppByID(ctx, &management.GetAppByIDRequest{ ProjectId: projectID, AppId: resp.GetAppId(), }) @@ -59,20 +59,20 @@ func (s *Tester) CreateOIDCClient(ctx context.Context, redirectURI, logoutRedire }) } -func (s *Tester) CreateOIDCNativeClient(ctx context.Context, redirectURI, logoutRedirectURI, projectID string, devMode bool) (*management.AddOIDCAppResponse, error) { - return s.CreateOIDCClient(ctx, redirectURI, logoutRedirectURI, projectID, app.OIDCAppType_OIDC_APP_TYPE_NATIVE, app.OIDCAuthMethodType_OIDC_AUTH_METHOD_TYPE_NONE, devMode) +func (i *Instance) CreateOIDCNativeClient(ctx context.Context, redirectURI, logoutRedirectURI, projectID string, devMode bool) (*management.AddOIDCAppResponse, error) { + return i.CreateOIDCClient(ctx, redirectURI, logoutRedirectURI, projectID, app.OIDCAppType_OIDC_APP_TYPE_NATIVE, app.OIDCAuthMethodType_OIDC_AUTH_METHOD_TYPE_NONE, devMode) } -func (s *Tester) CreateOIDCWebClientBasic(ctx context.Context, redirectURI, logoutRedirectURI, projectID string) (*management.AddOIDCAppResponse, error) { - return s.CreateOIDCClient(ctx, redirectURI, logoutRedirectURI, projectID, app.OIDCAppType_OIDC_APP_TYPE_WEB, app.OIDCAuthMethodType_OIDC_AUTH_METHOD_TYPE_BASIC, false) +func (i *Instance) CreateOIDCWebClientBasic(ctx context.Context, redirectURI, logoutRedirectURI, projectID string) (*management.AddOIDCAppResponse, error) { + return i.CreateOIDCClient(ctx, redirectURI, logoutRedirectURI, projectID, app.OIDCAppType_OIDC_APP_TYPE_WEB, app.OIDCAuthMethodType_OIDC_AUTH_METHOD_TYPE_BASIC, false) } -func (s *Tester) CreateOIDCWebClientJWT(ctx context.Context, redirectURI, logoutRedirectURI, projectID string, grantTypes ...app.OIDCGrantType) (client *management.AddOIDCAppResponse, keyData []byte, err error) { - client, err = s.CreateOIDCClient(ctx, redirectURI, logoutRedirectURI, projectID, app.OIDCAppType_OIDC_APP_TYPE_WEB, app.OIDCAuthMethodType_OIDC_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT, false, grantTypes...) +func (i *Instance) CreateOIDCWebClientJWT(ctx context.Context, redirectURI, logoutRedirectURI, projectID string, grantTypes ...app.OIDCGrantType) (client *management.AddOIDCAppResponse, keyData []byte, err error) { + client, err = i.CreateOIDCClient(ctx, redirectURI, logoutRedirectURI, projectID, app.OIDCAppType_OIDC_APP_TYPE_WEB, app.OIDCAuthMethodType_OIDC_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT, false, grantTypes...) if err != nil { return nil, nil, err } - key, err := s.Client.Mgmt.AddAppKey(ctx, &management.AddAppKeyRequest{ + key, err := i.Client.Mgmt.AddAppKey(ctx, &management.AddAppKeyRequest{ ProjectId: projectID, AppId: client.GetAppId(), Type: authn.KeyType_KEY_TYPE_JSON, @@ -81,15 +81,23 @@ func (s *Tester) CreateOIDCWebClientJWT(ctx context.Context, redirectURI, logout if err != nil { return nil, nil, err } + mustAwait(func() error { + _, err := i.Client.Mgmt.GetAppByID(ctx, &management.GetAppByIDRequest{ + ProjectId: projectID, + AppId: client.GetAppId(), + }) + return err + }) + return client, key.GetKeyDetails(), nil } -func (s *Tester) CreateOIDCInactivateClient(ctx context.Context, redirectURI, logoutRedirectURI, projectID string) (*management.AddOIDCAppResponse, error) { - client, err := s.CreateOIDCNativeClient(ctx, redirectURI, logoutRedirectURI, projectID, false) +func (i *Instance) CreateOIDCInactivateClient(ctx context.Context, redirectURI, logoutRedirectURI, projectID string) (*management.AddOIDCAppResponse, error) { + client, err := i.CreateOIDCNativeClient(ctx, redirectURI, logoutRedirectURI, projectID, false) if err != nil { return nil, err } - _, err = s.Client.Mgmt.DeactivateApp(ctx, &management.DeactivateAppRequest{ + _, err = i.Client.Mgmt.DeactivateApp(ctx, &management.DeactivateAppRequest{ ProjectId: projectID, AppId: client.GetAppId(), }) @@ -99,14 +107,14 @@ func (s *Tester) CreateOIDCInactivateClient(ctx context.Context, redirectURI, lo return client, err } -func (s *Tester) CreateOIDCImplicitFlowClient(ctx context.Context, redirectURI string) (*management.AddOIDCAppResponse, error) { - project, err := s.Client.Mgmt.AddProject(ctx, &management.AddProjectRequest{ +func (i *Instance) CreateOIDCImplicitFlowClient(ctx context.Context, redirectURI string) (*management.AddOIDCAppResponse, error) { + project, err := i.Client.Mgmt.AddProject(ctx, &management.AddProjectRequest{ Name: fmt.Sprintf("project-%d", time.Now().UnixNano()), }) if err != nil { return nil, err } - resp, err := s.Client.Mgmt.AddOIDCApp(ctx, &management.AddOIDCAppRequest{ + resp, err := i.Client.Mgmt.AddOIDCApp(ctx, &management.AddOIDCAppRequest{ ProjectId: project.GetId(), Name: fmt.Sprintf("app-%d", time.Now().UnixNano()), RedirectUris: []string{redirectURI}, @@ -129,7 +137,7 @@ func (s *Tester) CreateOIDCImplicitFlowClient(ctx context.Context, redirectURI s return nil, err } return resp, await(func() error { - _, err := s.Client.Mgmt.GetAppByID(ctx, &management.GetAppByIDRequest{ + _, err := i.Client.Mgmt.GetAppByID(ctx, &management.GetAppByIDRequest{ ProjectId: project.GetId(), AppId: resp.GetAppId(), }) @@ -137,32 +145,32 @@ func (s *Tester) CreateOIDCImplicitFlowClient(ctx context.Context, redirectURI s }) } -func (s *Tester) CreateOIDCTokenExchangeClient(ctx context.Context) (client *management.AddOIDCAppResponse, keyData []byte, err error) { - project, err := s.Client.Mgmt.AddProject(ctx, &management.AddProjectRequest{ +func (i *Instance) CreateOIDCTokenExchangeClient(ctx context.Context) (client *management.AddOIDCAppResponse, keyData []byte, err error) { + project, err := i.Client.Mgmt.AddProject(ctx, &management.AddProjectRequest{ Name: fmt.Sprintf("project-%d", time.Now().UnixNano()), }) if err != nil { return nil, nil, err } - return s.CreateOIDCWebClientJWT(ctx, "", "", project.GetId(), app.OIDCGrantType_OIDC_GRANT_TYPE_TOKEN_EXCHANGE, app.OIDCGrantType_OIDC_GRANT_TYPE_AUTHORIZATION_CODE, app.OIDCGrantType_OIDC_GRANT_TYPE_REFRESH_TOKEN) + return i.CreateOIDCWebClientJWT(ctx, "", "", project.GetId(), app.OIDCGrantType_OIDC_GRANT_TYPE_TOKEN_EXCHANGE, app.OIDCGrantType_OIDC_GRANT_TYPE_AUTHORIZATION_CODE, app.OIDCGrantType_OIDC_GRANT_TYPE_REFRESH_TOKEN) } -func (s *Tester) CreateProject(ctx context.Context) (*management.AddProjectResponse, error) { - return s.Client.Mgmt.AddProject(ctx, &management.AddProjectRequest{ +func (i *Instance) CreateProject(ctx context.Context) (*management.AddProjectResponse, error) { + return i.Client.Mgmt.AddProject(ctx, &management.AddProjectRequest{ Name: fmt.Sprintf("project-%d", time.Now().UnixNano()), }) } -func (s *Tester) CreateAPIClientJWT(ctx context.Context, projectID string) (*management.AddAPIAppResponse, error) { - return s.Client.Mgmt.AddAPIApp(ctx, &management.AddAPIAppRequest{ +func (i *Instance) CreateAPIClientJWT(ctx context.Context, projectID string) (*management.AddAPIAppResponse, error) { + return i.Client.Mgmt.AddAPIApp(ctx, &management.AddAPIAppRequest{ ProjectId: projectID, Name: fmt.Sprintf("api-%d", time.Now().UnixNano()), AuthMethodType: app.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT, }) } -func (s *Tester) CreateAPIClientBasic(ctx context.Context, projectID string) (*management.AddAPIAppResponse, error) { - return s.Client.Mgmt.AddAPIApp(ctx, &management.AddAPIAppRequest{ +func (i *Instance) CreateAPIClientBasic(ctx context.Context, projectID string) (*management.AddAPIAppResponse, error) { + return i.Client.Mgmt.AddAPIApp(ctx, &management.AddAPIAppRequest{ ProjectId: projectID, Name: fmt.Sprintf("api-%d", time.Now().UnixNano()), AuthMethodType: app.APIAuthMethodType_API_AUTH_METHOD_TYPE_BASIC, @@ -171,36 +179,36 @@ func (s *Tester) CreateAPIClientBasic(ctx context.Context, projectID string) (*m const CodeVerifier = "codeVerifier" -func (s *Tester) CreateOIDCAuthRequest(ctx context.Context, clientID, loginClient, redirectURI string, scope ...string) (authRequestID string, err error) { - return s.CreateOIDCAuthRequestWithDomain(ctx, s.Config.ExternalDomain, clientID, loginClient, redirectURI, scope...) +func (i *Instance) CreateOIDCAuthRequest(ctx context.Context, clientID, loginClient, redirectURI string, scope ...string) (authRequestID string, err error) { + return i.CreateOIDCAuthRequestWithDomain(ctx, i.Domain, clientID, loginClient, redirectURI, scope...) } -func (s *Tester) CreateOIDCAuthRequestWithDomain(ctx context.Context, domain, clientID, loginClient, redirectURI string, scope ...string) (authRequestID string, err error) { - provider, err := s.CreateRelyingPartyForDomain(ctx, domain, clientID, redirectURI, scope...) +func (i *Instance) CreateOIDCAuthRequestWithDomain(ctx context.Context, domain, clientID, loginClient, redirectURI string, scope ...string) (authRequestID string, err error) { + provider, err := i.CreateRelyingPartyForDomain(ctx, domain, clientID, redirectURI, scope...) if err != nil { - return "", err + return "", fmt.Errorf("create relying party: %w", err) } codeChallenge := oidc.NewSHACodeChallenge(CodeVerifier) authURL := rp.AuthURL("state", provider, rp.WithCodeChallenge(codeChallenge)) req, err := GetRequest(authURL, map[string]string{oidc_internal.LoginClientHeader: loginClient}) if err != nil { - return "", err + return "", fmt.Errorf("get request: %w", err) } loc, err := CheckRedirect(req) if err != nil { - return "", err + return "", fmt.Errorf("check redirect: %w", err) } - prefixWithHost := provider.Issuer() + s.Config.OIDC.DefaultLoginURLV2 + prefixWithHost := provider.Issuer() + i.Config.LoginURLV2 if !strings.HasPrefix(loc.String(), prefixWithHost) { return "", fmt.Errorf("login location has not prefix %s, but is %s", prefixWithHost, loc.String()) } return strings.TrimPrefix(loc.String(), prefixWithHost), nil } -func (s *Tester) CreateOIDCAuthRequestImplicit(ctx context.Context, clientID, loginClient, redirectURI string, scope ...string) (authRequestID string, err error) { - provider, err := s.CreateRelyingParty(ctx, clientID, redirectURI, scope...) +func (i *Instance) CreateOIDCAuthRequestImplicit(ctx context.Context, clientID, loginClient, redirectURI string, scope ...string) (authRequestID string, err error) { + provider, err := i.CreateRelyingParty(ctx, clientID, redirectURI, scope...) if err != nil { return "", err } @@ -224,48 +232,49 @@ func (s *Tester) CreateOIDCAuthRequestImplicit(ctx context.Context, clientID, lo return "", err } - prefixWithHost := provider.Issuer() + s.Config.OIDC.DefaultLoginURLV2 + prefixWithHost := provider.Issuer() + i.Config.LoginURLV2 if !strings.HasPrefix(loc.String(), prefixWithHost) { return "", fmt.Errorf("login location has not prefix %s, but is %s", prefixWithHost, loc.String()) } return strings.TrimPrefix(loc.String(), prefixWithHost), nil } -func (s *Tester) OIDCIssuer() string { - return http_util.BuildHTTP(s.Config.ExternalDomain, s.Config.Port, s.Config.ExternalSecure) +func (i *Instance) OIDCIssuer() string { + return http_util.BuildHTTP(i.Domain, i.Config.Port, i.Config.Secure) } -func (s *Tester) CreateRelyingParty(ctx context.Context, clientID, redirectURI string, scope ...string) (rp.RelyingParty, error) { - return s.CreateRelyingPartyForDomain(ctx, s.Config.ExternalDomain, clientID, redirectURI, scope...) +func (i *Instance) CreateRelyingParty(ctx context.Context, clientID, redirectURI string, scope ...string) (rp.RelyingParty, error) { + return i.CreateRelyingPartyForDomain(ctx, i.Domain, clientID, redirectURI, scope...) } -func (s *Tester) CreateRelyingPartyForDomain(ctx context.Context, domain, clientID, redirectURI string, scope ...string) (rp.RelyingParty, error) { +func (i *Instance) CreateRelyingPartyForDomain(ctx context.Context, domain, clientID, redirectURI string, scope ...string) (rp.RelyingParty, error) { if len(scope) == 0 { scope = []string{oidc.ScopeOpenID} } - loginClient := &http.Client{Transport: &loginRoundTripper{http.DefaultTransport}} - return rp.NewRelyingPartyOIDC(ctx, http_util.BuildHTTP(domain, s.Config.Port, s.Config.ExternalSecure), clientID, "", redirectURI, scope, rp.WithHTTPClient(loginClient)) + loginClient := &http.Client{Transport: &loginRoundTripper{http.DefaultTransport, i.Users.Get(UserTypeLogin).Username}} + return rp.NewRelyingPartyOIDC(ctx, http_util.BuildHTTP(domain, i.Config.Port, i.Config.Secure), clientID, "", redirectURI, scope, rp.WithHTTPClient(loginClient)) } type loginRoundTripper struct { http.RoundTripper + loginUsername string } func (c *loginRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - req.Header.Set(oidc_internal.LoginClientHeader, LoginUser) + req.Header.Set(oidc_internal.LoginClientHeader, c.loginUsername) return c.RoundTripper.RoundTrip(req) } -func (s *Tester) CreateResourceServerJWTProfile(ctx context.Context, keyFileData []byte) (rs.ResourceServer, error) { +func (i *Instance) CreateResourceServerJWTProfile(ctx context.Context, keyFileData []byte) (rs.ResourceServer, error) { keyFile, err := client.ConfigFromKeyFileData(keyFileData) if err != nil { return nil, err } - return rs.NewResourceServerJWTProfile(ctx, s.OIDCIssuer(), keyFile.ClientID, keyFile.KeyID, []byte(keyFile.Key)) + return rs.NewResourceServerJWTProfile(ctx, i.OIDCIssuer(), keyFile.ClientID, keyFile.KeyID, []byte(keyFile.Key)) } -func (s *Tester) CreateResourceServerClientCredentials(ctx context.Context, clientID, clientSecret string) (rs.ResourceServer, error) { - return rs.NewResourceServerClientCredentials(ctx, s.OIDCIssuer(), clientID, clientSecret) +func (i *Instance) CreateResourceServerClientCredentials(ctx context.Context, clientID, clientSecret string) (rs.ResourceServer, error) { + return rs.NewResourceServerClientCredentials(ctx, i.OIDCIssuer(), clientID, clientSecret) } func GetRequest(url string, headers map[string]string) (*http.Request, error) { @@ -313,9 +322,9 @@ func CheckRedirect(req *http.Request) (*url.URL, error) { return resp.Location() } -func (s *Tester) CreateOIDCCredentialsClient(ctx context.Context) (machine *management.AddMachineUserResponse, name, clientID, clientSecret string, err error) { +func (i *Instance) CreateOIDCCredentialsClient(ctx context.Context) (machine *management.AddMachineUserResponse, name, clientID, clientSecret string, err error) { name = gofakeit.Username() - machine, err = s.Client.Mgmt.AddMachineUser(ctx, &management.AddMachineUserRequest{ + machine, err = i.Client.Mgmt.AddMachineUser(ctx, &management.AddMachineUserRequest{ Name: name, UserName: name, AccessTokenType: user.AccessTokenType_ACCESS_TOKEN_TYPE_JWT, @@ -323,7 +332,7 @@ func (s *Tester) CreateOIDCCredentialsClient(ctx context.Context) (machine *mana if err != nil { return nil, "", "", "", err } - secret, err := s.Client.Mgmt.GenerateMachineSecret(ctx, &management.GenerateMachineSecretRequest{ + secret, err := i.Client.Mgmt.GenerateMachineSecret(ctx, &management.GenerateMachineSecretRequest{ UserId: machine.GetUserId(), }) if err != nil { @@ -332,9 +341,9 @@ func (s *Tester) CreateOIDCCredentialsClient(ctx context.Context) (machine *mana return machine, name, secret.GetClientId(), secret.GetClientSecret(), nil } -func (s *Tester) CreateOIDCJWTProfileClient(ctx context.Context) (machine *management.AddMachineUserResponse, name string, keyData []byte, err error) { +func (i *Instance) CreateOIDCJWTProfileClient(ctx context.Context) (machine *management.AddMachineUserResponse, name string, keyData []byte, err error) { name = gofakeit.Username() - machine, err = s.Client.Mgmt.AddMachineUser(ctx, &management.AddMachineUserRequest{ + machine, err = i.Client.Mgmt.AddMachineUser(ctx, &management.AddMachineUserRequest{ Name: name, UserName: name, AccessTokenType: user.AccessTokenType_ACCESS_TOKEN_TYPE_JWT, @@ -342,7 +351,7 @@ func (s *Tester) CreateOIDCJWTProfileClient(ctx context.Context) (machine *manag if err != nil { return nil, "", nil, err } - keyResp, err := s.Client.Mgmt.AddMachineKey(ctx, &management.AddMachineKeyRequest{ + keyResp, err := i.Client.Mgmt.AddMachineKey(ctx, &management.AddMachineKeyRequest{ UserId: machine.GetUserId(), Type: authn.KeyType_KEY_TYPE_JSON, ExpirationDate: timestamppb.New(time.Now().Add(time.Hour)), diff --git a/internal/integration/sink/channel.go b/internal/integration/sink/channel.go new file mode 100644 index 0000000000..e25ae4d70c --- /dev/null +++ b/internal/integration/sink/channel.go @@ -0,0 +1,9 @@ +package sink + +//go:generate enumer -type Channel -trimprefix Channel -transform snake +type Channel int + +const ( + ChannelMilestone Channel = iota + ChannelQuota +) diff --git a/internal/integration/sink/channel_enumer.go b/internal/integration/sink/channel_enumer.go new file mode 100644 index 0000000000..85792ffec7 --- /dev/null +++ b/internal/integration/sink/channel_enumer.go @@ -0,0 +1,78 @@ +// Code generated by "enumer -type Channel -trimprefix Channel -transform snake"; DO NOT EDIT. + +package sink + +import ( + "fmt" + "strings" +) + +const _ChannelName = "milestonequota" + +var _ChannelIndex = [...]uint8{0, 9, 14} + +const _ChannelLowerName = "milestonequota" + +func (i Channel) String() string { + if i < 0 || i >= Channel(len(_ChannelIndex)-1) { + return fmt.Sprintf("Channel(%d)", i) + } + return _ChannelName[_ChannelIndex[i]:_ChannelIndex[i+1]] +} + +// An "invalid array index" compiler error signifies that the constant values have changed. +// Re-run the stringer command to generate them again. +func _ChannelNoOp() { + var x [1]struct{} + _ = x[ChannelMilestone-(0)] + _ = x[ChannelQuota-(1)] +} + +var _ChannelValues = []Channel{ChannelMilestone, ChannelQuota} + +var _ChannelNameToValueMap = map[string]Channel{ + _ChannelName[0:9]: ChannelMilestone, + _ChannelLowerName[0:9]: ChannelMilestone, + _ChannelName[9:14]: ChannelQuota, + _ChannelLowerName[9:14]: ChannelQuota, +} + +var _ChannelNames = []string{ + _ChannelName[0:9], + _ChannelName[9:14], +} + +// ChannelString retrieves an enum value from the enum constants string name. +// Throws an error if the param is not part of the enum. +func ChannelString(s string) (Channel, error) { + if val, ok := _ChannelNameToValueMap[s]; ok { + return val, nil + } + + if val, ok := _ChannelNameToValueMap[strings.ToLower(s)]; ok { + return val, nil + } + return 0, fmt.Errorf("%s does not belong to Channel values", s) +} + +// ChannelValues returns all values of the enum +func ChannelValues() []Channel { + return _ChannelValues +} + +// ChannelStrings returns a slice of all String values of the enum +func ChannelStrings() []string { + strs := make([]string, len(_ChannelNames)) + copy(strs, _ChannelNames) + return strs +} + +// IsAChannel returns "true" if the value is listed in the enum definition. "false" otherwise +func (i Channel) IsAChannel() bool { + for _, v := range _ChannelValues { + if i == v { + return true + } + } + return false +} diff --git a/internal/integration/sink/server.go b/internal/integration/sink/server.go new file mode 100644 index 0000000000..959353ae5f --- /dev/null +++ b/internal/integration/sink/server.go @@ -0,0 +1,167 @@ +//go:build integration + +package sink + +import ( + "errors" + "io" + "net/http" + "net/url" + "path" + "sync" + "sync/atomic" + + "github.com/go-chi/chi/v5" + "github.com/gorilla/websocket" + "github.com/sirupsen/logrus" + "github.com/zitadel/logging" +) + +const ( + port = "8081" + listenAddr = "127.0.0.1:" + port + host = "localhost:" + port +) + +// CallURL returns the full URL to the handler of a [Channel]. +func CallURL(ch Channel) string { + u := url.URL{ + Scheme: "http", + Host: host, + Path: rootPath(ch), + } + return u.String() +} + +// StartServer starts a simple HTTP server on localhost:8081 +// ZITADEL can use the server to send HTTP requests which can be +// used to validate tests through [Subscribe]rs. +// For each [Channel] a route is registered on http://localhost:8081/. +// The route must be used to send the HTTP request to be validated. +// [CallURL] can be used to obtain the full URL for a given Channel. +// +// This function is only active when the `integration` build tag is enabled +func StartServer() (close func()) { + router := chi.NewRouter() + for _, ch := range ChannelValues() { + fwd := &forwarder{ + channelID: ch, + subscribers: make(map[int64]chan<- *Request), + } + router.HandleFunc(rootPath(ch), fwd.receiveHandler) + router.HandleFunc(subscribePath(ch), fwd.subscriptionHandler) + } + s := &http.Server{ + Addr: listenAddr, + Handler: router, + } + + logging.WithFields("listen_addr", listenAddr).Warn("!!!! A sink server is started which may expose sensitive data on a public endpoint. Make sure the `integration` build tag is disabled for production builds. !!!!") + go func() { + err := s.ListenAndServe() + if !errors.Is(err, http.ErrServerClosed) { + logging.WithError(err).Fatal("sink server") + } + }() + return func() { + logging.OnError(s.Close()).Error("sink server") + } +} + +func rootPath(c Channel) string { + return path.Join("/", c.String()) +} + +func subscribePath(c Channel) string { + return path.Join("/", c.String(), "subscribe") +} + +// forwarder handles incoming HTTP requests from ZITADEL and +// forwards them to all subscribed web sockets. +type forwarder struct { + channelID Channel + id atomic.Int64 + mtx sync.RWMutex + subscribers map[int64]chan<- *Request + upgrader websocket.Upgrader +} + +// receiveHandler receives a simple HTTP for a single [Channel] +// and forwards them on all active subscribers of that Channel. +func (c *forwarder) receiveHandler(w http.ResponseWriter, r *http.Request) { + req := &Request{ + Header: r.Header.Clone(), + } + var err error + req.Body, err = io.ReadAll(r.Body) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + } + + c.mtx.RLock() + for _, reqChan := range c.subscribers { + reqChan <- req + } + c.mtx.RUnlock() + w.WriteHeader(http.StatusOK) +} + +// subscriptionHandler upgrades HTTP request to a websocket connection for subscribers. +// All received HTTP requests on a subscriber's channel are send on the websocket to the client. +func (c *forwarder) subscriptionHandler(w http.ResponseWriter, r *http.Request) { + ws, err := c.upgrader.Upgrade(w, r, nil) + logging.OnError(err).Error("websocket upgrade") + if err != nil { + return + } + done := readLoop(ws) + + id := c.id.Add(1) + reqChannel := make(chan *Request, 100) + + c.mtx.Lock() + c.subscribers[id] = reqChannel + c.mtx.Unlock() + + logging.WithFields("id", id, "channel", c.channelID).Info("websocket opened") + + defer func() { + c.mtx.Lock() + delete(c.subscribers, id) + c.mtx.Unlock() + + ws.Close() + close(reqChannel) + }() + + for { + select { + case err := <-done: + logging.WithError(err).WithFields(logrus.Fields{"id": id, "channel": c.channelID}).Info("websocket closed") + return + case req := <-reqChannel: + if err := ws.WriteJSON(req); err != nil { + logging.WithError(err).WithFields(logrus.Fields{"id": id, "channel": c.channelID}).Error("websocket write json") + return + } + } + } +} + +// readLoop makes sure we can receive close messages +func readLoop(ws *websocket.Conn) (done chan error) { + done = make(chan error, 1) + + go func(done chan<- error) { + for { + _, _, err := ws.NextReader() + if err != nil { + done <- err + break + } + } + close(done) + }(done) + + return done +} diff --git a/internal/integration/sink/sink.go b/internal/integration/sink/sink.go new file mode 100644 index 0000000000..fa339e4763 --- /dev/null +++ b/internal/integration/sink/sink.go @@ -0,0 +1,4 @@ +// Package sink provides a simple HTTP server where Zitadel can send HTTP based messages, +// which are then possible to be observed using observers on websockets. +// The contents of this package become available when the `integration` build tag is enabled. +package sink diff --git a/internal/integration/sink/stub.go b/internal/integration/sink/stub.go new file mode 100644 index 0000000000..01d1047f34 --- /dev/null +++ b/internal/integration/sink/stub.go @@ -0,0 +1,9 @@ +//go:build !integration + +package sink + +// StartServer and its returned close function are a no-op +// when the `integration` build tag is disabled. +func StartServer() (close func()) { + return func() {} +} diff --git a/internal/integration/sink/subscription.go b/internal/integration/sink/subscription.go new file mode 100644 index 0000000000..7d5ca36e91 --- /dev/null +++ b/internal/integration/sink/subscription.go @@ -0,0 +1,90 @@ +//go:build integration + +package sink + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net" + "net/http" + "net/url" + "sync/atomic" + + "github.com/gorilla/websocket" + "github.com/zitadel/logging" +) + +// Request is a message forwarded from the handler to [Subscription]s. +type Request struct { + Header http.Header + Body json.RawMessage +} + +// Subscription is a websocket client to which [Request]s are forwarded by the server. +type Subscription struct { + conn *websocket.Conn + closed atomic.Bool + reqChannel chan *Request +} + +// Subscribe to a channel. +// The subscription forwards all requests it received on the channel's +// handler, after Subscribe has returned. +// Multiple subscription may be active on a single channel. +// Each request is always forwarded to each Subscription. +// Close must be called to cleanup up the Subscription's channel and go routine. +func Subscribe(ctx context.Context, ch Channel) *Subscription { + u := url.URL{ + Scheme: "ws", + Host: listenAddr, + Path: subscribePath(ch), + } + conn, resp, err := websocket.DefaultDialer.DialContext(ctx, u.String(), nil) + if err != nil { + if resp != nil { + defer resp.Body.Close() + body, _ := io.ReadAll(resp.Body) + err = fmt.Errorf("subscribe: %w, status: %s, body: %s", err, resp.Status, body) + } + panic(err) + } + + sub := &Subscription{ + conn: conn, + reqChannel: make(chan *Request, 10), + } + go sub.readToChan() + return sub +} + +func (s *Subscription) readToChan() { + for { + if s.closed.Load() { + break + } + req := new(Request) + if err := s.conn.ReadJSON(req); err != nil { + opErr := new(net.OpError) + if errors.As(err, &opErr) { + break + } + logging.WithError(err).Error("subscription read") + break + } + s.reqChannel <- req + } + close(s.reqChannel) +} + +// Recv returns the channel over which [Request]s are send. +func (s *Subscription) Recv() <-chan *Request { + return s.reqChannel +} + +func (s *Subscription) Close() error { + s.closed.Store(true) + return s.conn.Close() +} diff --git a/internal/integration/system.go b/internal/integration/system.go new file mode 100644 index 0000000000..a9673a40ae --- /dev/null +++ b/internal/integration/system.go @@ -0,0 +1,59 @@ +package integration + +import ( + "context" + _ "embed" + "sync" + "time" + + "github.com/zitadel/oidc/v3/pkg/client" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + + http_util "github.com/zitadel/zitadel/internal/api/http" + "github.com/zitadel/zitadel/pkg/grpc/system" +) + +var ( + //go:embed config/system-user-key.pem + systemUserKey []byte +) + +var ( + // SystemClient creates a system connection once and reuses it on every use. + // Each client call automatically gets the authorization context for the system user. + SystemClient = sync.OnceValue[system.SystemServiceClient](systemClient) + SystemToken string +) + +func systemClient() system.SystemServiceClient { + cc, err := grpc.NewClient(loadedConfig.Host(), + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithChainUnaryInterceptor(func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + ctx = WithSystemAuthorization(ctx) + return invoker(ctx, method, req, reply, cc, opts...) + }), + ) + if err != nil { + panic(err) + } + return system.NewSystemServiceClient(cc) +} + +func systemUserToken() string { + const ISSUER = "tester" + audience := http_util.BuildOrigin(loadedConfig.Host(), loadedConfig.Secure) + signer, err := client.NewSignerFromPrivateKeyByte(systemUserKey, "") + if err != nil { + panic(err) + } + token, err := client.SignedJWTProfileAssertion(ISSUER, []string{audience}, time.Hour, signer) + if err != nil { + panic(err) + } + return token +} + +func WithSystemAuthorization(ctx context.Context) context.Context { + return WithAuthorizationToken(ctx, SystemToken) +} diff --git a/internal/integration/user.go b/internal/integration/user.go index 60a6e41318..6eb26fa5a7 100644 --- a/internal/integration/user.go +++ b/internal/integration/user.go @@ -11,10 +11,10 @@ import ( "github.com/zitadel/zitadel/pkg/grpc/management" ) -func (s *Tester) CreateMachineUserPATWithMembership(ctx context.Context, roles ...string) (id, pat string, err error) { - user := s.CreateMachineUser(ctx) +func (i *Instance) CreateMachineUserPATWithMembership(ctx context.Context, roles ...string) (id, pat string, err error) { + user := i.CreateMachineUser(ctx) - patResp, err := s.Client.Mgmt.AddPersonalAccessToken(ctx, &management.AddPersonalAccessTokenRequest{ + patResp, err := i.Client.Mgmt.AddPersonalAccessToken(ctx, &management.AddPersonalAccessTokenRequest{ UserId: user.GetUserId(), ExpirationDate: timestamppb.New(time.Now().Add(24 * time.Hour)), }) @@ -35,7 +35,7 @@ func (s *Tester) CreateMachineUserPATWithMembership(ctx context.Context, roles . } if len(orgRoles) > 0 { - _, err := s.Client.Mgmt.AddOrgMember(ctx, &management.AddOrgMemberRequest{ + _, err := i.Client.Mgmt.AddOrgMember(ctx, &management.AddOrgMemberRequest{ UserId: user.GetUserId(), Roles: orgRoles, }) @@ -44,7 +44,7 @@ func (s *Tester) CreateMachineUserPATWithMembership(ctx context.Context, roles . } } if len(iamRoles) > 0 { - _, err := s.Client.Admin.AddIAMMember(ctx, &admin.AddIAMMemberRequest{ + _, err := i.Client.Admin.AddIAMMember(ctx, &admin.AddIAMMemberRequest{ UserId: user.GetUserId(), Roles: iamRoles, }) diff --git a/internal/integration/usertype_enumer.go b/internal/integration/usertype_enumer.go new file mode 100644 index 0000000000..66d49ced4d --- /dev/null +++ b/internal/integration/usertype_enumer.go @@ -0,0 +1,86 @@ +// Code generated by "enumer -type UserType -transform snake -trimprefix UserType"; DO NOT EDIT. + +package integration + +import ( + "fmt" + "strings" +) + +const _UserTypeName = "unspecifiediam_ownerorg_ownerlogin" + +var _UserTypeIndex = [...]uint8{0, 11, 20, 29, 34} + +const _UserTypeLowerName = "unspecifiediam_ownerorg_ownerlogin" + +func (i UserType) String() string { + if i < 0 || i >= UserType(len(_UserTypeIndex)-1) { + return fmt.Sprintf("UserType(%d)", i) + } + return _UserTypeName[_UserTypeIndex[i]:_UserTypeIndex[i+1]] +} + +// An "invalid array index" compiler error signifies that the constant values have changed. +// Re-run the stringer command to generate them again. +func _UserTypeNoOp() { + var x [1]struct{} + _ = x[UserTypeUnspecified-(0)] + _ = x[UserTypeIAMOwner-(1)] + _ = x[UserTypeOrgOwner-(2)] + _ = x[UserTypeLogin-(3)] +} + +var _UserTypeValues = []UserType{UserTypeUnspecified, UserTypeIAMOwner, UserTypeOrgOwner, UserTypeLogin} + +var _UserTypeNameToValueMap = map[string]UserType{ + _UserTypeName[0:11]: UserTypeUnspecified, + _UserTypeLowerName[0:11]: UserTypeUnspecified, + _UserTypeName[11:20]: UserTypeIAMOwner, + _UserTypeLowerName[11:20]: UserTypeIAMOwner, + _UserTypeName[20:29]: UserTypeOrgOwner, + _UserTypeLowerName[20:29]: UserTypeOrgOwner, + _UserTypeName[29:34]: UserTypeLogin, + _UserTypeLowerName[29:34]: UserTypeLogin, +} + +var _UserTypeNames = []string{ + _UserTypeName[0:11], + _UserTypeName[11:20], + _UserTypeName[20:29], + _UserTypeName[29:34], +} + +// UserTypeString retrieves an enum value from the enum constants string name. +// Throws an error if the param is not part of the enum. +func UserTypeString(s string) (UserType, error) { + if val, ok := _UserTypeNameToValueMap[s]; ok { + return val, nil + } + + if val, ok := _UserTypeNameToValueMap[strings.ToLower(s)]; ok { + return val, nil + } + return 0, fmt.Errorf("%s does not belong to UserType values", s) +} + +// UserTypeValues returns all values of the enum +func UserTypeValues() []UserType { + return _UserTypeValues +} + +// UserTypeStrings returns a slice of all String values of the enum +func UserTypeStrings() []string { + strs := make([]string, len(_UserTypeNames)) + copy(strs, _UserTypeNames) + return strs +} + +// IsAUserType returns "true" if the value is listed in the enum definition. "false" otherwise +func (i UserType) IsAUserType() bool { + for _, v := range _UserTypeValues { + if i == v { + return true + } + } + return false +} diff --git a/internal/integration/usertype_string.go b/internal/integration/usertype_string.go deleted file mode 100644 index 6477630986..0000000000 --- a/internal/integration/usertype_string.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by "stringer -type=UserType"; DO NOT EDIT. - -package integration - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[Unspecified-0] - _ = x[OrgOwner-1] - _ = x[Login-2] - _ = x[IAMOwner-3] - _ = x[SystemUser-4] -} - -const _UserType_name = "UnspecifiedOrgOwnerLoginIAMOwnerSystemUser" - -var _UserType_index = [...]uint8{0, 11, 19, 24, 32, 42} - -func (i UserType) String() string { - if i < 0 || i >= UserType(len(_UserType_index)-1) { - return "UserType(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _UserType_name[_UserType_index[i]:_UserType_index[i+1]] -} diff --git a/internal/notification/handlers/handlers_integration_test.go b/internal/notification/handlers/handlers_integration_test.go deleted file mode 100644 index 329bba1310..0000000000 --- a/internal/notification/handlers/handlers_integration_test.go +++ /dev/null @@ -1,36 +0,0 @@ -//go:build integration - -package handlers_test - -import ( - "context" - "os" - "testing" - "time" - - "github.com/zitadel/zitadel/internal/integration" -) - -var ( - CTX context.Context - SystemCTX context.Context - Tester *integration.Tester -) - -func TestMain(m *testing.M) { - os.Exit(func() int { - ctx, _, cancel := integration.Contexts(5 * time.Minute) - defer cancel() - CTX = ctx - - Tester = integration.NewTester(ctx, ` -Quotas: - Access: - Enabled: true -`) - defer Tester.Done() - - SystemCTX = Tester.WithAuthorization(ctx, integration.SystemUser) - return m.Run() - }()) -} diff --git a/internal/notification/handlers/integration_test/handlers_test.go b/internal/notification/handlers/integration_test/handlers_test.go new file mode 100644 index 0000000000..3b2dfe2406 --- /dev/null +++ b/internal/notification/handlers/integration_test/handlers_test.go @@ -0,0 +1,23 @@ +//go:build integration + +package handlers_test + +import ( + "context" + "os" + "testing" + "time" +) + +var ( + CTX context.Context +) + +func TestMain(m *testing.M) { + os.Exit(func() int { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute) + defer cancel() + CTX = ctx + return m.Run() + }()) +} diff --git a/internal/notification/handlers/telemetry_pusher_integration_test.go b/internal/notification/handlers/integration_test/telemetry_pusher_test.go similarity index 53% rename from internal/notification/handlers/telemetry_pusher_integration_test.go rename to internal/notification/handlers/integration_test/telemetry_pusher_test.go index 8f207b9de3..c12ab64f35 100644 --- a/internal/notification/handlers/telemetry_pusher_integration_test.go +++ b/internal/notification/handlers/integration_test/telemetry_pusher_test.go @@ -4,7 +4,6 @@ package handlers_test import ( "bytes" - "context" "encoding/json" "net/url" "testing" @@ -16,6 +15,7 @@ import ( "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/zitadel/internal/integration" + "github.com/zitadel/zitadel/internal/integration/sink" "github.com/zitadel/zitadel/pkg/grpc/app" "github.com/zitadel/zitadel/pkg/grpc/management" "github.com/zitadel/zitadel/pkg/grpc/object" @@ -25,16 +25,20 @@ import ( ) func TestServer_TelemetryPushMilestones(t *testing.T) { - primaryDomain, instanceID, adminID, iamOwnerCtx := Tester.UseIsolatedInstance(t, CTX, SystemCTX) - t.Log("testing against instance with primary domain", primaryDomain) - awaitMilestone(t, Tester.MilestoneChan, primaryDomain, "InstanceCreated") + sub := sink.Subscribe(CTX, sink.ChannelMilestone) + defer sub.Close() - projectAdded, err := Tester.Client.Mgmt.AddProject(iamOwnerCtx, &management.AddProjectRequest{Name: "integration"}) + instance := integration.NewInstance(CTX) + iamOwnerCtx := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + t.Log("testing against instance with primary domain", instance.Domain) + awaitMilestone(t, sub, instance.Domain, "InstanceCreated") + + projectAdded, err := instance.Client.Mgmt.AddProject(iamOwnerCtx, &management.AddProjectRequest{Name: "integration"}) require.NoError(t, err) - awaitMilestone(t, Tester.MilestoneChan, primaryDomain, "ProjectCreated") + awaitMilestone(t, sub, instance.Domain, "ProjectCreated") redirectURI := "http://localhost:8888" - application, err := Tester.Client.Mgmt.AddOIDCApp(iamOwnerCtx, &management.AddOIDCAppRequest{ + application, err := instance.Client.Mgmt.AddOIDCApp(iamOwnerCtx, &management.AddOIDCAppRequest{ ProjectId: projectAdded.GetId(), Name: "integration", RedirectUris: []string{redirectURI}, @@ -46,35 +50,37 @@ func TestServer_TelemetryPushMilestones(t *testing.T) { AccessTokenType: app.OIDCTokenType_OIDC_TOKEN_TYPE_JWT, }) require.NoError(t, err) - awaitMilestone(t, Tester.MilestoneChan, primaryDomain, "ApplicationCreated") + awaitMilestone(t, sub, instance.Domain, "ApplicationCreated") // create the session to be used for the authN of the clients - sessionID, sessionToken, _, _ := Tester.CreatePasswordSession(t, iamOwnerCtx, adminID, "Password1!") + sessionID, sessionToken, _, _ := instance.CreatePasswordSession(t, iamOwnerCtx, instance.AdminUserID, "Password1!") - console := consoleOIDCConfig(iamOwnerCtx, t) - loginToClient(iamOwnerCtx, t, primaryDomain, console.GetClientId(), instanceID, console.GetRedirectUris()[0], sessionID, sessionToken) - awaitMilestone(t, Tester.MilestoneChan, primaryDomain, "AuthenticationSucceededOnInstance") + console := consoleOIDCConfig(t, instance) + loginToClient(t, instance, console.GetClientId(), console.GetRedirectUris()[0], sessionID, sessionToken) + awaitMilestone(t, sub, instance.Domain, "AuthenticationSucceededOnInstance") // make sure the client has been projected require.EventuallyWithT(t, func(collectT *assert.CollectT) { - _, err := Tester.Client.Mgmt.GetAppByID(iamOwnerCtx, &management.GetAppByIDRequest{ + _, err := instance.Client.Mgmt.GetAppByID(iamOwnerCtx, &management.GetAppByIDRequest{ ProjectId: projectAdded.GetId(), AppId: application.GetAppId(), }) assert.NoError(collectT, err) - }, 1*time.Minute, 100*time.Millisecond, "app not found") - loginToClient(iamOwnerCtx, t, primaryDomain, application.GetClientId(), instanceID, redirectURI, sessionID, sessionToken) - awaitMilestone(t, Tester.MilestoneChan, primaryDomain, "AuthenticationSucceededOnApplication") + }, time.Minute, time.Second, "app not found") + loginToClient(t, instance, application.GetClientId(), redirectURI, sessionID, sessionToken) + awaitMilestone(t, sub, instance.Domain, "AuthenticationSucceededOnApplication") - _, err = Tester.Client.System.RemoveInstance(SystemCTX, &system.RemoveInstanceRequest{InstanceId: instanceID}) + _, err = integration.SystemClient().RemoveInstance(CTX, &system.RemoveInstanceRequest{InstanceId: instance.ID()}) require.NoError(t, err) - awaitMilestone(t, Tester.MilestoneChan, primaryDomain, "InstanceDeleted") + awaitMilestone(t, sub, instance.Domain, "InstanceDeleted") } -func loginToClient(iamOwnerCtx context.Context, t *testing.T, primaryDomain, clientID, instanceID, redirectURI, sessionID, sessionToken string) { - authRequestID, err := Tester.CreateOIDCAuthRequestWithDomain(iamOwnerCtx, primaryDomain, clientID, Tester.Users.Get(instanceID, integration.IAMOwner).ID, redirectURI, "openid") +func loginToClient(t *testing.T, instance *integration.Instance, clientID, redirectURI, sessionID, sessionToken string) { + iamOwnerCtx := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + + authRequestID, err := instance.CreateOIDCAuthRequestWithDomain(iamOwnerCtx, instance.Domain, clientID, instance.Users.Get(integration.UserTypeIAMOwner).ID, redirectURI, "openid") require.NoError(t, err) - callback, err := Tester.Client.OIDCv2.CreateCallback(iamOwnerCtx, &oidc_v2.CreateCallbackRequest{ + callback, err := instance.Client.OIDCv2.CreateCallback(iamOwnerCtx, &oidc_v2.CreateCallbackRequest{ AuthRequestId: authRequestID, CallbackKind: &oidc_v2.CreateCallbackRequest_Session{Session: &oidc_v2.Session{ SessionId: sessionID, @@ -82,7 +88,7 @@ func loginToClient(iamOwnerCtx context.Context, t *testing.T, primaryDomain, cli }}, }) require.NoError(t, err) - provider, err := Tester.CreateRelyingPartyForDomain(iamOwnerCtx, primaryDomain, clientID, redirectURI) + provider, err := instance.CreateRelyingPartyForDomain(iamOwnerCtx, instance.Domain, clientID, redirectURI) require.NoError(t, err) callbackURL, err := url.Parse(callback.GetCallbackUrl()) require.NoError(t, err) @@ -91,8 +97,10 @@ func loginToClient(iamOwnerCtx context.Context, t *testing.T, primaryDomain, cli require.NoError(t, err) } -func consoleOIDCConfig(iamOwnerCtx context.Context, t *testing.T) *app.OIDCConfig { - projects, err := Tester.Client.Mgmt.ListProjects(iamOwnerCtx, &management.ListProjectsRequest{ +func consoleOIDCConfig(t *testing.T, instance *integration.Instance) *app.OIDCConfig { + iamOwnerCtx := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner) + + projects, err := instance.Client.Mgmt.ListProjects(iamOwnerCtx, &management.ListProjectsRequest{ Queries: []*project.ProjectQuery{ { Query: &project.ProjectQuery_NameQuery{ @@ -106,7 +114,7 @@ func consoleOIDCConfig(iamOwnerCtx context.Context, t *testing.T) *app.OIDCConfi }) require.NoError(t, err) require.Len(t, projects.GetResult(), 1) - apps, err := Tester.Client.Mgmt.ListApps(iamOwnerCtx, &management.ListAppsRequest{ + apps, err := instance.Client.Mgmt.ListApps(iamOwnerCtx, &management.ListAppsRequest{ ProjectId: projects.GetResult()[0].GetId(), Queries: []*app.AppQuery{ { @@ -124,12 +132,12 @@ func consoleOIDCConfig(iamOwnerCtx context.Context, t *testing.T) *app.OIDCConfi return apps.GetResult()[0].GetOidcConfig() } -func awaitMilestone(t *testing.T, bodies chan []byte, primaryDomain, expectMilestoneType string) { +func awaitMilestone(t *testing.T, sub *sink.Subscription, primaryDomain, expectMilestoneType string) { for { select { - case body := <-bodies: + case req := <-sub.Recv(): plain := new(bytes.Buffer) - if err := json.Indent(plain, body, "", " "); err != nil { + if err := json.Indent(plain, req.Body, "", " "); err != nil { t.Fatal(err) } t.Log("received milestone", plain.String()) @@ -137,13 +145,13 @@ func awaitMilestone(t *testing.T, bodies chan []byte, primaryDomain, expectMiles Type string `json:"type"` PrimaryDomain string `json:"primaryDomain"` }{} - if err := json.Unmarshal(body, &milestone); err != nil { + if err := json.Unmarshal(req.Body, &milestone); err != nil { t.Error(err) } if milestone.Type == expectMilestoneType && milestone.PrimaryDomain == primaryDomain { return } - case <-time.After(60 * time.Second): + case <-time.After(2 * time.Minute): // why does it take so long to get a milestone !? t.Fatalf("timed out waiting for milestone %s in domain %s", expectMilestoneType, primaryDomain) } } diff --git a/internal/notification/handlers/quota_notifier_test.go b/internal/notification/handlers/quota_notifier_test.go deleted file mode 100644 index 14de4e369c..0000000000 --- a/internal/notification/handlers/quota_notifier_test.go +++ /dev/null @@ -1,155 +0,0 @@ -//go:build integration - -package handlers_test - -import ( - "bytes" - "encoding/json" - "fmt" - "strconv" - "testing" - "time" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/types/known/durationpb" - "google.golang.org/protobuf/types/known/timestamppb" - - "github.com/zitadel/zitadel/internal/repository/quota" - "github.com/zitadel/zitadel/pkg/grpc/admin" - quota_pb "github.com/zitadel/zitadel/pkg/grpc/quota" - "github.com/zitadel/zitadel/pkg/grpc/system" -) - -func TestServer_QuotaNotification_Limit(t *testing.T) { - _, instanceID, _, iamOwnerCtx := Tester.UseIsolatedInstance(t, CTX, SystemCTX) - amount := 10 - percent := 50 - percentAmount := amount * percent / 100 - - _, err := Tester.Client.System.AddQuota(SystemCTX, &system.AddQuotaRequest{ - InstanceId: instanceID, - Unit: quota_pb.Unit_UNIT_REQUESTS_ALL_AUTHENTICATED, - From: timestamppb.Now(), - ResetInterval: durationpb.New(time.Minute * 5), - Amount: uint64(amount), - Limit: true, - Notifications: []*quota_pb.Notification{ - { - Percent: uint32(percent), - Repeat: true, - CallUrl: "http://localhost:8082", - }, - { - Percent: 100, - Repeat: true, - CallUrl: "http://localhost:8082", - }, - }, - }) - require.NoError(t, err) - - for i := 0; i < percentAmount; i++ { - _, err := Tester.Client.Admin.GetDefaultOrg(iamOwnerCtx, &admin.GetDefaultOrgRequest{}) - if err != nil { - require.NoError(t, fmt.Errorf("error in %d call of %d: %f", i, percentAmount, err)) - } - } - awaitNotification(t, time.Now(), Tester.QuotaNotificationChan, quota.RequestsAllAuthenticated, percent) - - for i := 0; i < (amount - percentAmount); i++ { - _, err := Tester.Client.Admin.GetDefaultOrg(iamOwnerCtx, &admin.GetDefaultOrgRequest{}) - require.NoError(t, err) - } - awaitNotification(t, time.Now(), Tester.QuotaNotificationChan, quota.RequestsAllAuthenticated, 100) - - _, limitErr := Tester.Client.Admin.GetDefaultOrg(iamOwnerCtx, &admin.GetDefaultOrgRequest{}) - require.Error(t, limitErr) -} - -func TestServer_QuotaNotification_NoLimit(t *testing.T) { - _, instanceID, _, iamOwnerCtx := Tester.UseIsolatedInstance(t, CTX, SystemCTX) - amount := 10 - percent := 50 - percentAmount := amount * percent / 100 - - _, err := Tester.Client.System.AddQuota(SystemCTX, &system.AddQuotaRequest{ - InstanceId: instanceID, - Unit: quota_pb.Unit_UNIT_REQUESTS_ALL_AUTHENTICATED, - From: timestamppb.Now(), - ResetInterval: durationpb.New(time.Minute * 5), - Amount: uint64(amount), - Limit: false, - Notifications: []*quota_pb.Notification{ - { - Percent: uint32(percent), - Repeat: false, - CallUrl: "http://localhost:8082", - }, - { - Percent: 100, - Repeat: true, - CallUrl: "http://localhost:8082", - }, - }, - }) - require.NoError(t, err) - - for i := 0; i < percentAmount; i++ { - _, err := Tester.Client.Admin.GetDefaultOrg(iamOwnerCtx, &admin.GetDefaultOrgRequest{}) - if err != nil { - require.NoError(t, fmt.Errorf("error in %d call of %d: %f", i, percentAmount, err)) - } - } - awaitNotification(t, time.Now(), Tester.QuotaNotificationChan, quota.RequestsAllAuthenticated, percent) - - for i := 0; i < (amount - percentAmount); i++ { - _, err := Tester.Client.Admin.GetDefaultOrg(iamOwnerCtx, &admin.GetDefaultOrgRequest{}) - if err != nil { - require.NoError(t, fmt.Errorf("error in %d call of %d: %f", percentAmount+i, amount, err)) - } - } - awaitNotification(t, time.Now(), Tester.QuotaNotificationChan, quota.RequestsAllAuthenticated, 100) - - for i := 0; i < amount; i++ { - _, err := Tester.Client.Admin.GetDefaultOrg(iamOwnerCtx, &admin.GetDefaultOrgRequest{}) - if err != nil { - require.NoError(t, fmt.Errorf("error in %d call of %d over limit: %f", i, amount, err)) - } - } - awaitNotification(t, time.Now(), Tester.QuotaNotificationChan, quota.RequestsAllAuthenticated, 200) - - _, limitErr := Tester.Client.Admin.GetDefaultOrg(iamOwnerCtx, &admin.GetDefaultOrgRequest{}) - require.NoError(t, limitErr) -} - -func awaitNotification(t *testing.T, start time.Time, bodies chan []byte, unit quota.Unit, percent int) { - for { - select { - case body := <-bodies: - plain := new(bytes.Buffer) - if err := json.Indent(plain, body, "", " "); err != nil { - t.Fatal(err) - } - t.Log("received notificationDueEvent", plain.String()) - event := struct { - Unit quota.Unit `json:"unit"` - ID string `json:"id"` - CallURL string `json:"callURL"` - PeriodStart time.Time `json:"periodStart"` - Threshold uint16 `json:"threshold"` - Usage uint64 `json:"usage"` - }{} - if err := json.Unmarshal(body, &event); err != nil { - t.Error(err) - } - if event.ID == "" { - continue - } - if event.Unit == unit && event.Threshold == uint16(percent) { - return - } - case <-time.After(20 * time.Second): - t.Fatalf("start %s stop %s timed out waiting for unit %s and percent %d", start.Format(time.RFC3339), time.Now().Format(time.RFC3339), strconv.Itoa(int(unit)), percent) - } - } -} diff --git a/internal/webauthn/webauthn.go b/internal/webauthn/webauthn.go index 5938f885bc..998c013a3c 100644 --- a/internal/webauthn/webauthn.go +++ b/internal/webauthn/webauthn.go @@ -100,7 +100,7 @@ func (w *Config) FinishRegistration(ctx context.Context, user *domain.Human, web } credentialData, err := protocol.ParseCredentialCreationResponseBody(bytes.NewReader(credData)) if err != nil { - logging.WithFields("error", tryExtractProtocolErrMsg(err)).Debug("webauthn credential could not be parsed") + logging.WithFields("error", tryExtractProtocolErrMsg(err), "err_id", "WEBAU-sEr8c").Debug("webauthn credential could not be parsed") return nil, zerrors.ThrowInternal(err, "WEBAU-sEr8c", "Errors.User.WebAuthN.ErrorOnParseCredential") } sessionData := WebAuthNToSessionData(webAuthN) @@ -115,7 +115,7 @@ func (w *Config) FinishRegistration(ctx context.Context, user *domain.Human, web sessionData, credentialData) if err != nil { - logging.WithFields("error", tryExtractProtocolErrMsg(err)).Debug("webauthn credential could not be created") + logging.WithFields("error", tryExtractProtocolErrMsg(err), "err_id", "WEBAU-3Vb9s").Debug("webauthn credential could not be created") return nil, zerrors.ThrowInternal(err, "WEBAU-3Vb9s", "Errors.User.WebAuthN.CreateCredentialFailed") }