From c71bf85b7a9dfbb7b499a6a90dfdd1924eefffa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Thu, 12 Oct 2023 15:16:59 +0300 Subject: [PATCH 01/15] feat(api/v2): store user agent details in the session (#6711) This change adds the ability to set and get user agent data, such as fingerprint, IP, request headers and a description to the session. All fields are optional. Closes #6028 --- internal/api/grpc/session/v2/session.go | 56 ++++++- .../session/v2/session_integration_test.go | 84 +++++++--- internal/api/grpc/session/v2/session_test.go | 158 +++++++++++++++++- internal/command/auth_request_test.go | 44 ++++- internal/command/oidc_session_test.go | 22 ++- internal/command/session.go | 8 +- internal/command/session_test.go | 88 ++++++++-- internal/domain/user_agent.go | 17 ++ internal/query/prepare_test.go | 12 +- internal/query/projection/session.go | 94 +++++++---- internal/query/projection/session_test.go | 38 +++-- internal/query/session.go | 33 ++++ internal/query/sessions_test.go | 107 +++++++----- internal/repository/session/session.go | 3 + proto/zitadel/session/v2beta/session.proto | 16 ++ .../session/v2beta/session_service.proto | 1 + 16 files changed, 634 insertions(+), 147 deletions(-) create mode 100644 internal/domain/user_agent.go diff --git a/internal/api/grpc/session/v2/session.go b/internal/api/grpc/session/v2/session.go index fe8e0d874..be6907ae0 100644 --- a/internal/api/grpc/session/v2/session.go +++ b/internal/api/grpc/session/v2/session.go @@ -2,10 +2,13 @@ package session import ( "context" + "net" + "net/http" "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" + "github.com/muhlemmer/gu" "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/api/grpc/object/v2" "github.com/zitadel/zitadel/internal/command" @@ -41,7 +44,7 @@ func (s *Server) ListSessions(ctx context.Context, req *session.ListSessionsRequ } func (s *Server) CreateSession(ctx context.Context, req *session.CreateSessionRequest) (*session.CreateSessionResponse, error) { - checks, metadata, err := s.createSessionRequestToCommand(ctx, req) + checks, metadata, userAgent, err := s.createSessionRequestToCommand(ctx, req) if err != nil { return nil, err } @@ -50,7 +53,7 @@ func (s *Server) CreateSession(ctx context.Context, req *session.CreateSessionRe return nil, err } - set, err := s.command.CreateSession(ctx, cmds, metadata) + set, err := s.command.CreateSession(ctx, cmds, metadata, userAgent) if err != nil { return nil, err } @@ -113,9 +116,34 @@ func sessionToPb(s *query.Session) *session.Session { Sequence: s.Sequence, Factors: factorsToPb(s), Metadata: s.Metadata, + UserAgent: userAgentToPb(s.UserAgent), } } +func userAgentToPb(ua domain.UserAgent) *session.UserAgent { + if ua.IsEmpty() { + return nil + } + + out := &session.UserAgent{ + FingerprintId: ua.FingerprintID, + Description: ua.Description, + } + if ua.IP != nil { + out.Ip = gu.Ptr(ua.IP.String()) + } + if ua.Header == nil { + return out + } + out.Header = make(map[string]*session.UserAgent_HeaderValues, len(ua.Header)) + for k, v := range ua.Header { + out.Header[k] = &session.UserAgent_HeaderValues{ + Values: v, + } + } + return out +} + func factorsToPb(s *query.Session) *session.Factors { user := userFactorToPb(s.UserFactor) if user == nil { @@ -236,12 +264,30 @@ func idsQueryToQuery(q *session.IDsQuery) (query.SearchQuery, error) { return query.NewSessionIDsSearchQuery(q.Ids) } -func (s *Server) createSessionRequestToCommand(ctx context.Context, req *session.CreateSessionRequest) ([]command.SessionCommand, map[string][]byte, error) { +func (s *Server) createSessionRequestToCommand(ctx context.Context, req *session.CreateSessionRequest) ([]command.SessionCommand, map[string][]byte, *domain.UserAgent, error) { checks, err := s.checksToCommand(ctx, req.Checks) if err != nil { - return nil, nil, err + return nil, nil, nil, err } - return checks, req.GetMetadata(), nil + return checks, req.GetMetadata(), userAgentToCommand(req.GetUserAgent()), nil +} + +func userAgentToCommand(userAgent *session.UserAgent) *domain.UserAgent { + if userAgent == nil { + return nil + } + out := &domain.UserAgent{ + FingerprintID: userAgent.FingerprintId, + IP: net.ParseIP(userAgent.GetIp()), + Description: userAgent.Description, + } + if len(userAgent.Header) > 0 { + out.Header = make(http.Header, len(userAgent.Header)) + for k, values := range userAgent.Header { + out.Header[k] = values.GetValues() + } + } + return out } func (s *Server) setSessionRequestToCommand(ctx context.Context, req *session.SetSessionRequest) ([]command.SessionCommand, error) { diff --git a/internal/api/grpc/session/v2/session_integration_test.go b/internal/api/grpc/session/v2/session_integration_test.go index 1dcad7bc5..9aba59ee3 100644 --- a/internal/api/grpc/session/v2/session_integration_test.go +++ b/internal/api/grpc/session/v2/session_integration_test.go @@ -14,6 +14,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/grpc/metadata" + "google.golang.org/protobuf/proto" "github.com/zitadel/zitadel/internal/integration" object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" @@ -53,7 +54,7 @@ func TestMain(m *testing.M) { }()) } -func verifyCurrentSession(t testing.TB, id, token string, sequence uint64, window time.Duration, metadata map[string][]byte, factors ...wantFactor) *session.Session { +func verifyCurrentSession(t testing.TB, id, token string, sequence uint64, window time.Duration, metadata map[string][]byte, userAgent *session.UserAgent, factors ...wantFactor) *session.Session { t.Helper() require.NotEmpty(t, id) require.NotEmpty(t, token) @@ -70,6 +71,11 @@ func verifyCurrentSession(t testing.TB, id, token string, sequence uint64, windo assert.WithinRange(t, s.GetChangeDate().AsTime(), time.Now().Add(-window), time.Now().Add(window)) assert.Equal(t, sequence, s.GetSequence()) assert.Equal(t, metadata, s.GetMetadata()) + + if !proto.Equal(userAgent, s.GetUserAgent()) { + t.Errorf("user agent =\n%v\nwant\n%v", s.GetUserAgent(), userAgent) + } + verifyFactors(t, s.GetFactors(), window, factors) return s } @@ -131,11 +137,12 @@ func verifyFactors(t testing.TB, factors *session.Factors, window time.Duration, func TestServer_CreateSession(t *testing.T) { tests := []struct { - name string - req *session.CreateSessionRequest - want *session.CreateSessionResponse - wantErr bool - wantFactors []wantFactor + name string + req *session.CreateSessionRequest + want *session.CreateSessionResponse + wantErr bool + wantFactors []wantFactor + wantUserAgent *session.UserAgent }{ { name: "empty session", @@ -148,6 +155,33 @@ func TestServer_CreateSession(t *testing.T) { }, }, }, + { + name: "user agent", + req: &session.CreateSessionRequest{ + Metadata: map[string][]byte{"foo": []byte("bar")}, + UserAgent: &session.UserAgent{ + FingerprintId: gu.Ptr("fingerPrintID"), + Ip: gu.Ptr("1.2.3.4"), + Description: gu.Ptr("Description"), + Header: map[string]*session.UserAgent_HeaderValues{ + "foo": {Values: []string{"foo", "bar"}}, + }, + }, + }, + want: &session.CreateSessionResponse{ + Details: &object.Details{ + ResourceOwner: Tester.Organisation.ID, + }, + }, + wantUserAgent: &session.UserAgent{ + FingerprintId: gu.Ptr("fingerPrintID"), + Ip: gu.Ptr("1.2.3.4"), + Description: gu.Ptr("Description"), + Header: map[string]*session.UserAgent_HeaderValues{ + "foo": {Values: []string{"foo", "bar"}}, + }, + }, + }, { name: "with user", req: &session.CreateSessionRequest{ @@ -219,7 +253,7 @@ func TestServer_CreateSession(t *testing.T) { require.NoError(t, err) integration.AssertDetails(t, tt.want, got) - verifyCurrentSession(t, got.GetSessionId(), got.GetSessionToken(), got.GetDetails().GetSequence(), time.Minute, tt.req.GetMetadata(), tt.wantFactors...) + verifyCurrentSession(t, got.GetSessionId(), got.GetSessionToken(), got.GetDetails().GetSequence(), time.Minute, tt.req.GetMetadata(), tt.wantUserAgent, tt.wantFactors...) }) } } @@ -242,7 +276,7 @@ func TestServer_CreateSession_webauthn(t *testing.T) { }, }) require.NoError(t, err) - verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil) + verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil, nil) assertionData, err := Tester.WebAuthN.CreateAssertionResponse(createResp.GetChallenges().GetWebAuthN().GetPublicKeyCredentialRequestOptions(), true) require.NoError(t, err) @@ -258,7 +292,7 @@ func TestServer_CreateSession_webauthn(t *testing.T) { }, }) require.NoError(t, err) - verifyCurrentSession(t, createResp.GetSessionId(), updateResp.GetSessionToken(), updateResp.GetDetails().GetSequence(), time.Minute, nil, wantUserFactor, wantWebAuthNFactorUserVerified) + verifyCurrentSession(t, createResp.GetSessionId(), updateResp.GetSessionToken(), updateResp.GetDetails().GetSequence(), time.Minute, nil, nil, wantUserFactor, wantWebAuthNFactorUserVerified) } func TestServer_CreateSession_successfulIntent(t *testing.T) { @@ -274,7 +308,7 @@ func TestServer_CreateSession_successfulIntent(t *testing.T) { }, }) require.NoError(t, err) - verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil) + verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil, nil) intentID, token, _, _ := Tester.CreateSuccessfulOAuthIntent(t, idpID, User.GetUserId(), "id") updateResp, err := Client.SetSession(CTX, &session.SetSessionRequest{ @@ -288,7 +322,7 @@ func TestServer_CreateSession_successfulIntent(t *testing.T) { }, }) require.NoError(t, err) - verifyCurrentSession(t, createResp.GetSessionId(), updateResp.GetSessionToken(), updateResp.GetDetails().GetSequence(), time.Minute, nil, wantUserFactor, wantIntentFactor) + verifyCurrentSession(t, createResp.GetSessionId(), updateResp.GetSessionToken(), updateResp.GetDetails().GetSequence(), time.Minute, nil, nil, wantUserFactor, wantIntentFactor) } func TestServer_CreateSession_successfulIntentUnknownUserID(t *testing.T) { @@ -304,7 +338,7 @@ func TestServer_CreateSession_successfulIntentUnknownUserID(t *testing.T) { }, }) require.NoError(t, err) - verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil) + verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil, nil) idpUserID := "id" intentID, token, _, _ := Tester.CreateSuccessfulOAuthIntent(t, idpID, "", idpUserID) @@ -331,7 +365,7 @@ func TestServer_CreateSession_successfulIntentUnknownUserID(t *testing.T) { }, }) require.NoError(t, err) - verifyCurrentSession(t, createResp.GetSessionId(), updateResp.GetSessionToken(), updateResp.GetDetails().GetSequence(), time.Minute, nil, wantUserFactor, wantIntentFactor) + verifyCurrentSession(t, createResp.GetSessionId(), updateResp.GetSessionToken(), updateResp.GetDetails().GetSequence(), time.Minute, nil, nil, wantUserFactor, wantIntentFactor) } func TestServer_CreateSession_startedIntentFalseToken(t *testing.T) { @@ -347,7 +381,7 @@ func TestServer_CreateSession_startedIntentFalseToken(t *testing.T) { }, }) require.NoError(t, err) - verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil) + verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil, nil) intentID := Tester.CreateIntent(t, idpID) _, err = Client.SetSession(CTX, &session.SetSessionRequest{ @@ -399,7 +433,7 @@ func TestServer_SetSession_flow(t *testing.T) { createResp, err := Client.CreateSession(CTX, &session.CreateSessionRequest{}) require.NoError(t, err) sessionToken := createResp.GetSessionToken() - verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, createResp.GetDetails().GetSequence(), time.Minute, nil) + verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, createResp.GetDetails().GetSequence(), time.Minute, nil, nil) t.Run("check user", func(t *testing.T) { resp, err := Client.SetSession(CTX, &session.SetSessionRequest{ @@ -415,7 +449,7 @@ func TestServer_SetSession_flow(t *testing.T) { }) require.NoError(t, err) sessionToken = resp.GetSessionToken() - verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, wantUserFactor) + verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, nil, wantUserFactor) }) t.Run("check webauthn, user verified (passkey)", func(t *testing.T) { @@ -430,7 +464,7 @@ func TestServer_SetSession_flow(t *testing.T) { }, }) require.NoError(t, err) - verifyCurrentSession(t, createResp.GetSessionId(), resp.GetSessionToken(), resp.GetDetails().GetSequence(), time.Minute, nil) + verifyCurrentSession(t, createResp.GetSessionId(), resp.GetSessionToken(), resp.GetDetails().GetSequence(), time.Minute, nil, nil) sessionToken = resp.GetSessionToken() assertionData, err := Tester.WebAuthN.CreateAssertionResponse(resp.GetChallenges().GetWebAuthN().GetPublicKeyCredentialRequestOptions(), true) @@ -447,7 +481,7 @@ func TestServer_SetSession_flow(t *testing.T) { }) require.NoError(t, err) sessionToken = resp.GetSessionToken() - verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, wantUserFactor, wantWebAuthNFactorUserVerified) + verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, nil, wantUserFactor, wantWebAuthNFactorUserVerified) }) userAuthCtx := Tester.WithAuthorizationToken(CTX, sessionToken) @@ -474,7 +508,7 @@ func TestServer_SetSession_flow(t *testing.T) { }, }) require.NoError(t, err) - verifyCurrentSession(t, createResp.GetSessionId(), resp.GetSessionToken(), resp.GetDetails().GetSequence(), time.Minute, nil) + verifyCurrentSession(t, createResp.GetSessionId(), resp.GetSessionToken(), resp.GetDetails().GetSequence(), time.Minute, nil, nil) sessionToken = resp.GetSessionToken() assertionData, err := Tester.WebAuthN.CreateAssertionResponse(resp.GetChallenges().GetWebAuthN().GetPublicKeyCredentialRequestOptions(), false) @@ -491,7 +525,7 @@ func TestServer_SetSession_flow(t *testing.T) { }) require.NoError(t, err) sessionToken = resp.GetSessionToken() - verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, wantUserFactor, wantWebAuthNFactor) + verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, nil, wantUserFactor, wantWebAuthNFactor) }) } }) @@ -510,7 +544,7 @@ func TestServer_SetSession_flow(t *testing.T) { }) require.NoError(t, err) sessionToken = resp.GetSessionToken() - verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, wantUserFactor, wantWebAuthNFactor, wantTOTPFactor) + verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, nil, wantUserFactor, wantWebAuthNFactor, wantTOTPFactor) }) t.Run("check OTP SMS", func(t *testing.T) { @@ -522,7 +556,7 @@ func TestServer_SetSession_flow(t *testing.T) { }, }) require.NoError(t, err) - verifyCurrentSession(t, createResp.GetSessionId(), resp.GetSessionToken(), resp.GetDetails().GetSequence(), time.Minute, nil) + verifyCurrentSession(t, createResp.GetSessionId(), resp.GetSessionToken(), resp.GetDetails().GetSequence(), time.Minute, nil, nil) sessionToken = resp.GetSessionToken() otp := resp.GetChallenges().GetOtpSms() @@ -539,7 +573,7 @@ func TestServer_SetSession_flow(t *testing.T) { }) require.NoError(t, err) sessionToken = resp.GetSessionToken() - verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, wantUserFactor, wantWebAuthNFactor, wantOTPSMSFactor) + verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, nil, wantUserFactor, wantWebAuthNFactor, wantOTPSMSFactor) }) t.Run("check OTP Email", func(t *testing.T) { @@ -553,7 +587,7 @@ func TestServer_SetSession_flow(t *testing.T) { }, }) require.NoError(t, err) - verifyCurrentSession(t, createResp.GetSessionId(), resp.GetSessionToken(), resp.GetDetails().GetSequence(), time.Minute, nil) + verifyCurrentSession(t, createResp.GetSessionId(), resp.GetSessionToken(), resp.GetDetails().GetSequence(), time.Minute, nil, nil) sessionToken = resp.GetSessionToken() otp := resp.GetChallenges().GetOtpEmail() @@ -570,7 +604,7 @@ func TestServer_SetSession_flow(t *testing.T) { }) require.NoError(t, err) sessionToken = resp.GetSessionToken() - verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, wantUserFactor, wantWebAuthNFactor, wantOTPEmailFactor) + verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, nil, wantUserFactor, wantWebAuthNFactor, wantOTPEmailFactor) }) } diff --git a/internal/api/grpc/session/v2/session_test.go b/internal/api/grpc/session/v2/session_test.go index 33804caba..ae33fab4c 100644 --- a/internal/api/grpc/session/v2/session_test.go +++ b/internal/api/grpc/session/v2/session_test.go @@ -2,15 +2,18 @@ package session import ( "context" + "net" + "net/http" "testing" "time" + "github.com/muhlemmer/gu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/zitadel/zitadel/internal/api/authz" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" - "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/domain" caos_errs "github.com/zitadel/zitadel/internal/errors" "github.com/zitadel/zitadel/internal/query" @@ -23,7 +26,7 @@ func Test_sessionsToPb(t *testing.T) { past := now.Add(-time.Hour) sessions := []*query.Session{ - { // no factor + { // no factor, with user agent ID: "999", CreationDate: now, ChangeDate: now, @@ -32,6 +35,12 @@ func Test_sessionsToPb(t *testing.T) { ResourceOwner: "me", Creator: "he", Metadata: map[string][]byte{"hello": []byte("world")}, + UserAgent: domain.UserAgent{ + FingerprintID: gu.Ptr("fingerprintID"), + Description: gu.Ptr("description"), + IP: net.IPv4(1, 2, 3, 4), + Header: http.Header{"foo": []string{"foo", "bar"}}, + }, }, { // user factor ID: "999", @@ -114,13 +123,21 @@ func Test_sessionsToPb(t *testing.T) { } want := []*session.Session{ - { // no factor + { // no factor, with user agent Id: "999", CreationDate: timestamppb.New(now), ChangeDate: timestamppb.New(now), Sequence: 123, Factors: nil, Metadata: map[string][]byte{"hello": []byte("world")}, + UserAgent: &session.UserAgent{ + FingerprintId: gu.Ptr("fingerprintID"), + Description: gu.Ptr("description"), + Ip: gu.Ptr("1.2.3.4"), + Header: map[string]*session.UserAgent_HeaderValues{ + "foo": {Values: []string{"foo", "bar"}}, + }, + }, }, { // user factor Id: "999", @@ -208,6 +225,71 @@ func Test_sessionsToPb(t *testing.T) { } } +func Test_userAgentToPb(t *testing.T) { + type args struct { + ua domain.UserAgent + } + tests := []struct { + name string + args args + want *session.UserAgent + }{ + { + name: "empty", + args: args{domain.UserAgent{}}, + }, + { + name: "fingerprint id and description", + args: args{domain.UserAgent{ + FingerprintID: gu.Ptr("fingerPrintID"), + Description: gu.Ptr("description"), + }}, + want: &session.UserAgent{ + FingerprintId: gu.Ptr("fingerPrintID"), + Description: gu.Ptr("description"), + }, + }, + { + name: "with ip", + args: args{domain.UserAgent{ + FingerprintID: gu.Ptr("fingerPrintID"), + Description: gu.Ptr("description"), + IP: net.IPv4(1, 2, 3, 4), + }}, + want: &session.UserAgent{ + FingerprintId: gu.Ptr("fingerPrintID"), + Description: gu.Ptr("description"), + Ip: gu.Ptr("1.2.3.4"), + }, + }, + { + name: "with header", + args: args{domain.UserAgent{ + FingerprintID: gu.Ptr("fingerPrintID"), + Description: gu.Ptr("description"), + Header: http.Header{ + "foo": []string{"foo", "bar"}, + "hello": []string{"world"}, + }, + }}, + want: &session.UserAgent{ + FingerprintId: gu.Ptr("fingerPrintID"), + Description: gu.Ptr("description"), + Header: map[string]*session.UserAgent_HeaderValues{ + "foo": {Values: []string{"foo", "bar"}}, + "hello": {Values: []string{"world"}}, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := userAgentToPb(tt.args.ua) + assert.Equal(t, tt.want, got) + }) + } +} + func mustNewTextQuery(t testing.TB, column query.Column, value string, compare query.TextComparison) query.SearchQuery { q, err := query.NewTextQuery(column, value, compare) require.NoError(t, err) @@ -510,3 +592,73 @@ func Test_userVerificationRequirementToDomain(t *testing.T) { }) } } + +func Test_userAgentToCommand(t *testing.T) { + type args struct { + userAgent *session.UserAgent + } + tests := []struct { + name string + args args + want *domain.UserAgent + }{ + { + name: "nil", + args: args{nil}, + want: nil, + }, + { + name: "all fields", + args: args{&session.UserAgent{ + FingerprintId: gu.Ptr("fp1"), + Ip: gu.Ptr("1.2.3.4"), + Description: gu.Ptr("firefox"), + Header: map[string]*session.UserAgent_HeaderValues{ + "hello": { + Values: []string{"foo", "bar"}, + }, + }, + }}, + want: &domain.UserAgent{ + FingerprintID: gu.Ptr("fp1"), + IP: net.ParseIP("1.2.3.4"), + Description: gu.Ptr("firefox"), + Header: http.Header{ + "hello": []string{"foo", "bar"}, + }, + }, + }, + { + name: "invalid ip", + args: args{&session.UserAgent{ + FingerprintId: gu.Ptr("fp1"), + Ip: gu.Ptr("oops"), + Description: gu.Ptr("firefox"), + Header: map[string]*session.UserAgent_HeaderValues{ + "hello": { + Values: []string{"foo", "bar"}, + }, + }, + }}, + want: &domain.UserAgent{ + FingerprintID: gu.Ptr("fp1"), + IP: nil, + Description: gu.Ptr("firefox"), + Header: http.Header{ + "hello": []string{"foo", "bar"}, + }, + }, + }, + { + name: "nil fields", + args: args{&session.UserAgent{}}, + want: &domain.UserAgent{}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := userAgentToCommand(tt.args.userAgent) + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/internal/command/auth_request_test.go b/internal/command/auth_request_test.go index 9e6bf8328..61f7c9184 100644 --- a/internal/command/auth_request_test.go +++ b/internal/command/auth_request_test.go @@ -2,6 +2,8 @@ package command import ( "context" + "net" + "net/http" "testing" "time" @@ -358,7 +360,15 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) { ), expectFilter( eventFromEventPusher( - session.NewAddedEvent(mockCtx, &session.NewAggregate("sessionID", "org1").Aggregate)), + session.NewAddedEvent(mockCtx, + &session.NewAggregate("sessionID", "org1").Aggregate, + &domain.UserAgent{ + FingerprintID: gu.Ptr("fp1"), + IP: net.ParseIP("1.2.3.4"), + Description: gu.Ptr("firefox"), + Header: http.Header{"foo": []string{"bar"}}, + }, + )), ), ), tokenVerifier: func(ctx context.Context, sessionToken, sessionID, tokenID string) (err error) { @@ -401,7 +411,15 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) { ), expectFilter( eventFromEventPusher( - session.NewAddedEvent(mockCtx, &session.NewAggregate("sessionID", "org1").Aggregate)), + session.NewAddedEvent(mockCtx, + &session.NewAggregate("sessionID", "org1").Aggregate, + &domain.UserAgent{ + FingerprintID: gu.Ptr("fp1"), + IP: net.ParseIP("1.2.3.4"), + Description: gu.Ptr("firefox"), + Header: http.Header{"foo": []string{"bar"}}, + }, + )), ), ), tokenVerifier: func(ctx context.Context, sessionToken, sessionID, tokenID string) (err error) { @@ -444,8 +462,15 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) { ), expectFilter( eventFromEventPusher( - session.NewAddedEvent(mockCtx, &session.NewAggregate("sessionID", "org1").Aggregate), - ), + session.NewAddedEvent(mockCtx, + &session.NewAggregate("sessionID", "org1").Aggregate, + &domain.UserAgent{ + FingerprintID: gu.Ptr("fp1"), + IP: net.ParseIP("1.2.3.4"), + Description: gu.Ptr("firefox"), + Header: http.Header{"foo": []string{"bar"}}, + }, + )), eventFromEventPusher( session.NewUserCheckedEvent(mockCtx, &session.NewAggregate("sessionID", "org1").Aggregate, "userID", testNow), @@ -523,8 +548,15 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) { ), expectFilter( eventFromEventPusher( - session.NewAddedEvent(mockCtx, &session.NewAggregate("sessionID", "org1").Aggregate), - ), + session.NewAddedEvent(mockCtx, + &session.NewAggregate("sessionID", "org1").Aggregate, + &domain.UserAgent{ + FingerprintID: gu.Ptr("fp1"), + IP: net.ParseIP("1.2.3.4"), + Description: gu.Ptr("firefox"), + Header: http.Header{"foo": []string{"bar"}}, + }, + )), eventFromEventPusher( session.NewUserCheckedEvent(mockCtx, &session.NewAggregate("sessionID", "org1").Aggregate, "userID", testNow), diff --git a/internal/command/oidc_session_test.go b/internal/command/oidc_session_test.go index aba917fa2..59d8f7d3f 100644 --- a/internal/command/oidc_session_test.go +++ b/internal/command/oidc_session_test.go @@ -2,6 +2,8 @@ package command import ( "context" + "net" + "net/http" "testing" "time" @@ -164,7 +166,15 @@ func TestCommands_AddOIDCSessionAccessToken(t *testing.T) { ), expectFilter( eventFromEventPusher( - session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "instanceID").Aggregate), + session.NewAddedEvent(context.Background(), + &session.NewAggregate("sessionID", "org1").Aggregate, + &domain.UserAgent{ + FingerprintID: gu.Ptr("fp1"), + IP: net.ParseIP("1.2.3.4"), + Description: gu.Ptr("firefox"), + Header: http.Header{"foo": []string{"bar"}}, + }, + ), ), eventFromEventPusher( session.NewUserCheckedEvent(context.Background(), &session.NewAggregate("sessionID", "instanceID").Aggregate, @@ -365,7 +375,15 @@ func TestCommands_AddOIDCSessionRefreshAndAccessToken(t *testing.T) { ), expectFilter( eventFromEventPusher( - session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "instanceID").Aggregate), + session.NewAddedEvent(context.Background(), + &session.NewAggregate("sessionID", "org1").Aggregate, + &domain.UserAgent{ + FingerprintID: gu.Ptr("fp1"), + IP: net.ParseIP("1.2.3.4"), + Description: gu.Ptr("firefox"), + Header: http.Header{"foo": []string{"bar"}}, + }, + ), ), eventFromEventPusher( session.NewUserCheckedEvent(context.Background(), &session.NewAggregate("sessionID", "instanceID").Aggregate, diff --git a/internal/command/session.go b/internal/command/session.go index a58c5d2d3..caf3056f7 100644 --- a/internal/command/session.go +++ b/internal/command/session.go @@ -166,8 +166,8 @@ func (s *SessionCommands) Exec(ctx context.Context) error { return nil } -func (s *SessionCommands) Start(ctx context.Context) { - s.eventCommands = append(s.eventCommands, session.NewAddedEvent(ctx, s.sessionWriteModel.aggregate)) +func (s *SessionCommands) Start(ctx context.Context, userAgent *domain.UserAgent) { + s.eventCommands = append(s.eventCommands, session.NewAddedEvent(ctx, s.sessionWriteModel.aggregate, userAgent)) } func (s *SessionCommands) UserChecked(ctx context.Context, userID string, checkedAt time.Time) error { @@ -280,7 +280,7 @@ func (s *SessionCommands) commands(ctx context.Context) (string, []eventstore.Co return token, s.eventCommands, nil } -func (c *Commands) CreateSession(ctx context.Context, cmds []SessionCommand, metadata map[string][]byte) (set *SessionChanged, err error) { +func (c *Commands) CreateSession(ctx context.Context, cmds []SessionCommand, metadata map[string][]byte, userAgent *domain.UserAgent) (set *SessionChanged, err error) { sessionID, err := c.idGenerator.Next() if err != nil { return nil, err @@ -291,7 +291,7 @@ func (c *Commands) CreateSession(ctx context.Context, cmds []SessionCommand, met return nil, err } cmd := c.NewSessionCommands(cmds, sessionWriteModel) - cmd.Start(ctx) + cmd.Start(ctx, userAgent) return c.updateSession(ctx, cmd, metadata) } diff --git a/internal/command/session_test.go b/internal/command/session_test.go index 57f3ba971..048ed51e8 100644 --- a/internal/command/session_test.go +++ b/internal/command/session_test.go @@ -3,10 +3,13 @@ package command import ( "context" "io" + "net" + "net/http" "testing" "time" "github.com/golang/mock/gomock" + "github.com/muhlemmer/gu" "github.com/pquerna/otp/totp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -145,9 +148,10 @@ func TestCommands_CreateSession(t *testing.T) { tokenCreator func(sessionID string) (string, string, error) } type args struct { - ctx context.Context - checks []SessionCommand - metadata map[string][]byte + ctx context.Context + checks []SessionCommand + metadata map[string][]byte + userAgent *domain.UserAgent } type res struct { want *SessionChanged @@ -200,12 +204,26 @@ func TestCommands_CreateSession(t *testing.T) { }, args{ ctx: authz.NewMockContext("", "org1", ""), + userAgent: &domain.UserAgent{ + FingerprintID: gu.Ptr("fp1"), + IP: net.ParseIP("1.2.3.4"), + Description: gu.Ptr("firefox"), + Header: http.Header{"foo": []string{"bar"}}, + }, }, []expect{ expectFilter(), expectPush( eventPusherToEvents( - session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate), + session.NewAddedEvent(context.Background(), + &session.NewAggregate("sessionID", "org1").Aggregate, + &domain.UserAgent{ + FingerprintID: gu.Ptr("fp1"), + IP: net.ParseIP("1.2.3.4"), + Description: gu.Ptr("firefox"), + Header: http.Header{"foo": []string{"bar"}}, + }, + ), session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "tokenID", ), @@ -229,7 +247,7 @@ func TestCommands_CreateSession(t *testing.T) { idGenerator: tt.fields.idGenerator, sessionTokenCreator: tt.fields.tokenCreator, } - got, err := c.CreateSession(tt.args.ctx, tt.args.checks, tt.args.metadata) + got, err := c.CreateSession(tt.args.ctx, tt.args.checks, tt.args.metadata, tt.args.userAgent) require.ErrorIs(t, err, tt.res.err) assert.Equal(t, tt.res.want, got) }) @@ -278,7 +296,15 @@ func TestCommands_UpdateSession(t *testing.T) { eventstore: eventstoreExpect(t, expectFilter( eventFromEventPusher( - session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate)), + session.NewAddedEvent(context.Background(), + &session.NewAggregate("sessionID", "org1").Aggregate, + &domain.UserAgent{ + FingerprintID: gu.Ptr("fp1"), + IP: net.ParseIP("1.2.3.4"), + Description: gu.Ptr("firefox"), + Header: http.Header{"foo": []string{"bar"}}, + }, + )), eventFromEventPusher( session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "tokenID")), @@ -303,7 +329,15 @@ func TestCommands_UpdateSession(t *testing.T) { eventstore: eventstoreExpect(t, expectFilter( eventFromEventPusher( - session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate)), + session.NewAddedEvent(context.Background(), + &session.NewAggregate("sessionID", "org1").Aggregate, + &domain.UserAgent{ + FingerprintID: gu.Ptr("fp1"), + IP: net.ParseIP("1.2.3.4"), + Description: gu.Ptr("firefox"), + Header: http.Header{"foo": []string{"bar"}}, + }, + )), eventFromEventPusher( session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "tokenID")), @@ -868,7 +902,15 @@ func TestCommands_TerminateSession(t *testing.T) { eventstore: eventstoreExpect(t, expectFilter( eventFromEventPusher( - session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate)), + session.NewAddedEvent(context.Background(), + &session.NewAggregate("sessionID", "org1").Aggregate, + &domain.UserAgent{ + FingerprintID: gu.Ptr("fp1"), + IP: net.ParseIP("1.2.3.4"), + Description: gu.Ptr("firefox"), + Header: http.Header{"foo": []string{"bar"}}, + }, + )), eventFromEventPusher( session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "tokenID")), @@ -893,7 +935,15 @@ func TestCommands_TerminateSession(t *testing.T) { eventstore: eventstoreExpect(t, expectFilter( eventFromEventPusher( - session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate)), + session.NewAddedEvent(context.Background(), + &session.NewAggregate("sessionID", "org1").Aggregate, + &domain.UserAgent{ + FingerprintID: gu.Ptr("fp1"), + IP: net.ParseIP("1.2.3.4"), + Description: gu.Ptr("firefox"), + Header: http.Header{"foo": []string{"bar"}}, + }, + )), eventFromEventPusher( session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "tokenID")), @@ -922,7 +972,15 @@ func TestCommands_TerminateSession(t *testing.T) { eventstore: eventstoreExpect(t, expectFilter( eventFromEventPusher( - session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate)), + session.NewAddedEvent(context.Background(), + &session.NewAggregate("sessionID", "org1").Aggregate, + &domain.UserAgent{ + FingerprintID: gu.Ptr("fp1"), + IP: net.ParseIP("1.2.3.4"), + Description: gu.Ptr("firefox"), + Header: http.Header{"foo": []string{"bar"}}, + }, + )), eventFromEventPusher( session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "tokenID"), @@ -953,7 +1011,15 @@ func TestCommands_TerminateSession(t *testing.T) { eventstore: eventstoreExpect(t, expectFilter( eventFromEventPusher( - session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate)), + session.NewAddedEvent(context.Background(), + &session.NewAggregate("sessionID", "org1").Aggregate, + &domain.UserAgent{ + FingerprintID: gu.Ptr("fp1"), + IP: net.ParseIP("1.2.3.4"), + Description: gu.Ptr("firefox"), + Header: http.Header{"foo": []string{"bar"}}, + }, + )), eventFromEventPusher( session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "tokenID"), diff --git a/internal/domain/user_agent.go b/internal/domain/user_agent.go new file mode 100644 index 000000000..ca72c6bec --- /dev/null +++ b/internal/domain/user_agent.go @@ -0,0 +1,17 @@ +package domain + +import ( + "net" + httplib "net/http" +) + +type UserAgent struct { + FingerprintID *string `json:"fingerprint_id,omitempty"` + IP net.IP `json:"ip,omitempty"` + Description *string `json:"description,omitempty"` + Header httplib.Header `json:"header,omitempty"` +} + +func (ua UserAgent) IsEmpty() bool { + return ua.FingerprintID == nil && len(ua.IP) == 0 && ua.Description == nil && ua.Header == nil +} diff --git a/internal/query/prepare_test.go b/internal/query/prepare_test.go index 242b38740..c9770c0dd 100644 --- a/internal/query/prepare_test.go +++ b/internal/query/prepare_test.go @@ -54,7 +54,7 @@ func assertPrepare(t *testing.T, prepareFunc, expectedObject interface{}, sqlExp } return isErr(err) } - object, ok, didScan := execScan(&database.DB{DB: client}, builder, scan, errCheck) + object, ok, didScan := execScan(t, &database.DB{DB: client}, builder, scan, errCheck) if !ok { t.Error(object) return false @@ -168,7 +168,7 @@ var ( selectBuilderType = reflect.TypeOf(sq.SelectBuilder{}) ) -func execScan(client *database.DB, builder sq.SelectBuilder, scan interface{}, errCheck checkErr) (object interface{}, ok bool, didScan bool) { +func execScan(t testing.TB, client *database.DB, builder sq.SelectBuilder, scan interface{}, errCheck checkErr) (object interface{}, ok bool, didScan bool) { scanType := reflect.TypeOf(scan) err := validateScan(scanType) if err != nil { @@ -177,7 +177,7 @@ func execScan(client *database.DB, builder sq.SelectBuilder, scan interface{}, e stmt, args, err := builder.ToSql() if err != nil { - return fmt.Errorf("unexpeted error from sql builder: %w", err), false, false + return fmt.Errorf("unexpected error from sql builder: %w", err), false, false } //resultSet represents *sql.Row or *sql.Rows, @@ -199,6 +199,9 @@ func execScan(client *database.DB, builder sq.SelectBuilder, scan interface{}, e // if scan(*sql.Row)... } else if scanType.In(0).AssignableTo(rowType) { err = client.QueryRow(func(r *sql.Row) error { + if r.Err() != nil { + return r.Err() + } didScan = true res = reflect.ValueOf(scan).Call([]reflect.Value{reflect.ValueOf(r)}) if err, ok := res[1].Interface().(error); ok { @@ -213,6 +216,9 @@ func execScan(client *database.DB, builder sq.SelectBuilder, scan interface{}, e if err != nil { err, ok := errCheck(err) + if !ok { + t.Fatal(err) + } if didScan { return res[0].Interface(), ok, didScan } diff --git a/internal/query/projection/session.go b/internal/query/projection/session.go index 7305d6a87..f51d7c1b2 100644 --- a/internal/query/projection/session.go +++ b/internal/query/projection/session.go @@ -14,27 +14,31 @@ import ( ) const ( - SessionsProjectionTable = "projections.sessions5" + SessionsProjectionTable = "projections.sessions6" - SessionColumnID = "id" - SessionColumnCreationDate = "creation_date" - SessionColumnChangeDate = "change_date" - SessionColumnSequence = "sequence" - SessionColumnState = "state" - SessionColumnResourceOwner = "resource_owner" - SessionColumnInstanceID = "instance_id" - SessionColumnCreator = "creator" - SessionColumnUserID = "user_id" - SessionColumnUserCheckedAt = "user_checked_at" - SessionColumnPasswordCheckedAt = "password_checked_at" - SessionColumnIntentCheckedAt = "intent_checked_at" - SessionColumnWebAuthNCheckedAt = "webauthn_checked_at" - SessionColumnWebAuthNUserVerified = "webauthn_user_verified" - SessionColumnTOTPCheckedAt = "totp_checked_at" - SessionColumnOTPSMSCheckedAt = "otp_sms_checked_at" - SessionColumnOTPEmailCheckedAt = "otp_email_checked_at" - SessionColumnMetadata = "metadata" - SessionColumnTokenID = "token_id" + SessionColumnID = "id" + SessionColumnCreationDate = "creation_date" + SessionColumnChangeDate = "change_date" + SessionColumnSequence = "sequence" + SessionColumnState = "state" + SessionColumnResourceOwner = "resource_owner" + SessionColumnInstanceID = "instance_id" + SessionColumnCreator = "creator" + SessionColumnUserID = "user_id" + SessionColumnUserCheckedAt = "user_checked_at" + SessionColumnPasswordCheckedAt = "password_checked_at" + SessionColumnIntentCheckedAt = "intent_checked_at" + SessionColumnWebAuthNCheckedAt = "webauthn_checked_at" + SessionColumnWebAuthNUserVerified = "webauthn_user_verified" + SessionColumnTOTPCheckedAt = "totp_checked_at" + SessionColumnOTPSMSCheckedAt = "otp_sms_checked_at" + SessionColumnOTPEmailCheckedAt = "otp_email_checked_at" + SessionColumnMetadata = "metadata" + SessionColumnTokenID = "token_id" + SessionColumnUserAgentFingerprintID = "user_agent_fingerprint_id" + SessionColumnUserAgentIP = "user_agent_ip" + SessionColumnUserAgentDescription = "user_agent_description" + SessionColumnUserAgentHeader = "user_agent_header" ) type sessionProjection struct { @@ -66,8 +70,16 @@ func newSessionProjection(ctx context.Context, config crdb.StatementHandlerConfi crdb.NewColumn(SessionColumnOTPEmailCheckedAt, crdb.ColumnTypeTimestamp, crdb.Nullable()), crdb.NewColumn(SessionColumnMetadata, crdb.ColumnTypeJSONB, crdb.Nullable()), crdb.NewColumn(SessionColumnTokenID, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(SessionColumnUserAgentFingerprintID, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(SessionColumnUserAgentIP, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(SessionColumnUserAgentDescription, crdb.ColumnTypeText, crdb.Nullable()), + crdb.NewColumn(SessionColumnUserAgentHeader, crdb.ColumnTypeJSONB, crdb.Nullable()), }, crdb.NewPrimaryKey(SessionColumnInstanceID, SessionColumnID), + crdb.WithIndex(crdb.NewIndex( + SessionColumnUserAgentFingerprintID+"_idx", + []string{SessionColumnUserAgentFingerprintID}, + )), ), ) p.StatementHandler = crdb.NewStatementHandler(ctx, config) @@ -152,19 +164,35 @@ func (p *sessionProjection) reduceSessionAdded(event eventstore.Event) (*handler return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Sfrgf", "reduce.wrong.event.type %s", session.AddedType) } - return crdb.NewCreateStatement( - e, - []handler.Column{ - handler.NewCol(SessionColumnID, e.Aggregate().ID), - handler.NewCol(SessionColumnInstanceID, e.Aggregate().InstanceID), - handler.NewCol(SessionColumnCreationDate, e.CreationDate()), - handler.NewCol(SessionColumnChangeDate, e.CreationDate()), - handler.NewCol(SessionColumnResourceOwner, e.Aggregate().ResourceOwner), - handler.NewCol(SessionColumnState, domain.SessionStateActive), - handler.NewCol(SessionColumnSequence, e.Sequence()), - handler.NewCol(SessionColumnCreator, e.User), - }, - ), nil + cols := make([]handler.Column, 0, 12) + cols = append(cols, + handler.NewCol(SessionColumnID, e.Aggregate().ID), + handler.NewCol(SessionColumnInstanceID, e.Aggregate().InstanceID), + handler.NewCol(SessionColumnCreationDate, e.CreationDate()), + handler.NewCol(SessionColumnChangeDate, e.CreationDate()), + handler.NewCol(SessionColumnResourceOwner, e.Aggregate().ResourceOwner), + handler.NewCol(SessionColumnState, domain.SessionStateActive), + handler.NewCol(SessionColumnSequence, e.Sequence()), + handler.NewCol(SessionColumnCreator, e.User), + ) + if e.UserAgent != nil { + cols = append(cols, + handler.NewCol(SessionColumnUserAgentFingerprintID, e.UserAgent.FingerprintID), + handler.NewCol(SessionColumnUserAgentDescription, e.UserAgent.Description), + ) + if e.UserAgent.IP != nil { + cols = append(cols, + handler.NewCol(SessionColumnUserAgentIP, e.UserAgent.IP.String()), + ) + } + if e.UserAgent.Header != nil { + cols = append(cols, + handler.NewJSONCol(SessionColumnUserAgentHeader, e.UserAgent.Header), + ) + } + } + + return crdb.NewCreateStatement(e, cols), nil } func (p *sessionProjection) reduceUserChecked(event eventstore.Event) (*handler.Statement, error) { diff --git a/internal/query/projection/session_test.go b/internal/query/projection/session_test.go index 8ac52b748..e18f1ca59 100644 --- a/internal/query/projection/session_test.go +++ b/internal/query/projection/session_test.go @@ -4,6 +4,8 @@ import ( "testing" "time" + "github.com/muhlemmer/gu" + "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/errors" "github.com/zitadel/zitadel/internal/eventstore" @@ -31,7 +33,15 @@ func TestSessionProjection_reduces(t *testing.T) { session.AddedType, session.AggregateType, []byte(`{ - "domain": "domain" + "domain": "domain", + "user_agent": { + "fingerprint_id": "fp1", + "ip": "1.2.3.4", + "description": "firefox", + "header": { + "foo": ["bar"] + } + } }`), ), session.AddedEventMapper), }, @@ -43,7 +53,7 @@ func TestSessionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO projections.sessions5 (id, instance_id, creation_date, change_date, resource_owner, state, sequence, creator) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", + expectedStmt: "INSERT INTO projections.sessions6 (id, instance_id, creation_date, change_date, resource_owner, state, sequence, creator, user_agent_fingerprint_id, user_agent_description, user_agent_ip, user_agent_header) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)", expectedArgs: []interface{}{ "agg-id", "instance-id", @@ -53,6 +63,10 @@ func TestSessionProjection_reduces(t *testing.T) { domain.SessionStateActive, uint64(15), "editor-user", + gu.Ptr("fp1"), + gu.Ptr("firefox"), + "1.2.3.4", + []byte(`{"foo":["bar"]}`), }, }, }, @@ -79,7 +93,7 @@ func TestSessionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.sessions5 SET (change_date, sequence, user_id, user_checked_at) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)", + expectedStmt: "UPDATE projections.sessions6 SET (change_date, sequence, user_id, user_checked_at) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -112,7 +126,7 @@ func TestSessionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.sessions5 SET (change_date, sequence, password_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", + expectedStmt: "UPDATE projections.sessions6 SET (change_date, sequence, password_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -145,7 +159,7 @@ func TestSessionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.sessions5 SET (change_date, sequence, webauthn_checked_at, webauthn_user_verified) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)", + expectedStmt: "UPDATE projections.sessions6 SET (change_date, sequence, webauthn_checked_at, webauthn_user_verified) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -178,7 +192,7 @@ func TestSessionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.sessions5 SET (change_date, sequence, intent_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", + expectedStmt: "UPDATE projections.sessions6 SET (change_date, sequence, intent_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -210,7 +224,7 @@ func TestSessionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.sessions5 SET (change_date, sequence, totp_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", + expectedStmt: "UPDATE projections.sessions6 SET (change_date, sequence, totp_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -242,7 +256,7 @@ func TestSessionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.sessions5 SET (change_date, sequence, token_id) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", + expectedStmt: "UPDATE projections.sessions6 SET (change_date, sequence, token_id) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -276,7 +290,7 @@ func TestSessionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.sessions5 SET (change_date, sequence, metadata) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", + expectedStmt: "UPDATE projections.sessions6 SET (change_date, sequence, metadata) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -308,7 +322,7 @@ func TestSessionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM projections.sessions5 WHERE (id = $1) AND (instance_id = $2)", + expectedStmt: "DELETE FROM projections.sessions6 WHERE (id = $1) AND (instance_id = $2)", expectedArgs: []interface{}{ "agg-id", "instance-id", @@ -335,7 +349,7 @@ func TestSessionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "DELETE FROM projections.sessions5 WHERE (instance_id = $1)", + expectedStmt: "DELETE FROM projections.sessions6 WHERE (instance_id = $1)", expectedArgs: []interface{}{ "agg-id", }, @@ -366,7 +380,7 @@ func TestSessionProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.sessions5 SET password_checked_at = $1 WHERE (user_id = $2) AND (password_checked_at < $3)", + expectedStmt: "UPDATE projections.sessions6 SET password_checked_at = $1 WHERE (user_id = $2) AND (password_checked_at < $3)", expectedArgs: []interface{}{ nil, "agg-id", diff --git a/internal/query/session.go b/internal/query/session.go index c098d3d11..73ff5a968 100644 --- a/internal/query/session.go +++ b/internal/query/session.go @@ -4,6 +4,8 @@ import ( "context" "database/sql" errs "errors" + "net" + "net/http" "time" sq "github.com/Masterminds/squirrel" @@ -38,6 +40,7 @@ type Session struct { OTPSMSFactor SessionOTPFactor OTPEmailFactor SessionOTPFactor Metadata map[string][]byte + UserAgent domain.UserAgent } type SessionUserFactor struct { @@ -163,6 +166,22 @@ var ( name: projection.SessionColumnTokenID, table: sessionsTable, } + SessionColumnUserAgentFingerprintID = Column{ + name: projection.SessionColumnUserAgentFingerprintID, + table: sessionsTable, + } + SessionColumnUserAgentIP = Column{ + name: projection.SessionColumnUserAgentIP, + table: sessionsTable, + } + SessionColumnUserAgentDescription = Column{ + name: projection.SessionColumnUserAgentDescription, + table: sessionsTable, + } + SessionColumnUserAgentHeader = Column{ + name: projection.SessionColumnUserAgentHeader, + table: sessionsTable, + } ) func (q *Queries) SessionByID(ctx context.Context, shouldTriggerBulk bool, id, sessionToken string) (session *Session, err error) { @@ -261,6 +280,10 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil SessionColumnOTPEmailCheckedAt.identifier(), SessionColumnMetadata.identifier(), SessionColumnToken.identifier(), + SessionColumnUserAgentFingerprintID.identifier(), + SessionColumnUserAgentIP.identifier(), + SessionColumnUserAgentDescription.identifier(), + SessionColumnUserAgentHeader.identifier(), ).From(sessionsTable.identifier()). LeftJoin(join(LoginNameUserIDCol, SessionColumnUserID)). LeftJoin(join(HumanUserIDCol, SessionColumnUserID)). @@ -283,6 +306,8 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil otpEmailCheckedAt sql.NullTime metadata database.Map[[]byte] token sql.NullString + userAgentIP sql.NullString + userAgentHeader database.Map[[]string] ) err := row.Scan( @@ -307,6 +332,10 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil &otpEmailCheckedAt, &metadata, &token, + &session.UserAgent.FingerprintID, + &userAgentIP, + &session.UserAgent.Description, + &userAgentHeader, ) if err != nil { @@ -329,7 +358,11 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil session.OTPSMSFactor.OTPCheckedAt = otpSMSCheckedAt.Time session.OTPEmailFactor.OTPCheckedAt = otpEmailCheckedAt.Time session.Metadata = metadata + session.UserAgent.Header = http.Header(userAgentHeader) + if userAgentIP.Valid { + session.UserAgent.IP = net.ParseIP(userAgentIP.String) + } return session, token.String, nil } } diff --git a/internal/query/sessions_test.go b/internal/query/sessions_test.go index fa5209bdd..1bae095ec 100644 --- a/internal/query/sessions_test.go +++ b/internal/query/sessions_test.go @@ -6,10 +6,13 @@ import ( "database/sql/driver" "errors" "fmt" + "net" + "net/http" "regexp" "testing" sq "github.com/Masterminds/squirrel" + "github.com/muhlemmer/gu" "github.com/stretchr/testify/require" "github.com/zitadel/zitadel/internal/domain" @@ -17,57 +20,61 @@ import ( ) var ( - expectedSessionQuery = regexp.QuoteMeta(`SELECT projections.sessions5.id,` + - ` projections.sessions5.creation_date,` + - ` projections.sessions5.change_date,` + - ` projections.sessions5.sequence,` + - ` projections.sessions5.state,` + - ` projections.sessions5.resource_owner,` + - ` projections.sessions5.creator,` + - ` projections.sessions5.user_id,` + - ` projections.sessions5.user_checked_at,` + + expectedSessionQuery = regexp.QuoteMeta(`SELECT projections.sessions6.id,` + + ` projections.sessions6.creation_date,` + + ` projections.sessions6.change_date,` + + ` projections.sessions6.sequence,` + + ` projections.sessions6.state,` + + ` projections.sessions6.resource_owner,` + + ` projections.sessions6.creator,` + + ` projections.sessions6.user_id,` + + ` projections.sessions6.user_checked_at,` + ` projections.login_names2.login_name,` + ` projections.users8_humans.display_name,` + ` projections.users8.resource_owner,` + - ` projections.sessions5.password_checked_at,` + - ` projections.sessions5.intent_checked_at,` + - ` projections.sessions5.webauthn_checked_at,` + - ` projections.sessions5.webauthn_user_verified,` + - ` projections.sessions5.totp_checked_at,` + - ` projections.sessions5.otp_sms_checked_at,` + - ` projections.sessions5.otp_email_checked_at,` + - ` projections.sessions5.metadata,` + - ` projections.sessions5.token_id` + - ` FROM projections.sessions5` + - ` LEFT JOIN projections.login_names2 ON projections.sessions5.user_id = projections.login_names2.user_id AND projections.sessions5.instance_id = projections.login_names2.instance_id` + - ` LEFT JOIN projections.users8_humans ON projections.sessions5.user_id = projections.users8_humans.user_id AND projections.sessions5.instance_id = projections.users8_humans.instance_id` + - ` LEFT JOIN projections.users8 ON projections.sessions5.user_id = projections.users8.id AND projections.sessions5.instance_id = projections.users8.instance_id` + + ` projections.sessions6.password_checked_at,` + + ` projections.sessions6.intent_checked_at,` + + ` projections.sessions6.webauthn_checked_at,` + + ` projections.sessions6.webauthn_user_verified,` + + ` projections.sessions6.totp_checked_at,` + + ` projections.sessions6.otp_sms_checked_at,` + + ` projections.sessions6.otp_email_checked_at,` + + ` projections.sessions6.metadata,` + + ` projections.sessions6.token_id,` + + ` projections.sessions6.user_agent_fingerprint_id,` + + ` projections.sessions6.user_agent_ip,` + + ` projections.sessions6.user_agent_description,` + + ` projections.sessions6.user_agent_header` + + ` FROM projections.sessions6` + + ` LEFT JOIN projections.login_names2 ON projections.sessions6.user_id = projections.login_names2.user_id AND projections.sessions6.instance_id = projections.login_names2.instance_id` + + ` LEFT JOIN projections.users8_humans ON projections.sessions6.user_id = projections.users8_humans.user_id AND projections.sessions6.instance_id = projections.users8_humans.instance_id` + + ` LEFT JOIN projections.users8 ON projections.sessions6.user_id = projections.users8.id AND projections.sessions6.instance_id = projections.users8.instance_id` + ` AS OF SYSTEM TIME '-1 ms'`) - expectedSessionsQuery = regexp.QuoteMeta(`SELECT projections.sessions5.id,` + - ` projections.sessions5.creation_date,` + - ` projections.sessions5.change_date,` + - ` projections.sessions5.sequence,` + - ` projections.sessions5.state,` + - ` projections.sessions5.resource_owner,` + - ` projections.sessions5.creator,` + - ` projections.sessions5.user_id,` + - ` projections.sessions5.user_checked_at,` + + expectedSessionsQuery = regexp.QuoteMeta(`SELECT projections.sessions6.id,` + + ` projections.sessions6.creation_date,` + + ` projections.sessions6.change_date,` + + ` projections.sessions6.sequence,` + + ` projections.sessions6.state,` + + ` projections.sessions6.resource_owner,` + + ` projections.sessions6.creator,` + + ` projections.sessions6.user_id,` + + ` projections.sessions6.user_checked_at,` + ` projections.login_names2.login_name,` + ` projections.users8_humans.display_name,` + ` projections.users8.resource_owner,` + - ` projections.sessions5.password_checked_at,` + - ` projections.sessions5.intent_checked_at,` + - ` projections.sessions5.webauthn_checked_at,` + - ` projections.sessions5.webauthn_user_verified,` + - ` projections.sessions5.totp_checked_at,` + - ` projections.sessions5.otp_sms_checked_at,` + - ` projections.sessions5.otp_email_checked_at,` + - ` projections.sessions5.metadata,` + + ` projections.sessions6.password_checked_at,` + + ` projections.sessions6.intent_checked_at,` + + ` projections.sessions6.webauthn_checked_at,` + + ` projections.sessions6.webauthn_user_verified,` + + ` projections.sessions6.totp_checked_at,` + + ` projections.sessions6.otp_sms_checked_at,` + + ` projections.sessions6.otp_email_checked_at,` + + ` projections.sessions6.metadata,` + ` COUNT(*) OVER ()` + - ` FROM projections.sessions5` + - ` LEFT JOIN projections.login_names2 ON projections.sessions5.user_id = projections.login_names2.user_id AND projections.sessions5.instance_id = projections.login_names2.instance_id` + - ` LEFT JOIN projections.users8_humans ON projections.sessions5.user_id = projections.users8_humans.user_id AND projections.sessions5.instance_id = projections.users8_humans.instance_id` + - ` LEFT JOIN projections.users8 ON projections.sessions5.user_id = projections.users8.id AND projections.sessions5.instance_id = projections.users8.instance_id` + + ` FROM projections.sessions6` + + ` LEFT JOIN projections.login_names2 ON projections.sessions6.user_id = projections.login_names2.user_id AND projections.sessions6.instance_id = projections.login_names2.instance_id` + + ` LEFT JOIN projections.users8_humans ON projections.sessions6.user_id = projections.users8_humans.user_id AND projections.sessions6.instance_id = projections.users8_humans.instance_id` + + ` LEFT JOIN projections.users8 ON projections.sessions6.user_id = projections.users8.id AND projections.sessions6.instance_id = projections.users8.instance_id` + ` AS OF SYSTEM TIME '-1 ms'`) sessionCols = []string{ @@ -92,6 +99,10 @@ var ( "otp_email_checked_at", "metadata", "token", + "user_agent_fingerprint_id", + "user_agent_ip", + "user_agent_description", + "user_agent_header", } sessionsCols = []string{ @@ -443,6 +454,10 @@ func Test_SessionPrepare(t *testing.T) { testNow, []byte(`{"key": "dmFsdWU="}`), "tokenID", + "fingerPrintID", + "1.2.3.4", + "agentDescription", + []byte(`{"foo":["foo","bar"]}`), }, ), }, @@ -483,6 +498,12 @@ func Test_SessionPrepare(t *testing.T) { Metadata: map[string][]byte{ "key": []byte("value"), }, + UserAgent: domain.UserAgent{ + FingerprintID: gu.Ptr("fingerPrintID"), + IP: net.IPv4(1, 2, 3, 4), + Description: gu.Ptr("agentDescription"), + Header: http.Header{"foo": []string{"foo", "bar"}}, + }, }, }, { diff --git a/internal/repository/session/session.go b/internal/repository/session/session.go index c34ef5242..1966c178e 100644 --- a/internal/repository/session/session.go +++ b/internal/repository/session/session.go @@ -35,6 +35,7 @@ const ( type AddedEvent struct { eventstore.BaseEvent `json:"-"` + UserAgent *domain.UserAgent `json:"user_agent,omitempty"` } func (e *AddedEvent) Data() interface{} { @@ -47,6 +48,7 @@ func (e *AddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { func NewAddedEvent(ctx context.Context, aggregate *eventstore.Aggregate, + userAgent *domain.UserAgent, ) *AddedEvent { return &AddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( @@ -54,6 +56,7 @@ func NewAddedEvent(ctx context.Context, aggregate, AddedType, ), + UserAgent: userAgent, } } diff --git a/proto/zitadel/session/v2beta/session.proto b/proto/zitadel/session/v2beta/session.proto index ddbe14336..b0bfd4fb1 100644 --- a/proto/zitadel/session/v2beta/session.proto +++ b/proto/zitadel/session/v2beta/session.proto @@ -39,6 +39,7 @@ message Session { description: "\"custom key value list\""; } ]; + UserAgent user_agent = 7; } message Factors { @@ -131,3 +132,18 @@ message SearchQuery { message IDsQuery { repeated string ids = 1; } + +message UserAgent { + optional string fingerprint_id = 1; + optional string ip = 2; + optional string description = 3; + + // A header may have multiple values. + // In Go, headers are defined + // as map[string][]string, but protobuf + // doesn't allow this scheme. + message HeaderValues { + repeated string values = 1; + } + map header = 4; +} \ No newline at end of file diff --git a/proto/zitadel/session/v2beta/session_service.proto b/proto/zitadel/session/v2beta/session_service.proto index 745c43001..718a29381 100644 --- a/proto/zitadel/session/v2beta/session_service.proto +++ b/proto/zitadel/session/v2beta/session_service.proto @@ -274,6 +274,7 @@ message CreateSessionRequest{ } ]; RequestChallenges challenges = 3; + UserAgent user_agent = 4; } message CreateSessionResponse{ From 53034a5fb1e9614f9bf5d6d35e6c76856b468bca Mon Sep 17 00:00:00 2001 From: mffap Date: Thu, 12 Oct 2023 15:08:38 +0200 Subject: [PATCH 02/15] docs(legal): onboarding support services (#6665) * docs(legal): onboarding support services * remove trainings, outline * wip * finish * call to action * Apply suggestions from code review Co-authored-by: Florian Forster --------- Co-authored-by: Florian Forster --- docs/docs/legal/onboarding-support.md | 87 +++++++++++++++++++++ docs/docs/legal/support-services.md | 5 +- docs/docs/support/trainings/application.md | 36 --------- docs/docs/support/trainings/introduction.md | 30 ------- docs/docs/support/trainings/project.md | 35 --------- docs/docs/support/trainings/recurring.md | 33 -------- docs/sidebars.js | 17 ++-- 7 files changed, 96 insertions(+), 147 deletions(-) create mode 100644 docs/docs/legal/onboarding-support.md delete mode 100644 docs/docs/support/trainings/application.md delete mode 100644 docs/docs/support/trainings/introduction.md delete mode 100644 docs/docs/support/trainings/project.md delete mode 100644 docs/docs/support/trainings/recurring.md diff --git a/docs/docs/legal/onboarding-support.md b/docs/docs/legal/onboarding-support.md new file mode 100644 index 000000000..e9c76ac38 --- /dev/null +++ b/docs/docs/legal/onboarding-support.md @@ -0,0 +1,87 @@ +--- +title: Description of onboarding support services for ZITADEL +sidebar_label: Onboarding support +custom_edit_url: null +--- + +This annex of the [Framework Agreement](terms-of-service) describes the onboarding support services offered by us for our services. + +Last revised: October 12, 2023 + +Our onboarding support should help you, as a new customer, to get a better understanding on how to integrate ZITADEL into your solution, how to tackle the migration, and ensure a highly-available day-to-day operation. + +Onboarding support services can be offered to customers that enter a ZITADEL Cloud or a ZITADEL Enterprise subscription. + +If you intend to use the open source version exclusively then please join our community chat or Github. +Your questions might help other people in the community and will make our project better over time. + +Please [contact us](https://zitadel.com/contact) for a quote and to get started with onboarding support. +Below you will find topics covered and scope of the offered services. + +## Proof of value + +Within a short time-frame, f.e. 3 weeks, we can show the value of using our services and have the ability to establish the proof a of working setup for your most critical use cases. +We may offer to support you during an initial period to evaluate next steps. +Before the start of the period we may ask you to provide a description of your critical use cases and a high-level overview of your planned integration architecture. +During this period you should make sure that you have the necessary resources on your side to complete the proof of value. + +## Onboarding term + +With the onboarding support we provide the initial knowledge transfer to configure and operate ZITADEL. +During the term you will get direct access to our engineering team via [Technical Account Management](./support-services.md#technical-account-manager). +Duration is typically 3 months but this could vary depending on your requirements. + +We offer an onboarding term in combination with ZITADEL Enterprise subscriptions. + +### Topics covered + +Topics of the onboarding term may include: + +- Administration +- DevOps (Operation) +- Architecture +- Integration +- Migration +- Security Best Practices & Go-Live Checkup + +The scope will be tailored to your requirements. + +More details + +- IAM Configuration +- Walk-though all features +- Users / Manuals +- Authentication & Management APIs +- Validation of tokens +- Client integration best-practices +- Event types +- Database schemas and compute models +- Accessing database +- Observability (Logs, Errors, Metrics, Tracing) +- Operations best practices (Deployment, Backup, Networking etc.) +- Check prerequisites and architecture +- Troubleshoot installation and configuration of ZITADEL +- Troubleshoot and configuration connectivity to the database +- Functional testing of the ZITADEL instance + +
+ Out of scope +
    +
  • Performance testing
  • +
  • Setting up or maintaining backup storage
  • +
  • Running multiple ZITADEL instances on the same cluster
  • +
  • Integration into internal monitoring and alerting
  • +
  • Multi-cluster architecture deployments
  • +
  • DNS, Network and Firewall configuration
  • +
  • Customer-specific Kubernetes configuration needs
  • +
  • Non-production environments
  • +
  • Production deployment
  • +
  • Application-side coding, configuration, or tuning
  • + +
+
+ +## Continuous support + +After the onboarding phase has ended we will provide continuous support according to your subscription. +We can provide you with continued access to the technical account management in our Enterprise subscriptions. diff --git a/docs/docs/legal/support-services.md b/docs/docs/legal/support-services.md index 1c0f36b3f..1a6f0a155 100644 --- a/docs/docs/legal/support-services.md +++ b/docs/docs/legal/support-services.md @@ -10,7 +10,7 @@ This annex of the [Framework Agreement](terms-of-service) and the [Support Servi Support Services for products and services provided by ZITADEL is offered to customers according to the terms and conditions outlined in this document. The customer may purchase support services from ZITADEL (CAOS Ltd.) directly. -Last revised: March 15, 2023 +Last revised: October 6, 2023 ## Support Services @@ -82,7 +82,8 @@ Phone Support | +41 43 215 27 34 ZITADEL will enhance its support offering by providing eligible clients with a Technical Account Manager (TAM), who will perform the following tasks for up to the specified amount of time per week during the term of service: - Provide support and advice regarding best practices on platform, product and configuration covered by the applicable Support Services; -- Participate in review calls every other week at mutually agreed times addressing customer’s operational issues. +- Participate in review calls every other week at mutually agreed times addressing customer’s operational challenges or complex support requests; +- Walk-through of new features and customer feedback. We offer TAM services only bundled with specific subscription plans, and the option to add more TAM hours to these plans. If you require consulting for your projects, please request a quote via our [website](https://zitadel.com/contact). diff --git a/docs/docs/support/trainings/application.md b/docs/docs/support/trainings/application.md deleted file mode 100644 index cf313bb96..000000000 --- a/docs/docs/support/trainings/application.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: Application Support Trainings ---- - -## ZITADEL DevOps - -In this session your second level support and operations team will gain an understanding on how to extract relevant information for technical support questions and root cause analysis. We will also present our DevOps best practices and answer your questions. - -**Audience**: 2nd Level Support Staff, Operations -**Duration**: 0.5 day - -**Topics covered**: - -- Event types -- Database schemas and compute models -- Accessing database -- Observability (Logs, Errors, Metrics, Tracing) -- Operations best practices (Deployment, Backup, Networking etc.) -- Q&A - -## ZITADEL Administrator - -In this hands-on training your employees will get a complete overview of the system and learn how to configure and use ZITADEL. Your support staff will gain the required knowledge to provide user-support, while your solution owners gain an understanding about integration of clients. - -**Audience**: 1st / 2nd Level Support Staff, Solution Owner, QA Manager (optional) -**Duration**: 0.5 days - -**Topics covered**: - -- IAM Configuration -- Walk-though all features -- Users / Manuals -- APIs -- Validation of tokens -- Client integration best-practices -- Q&A diff --git a/docs/docs/support/trainings/introduction.md b/docs/docs/support/trainings/introduction.md deleted file mode 100644 index c597470f3..000000000 --- a/docs/docs/support/trainings/introduction.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: ZITADEL Trainings -sidebar_label: Introduction ---- - -The following pages describe the the trainings provided by ZITADEL. These trainings are intended for onboarding and during the course of a Support Program. - -Training should be held as block-sessions with the relevant staff from your organization. - -## Onboarding Project - -You receive professional onboarding support from our engineers, who help you to setup and configure ZITADEL on your infrastructure. - -[More information](project) - -## Application Support Trainings - -With the application support trainings we provide the initial knowledge transfer to manage and support ZITADEL. The trainings are held as block-sessions with relevant staff from your organization. Prices are flat-fee, excl. expenses. - -* [ZITADEL DevOps](application#zitadel-devops) -* [ZITADEL Administrator](application#zitadel-administrator) - -## Recurring Trainings - -While you can benefit from a technical account manager during your term, these trainings are designed to onboard new staff or update staff about larger changes to the platform. Prices are flat-fee, excl. expenses. - -* [ZITADEL Support Refresher](recurring#zitadel-support-refresher) -* [ZITADEL Support Onboarding](recurring#zitadel-support-onboarding) - -In case you have any questions please [get in touch](https://zitadel.com/contact). diff --git a/docs/docs/support/trainings/project.md b/docs/docs/support/trainings/project.md deleted file mode 100644 index 35f3259b4..000000000 --- a/docs/docs/support/trainings/project.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Onboarding Project ---- - -Effort required during depends on the complexity of your infrastructure and the overall setup. With a Multi-Zone Setup (excl. Multi-Region), support during this phase requires around 10-25h over 2 weeks. Actual effort is based on time and material. - -Scope of the project is agreed on individual basis. - -## In Scope - -- Check prerequisites and architecture -- Troubleshoot installation and configuration of ZITADEL -- Troubleshoot and configuration connectivity to the database -- Functional testing of the ZITADEL instance - -## Out of Scope - -- Running multiple ZITADEL instances on the same cluster -- Integration into internal monitoring and alerting -- Multi-cluster architecture deployments -- DNS, Network and Firewall configuration -- Customer-specific Kubernetes configuration needs -- Changes for specific environments -- Performance testing -- Production deployment -- Application-side coding, configuration, or tuning -- Changes or configuration on assets used in ZITADEL -- Setting up or maintaining backup storage - -## Prerequisites - -- Running Kubernetes with possibility to deploy to namespaces -- Inbound and outbound HTTP/2 traffic possible -- For being able to send SMS, we need a Twilio sender name, SID and an auth token -- ZITADEL also needs to connect to an email relay of your choice. We need the SMTP host, user and app key as well as the ZITADEL emails sender address and name. diff --git a/docs/docs/support/trainings/recurring.md b/docs/docs/support/trainings/recurring.md deleted file mode 100644 index 29982cf62..000000000 --- a/docs/docs/support/trainings/recurring.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Recurring Trainings ---- - -## ZITADEL Support Refresher - -In this session you can refresh knowledge about existing and gain experience with new features of ZITADEL to keep the quality of your support high. We recommend an half day training per support staff. - -**Audience**: 1st / 2nd Level Support Staff, Solution Owner, QA Manager (optional) -**Duration**: 0.5 day / support staff - -**Topics covered**: - -* Walk-through new features -* Review of difficult support issues -* Review of customer feedback -* Q&A - -## ZITADEL Support Onboarding - -In this hands-on training new support staff will get an overview of the system and learn how to configure and use ZITADEL to provide support for users. - -**Audience**: 1st / 2nd Level Support Staff, Solution Owner, QA Manager (optional) -**Duration**: 0.5 days / support staff - -**Topics covered**: - -* Event types -* Accessing database -* Logs and Errors -* Validation of tokens -* Walk-through key features -* Q&A diff --git a/docs/sidebars.js b/docs/sidebars.js index 1c82d8285..a2ba179c8 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -425,6 +425,11 @@ module.exports = { items: [ "support/software-release-cycles-support", "support/troubleshooting", + { + type: 'link', + label: 'Support Service Descriptions', + href: '/legal/support-services', + }, { type: 'category', label: "Technical Advisory", @@ -440,17 +445,6 @@ module.exports = { }, ], }, - { - type: "category", - label: "Trainings", - collapsed: true, - items: [ - "support/trainings/introduction", - "support/trainings/application", - "support/trainings/recurring", - "support/trainings/project", - ], - }, ] }, ], @@ -697,6 +691,7 @@ module.exports = { "legal/cloud-service-description", "legal/service-level-description", "legal/support-services", + "legal/onboarding-support", ], }, { From b24e120c66081be2396b097bfada30e000d3296e Mon Sep 17 00:00:00 2001 From: Austin Turner Date: Thu, 12 Oct 2023 09:12:22 -0600 Subject: [PATCH 03/15] fix: typo in verify email default text (#6694) Fix typo in Verify email default text Co-authored-by: Elio Bischof --- cmd/defaults.yaml | 2 +- proto/zitadel/admin.proto | 2 +- proto/zitadel/management.proto | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/defaults.yaml b/cmd/defaults.yaml index 891828941..abceff1f6 100644 --- a/cmd/defaults.yaml +++ b/cmd/defaults.yaml @@ -735,7 +735,7 @@ DefaultInstance: PreHeader: Verify email Subject: Verify email Greeting: Hello {{.DisplayName}}, - Text: A new email has been added. Please use the button below to verify your mail. (Code {{.Code}}) If you din't add a new email, please ignore this email. + Text: A new email has been added. Please use the button below to verify your email. (Code {{.Code}}) If you din't add a new email, please ignore this email. ButtonText: Verify email - MessageTextType: VerifyPhone Language: en diff --git a/proto/zitadel/admin.proto b/proto/zitadel/admin.proto index 620936f12..ea183aa3f 100644 --- a/proto/zitadel/admin.proto +++ b/proto/zitadel/admin.proto @@ -6837,7 +6837,7 @@ message SetDefaultVerifyEmailMessageTextRequest { string text = 6 [ (validate.rules).string = {max_bytes: 40000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { - example: "\"A new email has been added. Please use the button below to verify your mail. (Code {{.Code}}) If you didn't add a new email, please ignore this email.\"" + example: "\"A new email has been added. Please use the button below to verify your email. (Code {{.Code}}) If you didn't add a new email, please ignore this email.\"" max_length: 10000; } ]; diff --git a/proto/zitadel/management.proto b/proto/zitadel/management.proto index 6770f7742..7741224fa 100644 --- a/proto/zitadel/management.proto +++ b/proto/zitadel/management.proto @@ -10914,7 +10914,7 @@ message SetCustomVerifyEmailMessageTextRequest { string text = 6 [ (validate.rules).string = {max_bytes: 40000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { - example: "\"A new email has been added. Please use the button below to verify your mail. (Code {{.Code}}) If you didn't add a new email, please ignore this email.\"" + example: "\"A new email has been added. Please use the button below to verify your email. (Code {{.Code}}) If you didn't add a new email, please ignore this email.\"" max_length: 10000; } ]; From 831a21a6e221ac6c4cbad7a87726e39bebf1f34e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Oct 2023 16:51:50 +0000 Subject: [PATCH 04/15] chore(deps): bump node from 18-buster to 20-buster in /build (#6258) Bumps node from 18-buster to 20-buster. --- updated-dependencies: - dependency-name: node dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build/workflow.Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/workflow.Dockerfile b/build/workflow.Dockerfile index c9fb7e6c2..db27daf91 100644 --- a/build/workflow.Dockerfile +++ b/build/workflow.Dockerfile @@ -103,7 +103,7 @@ COPY --from=core-assets /go/src/github.com/zitadel/zitadel/internal ./internal # ####################################### # download console dependencies # ####################################### -FROM node:18-buster AS console-deps +FROM node:20-buster AS console-deps WORKDIR /zitadel/console @@ -115,7 +115,7 @@ RUN yarn install --frozen-lockfile # ####################################### # generate console client # ####################################### -FROM node:18-buster AS console-client +FROM node:20-buster AS console-client WORKDIR /zitadel/console From 5a9609ef29cb724f65f711f580917788fba728b7 Mon Sep 17 00:00:00 2001 From: cpli <34531687+gwimm@users.noreply.github.com> Date: Fri, 13 Oct 2023 07:31:23 +0000 Subject: [PATCH 05/15] feat(actions): add "zitadel/uuid" module (#6135) * feat: add "zitadel/uuid" module * feat(actions/uuid): add v1, v3, and v4 UUIDs * add namespaces and improve hash based functions * add docs --------- Co-authored-by: Florian Forster Co-authored-by: Livio Spring --- docs/docs/apis/actions/modules.md | 55 +++++++++++++++++ internal/actions/uuid_module.go | 83 ++++++++++++++++++++++++++ internal/api/oidc/client.go | 4 +- internal/api/ui/login/custom_action.go | 8 +-- 4 files changed, 144 insertions(+), 6 deletions(-) create mode 100644 internal/actions/uuid_module.go diff --git a/docs/docs/apis/actions/modules.md b/docs/docs/apis/actions/modules.md index 2cc99a222..6624ff9de 100644 --- a/docs/docs/apis/actions/modules.md +++ b/docs/docs/apis/actions/modules.md @@ -51,3 +51,58 @@ The object has the following fields and methods: Returns the body as JSON object, or throws an error if the body is not a json object. - `text()` *string* Returns the body + +## UUID + +This module provides functionality to generate a UUID + +### Import + +```js + let uuid = require("zitadel/uuid") +``` + +### `uuid.vX()` function + +This function generates a UUID using [google/uuid](https://github.com/google/uuid). `vX` allows to define the UUID version: + +- `uuid.v1()` *string* + Generates a UUID version 1, based on date-time and MAC address +- `uuid.v3(namespace, data)` *string* + Generates a UUID version 3, based on the provided namespace using MD5 +- `uuid.v4()` *string* + Generates a UUID version 4, which is randomly generated +- `uuid.v5(namespace, data)` *string* + Generates a UUID version 5, based on the provided namespace using SHA1 + +#### Parameters + +- `namespace` *UUID*/*string* + Namespace to be used in the hashing function. Either provide one of defined [namespaces](#namespaces) or a string representing a UUID. +- `data` *[]byte*/*string* + data to be used in the hashing function. Possible types are []byte or string. + +### Namespaces + +The following predefined namespaces can be used for `uuid.v3` and `uuid.v5`: + +- `uuid.namespaceDNS` *UUID* + 6ba7b810-9dad-11d1-80b4-00c04fd430c8 +- `uuid.namespaceURL` *UUID* + 6ba7b811-9dad-11d1-80b4-00c04fd430c8 +- `uuid.namespaceOID` *UUID* + 6ba7b812-9dad-11d1-80b4-00c04fd430c8 +- `uuid.namespaceX500` *UUID* + 6ba7b814-9dad-11d1-80b4-00c04fd430c8 + +### Example +```js +let uuid = require("zitadel/uuid") +function setUUID(ctx, api) { + if (api.metadata === undefined) { + return; + } + + api.v1.user.appendMetadata('custom-id', uuid.v4()); +} +``` \ No newline at end of file diff --git a/internal/actions/uuid_module.go b/internal/actions/uuid_module.go new file mode 100644 index 000000000..15d299212 --- /dev/null +++ b/internal/actions/uuid_module.go @@ -0,0 +1,83 @@ +package actions + +import ( + "context" + + "github.com/dop251/goja" + "github.com/google/uuid" + "github.com/zitadel/logging" +) + +func WithUUID(ctx context.Context) Option { + return func(c *runConfig) { + c.modules["zitadel/uuid"] = func(runtime *goja.Runtime, module *goja.Object) { + requireUUID(ctx, runtime, module) + } + } +} + +func requireUUID(_ context.Context, runtime *goja.Runtime, module *goja.Object) { + o := module.Get("exports").(*goja.Object) + logging.OnError(o.Set("v1", inRuntime(uuid.NewUUID, runtime))).Warn("unable to set module") + logging.OnError(o.Set("v3", inRuntimeHash(uuid.NewMD5, runtime))).Warn("unable to set module") + logging.OnError(o.Set("v4", inRuntime(uuid.NewRandom, runtime))).Warn("unable to set module") + logging.OnError(o.Set("v5", inRuntimeHash(uuid.NewSHA1, runtime))).Warn("unable to set module") + logging.OnError(o.Set("namespaceDNS", uuid.NameSpaceDNS)).Warn("unable to set namespace") + logging.OnError(o.Set("namespaceURL", uuid.NameSpaceURL)).Warn("unable to set namespace") + logging.OnError(o.Set("namespaceOID", uuid.NameSpaceOID)).Warn("unable to set namespace") + logging.OnError(o.Set("namespaceX500", uuid.NameSpaceX500)).Warn("unable to set namespace") +} + +func inRuntime(function func() (uuid.UUID, error), runtime *goja.Runtime) func(call goja.FunctionCall) goja.Value { + return func(call goja.FunctionCall) goja.Value { + if len(call.Arguments) != 0 { + panic("invalid arg count") + } + + uuid, err := function() + if err != nil { + logging.WithError(err) + panic(err) + } + + return runtime.ToValue(uuid.String()) + } +} + +func inRuntimeHash(function func(uuid.UUID, []byte) uuid.UUID, runtime *goja.Runtime) func(call goja.FunctionCall) goja.Value { + return func(call goja.FunctionCall) goja.Value { + if len(call.Arguments) != 2 { + logging.WithFields("count", len(call.Arguments)).Debug("other than 2 args provided") + panic("invalid arg count") + } + + var err error + var namespace uuid.UUID + switch n := call.Arguments[0].Export().(type) { + case string: + namespace, err = uuid.Parse(n) + if err != nil { + logging.WithError(err).Debug("namespace failed parsing as UUID") + panic(err) + } + case uuid.UUID: + namespace = n + default: + logging.WithError(err).Debug("invalid type for namespace") + panic(err) + } + + var data []byte + switch d := call.Arguments[1].Export().(type) { + case string: + data = []byte(d) + case []byte: + data = d + default: + logging.WithError(err).Debug("invalid type for data") + panic(err) + } + + return runtime.ToValue(function(namespace, data).String()) + } +} diff --git a/internal/api/oidc/client.go b/internal/api/oidc/client.go index 6a8dc6be6..4bfbb6449 100644 --- a/internal/api/oidc/client.go +++ b/internal/api/oidc/client.go @@ -564,7 +564,7 @@ func (o *OPStorage) userinfoFlows(ctx context.Context, user *query.User, userGra apiFields, action.Script, action.Name, - append(actions.ActionToOptions(action), actions.WithHTTP(actionCtx))..., + append(actions.ActionToOptions(action), actions.WithHTTP(actionCtx), actions.WithUUID(actionCtx))..., ) cancel() if err != nil { @@ -745,7 +745,7 @@ func (o *OPStorage) privateClaimsFlows(ctx context.Context, userID string, userG apiFields, action.Script, action.Name, - append(actions.ActionToOptions(action), actions.WithHTTP(actionCtx))..., + append(actions.ActionToOptions(action), actions.WithHTTP(actionCtx), actions.WithUUID(actionCtx))..., ) cancel() if err != nil { diff --git a/internal/api/ui/login/custom_action.go b/internal/api/ui/login/custom_action.go index 516f7bc3d..22b3f72cc 100644 --- a/internal/api/ui/login/custom_action.go +++ b/internal/api/ui/login/custom_action.go @@ -133,7 +133,7 @@ func (l *Login) runPostExternalAuthenticationActions( apiFields, a.Script, a.Name, - append(actions.ActionToOptions(a), actions.WithHTTP(actionCtx))..., + append(actions.ActionToOptions(a), actions.WithHTTP(actionCtx), actions.WithUUID(actionCtx))..., ) cancel() if err != nil { @@ -206,7 +206,7 @@ func (l *Login) runPostInternalAuthenticationActions( apiFields, a.Script, a.Name, - append(actions.ActionToOptions(a), actions.WithHTTP(actionCtx))..., + append(actions.ActionToOptions(a), actions.WithHTTP(actionCtx), actions.WithUUID(actionCtx))..., ) cancel() if err != nil { @@ -307,7 +307,7 @@ func (l *Login) runPreCreationActions( apiFields, a.Script, a.Name, - append(actions.ActionToOptions(a), actions.WithHTTP(actionCtx))..., + append(actions.ActionToOptions(a), actions.WithHTTP(actionCtx), actions.WithUUID(actionCtx))..., ) cancel() if err != nil { @@ -365,7 +365,7 @@ func (l *Login) runPostCreationActions( apiFields, a.Script, a.Name, - append(actions.ActionToOptions(a), actions.WithHTTP(actionCtx))..., + append(actions.ActionToOptions(a), actions.WithHTTP(actionCtx), actions.WithUUID(actionCtx))..., ) cancel() if err != nil { From 27e03120dce9b9fb7eb4f0d6ff6b2017f4be71a0 Mon Sep 17 00:00:00 2001 From: Livio Spring Date: Fri, 13 Oct 2023 14:31:39 +0300 Subject: [PATCH 06/15] fix(api): extend client_secret length for generic oauth and oidc providers to 1000 (#6722) --- proto/zitadel/admin.proto | 8 ++++---- proto/zitadel/management.proto | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/proto/zitadel/admin.proto b/proto/zitadel/admin.proto index ea183aa3f..4fce496fe 100644 --- a/proto/zitadel/admin.proto +++ b/proto/zitadel/admin.proto @@ -4887,7 +4887,7 @@ message AddGenericOAuthProviderRequest { } ]; string client_secret = 3 [ - (validate.rules).string = {min_len: 1, max_len: 200}, + (validate.rules).string = {min_len: 1, max_len: 1000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"client-secret\""; description: "Client secret generated by the identity provider"; @@ -4954,7 +4954,7 @@ message UpdateGenericOAuthProviderRequest { ]; // client_secret will only be updated if provided string client_secret = 4 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_len: 1000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"client-secret\""; description: "Client secret will only be updated if provided"; @@ -5025,7 +5025,7 @@ message AddGenericOIDCProviderRequest { } ]; string client_secret = 4 [ - (validate.rules).string = {min_len: 1, max_len: 200}, + (validate.rules).string = {min_len: 1, max_len: 1000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"secret\""; description: "secret generated by the identity provider" @@ -5076,7 +5076,7 @@ message UpdateGenericOIDCProviderRequest { ]; // client_secret will only be updated if provided string client_secret = 5 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_len: 1000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"secret\""; description: "client secret will only be updated if provided"; diff --git a/proto/zitadel/management.proto b/proto/zitadel/management.proto index 7741224fa..9f2e35f2c 100644 --- a/proto/zitadel/management.proto +++ b/proto/zitadel/management.proto @@ -11759,7 +11759,7 @@ message AddGenericOAuthProviderRequest { } ]; string client_secret = 3 [ - (validate.rules).string = {min_len: 1, max_len: 200}, + (validate.rules).string = {min_len: 1, max_len: 1000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"client-secret\""; description: "Client secret generated by the identity provider"; @@ -11826,7 +11826,7 @@ message UpdateGenericOAuthProviderRequest { ]; // client_secret will only be updated if provided string client_secret = 4 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_len: 1000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"client-secret\""; description: "Client secret will only be updated if provided"; @@ -11897,7 +11897,7 @@ message AddGenericOIDCProviderRequest { } ]; string client_secret = 4 [ - (validate.rules).string = {min_len: 1, max_len: 200}, + (validate.rules).string = {min_len: 1, max_len: 1000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"secret\""; description: "secret generated by the identity provider" @@ -11948,7 +11948,7 @@ message UpdateGenericOIDCProviderRequest { ]; // client_secret will only be updated if provided string client_secret = 5 [ - (validate.rules).string = {max_len: 200}, + (validate.rules).string = {max_len: 1000}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { example: "\"secret\""; description: "client secret will only be updated if provided"; From 95889cf576519e71d818fd0f1ed7452a20c5f3d6 Mon Sep 17 00:00:00 2001 From: Livio Spring Date: Fri, 13 Oct 2023 15:37:35 +0300 Subject: [PATCH 07/15] fix(api): use organization instead of organisation (#6720) * fix(api): use organization instead of organisation * fix test * docs: add deprecation notice * remove validation --- .../server/middleware/auth_interceptor.go | 40 ++++++++++++++----- internal/api/grpc/session/v2/session.go | 1 + internal/api/grpc/session/v2/session_test.go | 7 +++- .../protoc-gen-zitadel/zitadel.pb.go.tmpl | 4 +- .../v2beta/user_service_org.pb.zitadel.go | 12 ++++++ proto/zitadel/admin.proto | 2 +- proto/zitadel/management.proto | 4 +- proto/zitadel/object/v2beta/object.proto | 8 ++++ proto/zitadel/project.proto | 2 +- proto/zitadel/session/v2beta/session.proto | 8 +++- proto/zitadel/user/v2beta/user_service.proto | 10 ++++- 11 files changed, 79 insertions(+), 19 deletions(-) create mode 100644 pkg/grpc/user/v2beta/user_service_org.pb.zitadel.go diff --git a/internal/api/grpc/server/middleware/auth_interceptor.go b/internal/api/grpc/server/middleware/auth_interceptor.go index 96426e857..d2a81203e 100644 --- a/internal/api/grpc/server/middleware/auth_interceptor.go +++ b/internal/api/grpc/server/middleware/auth_interceptor.go @@ -33,12 +33,7 @@ func authorize(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, return nil, status.Error(codes.Unauthenticated, "auth header missing") } - var orgDomain string - orgID := grpc_util.GetHeader(authCtx, http.ZitadelOrgID) - if o, ok := req.(OrganisationFromRequest); ok { - orgID = o.OrganisationFromRequest().ID - orgDomain = o.OrganisationFromRequest().Domain - } + orgID, orgDomain := orgIDAndDomainFromRequest(authCtx, req) ctxSetter, err := authz.CheckUserAuthorization(authCtx, req, authToken, orgID, orgDomain, verifier, authConfig, authOpt, info.FullMethod) if err != nil { return nil, err @@ -47,11 +42,38 @@ func authorize(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, return handler(ctxSetter(ctx), req) } -type OrganisationFromRequest interface { - OrganisationFromRequest() *Organisation +func orgIDAndDomainFromRequest(ctx context.Context, req interface{}) (id, domain string) { + orgID := grpc_util.GetHeader(ctx, http.ZitadelOrgID) + o, ok := req.(OrganizationFromRequest) + if !ok { + return orgID, "" + } + id = o.OrganizationFromRequest().ID + domain = o.OrganizationFromRequest().Domain + if id != "" || domain != "" { + return id, domain + } + // check if the deprecated organisation is used. + // to be removed before going GA (https://github.com/zitadel/zitadel/issues/6718) + id = o.OrganisationFromRequest().ID + domain = o.OrganisationFromRequest().Domain + if id != "" || domain != "" { + return id, domain + } + return orgID, domain } -type Organisation struct { +// Deprecated: will be removed in favor of OrganizationFromRequest (https://github.com/zitadel/zitadel/issues/6718) +type OrganisationFromRequest interface { + OrganisationFromRequest() *Organization +} + +type Organization struct { ID string Domain string } + +type OrganizationFromRequest interface { + OrganizationFromRequest() *Organization + OrganisationFromRequest +} diff --git a/internal/api/grpc/session/v2/session.go b/internal/api/grpc/session/v2/session.go index be6907ae0..f98983936 100644 --- a/internal/api/grpc/session/v2/session.go +++ b/internal/api/grpc/session/v2/session.go @@ -216,6 +216,7 @@ func userFactorToPb(factor query.SessionUserFactor) *session.UserFactor { LoginName: factor.LoginName, DisplayName: factor.DisplayName, OrganisationId: factor.ResourceOwner, + OrganizationId: factor.ResourceOwner, } } diff --git a/internal/api/grpc/session/v2/session_test.go b/internal/api/grpc/session/v2/session_test.go index ae33fab4c..8422b675b 100644 --- a/internal/api/grpc/session/v2/session_test.go +++ b/internal/api/grpc/session/v2/session_test.go @@ -10,10 +10,11 @@ import ( "github.com/muhlemmer/gu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/zitadel/internal/api/authz" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" + "github.com/zitadel/zitadel/internal/api/authz" + "github.com/zitadel/zitadel/internal/domain" caos_errs "github.com/zitadel/zitadel/internal/errors" "github.com/zitadel/zitadel/internal/query" @@ -151,6 +152,7 @@ func Test_sessionsToPb(t *testing.T) { LoginName: "donald", DisplayName: "donald duck", OrganisationId: "org1", + OrganizationId: "org1", }, }, Metadata: map[string][]byte{"hello": []byte("world")}, @@ -167,6 +169,7 @@ func Test_sessionsToPb(t *testing.T) { LoginName: "donald", DisplayName: "donald duck", OrganisationId: "org1", + OrganizationId: "org1", }, Password: &session.PasswordFactor{ VerifiedAt: timestamppb.New(past), @@ -186,6 +189,7 @@ func Test_sessionsToPb(t *testing.T) { LoginName: "donald", DisplayName: "donald duck", OrganisationId: "org1", + OrganizationId: "org1", }, WebAuthN: &session.WebAuthNFactor{ VerifiedAt: timestamppb.New(past), @@ -206,6 +210,7 @@ func Test_sessionsToPb(t *testing.T) { LoginName: "donald", DisplayName: "donald duck", OrganisationId: "org1", + OrganizationId: "org1", }, Totp: &session.TOTPFactor{ VerifiedAt: timestamppb.New(past), diff --git a/internal/protoc/protoc-gen-zitadel/zitadel.pb.go.tmpl b/internal/protoc/protoc-gen-zitadel/zitadel.pb.go.tmpl index bc0123c75..adb71c42f 100644 --- a/internal/protoc/protoc-gen-zitadel/zitadel.pb.go.tmpl +++ b/internal/protoc/protoc-gen-zitadel/zitadel.pb.go.tmpl @@ -17,8 +17,8 @@ var {{.ServiceName}}_AuthMethods = authz.MethodMapping { } {{ range $m := .AuthContext}} -func (r *{{ $m.Name }}) OrganisationFromRequest() *middleware.Organisation { - return &middleware.Organisation{ +func (r *{{ $m.Name }}) OrganizationFromRequest() *middleware.Organization { + return &middleware.Organization{ ID: r{{$m.OrgMethod}}.GetOrgId(), Domain: r{{$m.OrgMethod}}.GetOrgDomain(), } diff --git a/pkg/grpc/user/v2beta/user_service_org.pb.zitadel.go b/pkg/grpc/user/v2beta/user_service_org.pb.zitadel.go new file mode 100644 index 000000000..fe2509bd9 --- /dev/null +++ b/pkg/grpc/user/v2beta/user_service_org.pb.zitadel.go @@ -0,0 +1,12 @@ +package user + +import "github.com/zitadel/zitadel/internal/api/grpc/server/middleware" + +// OrganisationFromRequest implements deprecated [middleware.OrganisationFromRequest] interface. +// it will be removed before going GA (https://github.com/zitadel/zitadel/issues/6718) +func (r *AddHumanUserRequest) OrganisationFromRequest() *middleware.Organization { + return &middleware.Organization{ + ID: r.GetOrganisation().GetOrgId(), + Domain: r.GetOrganisation().GetOrgDomain(), + } +} diff --git a/proto/zitadel/admin.proto b/proto/zitadel/admin.proto index 4fce496fe..c1f32616b 100644 --- a/proto/zitadel/admin.proto +++ b/proto/zitadel/admin.proto @@ -3763,7 +3763,7 @@ service AdminService { // Activates the "LoginDefaultOrg" feature by setting the flag to "true" // This is irreversible! - // Once activated, the login UI will use the settings of the default org (and not from the instance) if not organisation context is set + // Once activated, the login UI will use the settings of the default org (and not from the instance) if not organization context is set rpc ActivateFeatureLoginDefaultOrg(ActivateFeatureLoginDefaultOrgRequest) returns (ActivateFeatureLoginDefaultOrgResponse) { option (google.api.http) = { put: "/features/login_default_org" diff --git a/proto/zitadel/management.proto b/proto/zitadel/management.proto index 9f2e35f2c..6a17b3cf5 100644 --- a/proto/zitadel/management.proto +++ b/proto/zitadel/management.proto @@ -6806,7 +6806,7 @@ service ManagementService { }; } - // Add a new Azure AD identity provider in the organisation + // Add a new Azure AD identity provider in the organization rpc AddAzureADProvider(AddAzureADProviderRequest) returns (AddAzureADProviderResponse) { option (google.api.http) = { post: "/idps/azure" @@ -6824,7 +6824,7 @@ service ManagementService { }; } - // Change an existing Azure AD identity provider in the organisation + // Change an existing Azure AD identity provider in the organization rpc UpdateAzureADProvider(UpdateAzureADProviderRequest) returns (UpdateAzureADProviderResponse) { option (google.api.http) = { put: "/idps/azure/{id}" diff --git a/proto/zitadel/object/v2beta/object.proto b/proto/zitadel/object/v2beta/object.proto index 75f82d98a..c7c68f31c 100644 --- a/proto/zitadel/object/v2beta/object.proto +++ b/proto/zitadel/object/v2beta/object.proto @@ -8,6 +8,7 @@ import "google/protobuf/timestamp.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; import "validate/validate.proto"; +// Deprecated: use Organization message Organisation { oneof org { string org_id = 1; @@ -15,6 +16,13 @@ message Organisation { } } +message Organization { + oneof org { + string org_id = 1; + string org_domain = 2; + } +} + message RequestContext { oneof resource_owner { string org_id = 1; diff --git a/proto/zitadel/project.proto b/proto/zitadel/project.proto index e050ba3df..b487a2dd3 100644 --- a/proto/zitadel/project.proto +++ b/proto/zitadel/project.proto @@ -48,7 +48,7 @@ message GrantedProject { ]; string granted_org_name = 3 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { - example: "\"Some Organisation\"" + example: "\"Some Organization\"" } ]; repeated string granted_role_keys = 4 [ diff --git a/proto/zitadel/session/v2beta/session.proto b/proto/zitadel/session/v2beta/session.proto index b0bfd4fb1..08ef97e21 100644 --- a/proto/zitadel/session/v2beta/session.proto +++ b/proto/zitadel/session/v2beta/session.proto @@ -73,9 +73,15 @@ message UserFactor { description: "\"display name of the checked user\""; } ]; + // deprecated: use organization_id, will be remove before GA (https://github.com/zitadel/zitadel/issues/6718) string organisation_id = 5 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { - description: "\"organisation id of the checked user\""; + description: "\"organization id of the checked user; deprecated: use organization_id\""; + } + ]; + string organization_id = 6 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "\"organization id of the checked user\""; } ]; } diff --git a/proto/zitadel/user/v2beta/user_service.proto b/proto/zitadel/user/v2beta/user_service.proto index 01abeceed..36517dc4c 100644 --- a/proto/zitadel/user/v2beta/user_service.proto +++ b/proto/zitadel/user/v2beta/user_service.proto @@ -119,7 +119,7 @@ service UserService { option (zitadel.protoc_gen_zitadel.v2.options) = { auth_option: { permission: "user.write" - org_field: "organisation" + org_field: "organization" } http_response: { success_code: 201 @@ -655,7 +655,13 @@ message AddHumanUserRequest{ example: "\"minnie-mouse\""; } ]; - zitadel.object.v2beta.Organisation organisation = 3; + // deprecated: use organization (if both are set, organization will take precedence) + zitadel.object.v2beta.Organisation organisation = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "deprecated: use organization (if both are set, organization will take precedence)" + } + ]; + zitadel.object.v2beta.Organization organization = 11; SetHumanProfile profile = 4 [ (validate.rules).message.required = true, (google.api.field_behavior) = REQUIRED From 0af1c65c4ca0f4917b20f9502f99f66630a62951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Fri, 13 Oct 2023 16:11:20 +0300 Subject: [PATCH 08/15] fix: allow unused keys in hasher config (#6724) --- internal/crypto/passwap.go | 2 +- internal/crypto/passwap_test.go | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/crypto/passwap.go b/internal/crypto/passwap.go index a5a293a44..479d5731e 100644 --- a/internal/crypto/passwap.go +++ b/internal/crypto/passwap.go @@ -147,7 +147,7 @@ func (c *HasherConfig) buildHasher() (hasher passwap.Hasher, prefixes []string, func (c *HasherConfig) decodeParams(dst any) error { decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ - ErrorUnused: true, + ErrorUnused: false, ErrorUnset: true, Result: dst, }) diff --git a/internal/crypto/passwap_test.go b/internal/crypto/passwap_test.go index b557ca4a5..0538ac631 100644 --- a/internal/crypto/passwap_test.go +++ b/internal/crypto/passwap_test.go @@ -379,7 +379,10 @@ func TestHasherConfig_decodeParams(t *testing.T) { "b": 2, "c": 3, }, - wantErr: true, + want: dst{ + A: 1, + B: 2, + }, }, { name: "unset", From ce719a3fa4b2559c234f545b3795f51d263ae88f Mon Sep 17 00:00:00 2001 From: Livio Spring Date: Fri, 13 Oct 2023 17:45:38 +0300 Subject: [PATCH 09/15] fix(notification): get origin from all relevant events and fix nil pointer (#6726) --- internal/notification/handlers/origin.go | 9 ++++--- internal/notification/types/user_email.go | 2 +- internal/notification/types/user_phone.go | 3 ++- internal/repository/session/session.go | 18 ++++++++----- internal/repository/user/human_mfa_otp.go | 33 ++++++++++++++++------- internal/repository/user/human_phone.go | 19 ++++++++----- 6 files changed, 57 insertions(+), 27 deletions(-) diff --git a/internal/notification/handlers/origin.go b/internal/notification/handlers/origin.go index a807edd2d..915e1fed1 100644 --- a/internal/notification/handlers/origin.go +++ b/internal/notification/handlers/origin.go @@ -2,9 +2,10 @@ package handlers import ( "context" - "fmt" "net/url" + "github.com/zitadel/logging" + "github.com/zitadel/zitadel/internal/api/authz" http_utils "github.com/zitadel/zitadel/internal/api/http" "github.com/zitadel/zitadel/internal/errors" @@ -18,11 +19,13 @@ type OriginEvent interface { } func (n *NotificationQueries) Origin(ctx context.Context, e eventstore.Event) (context.Context, error) { + var origin string originEvent, ok := e.(OriginEvent) if !ok { - return ctx, errors.ThrowInternal(fmt.Errorf("event of type %T doesn't implement OriginEvent", e), "NOTIF-3m9fs", "Errors.Internal") + logging.Errorf("event of type %T doesn't implement OriginEvent", e) + } else { + origin = originEvent.TriggerOrigin() } - origin := originEvent.TriggerOrigin() if origin != "" { originURL, err := url.Parse(origin) if err != nil { diff --git a/internal/notification/types/user_email.go b/internal/notification/types/user_email.go index 7cb3498e4..152b63076 100644 --- a/internal/notification/types/user_email.go +++ b/internal/notification/types/user_email.go @@ -33,7 +33,7 @@ func generateEmail( if err != nil { return err } - if emailChannels.Len() == 0 { + if emailChannels == nil || emailChannels.Len() == 0 { return errors.ThrowPreconditionFailed(nil, "MAIL-83nof", "Errors.Notification.Channels.NotPresent") } return emailChannels.HandleMessage(message) diff --git a/internal/notification/types/user_phone.go b/internal/notification/types/user_phone.go index 50b7f8637..6eb3314cd 100644 --- a/internal/notification/types/user_phone.go +++ b/internal/notification/types/user_phone.go @@ -4,6 +4,7 @@ import ( "context" "github.com/zitadel/logging" + "github.com/zitadel/zitadel/internal/errors" "github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/notification/messages" @@ -21,7 +22,7 @@ func generateSms( number := "" smsChannels, twilioConfig, err := channels.SMS(ctx) logging.OnError(err).Error("could not create sms channel") - if smsChannels.Len() == 0 { + if smsChannels == nil || smsChannels.Len() == 0 { return errors.ThrowPreconditionFailed(nil, "PHONE-w8nfow", "Errors.Notification.Channels.NotPresent") } if err == nil { diff --git a/internal/repository/session/session.go b/internal/repository/session/session.go index 1966c178e..106b20518 100644 --- a/internal/repository/session/session.go +++ b/internal/repository/session/session.go @@ -312,9 +312,10 @@ func NewTOTPCheckedEvent( type OTPSMSChallengedEvent struct { eventstore.BaseEvent `json:"-"` - Code *crypto.CryptoValue `json:"code"` - Expiry time.Duration `json:"expiry"` - CodeReturned bool `json:"codeReturned,omitempty"` + Code *crypto.CryptoValue `json:"code"` + Expiry time.Duration `json:"expiry"` + CodeReturned bool `json:"codeReturned,omitempty"` + TriggeredAtOrigin string `json:"triggerOrigin,omitempty"` } func (e *OTPSMSChallengedEvent) Data() interface{} { @@ -329,6 +330,10 @@ func (e *OTPSMSChallengedEvent) SetBaseEvent(base *eventstore.BaseEvent) { e.BaseEvent = *base } +func (e *OTPSMSChallengedEvent) TriggerOrigin() string { + return e.TriggeredAtOrigin +} + func NewOTPSMSChallengedEvent( ctx context.Context, aggregate *eventstore.Aggregate, @@ -342,9 +347,10 @@ func NewOTPSMSChallengedEvent( aggregate, OTPSMSChallengedType, ), - Code: code, - Expiry: expiry, - CodeReturned: codeReturned, + Code: code, + Expiry: expiry, + CodeReturned: codeReturned, + TriggeredAtOrigin: http.ComposedOrigin(ctx), } } diff --git a/internal/repository/user/human_mfa_otp.go b/internal/repository/user/human_mfa_otp.go index 52d5ad7a0..d3dd2824c 100644 --- a/internal/repository/user/human_mfa_otp.go +++ b/internal/repository/user/human_mfa_otp.go @@ -5,6 +5,7 @@ import ( "encoding/json" "time" + "github.com/zitadel/zitadel/internal/api/http" "github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/crypto" @@ -279,8 +280,9 @@ func NewHumanOTPSMSRemovedEvent( type HumanOTPSMSCodeAddedEvent struct { eventstore.BaseEvent `json:"-"` - Code *crypto.CryptoValue `json:"code,omitempty"` - Expiry time.Duration `json:"expiry,omitempty"` + Code *crypto.CryptoValue `json:"code,omitempty"` + Expiry time.Duration `json:"expiry,omitempty"` + TriggeredAtOrigin string `json:"triggerOrigin,omitempty"` *AuthRequestInfo } @@ -296,6 +298,10 @@ func (e *HumanOTPSMSCodeAddedEvent) SetBaseEvent(event *eventstore.BaseEvent) { e.BaseEvent = *event } +func (e *HumanOTPSMSCodeAddedEvent) TriggerOrigin() string { + return e.TriggeredAtOrigin +} + func NewHumanOTPSMSCodeAddedEvent( ctx context.Context, aggregate *eventstore.Aggregate, @@ -309,9 +315,10 @@ func NewHumanOTPSMSCodeAddedEvent( aggregate, HumanOTPSMSCodeAddedType, ), - Code: code, - Expiry: expiry, - AuthRequestInfo: info, + Code: code, + Expiry: expiry, + TriggeredAtOrigin: http.ComposedOrigin(ctx), + AuthRequestInfo: info, } } @@ -473,8 +480,9 @@ func NewHumanOTPEmailRemovedEvent( type HumanOTPEmailCodeAddedEvent struct { eventstore.BaseEvent `json:"-"` - Code *crypto.CryptoValue `json:"code,omitempty"` - Expiry time.Duration `json:"expiry,omitempty"` + Code *crypto.CryptoValue `json:"code,omitempty"` + Expiry time.Duration `json:"expiry,omitempty"` + TriggeredAtOrigin string `json:"triggerOrigin,omitempty"` *AuthRequestInfo } @@ -490,6 +498,10 @@ func (e *HumanOTPEmailCodeAddedEvent) SetBaseEvent(event *eventstore.BaseEvent) e.BaseEvent = *event } +func (e *HumanOTPEmailCodeAddedEvent) TriggerOrigin() string { + return e.TriggeredAtOrigin +} + func NewHumanOTPEmailCodeAddedEvent( ctx context.Context, aggregate *eventstore.Aggregate, @@ -503,9 +515,10 @@ func NewHumanOTPEmailCodeAddedEvent( aggregate, HumanOTPEmailCodeAddedType, ), - Code: code, - Expiry: expiry, - AuthRequestInfo: info, + Code: code, + Expiry: expiry, + AuthRequestInfo: info, + TriggeredAtOrigin: http.ComposedOrigin(ctx), } } diff --git a/internal/repository/user/human_phone.go b/internal/repository/user/human_phone.go index c6586c54e..135b8f899 100644 --- a/internal/repository/user/human_phone.go +++ b/internal/repository/user/human_phone.go @@ -5,6 +5,7 @@ import ( "encoding/json" "time" + "github.com/zitadel/zitadel/internal/api/http" "github.com/zitadel/zitadel/internal/crypto" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/errors" @@ -149,9 +150,10 @@ func HumanPhoneVerificationFailedEventMapper(event *repository.Event) (eventstor type HumanPhoneCodeAddedEvent struct { eventstore.BaseEvent `json:"-"` - Code *crypto.CryptoValue `json:"code,omitempty"` - Expiry time.Duration `json:"expiry,omitempty"` - CodeReturned bool `json:"code_returned,omitempty"` + Code *crypto.CryptoValue `json:"code,omitempty"` + Expiry time.Duration `json:"expiry,omitempty"` + CodeReturned bool `json:"code_returned,omitempty"` + TriggeredAtOrigin string `json:"triggerOrigin,omitempty"` } func (e *HumanPhoneCodeAddedEvent) Data() interface{} { @@ -162,6 +164,10 @@ func (e *HumanPhoneCodeAddedEvent) UniqueConstraints() []*eventstore.EventUnique return nil } +func (e *HumanPhoneCodeAddedEvent) TriggerOrigin() string { + return e.TriggeredAtOrigin +} + func NewHumanPhoneCodeAddedEvent( ctx context.Context, aggregate *eventstore.Aggregate, @@ -183,9 +189,10 @@ func NewHumanPhoneCodeAddedEventV2( aggregate, HumanPhoneCodeAddedType, ), - Code: code, - Expiry: expiry, - CodeReturned: codeReturned, + Code: code, + Expiry: expiry, + CodeReturned: codeReturned, + TriggeredAtOrigin: http.ComposedOrigin(ctx), } } From cb0a0f996e0771a30dd1b2d6a81d78782aa7fc94 Mon Sep 17 00:00:00 2001 From: Livio Spring Date: Mon, 16 Oct 2023 10:49:02 +0300 Subject: [PATCH 10/15] fix(api): add remove otp sms and email to management api (#6721) * fix(api): add remove otp sms and email to management api * fix(console): remove otpsms and otpemail from user --------- Co-authored-by: peintnermax --- .../auth-user-mfa/auth-user-mfa.component.ts | 4 +- .../user-mfa/user-mfa.component.ts | 30 +++++++ console/src/app/services/mgmt.service.ts | 16 ++++ internal/api/grpc/management/user.go | 20 +++++ proto/zitadel/management.proto | 80 ++++++++++++++++++- 5 files changed, 147 insertions(+), 3 deletions(-) diff --git a/console/src/app/pages/users/user-detail/auth-user-detail/auth-user-mfa/auth-user-mfa.component.ts b/console/src/app/pages/users/user-detail/auth-user-detail/auth-user-mfa/auth-user-mfa.component.ts index 6a81838c4..c4a3d6403 100644 --- a/console/src/app/pages/users/user-detail/auth-user-detail/auth-user-mfa/auth-user-mfa.component.ts +++ b/console/src/app/pages/users/user-detail/auth-user-detail/auth-user-mfa/auth-user-mfa.component.ts @@ -157,7 +157,7 @@ export class AuthUserMfaComponent implements OnInit, OnDestroy { this.service .removeMyAuthFactorOTPEmail() .then(() => { - this.toast.showInfo('USER.TOAST.U2FREMOVED', true); + this.toast.showInfo('USER.TOAST.OTPREMOVED', true); this.cleanupList(); this.getMFAs(); @@ -169,7 +169,7 @@ export class AuthUserMfaComponent implements OnInit, OnDestroy { this.service .removeMyAuthFactorOTPSMS() .then(() => { - this.toast.showInfo('USER.TOAST.U2FREMOVED', true); + this.toast.showInfo('USER.TOAST.OTPREMOVED', true); this.cleanupList(); this.getMFAs(); diff --git a/console/src/app/pages/users/user-detail/user-detail/user-mfa/user-mfa.component.ts b/console/src/app/pages/users/user-detail/user-detail/user-mfa/user-mfa.component.ts index c9be008e0..29418e80f 100644 --- a/console/src/app/pages/users/user-detail/user-detail/user-mfa/user-mfa.component.ts +++ b/console/src/app/pages/users/user-detail/user-detail/user-mfa/user-mfa.component.ts @@ -102,6 +102,36 @@ export class UserMfaComponent implements OnInit, OnDestroy { .catch((error) => { this.toast.showError(error); }); + } else if (factor.otpEmail) { + this.mgmtUserService + .removeHumanAuthFactorOTPEmail(this.user.id) + .then(() => { + this.toast.showInfo('USER.TOAST.OTPREMOVED', true); + + const index = this.dataSource.data.findIndex((mfa) => !!mfa.otpEmail); + if (index > -1) { + this.dataSource.data.splice(index, 1); + } + this.getMFAs(); + }) + .catch((error) => { + this.toast.showError(error); + }); + } else if (factor.otpSms) { + this.mgmtUserService + .removeHumanAuthFactorOTPSMS(this.user.id) + .then(() => { + this.toast.showInfo('USER.TOAST.OTPREMOVED', true); + + const index = this.dataSource.data.findIndex((mfa) => !!mfa.otpSms); + if (index > -1) { + this.dataSource.data.splice(index, 1); + } + this.getMFAs(); + }) + .catch((error) => { + this.toast.showError(error); + }); } } }); diff --git a/console/src/app/services/mgmt.service.ts b/console/src/app/services/mgmt.service.ts index c80e9e9b4..f2389a25e 100644 --- a/console/src/app/services/mgmt.service.ts +++ b/console/src/app/services/mgmt.service.ts @@ -322,8 +322,12 @@ import { RemoveCustomLabelPolicyLogoDarkResponse, RemoveCustomLabelPolicyLogoRequest, RemoveCustomLabelPolicyLogoResponse, + RemoveHumanAuthFactorOTPEmailRequest, + RemoveHumanAuthFactorOTPEmailResponse, RemoveHumanAuthFactorOTPRequest, RemoveHumanAuthFactorOTPResponse, + RemoveHumanAuthFactorOTPSMSRequest, + RemoveHumanAuthFactorOTPSMSResponse, RemoveHumanAuthFactorU2FRequest, RemoveHumanAuthFactorU2FResponse, RemoveHumanLinkedIDPRequest, @@ -1805,6 +1809,18 @@ export class ManagementService { return this.grpcService.mgmt.removeHumanAuthFactorU2F(req, null).then((resp) => resp.toObject()); } + public removeHumanAuthFactorOTPSMS(userId: string): Promise { + const req = new RemoveHumanAuthFactorOTPSMSRequest(); + req.setUserId(userId); + return this.grpcService.mgmt.removeHumanAuthFactorOTPSMS(req, null).then((resp) => resp.toObject()); + } + + public removeHumanAuthFactorOTPEmail(userId: string): Promise { + const req = new RemoveHumanAuthFactorOTPEmailRequest(); + req.setUserId(userId); + return this.grpcService.mgmt.removeHumanAuthFactorOTPEmail(req, null).then((resp) => resp.toObject()); + } + public updateHumanProfile( userId: string, firstName?: string, diff --git a/internal/api/grpc/management/user.go b/internal/api/grpc/management/user.go index 804a90521..2cc4fe21d 100644 --- a/internal/api/grpc/management/user.go +++ b/internal/api/grpc/management/user.go @@ -646,6 +646,26 @@ func (s *Server) RemoveHumanAuthFactorU2F(ctx context.Context, req *mgmt_pb.Remo }, nil } +func (s *Server) RemoveHumanAuthFactorOTPSMS(ctx context.Context, req *mgmt_pb.RemoveHumanAuthFactorOTPSMSRequest) (*mgmt_pb.RemoveHumanAuthFactorOTPSMSResponse, error) { + objectDetails, err := s.command.RemoveHumanOTPSMS(ctx, req.UserId, authz.GetCtxData(ctx).OrgID) + if err != nil { + return nil, err + } + return &mgmt_pb.RemoveHumanAuthFactorOTPSMSResponse{ + Details: obj_grpc.DomainToChangeDetailsPb(objectDetails), + }, nil +} + +func (s *Server) RemoveHumanAuthFactorOTPEmail(ctx context.Context, req *mgmt_pb.RemoveHumanAuthFactorOTPEmailRequest) (*mgmt_pb.RemoveHumanAuthFactorOTPEmailResponse, error) { + objectDetails, err := s.command.RemoveHumanOTPEmail(ctx, req.UserId, authz.GetCtxData(ctx).OrgID) + if err != nil { + return nil, err + } + return &mgmt_pb.RemoveHumanAuthFactorOTPEmailResponse{ + Details: obj_grpc.DomainToChangeDetailsPb(objectDetails), + }, nil +} + func (s *Server) ListHumanPasswordless(ctx context.Context, req *mgmt_pb.ListHumanPasswordlessRequest) (*mgmt_pb.ListHumanPasswordlessResponse, error) { query := new(query.UserAuthMethodSearchQueries) err := query.AppendUserIDQuery(req.UserId) diff --git a/proto/zitadel/management.proto b/proto/zitadel/management.proto index 6a17b3cf5..3c485f7a9 100644 --- a/proto/zitadel/management.proto +++ b/proto/zitadel/management.proto @@ -1255,7 +1255,7 @@ service ManagementService { option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { summary: "Remove Multi-Factor OTP"; - description: "Remove the configured One-Time-Password (OTP) as a factor from the user. OTP is an authentication app, like Authy or Google/Microsoft Authenticator.." + description: "Remove the configured One-Time-Password (OTP) as a factor from the user. OTP is an authentication app, like Authy or Google/Microsoft Authenticator." tags: "Users"; tags: "User Human"; responses: { @@ -1306,6 +1306,68 @@ service ManagementService { }; } + rpc RemoveHumanAuthFactorOTPSMS(RemoveHumanAuthFactorOTPSMSRequest) returns (RemoveHumanAuthFactorOTPSMSResponse) { + option (google.api.http) = { + delete: "/users/{user_id}/auth_factors/otp_sms" + }; + + option (zitadel.v1.auth_option) = { + permission: "user.write" + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Remove Multi-Factor OTP SMS"; + description: "Remove the configured One-Time-Password (OTP) SMS as a factor from the user. As only one OTP SMS per user is allowed, the user will not have OTP SMS as a second-factor afterward." + tags: "Users"; + tags: "User Human"; + responses: { + key: "200" + value: { + description: "OK"; + } + }; + parameters: { + headers: { + name: "x-zitadel-orgid"; + description: "The default is always the organization of the requesting user. If you like to get a user from another organization include the header. Make sure the requesting user has permission in the requested organization."; + type: STRING, + required: false; + }; + }; + }; + } + + rpc RemoveHumanAuthFactorOTPEmail(RemoveHumanAuthFactorOTPEmailRequest) returns (RemoveHumanAuthFactorOTPEmailResponse) { + option (google.api.http) = { + delete: "/users/{user_id}/auth_factors/otp_email" + }; + + option (zitadel.v1.auth_option) = { + permission: "user.write" + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Remove Multi-Factor OTP SMS"; + description: "Remove the configured One-Time-Password (OTP) Email as a factor from the user. As only one OTP Email per user is allowed, the user will not have OTP Email as a second-factor afterward." + tags: "Users"; + tags: "User Human"; + responses: { + key: "200" + value: { + description: "OK"; + } + }; + parameters: { + headers: { + name: "x-zitadel-orgid"; + description: "The default is always the organization of the requesting user. If you like to get a user from another organization include the header. Make sure the requesting user has permission in the requested organization."; + type: STRING, + required: false; + }; + }; + }; + } + rpc ListHumanPasswordless(ListHumanPasswordlessRequest) returns (ListHumanPasswordlessResponse) { option (google.api.http) = { post: "/users/{user_id}/passwordless/_search" @@ -8246,6 +8308,22 @@ message RemoveHumanAuthFactorU2FResponse { zitadel.v1.ObjectDetails details = 1; } +message RemoveHumanAuthFactorOTPSMSRequest { + string user_id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}]; +} + +message RemoveHumanAuthFactorOTPSMSResponse { + zitadel.v1.ObjectDetails details = 1; +} + +message RemoveHumanAuthFactorOTPEmailRequest { + string user_id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}]; +} + +message RemoveHumanAuthFactorOTPEmailResponse { + zitadel.v1.ObjectDetails details = 1; +} + message ListHumanPasswordlessRequest { string user_id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}]; } From 7b91d90eb2f6ba97e519bef6a0fad639a0b42444 Mon Sep 17 00:00:00 2001 From: Christoph Schmatzler Date: Mon, 16 Oct 2023 11:59:55 +0200 Subject: [PATCH 11/15] docs: fix environment variable name for steps (#6728) The yaml schema has a `Machine` object nested inside another one, which was improperly represented in the corresponding environment variable. Signed-off-by: Christoph Schmatzler Co-authored-by: Elio Bischof --- cmd/setup/steps.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/setup/steps.yaml b/cmd/setup/steps.yaml index 1497b7be4..c585c535b 100644 --- a/cmd/setup/steps.yaml +++ b/cmd/setup/steps.yaml @@ -35,8 +35,8 @@ FirstInstance: # If FirstInstance.Org.Machine.Machine is defined, a service user is created with the IAM_OWNER role, not a human user. Machine: Machine: - Username: # ZITADEL_FIRSTINSTANCE_ORG_MACHINE_USERNAME - Name: # ZITADEL_FIRSTINSTANCE_ORG_MACHINE_NAME + Username: # ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_USERNAME + Name: # ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_NAME MachineKey: # date format: 2023-01-01T00:00:00Z ExpirationDate: # ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINEKEY_EXPIRATIONDATE From bb1994c3181b02564dac1f30cfa073785933d368 Mon Sep 17 00:00:00 2001 From: Elio Bischof Date: Tue, 17 Oct 2023 15:01:47 +0200 Subject: [PATCH 12/15] fix: origin from proxies (#6738) * fix: origin from proxies * test multiple forwarded header values --- .../api/http/middleware/origin_interceptor.go | 85 +++--------- .../middleware/origin_interceptor_test.go | 122 ++++++++++++++++++ 2 files changed, 143 insertions(+), 64 deletions(-) create mode 100644 internal/api/http/middleware/origin_interceptor_test.go diff --git a/internal/api/http/middleware/origin_interceptor.go b/internal/api/http/middleware/origin_interceptor.go index 2cf9a644f..da03145ab 100644 --- a/internal/api/http/middleware/origin_interceptor.go +++ b/internal/api/http/middleware/origin_interceptor.go @@ -3,7 +3,6 @@ package middleware import ( "fmt" "net/http" - "net/url" "github.com/muhlemmer/httpforwarded" "github.com/zitadel/logging" @@ -24,74 +23,32 @@ func OriginHandler(next http.Handler) http.Handler { } func composeOrigin(r *http.Request) string { - if origin, err := originFromForwardedHeader(r); err != nil { - logging.OnError(err).Debug("failed to build origin from forwarded header, trying x-forwarded-* headers") - } else { - return origin + var proto, host string + fwd, fwdErr := httpforwarded.ParseFromRequest(r) + if fwdErr == nil { + proto = oldestForwardedValue(fwd, "proto") + host = oldestForwardedValue(fwd, "host") } - if origin, err := originFromXForwardedHeaders(r); err != nil { - logging.OnError(err).Debug("failed to build origin from x-forwarded-* headers, using host header") - } else { - return origin + if proto == "" { + proto = r.Header.Get("X-Forwarded-Proto") } - scheme := "https" - if r.TLS == nil { - scheme = "http" - } - return fmt.Sprintf("%s://%s", scheme, r.Host) -} - -func originFromForwardedHeader(r *http.Request) (string, error) { - fwd, err := httpforwarded.ParseFromRequest(r) - if err != nil { - return "", err - } - var fwdProto, fwdHost, fwdPort string - if fwdProto = mostRecentValue(fwd, "proto"); fwdProto == "" { - return "", fmt.Errorf("no proto in forwarded header") - } - if fwdHost = mostRecentValue(fwd, "host"); fwdHost == "" { - return "", fmt.Errorf("no host in forwarded header") - } - fwdPort, foundFwdFor := extractPort(mostRecentValue(fwd, "for")) - if !foundFwdFor { - return "", fmt.Errorf("no for in forwarded header") - } - o := fmt.Sprintf("%s://%s", fwdProto, fwdHost) - if fwdPort != "" { - o += ":" + fwdPort - } - return o, nil -} - -func originFromXForwardedHeaders(r *http.Request) (string, error) { - scheme := r.Header.Get("X-Forwarded-Proto") - if scheme == "" { - return "", fmt.Errorf("no X-Forwarded-Proto header") - } - host := r.Header.Get("X-Forwarded-Host") if host == "" { - return "", fmt.Errorf("no X-Forwarded-Host header") + host = r.Header.Get("X-Forwarded-Host") } - return fmt.Sprintf("%s://%s", scheme, host), nil + if proto == "" { + if r.TLS == nil { + proto = "http" + } else { + proto = "https" + } + } + if host == "" { + host = r.Host + } + return fmt.Sprintf("%s://%s", proto, host) } -func extractPort(raw string) (string, bool) { - if u, ok := parseURL(raw); ok { - return u.Port(), ok - } - return "", false -} - -func parseURL(raw string) (*url.URL, bool) { - if raw == "" { - return nil, false - } - u, err := url.Parse(raw) - return u, err == nil -} - -func mostRecentValue(forwarded map[string][]string, key string) string { +func oldestForwardedValue(forwarded map[string][]string, key string) string { if forwarded == nil { return "" } @@ -99,5 +56,5 @@ func mostRecentValue(forwarded map[string][]string, key string) string { if len(values) == 0 { return "" } - return values[len(values)-1] + return values[0] } diff --git a/internal/api/http/middleware/origin_interceptor_test.go b/internal/api/http/middleware/origin_interceptor_test.go new file mode 100644 index 000000000..e8e4f306b --- /dev/null +++ b/internal/api/http/middleware/origin_interceptor_test.go @@ -0,0 +1,122 @@ +package middleware + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_composeOrigin(t *testing.T) { + type args struct { + h http.Header + } + tests := []struct { + name string + args args + want string + }{{ + name: "no proxy headers", + want: "http://host.header", + }, { + name: "forwarded proto", + args: args{ + h: http.Header{ + "Forwarded": []string{"proto=https"}, + }, + }, + want: "https://host.header", + }, { + name: "forwarded host", + args: args{ + h: http.Header{ + "Forwarded": []string{"host=forwarded.host"}, + }, + }, + want: "http://forwarded.host", + }, { + name: "forwarded proto and host", + args: args{ + h: http.Header{ + "Forwarded": []string{"proto=https;host=forwarded.host"}, + }, + }, + want: "https://forwarded.host", + }, { + name: "forwarded proto and host with multiple complete entries", + args: args{ + h: http.Header{ + "Forwarded": []string{"proto=https;host=forwarded.host, proto=http;host=forwarded.host2"}, + }, + }, + want: "https://forwarded.host", + }, { + name: "forwarded proto and host with multiple incomplete entries", + args: args{ + h: http.Header{ + "Forwarded": []string{"proto=https;host=forwarded.host, proto=http"}, + }, + }, + want: "https://forwarded.host", + }, { + name: "forwarded proto and host with incomplete entries in different values", + args: args{ + h: http.Header{ + "Forwarded": []string{"proto=http", "proto=https;host=forwarded.host", "proto=http"}, + }, + }, + want: "http://forwarded.host", + }, { + name: "x-forwarded-proto", + args: args{ + h: http.Header{ + "X-Forwarded-Proto": []string{"https"}, + }, + }, + want: "https://host.header", + }, { + name: "x-forwarded-host", + args: args{ + h: http.Header{ + "X-Forwarded-Host": []string{"x-forwarded.host"}, + }, + }, + want: "http://x-forwarded.host", + }, { + name: "x-forwarded-proto and x-forwarded-host", + args: args{ + h: http.Header{ + "X-Forwarded-Proto": []string{"https"}, + "X-Forwarded-Host": []string{"x-forwarded.host"}, + }, + }, + want: "https://x-forwarded.host", + }, { + name: "forwarded host and x-forwarded-host", + args: args{ + h: http.Header{ + "Forwarded": []string{"host=forwarded.host"}, + "X-Forwarded-Host": []string{"x-forwarded.host"}, + }, + }, + want: "http://forwarded.host", + }, { + name: "forwarded host and x-forwarded-proto", + args: args{ + h: http.Header{ + "Forwarded": []string{"host=forwarded.host"}, + "X-Forwarded-Proto": []string{"https"}, + }, + }, + want: "https://forwarded.host", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, composeOrigin(&http.Request{ + Host: "host.header", + Header: tt.args.h, + }), "headers: %+v", tt.args.h) + }) + } +} From 3bbcc3434ab58d11bb24a07949f54eedcf3cea5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Tue, 17 Oct 2023 18:19:51 +0300 Subject: [PATCH 13/15] chore(deps): upgrade to oidc v3 (#6737) This pr upgrades oidc to v3 . Function signature changes have been migrated as well. Specifically there are more client calls that take a context now. Where feasable a context is added to those calls. Where a context is not (easily) available context.TODO() is used as a reminder for when it does. Related to #6619 --- cmd/start/start.go | 2 +- go.mod | 30 +++--- go.sum | 53 +++++------ internal/api/authz/token.go | 6 +- internal/api/grpc/management/information.go | 2 +- internal/api/grpc/management/user.go | 2 +- internal/api/grpc/oidc/v2/oidc.go | 2 +- .../api/grpc/oidc/v2/oidc_integration_test.go | 12 +-- internal/api/grpc/oidc/v2/server.go | 2 +- .../api/grpc/system/instance_converter.go | 2 +- internal/api/oidc/auth_request.go | 4 +- internal/api/oidc/auth_request_converter.go | 4 +- .../api/oidc/auth_request_converter_v2.go | 2 +- .../api/oidc/auth_request_integration_test.go | 91 ++++++++----------- internal/api/oidc/client.go | 6 +- internal/api/oidc/client_converter.go | 4 +- internal/api/oidc/client_credentials.go | 4 +- internal/api/oidc/client_integration_test.go | 14 +-- internal/api/oidc/device_auth.go | 4 +- internal/api/oidc/jwt-profile.go | 4 +- internal/api/oidc/key.go | 4 +- internal/api/oidc/oidc_integration_test.go | 12 +-- internal/api/oidc/op.go | 4 +- internal/api/saml/certificate.go | 2 +- internal/api/ui/console/console.go | 2 +- internal/api/ui/login/custom_action.go | 2 +- .../api/ui/login/external_provider_handler.go | 4 +- internal/api/ui/login/jwt_handler.go | 2 +- .../eventstore/token_verifier.go | 8 +- internal/command/idp_intent.go | 2 +- internal/command/idp_intent_test.go | 2 +- internal/command/idp_model.go | 2 +- internal/command/instance_idp_test.go | 2 +- internal/command/org_idp_test.go | 2 +- internal/command/org_test.go | 2 +- .../command/user_human_refresh_token_test.go | 2 +- internal/idp/providers/apple/apple.go | 6 +- internal/idp/providers/apple/session.go | 2 +- internal/idp/providers/apple/session_test.go | 2 +- internal/idp/providers/azuread/azuread.go | 2 +- .../idp/providers/azuread/azuread_test.go | 4 +- internal/idp/providers/azuread/session.go | 4 +- .../idp/providers/azuread/session_test.go | 2 +- internal/idp/providers/github/session_test.go | 2 +- internal/idp/providers/gitlab/gitlab.go | 2 +- internal/idp/providers/gitlab/session_test.go | 4 +- internal/idp/providers/google/google.go | 2 +- internal/idp/providers/google/session_test.go | 4 +- internal/idp/providers/jwt/session.go | 4 +- internal/idp/providers/jwt/session_test.go | 4 +- internal/idp/providers/oauth/oauth2.go | 4 +- internal/idp/providers/oauth/oauth2_test.go | 2 +- internal/idp/providers/oauth/session.go | 6 +- internal/idp/providers/oauth/session_test.go | 2 +- internal/idp/providers/oidc/oidc.go | 6 +- internal/idp/providers/oidc/oidc_test.go | 4 +- internal/idp/providers/oidc/session.go | 6 +- internal/idp/providers/oidc/session_test.go | 6 +- internal/integration/client.go | 2 +- internal/integration/integration.go | 4 +- internal/integration/oidc.go | 24 ++--- 61 files changed, 198 insertions(+), 216 deletions(-) diff --git a/cmd/start/start.go b/cmd/start/start.go index 6a017af0d..7e49b0a39 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -19,7 +19,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v2/pkg/op" + "github.com/zitadel/oidc/v3/pkg/op" "github.com/zitadel/saml/pkg/provider" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" diff --git a/go.mod b/go.mod index f4e513fbb..875f6bb0e 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,7 @@ require ( github.com/drone/envsubst v1.0.3 github.com/envoyproxy/protoc-gen-validate v1.0.2 github.com/fatih/color v1.15.0 + github.com/go-jose/go-jose/v3 v3.0.0 github.com/go-ldap/ldap/v3 v3.4.5 github.com/go-webauthn/webauthn v0.8.6 github.com/golang/mock v1.6.0 @@ -48,11 +49,12 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/muesli/gamut v0.3.1 github.com/muhlemmer/gu v0.3.1 + github.com/muhlemmer/httpforwarded v0.1.0 github.com/nicksnyder/go-i18n/v2 v2.2.1 github.com/pkg/errors v0.9.1 github.com/pquerna/otp v1.4.0 github.com/rakyll/statik v0.1.7 - github.com/rs/cors v1.10.0 + github.com/rs/cors v1.10.1 github.com/sony/sonyflake v1.2.0 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.16.0 @@ -60,36 +62,35 @@ require ( github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203 github.com/ttacon/libphonenumber v1.2.1 github.com/zitadel/logging v0.4.0 - github.com/zitadel/oidc/v2 v2.11.0 + github.com/zitadel/oidc/v3 v3.0.2 github.com/zitadel/passwap v0.4.0 github.com/zitadel/saml v0.1.2 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.43.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.43.0 - go.opentelemetry.io/otel v1.17.0 + go.opentelemetry.io/otel v1.19.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.17.0 go.opentelemetry.io/otel/exporters/prometheus v0.40.0 go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.17.0 - go.opentelemetry.io/otel/metric v1.17.0 + go.opentelemetry.io/otel/metric v1.19.0 go.opentelemetry.io/otel/sdk v1.17.0 go.opentelemetry.io/otel/sdk/metric v0.40.0 - go.opentelemetry.io/otel/trace v1.17.0 - golang.org/x/crypto v0.13.0 - golang.org/x/net v0.15.0 - golang.org/x/oauth2 v0.12.0 + go.opentelemetry.io/otel/trace v1.19.0 + golang.org/x/crypto v0.14.0 + golang.org/x/net v0.17.0 + golang.org/x/oauth2 v0.13.0 golang.org/x/sync v0.3.0 golang.org/x/text v0.13.0 google.golang.org/api v0.138.0 google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d google.golang.org/grpc v1.57.0 google.golang.org/protobuf v1.31.0 - gopkg.in/square/go-jose.v2 v2.6.0 sigs.k8s.io/yaml v1.3.0 ) require ( github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.43.1 // indirect github.com/crewjam/httperr v0.2.0 // indirect - github.com/dmarkham/enumer v1.5.8 // indirect + github.com/go-chi/chi/v5 v5.0.10 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-sql-driver/mysql v1.6.0 // indirect @@ -105,14 +106,11 @@ require ( github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect - github.com/muhlemmer/httpforwarded v0.1.0 // indirect - github.com/pascaldekloe/name v1.0.0 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/smartystreets/assertions v1.0.0 // indirect github.com/zenazn/goji v1.0.1 // indirect + github.com/zitadel/schema v1.3.0 // indirect golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect ) @@ -154,7 +152,7 @@ require ( github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/go-cmp v0.5.9 // indirect - github.com/google/uuid v1.3.1 // indirect + github.com/google/uuid v1.3.1 github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/gorilla/handlers v1.5.1 // indirect @@ -203,7 +201,7 @@ require ( go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.17.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect - golang.org/x/sys v0.12.0 + golang.org/x/sys v0.13.0 golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index 9e7ae585c..018d31f9e 100644 --- a/go.sum +++ b/go.sum @@ -184,8 +184,6 @@ github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwu github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0= github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/dmarkham/enumer v1.5.8 h1:fIF11F9l5jyD++YYvxcSH5WgHfeaSGPaN/T4kOQ4qEM= -github.com/dmarkham/enumer v1.5.8/go.mod h1:d10o8R3t/gROm2p3BXqTkMt2+HMuxEmWCXzorAruYak= github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= github.com/dop251/goja v0.0.0-20230531210528-d7324b2d74f7/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= github.com/dop251/goja v0.0.0-20230828202809-3dbe69dd2b8e h1:UvQD6hTSfeM6hhTQ24Dlw2RppP05W7SWbWb6kubJAog= @@ -267,6 +265,8 @@ github.com/gin-gonic/gin v1.7.4 h1:QmUZXrvJ9qZ3GfWvQ+2wnW/1ePrTEJqPKMYEU3lD/DM= github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A= github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= +github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= +github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs= github.com/go-errors/errors v1.1.1/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs= @@ -275,6 +275,8 @@ github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3Bop github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo= +github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= @@ -720,8 +722,6 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/name v1.0.0 h1:n7LKFgHixETzxpRv2R77YgPUFo85QHGZKrdaYm7eY5U= -github.com/pascaldekloe/name v1.0.0/go.mod h1:Z//MfYJnH4jVpQ9wkclwu2I2MkHmXTlT9wR5UZScttM= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= @@ -782,8 +782,8 @@ github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/f github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/cors v1.10.0 h1:62NOS1h+r8p1mW6FM0FSB0exioXLhd/sh15KpjWBZ+8= -github.com/rs/cors v1.10.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= +github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= @@ -883,12 +883,14 @@ github.com/zenazn/goji v1.0.1 h1:4lbD8Mx2h7IvloP7r2C0D6ltZP6Ufip8Hn0wmSK5LR8= github.com/zenazn/goji v1.0.1/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zitadel/logging v0.4.0 h1:lRAIFgaRoJpLNbsL7jtIYHcMDoEJP9QZB4GqMfl4xaA= github.com/zitadel/logging v0.4.0/go.mod h1:6uALRJawpkkuUPCkgzfgcPR3c2N908wqnOnIrRelUFc= -github.com/zitadel/oidc/v2 v2.11.0 h1:Am4/yQr4iiM5bznRgF3FOp+wLdKx2gzSU73uyI9vvBE= -github.com/zitadel/oidc/v2 v2.11.0/go.mod h1:enFSVBQI6aE0TEB1ntjXs9r6O6DEosxX4uhEBLBVD8o= +github.com/zitadel/oidc/v3 v3.0.2 h1:fw0EAjx8lIlDMJ54hDz2fWIhpW/Y13tW5gd1qWGqbr4= +github.com/zitadel/oidc/v3 v3.0.2/go.mod h1:ne9V9FHug4iUZDV42JirWVLHcbmwaxY8LnkcfekHgRg= github.com/zitadel/passwap v0.4.0 h1:cMaISx+Ve7ilgG7Q8xOli4Z6IWr8Gndss+jeBk5A3O0= github.com/zitadel/passwap v0.4.0/go.mod h1:yHaDM4A68yRkdic5BZ4iUNoc19hT+kYt8n1/Nz+I87g= github.com/zitadel/saml v0.1.2 h1:RICwNTuP2upX4A1sZ8iq1rv4/x3DhZHzFx1e5bTKoTo= github.com/zitadel/saml v0.1.2/go.mod h1:M+X+3vMUulpoLofKeH/W1/qjQQ3owitc2GuGDu3oYpM= +github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0= +github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -905,8 +907,8 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.4 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.43.0/go.mod h1:1WpsUwjQrUJSNugfMlPn0rPRJ9Do7wwBgTBPK7MLiS4= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.43.0 h1:HKORGpiOY0R0nAPtKx/ub8/7XoHhRooP8yNRkuPfelI= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.43.0/go.mod h1:e+y1M74SYXo/FcIx3UATwth2+5dDkM8dBi7eXg1tbw8= -go.opentelemetry.io/otel v1.17.0 h1:MW+phZ6WZ5/uk2nd93ANk/6yJ+dVrvNWUjGhnnFU5jM= -go.opentelemetry.io/otel v1.17.0/go.mod h1:I2vmBGtFaODIVMBSTPVDlJSzBDNf93k60E6Ft0nyjo0= +go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= +go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.17.0 h1:U5GYackKpVKlPrd/5gKMlrTlP2dCESAAFU682VCpieY= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.17.0/go.mod h1:aFsJfCEnLzEu9vRRAcUiB/cpRTbVsNdF3OHSPpdjxZQ= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.17.0 h1:iGeIsSYwpYSvh5UGzWrJfTDJvPjrXtxl3GUppj6IXQU= @@ -915,14 +917,14 @@ go.opentelemetry.io/otel/exporters/prometheus v0.40.0 h1:9h6lCssr1j5aYVvWT6oc+ER go.opentelemetry.io/otel/exporters/prometheus v0.40.0/go.mod h1:5USWZ0ovyQB5CIM3IO3bGRSoDPMXiT3t+15gu8Zo9HQ= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.17.0 h1:Ut6hgtYcASHwCzRHkXEtSsM251cXJPW+Z9DyLwEn6iI= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.17.0/go.mod h1:TYeE+8d5CjrgBa0ZuRaDeMpIC1xZ7atg4g+nInjuSjc= -go.opentelemetry.io/otel/metric v1.17.0 h1:iG6LGVz5Gh+IuO0jmgvpTB6YVrCGngi8QGm+pMd8Pdc= -go.opentelemetry.io/otel/metric v1.17.0/go.mod h1:h4skoxdZI17AxwITdmdZjjYJQH5nzijUUjm+wtPph5o= +go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= +go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= go.opentelemetry.io/otel/sdk v1.17.0 h1:FLN2X66Ke/k5Sg3V623Q7h7nt3cHXaW1FOvKKrW0IpE= go.opentelemetry.io/otel/sdk v1.17.0/go.mod h1:U87sE0f5vQB7hwUoW98pW5Rz4ZDuCFBZFNUBlSgmDFQ= go.opentelemetry.io/otel/sdk/metric v0.40.0 h1:qOM29YaGcxipWjL5FzpyZDpCYrDREvX0mVlmXdOjCHU= go.opentelemetry.io/otel/sdk/metric v0.40.0/go.mod h1:dWxHtdzdJvg+ciJUKLTKwrMe5P6Dv3FyDbh8UkfgkVs= -go.opentelemetry.io/otel/trace v1.17.0 h1:/SWhSRHmDPOImIAetP1QAeMnZYiQXrTy4fMMYOdSKWQ= -go.opentelemetry.io/otel/trace v1.17.0/go.mod h1:I/4vKTgFclIsXRVucpH25X0mpFSczM7aHeaz0ZBLWjY= +go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= +go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= @@ -952,6 +954,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -965,8 +968,8 @@ golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1007,8 +1010,6 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1059,8 +1060,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1070,8 +1071,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= -golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= +golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= +golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1154,8 +1155,8 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1242,8 +1243,6 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1384,8 +1383,6 @@ gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:a gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= -gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= diff --git a/internal/api/authz/token.go b/internal/api/authz/token.go index 615543093..187a97c90 100644 --- a/internal/api/authz/token.go +++ b/internal/api/authz/token.go @@ -10,8 +10,8 @@ import ( "sync" "time" - "github.com/zitadel/oidc/v2/pkg/op" - "gopkg.in/square/go-jose.v2" + "github.com/go-jose/go-jose/v3" + "github.com/zitadel/oidc/v3/pkg/op" "github.com/zitadel/zitadel/internal/crypto" caos_errs "github.com/zitadel/zitadel/internal/errors" @@ -28,7 +28,7 @@ type TokenVerifier struct { authZRepo authZRepo clients sync.Map authMethods MethodMapping - systemJWTProfile op.JWTProfileVerifier + systemJWTProfile *op.JWTProfileVerifier } type MembershipsResolver interface { diff --git a/internal/api/grpc/management/information.go b/internal/api/grpc/management/information.go index 29ce6ac01..d18e115bf 100644 --- a/internal/api/grpc/management/information.go +++ b/internal/api/grpc/management/information.go @@ -3,7 +3,7 @@ package management import ( "context" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/api/http" diff --git a/internal/api/grpc/management/user.go b/internal/api/grpc/management/user.go index 2cc4fe21d..de7f57b25 100644 --- a/internal/api/grpc/management/user.go +++ b/internal/api/grpc/management/user.go @@ -4,7 +4,7 @@ import ( "context" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/text/language" "google.golang.org/protobuf/types/known/durationpb" diff --git a/internal/api/grpc/oidc/v2/oidc.go b/internal/api/grpc/oidc/v2/oidc.go index d35a5dcff..465303b98 100644 --- a/internal/api/grpc/oidc/v2/oidc.go +++ b/internal/api/grpc/oidc/v2/oidc.go @@ -4,7 +4,7 @@ import ( "context" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v2/pkg/op" + "github.com/zitadel/oidc/v3/pkg/op" "google.golang.org/protobuf/types/known/durationpb" "google.golang.org/protobuf/types/known/timestamppb" diff --git a/internal/api/grpc/oidc/v2/oidc_integration_test.go b/internal/api/grpc/oidc/v2/oidc_integration_test.go index b64b71325..db11f9022 100644 --- a/internal/api/grpc/oidc/v2/oidc_integration_test.go +++ b/internal/api/grpc/oidc/v2/oidc_integration_test.go @@ -54,7 +54,7 @@ func TestServer_GetAuthRequest(t *testing.T) { require.NoError(t, err) client, err := Tester.CreateOIDCNativeClient(CTX, redirectURI, logoutRedirectURI, project.GetId()) require.NoError(t, err) - authRequestID, err := Tester.CreateOIDCAuthRequest(client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI) + authRequestID, err := Tester.CreateOIDCAuthRequest(CTX, client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI) require.NoError(t, err) now := time.Now() @@ -134,7 +134,7 @@ func TestServer_CreateCallback(t *testing.T) { name: "session not found", req: &oidc_pb.CreateCallbackRequest{ AuthRequestId: func() string { - authRequestID, err := Tester.CreateOIDCAuthRequest(client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI) + authRequestID, err := Tester.CreateOIDCAuthRequest(CTX, client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI) require.NoError(t, err) return authRequestID }(), @@ -151,7 +151,7 @@ func TestServer_CreateCallback(t *testing.T) { name: "session token invalid", req: &oidc_pb.CreateCallbackRequest{ AuthRequestId: func() string { - authRequestID, err := Tester.CreateOIDCAuthRequest(client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI) + authRequestID, err := Tester.CreateOIDCAuthRequest(CTX, client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI) require.NoError(t, err) return authRequestID }(), @@ -168,7 +168,7 @@ func TestServer_CreateCallback(t *testing.T) { name: "fail callback", req: &oidc_pb.CreateCallbackRequest{ AuthRequestId: func() string { - authRequestID, err := Tester.CreateOIDCAuthRequest(client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI) + authRequestID, err := Tester.CreateOIDCAuthRequest(CTX, client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI) require.NoError(t, err) return authRequestID }(), @@ -192,7 +192,7 @@ func TestServer_CreateCallback(t *testing.T) { name: "code callback", req: &oidc_pb.CreateCallbackRequest{ AuthRequestId: func() string { - authRequestID, err := Tester.CreateOIDCAuthRequest(client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI) + authRequestID, err := Tester.CreateOIDCAuthRequest(CTX, client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI) require.NoError(t, err) return authRequestID }(), @@ -217,7 +217,7 @@ func TestServer_CreateCallback(t *testing.T) { AuthRequestId: func() string { client, err := Tester.CreateOIDCImplicitFlowClient(CTX, redirectURIImplicit) require.NoError(t, err) - authRequestID, err := Tester.CreateOIDCAuthRequestImplicit(client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURIImplicit) + authRequestID, err := Tester.CreateOIDCAuthRequestImplicit(CTX, client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURIImplicit) require.NoError(t, err) return authRequestID }(), diff --git a/internal/api/grpc/oidc/v2/server.go b/internal/api/grpc/oidc/v2/server.go index a7587dfdc..823594fbd 100644 --- a/internal/api/grpc/oidc/v2/server.go +++ b/internal/api/grpc/oidc/v2/server.go @@ -1,7 +1,7 @@ package oidc import ( - "github.com/zitadel/oidc/v2/pkg/op" + "github.com/zitadel/oidc/v3/pkg/op" "google.golang.org/grpc" "github.com/zitadel/zitadel/internal/api/authz" diff --git a/internal/api/grpc/system/instance_converter.go b/internal/api/grpc/system/instance_converter.go index 4eea0a18f..551079aec 100644 --- a/internal/api/grpc/system/instance_converter.go +++ b/internal/api/grpc/system/instance_converter.go @@ -3,7 +3,7 @@ package system import ( "strings" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/text/language" "github.com/zitadel/zitadel/internal/api/grpc/authn" diff --git a/internal/api/oidc/auth_request.go b/internal/api/oidc/auth_request.go index 4ba077d04..56c0902b1 100644 --- a/internal/api/oidc/auth_request.go +++ b/internal/api/oidc/auth_request.go @@ -7,8 +7,8 @@ import ( "time" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v2/pkg/oidc" - "github.com/zitadel/oidc/v2/pkg/op" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/op" "github.com/zitadel/zitadel/internal/api/authz" http_utils "github.com/zitadel/zitadel/internal/api/http" diff --git a/internal/api/oidc/auth_request_converter.go b/internal/api/oidc/auth_request_converter.go index 5999f21e5..8fbd18530 100644 --- a/internal/api/oidc/auth_request_converter.go +++ b/internal/api/oidc/auth_request_converter.go @@ -6,8 +6,8 @@ import ( "strings" "time" - "github.com/zitadel/oidc/v2/pkg/oidc" - "github.com/zitadel/oidc/v2/pkg/op" + "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" diff --git a/internal/api/oidc/auth_request_converter_v2.go b/internal/api/oidc/auth_request_converter_v2.go index 9f4c0d0a1..3a35b0157 100644 --- a/internal/api/oidc/auth_request_converter_v2.go +++ b/internal/api/oidc/auth_request_converter_v2.go @@ -3,7 +3,7 @@ package oidc import ( "time" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/zitadel/internal/command" ) diff --git a/internal/api/oidc/auth_request_integration_test.go b/internal/api/oidc/auth_request_integration_test.go index 532814bee..5b013fe86 100644 --- a/internal/api/oidc/auth_request_integration_test.go +++ b/internal/api/oidc/auth_request_integration_test.go @@ -11,8 +11,8 @@ import ( "github.com/muhlemmer/gu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v2/pkg/client/rp" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client/rp" + "github.com/zitadel/oidc/v3/pkg/oidc" http_utils "github.com/zitadel/zitadel/internal/api/http" oidc_api "github.com/zitadel/zitadel/internal/api/oidc" @@ -103,7 +103,7 @@ func TestOPStorage_CreateAccessToken_implicit(t *testing.T) { assert.Equal(t, "state", values.Get("state")) // check id_token / claims - provider, err := Tester.CreateRelyingParty(clientID, redirectURIImplicit) + provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURIImplicit) require.NoError(t, err) claims, err := rp.VerifyTokens[*oidc.IDTokenClaims](context.Background(), accessToken, idToken, provider.IDTokenVerifier()) require.NoError(t, err) @@ -147,7 +147,7 @@ func TestOPStorage_CreateAccessAndRefreshTokens_code(t *testing.T) { func TestOPStorage_CreateAccessAndRefreshTokens_refresh(t *testing.T) { clientID := createClient(t) - provider, err := Tester.CreateRelyingParty(clientID, redirectURI) + provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) @@ -177,13 +177,13 @@ func TestOPStorage_CreateAccessAndRefreshTokens_refresh(t *testing.T) { assertIDTokenClaims(t, newTokens.IDTokenClaims, armPasskey, startTime, changeTime) // refresh with an old refresh_token must fail - _, err = rp.RefreshAccessToken(provider, tokens.RefreshToken, "", "") + _, err = rp.RefreshTokens[*oidc.IDTokenClaims](CTX, provider, tokens.RefreshToken, "", "") require.Error(t, err) } func TestOPStorage_RevokeToken_access_token(t *testing.T) { clientID := createClient(t) - provider, err := Tester.CreateRelyingParty(clientID, redirectURI) + provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) @@ -206,11 +206,11 @@ func TestOPStorage_RevokeToken_access_token(t *testing.T) { assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime) // revoke access token - err = rp.RevokeToken(provider, tokens.AccessToken, "access_token") + err = rp.RevokeToken(CTX, provider, tokens.AccessToken, "access_token") require.NoError(t, err) // userinfo must fail - _, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) + _, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) require.Error(t, err) // refresh grant must still work @@ -218,15 +218,15 @@ func TestOPStorage_RevokeToken_access_token(t *testing.T) { require.NoError(t, err) // revocation with the same access token must not fail (with or without hint) - err = rp.RevokeToken(provider, tokens.AccessToken, "access_token") + err = rp.RevokeToken(CTX, provider, tokens.AccessToken, "access_token") require.NoError(t, err) - err = rp.RevokeToken(provider, tokens.AccessToken, "") + err = rp.RevokeToken(CTX, provider, tokens.AccessToken, "") require.NoError(t, err) } func TestOPStorage_RevokeToken_access_token_invalid_token_hint_type(t *testing.T) { clientID := createClient(t) - provider, err := Tester.CreateRelyingParty(clientID, redirectURI) + provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) @@ -249,11 +249,11 @@ func TestOPStorage_RevokeToken_access_token_invalid_token_hint_type(t *testing.T assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime) // revoke access token - err = rp.RevokeToken(provider, tokens.AccessToken, "refresh_token") + err = rp.RevokeToken(CTX, provider, tokens.AccessToken, "refresh_token") require.NoError(t, err) // userinfo must fail - _, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) + _, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) require.Error(t, err) // refresh grant must still work @@ -263,7 +263,7 @@ 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(clientID, redirectURI) + provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) @@ -286,11 +286,11 @@ func TestOPStorage_RevokeToken_refresh_token(t *testing.T) { assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime) // revoke refresh token -> invalidates also access token - err = rp.RevokeToken(provider, tokens.RefreshToken, "refresh_token") + err = rp.RevokeToken(CTX, provider, tokens.RefreshToken, "refresh_token") require.NoError(t, err) // userinfo must fail - _, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) + _, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) require.Error(t, err) // refresh must fail @@ -298,15 +298,15 @@ func TestOPStorage_RevokeToken_refresh_token(t *testing.T) { require.Error(t, err) // revocation with the same refresh token must not fail (with or without hint) - err = rp.RevokeToken(provider, tokens.RefreshToken, "refresh_token") + err = rp.RevokeToken(CTX, provider, tokens.RefreshToken, "refresh_token") require.NoError(t, err) - err = rp.RevokeToken(provider, tokens.RefreshToken, "") + err = rp.RevokeToken(CTX, provider, tokens.RefreshToken, "") require.NoError(t, err) } func TestOPStorage_RevokeToken_refresh_token_invalid_token_type_hint(t *testing.T) { clientID := createClient(t) - provider, err := Tester.CreateRelyingParty(clientID, redirectURI) + provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) @@ -329,11 +329,11 @@ func TestOPStorage_RevokeToken_refresh_token_invalid_token_type_hint(t *testing. assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime) // revoke refresh token even with a wrong hint - err = rp.RevokeToken(provider, tokens.RefreshToken, "access_token") + err = rp.RevokeToken(CTX, provider, tokens.RefreshToken, "access_token") require.NoError(t, err) // userinfo must fail - _, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) + _, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) require.Error(t, err) // refresh must fail @@ -365,15 +365,15 @@ func TestOPStorage_RevokeToken_invalid_client(t *testing.T) { // simulate second client (not part of the audience) trying to revoke the token otherClientID := createClient(t) - provider, err := Tester.CreateRelyingParty(otherClientID, redirectURI) + provider, err := Tester.CreateRelyingParty(CTX, otherClientID, redirectURI) require.NoError(t, err) - err = rp.RevokeToken(provider, tokens.AccessToken, "") + err = rp.RevokeToken(CTX, provider, tokens.AccessToken, "") require.Error(t, err) } func TestOPStorage_TerminateSession(t *testing.T) { clientID := createClient(t) - provider, err := Tester.CreateRelyingParty(clientID, redirectURI) + provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) authRequestID := createAuthRequest(t, clientID, redirectURI) sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) @@ -396,21 +396,21 @@ func TestOPStorage_TerminateSession(t *testing.T) { assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime) // userinfo must not fail - _, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) + _, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) require.NoError(t, err) - postLogoutRedirect, err := rp.EndSession(provider, tokens.IDToken, logoutRedirectURI, "state") + postLogoutRedirect, err := rp.EndSession(CTX, provider, tokens.IDToken, logoutRedirectURI, "state") require.NoError(t, err) assert.Equal(t, logoutRedirectURI+"?state=state", postLogoutRedirect.String()) // userinfo must fail - _, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) + _, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) require.Error(t, err) } func TestOPStorage_TerminateSession_refresh_grant(t *testing.T) { clientID := createClient(t) - provider, err := Tester.CreateRelyingParty(clientID, redirectURI) + provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess) sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) @@ -433,28 +433,28 @@ func TestOPStorage_TerminateSession_refresh_grant(t *testing.T) { assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime) // userinfo must not fail - _, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) + _, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) require.NoError(t, err) - postLogoutRedirect, err := rp.EndSession(provider, tokens.IDToken, logoutRedirectURI, "state") + postLogoutRedirect, err := rp.EndSession(CTX, provider, tokens.IDToken, logoutRedirectURI, "state") require.NoError(t, err) assert.Equal(t, logoutRedirectURI+"?state=state", postLogoutRedirect.String()) // userinfo must fail - _, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) + _, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) require.Error(t, err) refreshedTokens, err := refreshTokens(t, clientID, tokens.RefreshToken) require.NoError(t, err) // userinfo must not fail - _, err = rp.Userinfo(refreshedTokens.AccessToken, refreshedTokens.TokenType, refreshedTokens.IDTokenClaims.Subject, provider) + _, err = rp.Userinfo[*oidc.UserInfo](CTX, refreshedTokens.AccessToken, refreshedTokens.TokenType, refreshedTokens.IDTokenClaims.Subject, provider) require.NoError(t, err) } func TestOPStorage_TerminateSession_empty_id_token_hint(t *testing.T) { clientID := createClient(t) - provider, err := Tester.CreateRelyingParty(clientID, redirectURI) + provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) authRequestID := createAuthRequest(t, clientID, redirectURI) sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) @@ -476,12 +476,12 @@ func TestOPStorage_TerminateSession_empty_id_token_hint(t *testing.T) { assertTokens(t, tokens, false) assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime) - postLogoutRedirect, err := rp.EndSession(provider, "", logoutRedirectURI, "state") + 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()) // userinfo must not fail until login UI terminated session - _, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) + _, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) require.NoError(t, err) // simulate termination by login UI @@ -492,12 +492,12 @@ func TestOPStorage_TerminateSession_empty_id_token_hint(t *testing.T) { require.NoError(t, err) // userinfo must fail - _, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) + _, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) require.Error(t, err) } func exchangeTokens(t testing.TB, clientID, code string) (*oidc.Tokens[*oidc.IDTokenClaims], error) { - provider, err := Tester.CreateRelyingParty(clientID, redirectURI) + provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) codeVerifier := "codeVerifier" @@ -505,23 +505,10 @@ func exchangeTokens(t testing.TB, clientID, code string) (*oidc.Tokens[*oidc.IDT } func refreshTokens(t testing.TB, clientID, refreshToken string) (*oidc.Tokens[*oidc.IDTokenClaims], error) { - provider, err := Tester.CreateRelyingParty(clientID, redirectURI) + provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) - tokens, err := rp.RefreshAccessToken(provider, refreshToken, "", "") - if err != nil { - return nil, err - } - idToken, _ := tokens.Extra("id_token").(string) - claims, err := rp.VerifyTokens[*oidc.IDTokenClaims](context.Background(), tokens.AccessToken, idToken, provider.IDTokenVerifier()) - if err != nil { - return nil, err - } - return &oidc.Tokens[*oidc.IDTokenClaims]{ - Token: tokens, - IDToken: idToken, - IDTokenClaims: claims, - }, nil + return rp.RefreshTokens[*oidc.IDTokenClaims](CTX, provider, refreshToken, "", "") } func assertCodeResponse(t *testing.T, callback string) string { diff --git a/internal/api/oidc/client.go b/internal/api/oidc/client.go index 4bfbb6449..7c5628817 100644 --- a/internal/api/oidc/client.go +++ b/internal/api/oidc/client.go @@ -9,10 +9,10 @@ import ( "time" "github.com/dop251/goja" + "github.com/go-jose/go-jose/v3" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v2/pkg/oidc" - "github.com/zitadel/oidc/v2/pkg/op" - "gopkg.in/square/go-jose.v2" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/op" "github.com/zitadel/zitadel/internal/actions" "github.com/zitadel/zitadel/internal/actions/object" diff --git a/internal/api/oidc/client_converter.go b/internal/api/oidc/client_converter.go index 5f3f25f75..ec208db27 100644 --- a/internal/api/oidc/client_converter.go +++ b/internal/api/oidc/client_converter.go @@ -4,8 +4,8 @@ import ( "strings" "time" - "github.com/zitadel/oidc/v2/pkg/oidc" - "github.com/zitadel/oidc/v2/pkg/op" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/op" "github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/domain" diff --git a/internal/api/oidc/client_credentials.go b/internal/api/oidc/client_credentials.go index fda1f6c94..3c2f272ea 100644 --- a/internal/api/oidc/client_credentials.go +++ b/internal/api/oidc/client_credentials.go @@ -3,8 +3,8 @@ package oidc import ( "time" - "github.com/zitadel/oidc/v2/pkg/oidc" - "github.com/zitadel/oidc/v2/pkg/op" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/op" ) type clientCredentialsRequest struct { diff --git a/internal/api/oidc/client_integration_test.go b/internal/api/oidc/client_integration_test.go index 11121a8fa..8a7f58a44 100644 --- a/internal/api/oidc/client_integration_test.go +++ b/internal/api/oidc/client_integration_test.go @@ -9,9 +9,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v2/pkg/client/rp" - "github.com/zitadel/oidc/v2/pkg/client/rs" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client/rp" + "github.com/zitadel/oidc/v3/pkg/client/rs" + "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/zitadel/pkg/grpc/authn" "github.com/zitadel/zitadel/pkg/grpc/management" @@ -41,9 +41,9 @@ func TestOPStorage_SetUserinfoFromToken(t *testing.T) { assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime) // test actual userinfo - provider, err := Tester.CreateRelyingParty(clientID, redirectURI) + provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) - userinfo, err := rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) + userinfo, err := rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider) require.NoError(t, err) assertUserinfo(t, userinfo) } @@ -62,7 +62,7 @@ func TestOPStorage_SetIntrospectionFromToken(t *testing.T) { ExpirationDate: nil, }) require.NoError(t, err) - resourceServer, err := Tester.CreateResourceServer(keyResp.GetKeyDetails()) + resourceServer, err := Tester.CreateResourceServer(CTX, keyResp.GetKeyDetails()) require.NoError(t, err) scope := []string{oidc.ScopeOpenID, oidc.ScopeProfile, oidc.ScopeEmail, oidc.ScopeOfflineAccess} @@ -87,7 +87,7 @@ func TestOPStorage_SetIntrospectionFromToken(t *testing.T) { assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime) // test actual introspection - introspection, err := rs.Introspect(context.Background(), resourceServer, tokens.AccessToken) + introspection, err := rs.Introspect[*oidc.IntrospectionResponse](context.Background(), resourceServer, tokens.AccessToken) require.NoError(t, err) assertIntrospection(t, introspection, Tester.OIDCIssuer(), app.GetClientId(), diff --git a/internal/api/oidc/device_auth.go b/internal/api/oidc/device_auth.go index 7eee06096..80298e8af 100644 --- a/internal/api/oidc/device_auth.go +++ b/internal/api/oidc/device_auth.go @@ -5,8 +5,8 @@ import ( "time" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v2/pkg/oidc" - "github.com/zitadel/oidc/v2/pkg/op" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/op" "github.com/zitadel/zitadel/internal/api/ui/login" "github.com/zitadel/zitadel/internal/domain" diff --git a/internal/api/oidc/jwt-profile.go b/internal/api/oidc/jwt-profile.go index 47805783c..e2592a573 100644 --- a/internal/api/oidc/jwt-profile.go +++ b/internal/api/oidc/jwt-profile.go @@ -3,8 +3,8 @@ package oidc import ( "context" - "github.com/zitadel/oidc/v2/pkg/oidc" - "github.com/zitadel/oidc/v2/pkg/op" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/op" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/errors" diff --git a/internal/api/oidc/key.go b/internal/api/oidc/key.go index 237af7db4..b6252a565 100644 --- a/internal/api/oidc/key.go +++ b/internal/api/oidc/key.go @@ -5,9 +5,9 @@ import ( "fmt" "time" + "github.com/go-jose/go-jose/v3" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v2/pkg/op" - "gopkg.in/square/go-jose.v2" + "github.com/zitadel/oidc/v3/pkg/op" "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/crypto" diff --git a/internal/api/oidc/oidc_integration_test.go b/internal/api/oidc/oidc_integration_test.go index 1a1516040..7738e3d61 100644 --- a/internal/api/oidc/oidc_integration_test.go +++ b/internal/api/oidc/oidc_integration_test.go @@ -11,8 +11,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v2/pkg/client/rp" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client/rp" + "github.com/zitadel/oidc/v3/pkg/oidc" "google.golang.org/grpc/metadata" "github.com/zitadel/zitadel/internal/domain" @@ -216,7 +216,7 @@ func Test_ZITADEL_API_inactive_access_token(t *testing.T) { func Test_ZITADEL_API_terminated_session(t *testing.T) { clientID := createClient(t) - provider, err := Tester.CreateRelyingParty(clientID, redirectURI) + provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI) require.NoError(t, err) authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess, zitadelAudienceScope) sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId()) @@ -245,7 +245,7 @@ func Test_ZITADEL_API_terminated_session(t *testing.T) { require.Equal(t, User.GetUserId(), myUserResp.GetUser().GetId()) // refresh token - postLogoutRedirect, err := rp.EndSession(provider, tokens.IDToken, logoutRedirectURI, "state") + postLogoutRedirect, err := rp.EndSession(CTX, provider, tokens.IDToken, logoutRedirectURI, "state") require.NoError(t, err) assert.Equal(t, logoutRedirectURI+"?state=state", postLogoutRedirect.String()) @@ -271,13 +271,13 @@ func createImplicitClient(t testing.TB) string { } func createAuthRequest(t testing.TB, clientID, redirectURI string, scope ...string) string { - redURL, err := Tester.CreateOIDCAuthRequest(clientID, Tester.Users[integration.FirstInstanceUsersKey][integration.Login].ID, redirectURI, scope...) + redURL, err := Tester.CreateOIDCAuthRequest(CTX, clientID, Tester.Users[integration.FirstInstanceUsersKey][integration.Login].ID, redirectURI, scope...) require.NoError(t, err) return redURL } func createAuthRequestImplicit(t testing.TB, clientID, redirectURI string, scope ...string) string { - redURL, err := Tester.CreateOIDCAuthRequestImplicit(clientID, Tester.Users[integration.FirstInstanceUsersKey][integration.Login].ID, redirectURI, scope...) + redURL, err := Tester.CreateOIDCAuthRequestImplicit(CTX, clientID, Tester.Users[integration.FirstInstanceUsersKey][integration.Login].ID, redirectURI, scope...) require.NoError(t, err) return redURL } diff --git a/internal/api/oidc/op.go b/internal/api/oidc/op.go index da96302e6..c165b117b 100644 --- a/internal/api/oidc/op.go +++ b/internal/api/oidc/op.go @@ -7,8 +7,8 @@ import ( "time" "github.com/rakyll/statik/fs" - "github.com/zitadel/oidc/v2/pkg/oidc" - "github.com/zitadel/oidc/v2/pkg/op" + "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/assets" diff --git a/internal/api/saml/certificate.go b/internal/api/saml/certificate.go index 9e85e5098..972b3ac16 100644 --- a/internal/api/saml/certificate.go +++ b/internal/api/saml/certificate.go @@ -5,9 +5,9 @@ import ( "fmt" "time" + "github.com/go-jose/go-jose/v3" "github.com/zitadel/logging" "github.com/zitadel/saml/pkg/provider/key" - "gopkg.in/square/go-jose.v2" "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/crypto" diff --git a/internal/api/ui/console/console.go b/internal/api/ui/console/console.go index 7e00605b7..6f632136f 100644 --- a/internal/api/ui/console/console.go +++ b/internal/api/ui/console/console.go @@ -15,7 +15,7 @@ import ( "github.com/gorilla/mux" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v2/pkg/op" + "github.com/zitadel/oidc/v3/pkg/op" "github.com/zitadel/zitadel/cmd/build" "github.com/zitadel/zitadel/internal/api/authz" diff --git a/internal/api/ui/login/custom_action.go b/internal/api/ui/login/custom_action.go index 22b3f72cc..f7287dd1d 100644 --- a/internal/api/ui/login/custom_action.go +++ b/internal/api/ui/login/custom_action.go @@ -7,7 +7,7 @@ import ( "github.com/dop251/goja" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/text/language" "github.com/zitadel/zitadel/internal/actions" diff --git a/internal/api/ui/login/external_provider_handler.go b/internal/api/ui/login/external_provider_handler.go index c9cc94203..d9c8c04fc 100644 --- a/internal/api/ui/login/external_provider_handler.go +++ b/internal/api/ui/login/external_provider_handler.go @@ -7,8 +7,8 @@ import ( "github.com/crewjam/saml/samlsp" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v2/pkg/client/rp" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client/rp" + "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/oauth2" "golang.org/x/text/language" diff --git a/internal/api/ui/login/jwt_handler.go b/internal/api/ui/login/jwt_handler.go index 51b079584..aa7a4466d 100644 --- a/internal/api/ui/login/jwt_handler.go +++ b/internal/api/ui/login/jwt_handler.go @@ -8,7 +8,7 @@ import ( "strings" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/oauth2" http_util "github.com/zitadel/zitadel/internal/api/http" diff --git a/internal/authz/repository/eventsourcing/eventstore/token_verifier.go b/internal/authz/repository/eventsourcing/eventstore/token_verifier.go index f8ca3bf76..215338a88 100644 --- a/internal/authz/repository/eventsourcing/eventstore/token_verifier.go +++ b/internal/authz/repository/eventsourcing/eventstore/token_verifier.go @@ -7,10 +7,10 @@ import ( "strings" "time" + "github.com/go-jose/go-jose/v3" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v2/pkg/oidc" - "github.com/zitadel/oidc/v2/pkg/op" - "gopkg.in/square/go-jose.v2" + "github.com/zitadel/oidc/v3/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/op" "github.com/zitadel/zitadel/internal/api/authz" http_util "github.com/zitadel/zitadel/internal/api/http" @@ -275,7 +275,7 @@ func (repo *TokenVerifierRepo) getTokenIDAndSubject(ctx context.Context, accessT return splitToken[0], splitToken[1], true } -func (repo *TokenVerifierRepo) jwtTokenVerifier(ctx context.Context) op.AccessTokenVerifier { +func (repo *TokenVerifierRepo) jwtTokenVerifier(ctx context.Context) *op.AccessTokenVerifier { keySet := &openIDKeySet{repo.Query} issuer := http_util.BuildOrigin(authz.GetInstance(ctx).RequestedHost(), repo.ExternalSecure) return op.NewAccessTokenVerifier(issuer, keySet) diff --git a/internal/command/idp_intent.go b/internal/command/idp_intent.go index 265293a3a..edf28ef46 100644 --- a/internal/command/idp_intent.go +++ b/internal/command/idp_intent.go @@ -9,7 +9,7 @@ import ( "github.com/crewjam/saml" "github.com/crewjam/saml/samlsp" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/zitadel/internal/command/preparation" "github.com/zitadel/zitadel/internal/crypto" diff --git a/internal/command/idp_intent_test.go b/internal/command/idp_intent_test.go index aeffe72eb..27753bffb 100644 --- a/internal/command/idp_intent_test.go +++ b/internal/command/idp_intent_test.go @@ -9,7 +9,7 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/oauth2" "golang.org/x/text/language" diff --git a/internal/command/idp_model.go b/internal/command/idp_model.go index 2736087de..fc0665b57 100644 --- a/internal/command/idp_model.go +++ b/internal/command/idp_model.go @@ -7,7 +7,7 @@ import ( "time" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v2/pkg/client/rp" + "github.com/zitadel/oidc/v3/pkg/client/rp" "golang.org/x/oauth2" "github.com/zitadel/zitadel/internal/crypto" diff --git a/internal/command/instance_idp_test.go b/internal/command/instance_idp_test.go index a0be4798c..bf9456bf1 100644 --- a/internal/command/instance_idp_test.go +++ b/internal/command/instance_idp_test.go @@ -8,7 +8,7 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" - openid "github.com/zitadel/oidc/v2/pkg/oidc" + openid "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/crypto" diff --git a/internal/command/org_idp_test.go b/internal/command/org_idp_test.go index f85fb1c21..7740c0186 100644 --- a/internal/command/org_idp_test.go +++ b/internal/command/org_idp_test.go @@ -8,7 +8,7 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" - openid "github.com/zitadel/oidc/v2/pkg/oidc" + openid "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/zitadel/internal/crypto" "github.com/zitadel/zitadel/internal/domain" diff --git a/internal/command/org_test.go b/internal/command/org_test.go index 8696b3fb2..346f9f11a 100644 --- a/internal/command/org_test.go +++ b/internal/command/org_test.go @@ -7,7 +7,7 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" - openid "github.com/zitadel/oidc/v2/pkg/oidc" + openid "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/text/language" "github.com/zitadel/zitadel/internal/api/authz" diff --git a/internal/command/user_human_refresh_token_test.go b/internal/command/user_human_refresh_token_test.go index 760604c66..10f6b0ce5 100644 --- a/internal/command/user_human_refresh_token_test.go +++ b/internal/command/user_human_refresh_token_test.go @@ -8,7 +8,7 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/zitadel/internal/crypto" "github.com/zitadel/zitadel/internal/domain" diff --git a/internal/idp/providers/apple/apple.go b/internal/idp/providers/apple/apple.go index 9463cb61b..9664e006c 100644 --- a/internal/idp/providers/apple/apple.go +++ b/internal/idp/providers/apple/apple.go @@ -5,9 +5,9 @@ import ( "encoding/pem" "time" - "github.com/zitadel/oidc/v2/pkg/crypto" - openid "github.com/zitadel/oidc/v2/pkg/oidc" - "gopkg.in/square/go-jose.v2" + "github.com/go-jose/go-jose/v3" + "github.com/zitadel/oidc/v3/pkg/crypto" + openid "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/zitadel/internal/idp" "github.com/zitadel/zitadel/internal/idp/providers/oidc" diff --git a/internal/idp/providers/apple/session.go b/internal/idp/providers/apple/session.go index ae629f957..5e9143f05 100644 --- a/internal/idp/providers/apple/session.go +++ b/internal/idp/providers/apple/session.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" - openid "github.com/zitadel/oidc/v2/pkg/oidc" + openid "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/zitadel/internal/idp" "github.com/zitadel/zitadel/internal/idp/providers/oidc" diff --git a/internal/idp/providers/apple/session_test.go b/internal/idp/providers/apple/session_test.go index 207f21981..3c1ab5976 100644 --- a/internal/idp/providers/apple/session_test.go +++ b/internal/idp/providers/apple/session_test.go @@ -9,7 +9,7 @@ import ( "github.com/h2non/gock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - openid "github.com/zitadel/oidc/v2/pkg/oidc" + openid "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/oauth2" "golang.org/x/text/language" diff --git a/internal/idp/providers/azuread/azuread.go b/internal/idp/providers/azuread/azuread.go index 244f383e1..46445a397 100644 --- a/internal/idp/providers/azuread/azuread.go +++ b/internal/idp/providers/azuread/azuread.go @@ -3,7 +3,7 @@ package azuread import ( "fmt" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/oauth2" "golang.org/x/text/language" diff --git a/internal/idp/providers/azuread/azuread_test.go b/internal/idp/providers/azuread/azuread_test.go index 3febb43f9..122a70bb0 100644 --- a/internal/idp/providers/azuread/azuread_test.go +++ b/internal/idp/providers/azuread/azuread_test.go @@ -6,8 +6,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v2/pkg/client/rp" - openid "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client/rp" + openid "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/zitadel/internal/idp" "github.com/zitadel/zitadel/internal/idp/providers/oauth" diff --git a/internal/idp/providers/azuread/session.go b/internal/idp/providers/azuread/session.go index 5bc7bb84c..698cdad19 100644 --- a/internal/idp/providers/azuread/session.go +++ b/internal/idp/providers/azuread/session.go @@ -3,8 +3,8 @@ package azuread import ( "net/http" - httphelper "github.com/zitadel/oidc/v2/pkg/http" - "github.com/zitadel/oidc/v2/pkg/oidc" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/zitadel/internal/idp/providers/oauth" ) diff --git a/internal/idp/providers/azuread/session_test.go b/internal/idp/providers/azuread/session_test.go index 531d909b9..f68c4cc7d 100644 --- a/internal/idp/providers/azuread/session_test.go +++ b/internal/idp/providers/azuread/session_test.go @@ -10,7 +10,7 @@ import ( "github.com/h2non/gock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/oauth2" "golang.org/x/text/language" diff --git a/internal/idp/providers/github/session_test.go b/internal/idp/providers/github/session_test.go index 2ad9f449f..247ef35c6 100644 --- a/internal/idp/providers/github/session_test.go +++ b/internal/idp/providers/github/session_test.go @@ -10,7 +10,7 @@ import ( "github.com/h2non/gock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/oauth2" "golang.org/x/text/language" diff --git a/internal/idp/providers/gitlab/gitlab.go b/internal/idp/providers/gitlab/gitlab.go index 1bb02302f..76e9a74b4 100644 --- a/internal/idp/providers/gitlab/gitlab.go +++ b/internal/idp/providers/gitlab/gitlab.go @@ -1,7 +1,7 @@ package gitlab import ( - openid "github.com/zitadel/oidc/v2/pkg/oidc" + openid "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/zitadel/internal/idp" "github.com/zitadel/zitadel/internal/idp/providers/oidc" diff --git a/internal/idp/providers/gitlab/session_test.go b/internal/idp/providers/gitlab/session_test.go index de5904432..0853f3ce3 100644 --- a/internal/idp/providers/gitlab/session_test.go +++ b/internal/idp/providers/gitlab/session_test.go @@ -9,8 +9,8 @@ import ( "github.com/h2non/gock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v2/pkg/client/rp" - openid "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client/rp" + openid "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/oauth2" "golang.org/x/text/language" diff --git a/internal/idp/providers/google/google.go b/internal/idp/providers/google/google.go index 7036d4e10..221f2b61a 100644 --- a/internal/idp/providers/google/google.go +++ b/internal/idp/providers/google/google.go @@ -1,7 +1,7 @@ package google import ( - openid "github.com/zitadel/oidc/v2/pkg/oidc" + openid "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/zitadel/internal/idp" "github.com/zitadel/zitadel/internal/idp/providers/oidc" diff --git a/internal/idp/providers/google/session_test.go b/internal/idp/providers/google/session_test.go index d3edde0ea..1915adf1b 100644 --- a/internal/idp/providers/google/session_test.go +++ b/internal/idp/providers/google/session_test.go @@ -9,8 +9,8 @@ import ( "github.com/h2non/gock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v2/pkg/client/rp" - openid "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client/rp" + openid "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/oauth2" "golang.org/x/text/language" diff --git a/internal/idp/providers/jwt/session.go b/internal/idp/providers/jwt/session.go index be3ffc053..54fcc039e 100644 --- a/internal/idp/providers/jwt/session.go +++ b/internal/idp/providers/jwt/session.go @@ -8,8 +8,8 @@ import ( "time" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v2/pkg/client/rp" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client/rp" + "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/text/language" "github.com/zitadel/zitadel/internal/domain" diff --git a/internal/idp/providers/jwt/session_test.go b/internal/idp/providers/jwt/session_test.go index ae79ed22e..3a8210aec 100644 --- a/internal/idp/providers/jwt/session_test.go +++ b/internal/idp/providers/jwt/session_test.go @@ -7,14 +7,14 @@ import ( "testing" "time" + "github.com/go-jose/go-jose/v3" "github.com/golang/mock/gomock" "github.com/h2non/gock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/oauth2" "golang.org/x/text/language" - "gopkg.in/square/go-jose.v2" "github.com/zitadel/zitadel/internal/crypto" "github.com/zitadel/zitadel/internal/domain" diff --git a/internal/idp/providers/oauth/oauth2.go b/internal/idp/providers/oauth/oauth2.go index a31e9d4c2..ad8cbbd45 100644 --- a/internal/idp/providers/oauth/oauth2.go +++ b/internal/idp/providers/oauth/oauth2.go @@ -3,8 +3,8 @@ package oauth import ( "context" - "github.com/zitadel/oidc/v2/pkg/client/rp" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client/rp" + "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/oauth2" "github.com/zitadel/zitadel/internal/idp" diff --git a/internal/idp/providers/oauth/oauth2_test.go b/internal/idp/providers/oauth/oauth2_test.go index 5fdfbc218..814a7ac9c 100644 --- a/internal/idp/providers/oauth/oauth2_test.go +++ b/internal/idp/providers/oauth/oauth2_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v2/pkg/client/rp" + "github.com/zitadel/oidc/v3/pkg/client/rp" "golang.org/x/oauth2" "github.com/zitadel/zitadel/internal/idp" diff --git a/internal/idp/providers/oauth/session.go b/internal/idp/providers/oauth/session.go index e85116afa..810fc0472 100644 --- a/internal/idp/providers/oauth/session.go +++ b/internal/idp/providers/oauth/session.go @@ -5,9 +5,9 @@ import ( "errors" "net/http" - "github.com/zitadel/oidc/v2/pkg/client/rp" - httphelper "github.com/zitadel/oidc/v2/pkg/http" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client/rp" + httphelper "github.com/zitadel/oidc/v3/pkg/http" + "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/zitadel/internal/idp" ) diff --git a/internal/idp/providers/oauth/session_test.go b/internal/idp/providers/oauth/session_test.go index 9901ea11c..ce6fa3f10 100644 --- a/internal/idp/providers/oauth/session_test.go +++ b/internal/idp/providers/oauth/session_test.go @@ -9,7 +9,7 @@ import ( "github.com/h2non/gock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/oauth2" "golang.org/x/text/language" diff --git a/internal/idp/providers/oidc/oidc.go b/internal/idp/providers/oidc/oidc.go index aab525548..30d4d11ab 100644 --- a/internal/idp/providers/oidc/oidc.go +++ b/internal/idp/providers/oidc/oidc.go @@ -3,8 +3,8 @@ package oidc import ( "context" - "github.com/zitadel/oidc/v2/pkg/client/rp" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client/rp" + "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/zitadel/internal/idp" ) @@ -100,7 +100,7 @@ func New(name, issuer, clientID, clientSecret, redirectURI string, scopes []stri for _, option := range options { option(provider) } - provider.RelyingParty, err = rp.NewRelyingPartyOIDC(issuer, clientID, clientSecret, redirectURI, setDefaultScope(scopes), provider.options...) + provider.RelyingParty, err = rp.NewRelyingPartyOIDC(context.TODO(), issuer, clientID, clientSecret, redirectURI, setDefaultScope(scopes), provider.options...) if err != nil { return nil, err } diff --git a/internal/idp/providers/oidc/oidc_test.go b/internal/idp/providers/oidc/oidc_test.go index bbe08155c..d510bf15c 100644 --- a/internal/idp/providers/oidc/oidc_test.go +++ b/internal/idp/providers/oidc/oidc_test.go @@ -7,8 +7,8 @@ import ( "github.com/h2non/gock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v2/pkg/client/rp" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client/rp" + "github.com/zitadel/oidc/v3/pkg/oidc" "github.com/zitadel/zitadel/internal/idp" ) diff --git a/internal/idp/providers/oidc/session.go b/internal/idp/providers/oidc/session.go index 366e42643..bb44fb114 100644 --- a/internal/idp/providers/oidc/session.go +++ b/internal/idp/providers/oidc/session.go @@ -4,8 +4,8 @@ import ( "context" "errors" - "github.com/zitadel/oidc/v2/pkg/client/rp" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client/rp" + "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/text/language" "github.com/zitadel/zitadel/internal/domain" @@ -38,7 +38,7 @@ func (s *Session) FetchUser(ctx context.Context) (user idp.User, err error) { return nil, err } } - info, err := rp.Userinfo( + info, err := rp.Userinfo[*oidc.UserInfo](ctx, s.Tokens.AccessToken, s.Tokens.TokenType, s.Tokens.IDTokenClaims.GetSubject(), diff --git a/internal/idp/providers/oidc/session_test.go b/internal/idp/providers/oidc/session_test.go index afaa35804..200dac8fc 100644 --- a/internal/idp/providers/oidc/session_test.go +++ b/internal/idp/providers/oidc/session_test.go @@ -7,14 +7,14 @@ import ( "testing" "time" + "github.com/go-jose/go-jose/v3" "github.com/h2non/gock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zitadel/oidc/v2/pkg/client/rp" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client/rp" + "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/oauth2" "golang.org/x/text/language" - "gopkg.in/square/go-jose.v2" "github.com/zitadel/zitadel/internal/crypto" "github.com/zitadel/zitadel/internal/domain" diff --git a/internal/integration/client.go b/internal/integration/client.go index 71bc9805c..98a577be1 100644 --- a/internal/integration/client.go +++ b/internal/integration/client.go @@ -9,7 +9,7 @@ import ( crewjam_saml "github.com/crewjam/saml" "github.com/stretchr/testify/require" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/oauth2" "golang.org/x/text/language" "google.golang.org/grpc" diff --git a/internal/integration/integration.go b/internal/integration/integration.go index 3e270b1d7..61d7f9d90 100644 --- a/internal/integration/integration.go +++ b/internal/integration/integration.go @@ -19,8 +19,8 @@ import ( "github.com/spf13/viper" "github.com/zitadel/logging" - "github.com/zitadel/oidc/v2/pkg/client" - "github.com/zitadel/oidc/v2/pkg/oidc" + "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" diff --git a/internal/integration/oidc.go b/internal/integration/oidc.go index ad1a44de3..b6edcd3ae 100644 --- a/internal/integration/oidc.go +++ b/internal/integration/oidc.go @@ -8,10 +8,10 @@ import ( "strings" "time" - "github.com/zitadel/oidc/v2/pkg/client" - "github.com/zitadel/oidc/v2/pkg/client/rp" - "github.com/zitadel/oidc/v2/pkg/client/rs" - "github.com/zitadel/oidc/v2/pkg/oidc" + "github.com/zitadel/oidc/v3/pkg/client" + "github.com/zitadel/oidc/v3/pkg/client/rp" + "github.com/zitadel/oidc/v3/pkg/client/rs" + "github.com/zitadel/oidc/v3/pkg/oidc" http_util "github.com/zitadel/zitadel/internal/api/http" oidc_internal "github.com/zitadel/zitadel/internal/api/oidc" @@ -83,8 +83,8 @@ func (s *Tester) CreateAPIClient(ctx context.Context, projectID string) (*manage }) } -func (s *Tester) CreateOIDCAuthRequest(clientID, loginClient, redirectURI string, scope ...string) (authRequestID string, err error) { - provider, err := s.CreateRelyingParty(clientID, redirectURI, scope...) +func (s *Tester) CreateOIDCAuthRequest(ctx context.Context, clientID, loginClient, redirectURI string, scope ...string) (authRequestID string, err error) { + provider, err := s.CreateRelyingParty(ctx, clientID, redirectURI, scope...) if err != nil { return "", err } @@ -110,8 +110,8 @@ func (s *Tester) CreateOIDCAuthRequest(clientID, loginClient, redirectURI string return strings.TrimPrefix(loc.String(), prefixWithHost), nil } -func (s *Tester) CreateOIDCAuthRequestImplicit(clientID, loginClient, redirectURI string, scope ...string) (authRequestID string, err error) { - provider, err := s.CreateRelyingParty(clientID, redirectURI, scope...) +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...) if err != nil { return "", err } @@ -146,12 +146,12 @@ func (s *Tester) OIDCIssuer() string { return http_util.BuildHTTP(s.Config.ExternalDomain, s.Config.Port, s.Config.ExternalSecure) } -func (s *Tester) CreateRelyingParty(clientID, redirectURI string, scope ...string) (rp.RelyingParty, error) { +func (s *Tester) CreateRelyingParty(ctx context.Context, 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(s.OIDCIssuer(), clientID, "", redirectURI, scope, rp.WithHTTPClient(loginClient)) + return rp.NewRelyingPartyOIDC(ctx, s.OIDCIssuer(), clientID, "", redirectURI, scope, rp.WithHTTPClient(loginClient)) } type loginRoundTripper struct { @@ -163,12 +163,12 @@ func (c *loginRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) return c.RoundTripper.RoundTrip(req) } -func (s *Tester) CreateResourceServer(keyFileData []byte) (rs.ResourceServer, error) { +func (s *Tester) CreateResourceServer(ctx context.Context, keyFileData []byte) (rs.ResourceServer, error) { keyFile, err := client.ConfigFromKeyFileData(keyFileData) if err != nil { return nil, err } - return rs.NewResourceServerJWTProfile(s.OIDCIssuer(), keyFile.ClientID, keyFile.KeyID, []byte(keyFile.Key)) + return rs.NewResourceServerJWTProfile(ctx, s.OIDCIssuer(), keyFile.ClientID, keyFile.KeyID, []byte(keyFile.Key)) } func GetRequest(url string, headers map[string]string) (*http.Request, error) { From fb2bd157809a1b41ba58ef0f5b9da687111f17de Mon Sep 17 00:00:00 2001 From: Silvan Date: Tue, 17 Oct 2023 17:53:00 +0200 Subject: [PATCH 14/15] ci: allow restore errors (#6740) --- .github/workflows/console.yml | 1 + .github/workflows/core-integration-test.yml | 1 + .github/workflows/core-unit-test.yml | 1 + .github/workflows/core.yml | 1 + 4 files changed, 4 insertions(+) diff --git a/.github/workflows/console.yml b/.github/workflows/console.yml index bc4c5f089..8471bf5af 100644 --- a/.github/workflows/console.yml +++ b/.github/workflows/console.yml @@ -30,6 +30,7 @@ jobs: - uses: actions/cache/restore@v3 timeout-minutes: 1 + continue-on-error: true id: cache with: key: console-${{ hashFiles('console', 'proto', '!console/dist') }} diff --git a/.github/workflows/core-integration-test.yml b/.github/workflows/core-integration-test.yml index c99987d25..f57a79767 100644 --- a/.github/workflows/core-integration-test.yml +++ b/.github/workflows/core-integration-test.yml @@ -56,6 +56,7 @@ jobs: uses: actions/cache/restore@v3 id: cache timeout-minutes: 1 + continue-on-error: true name: restore previous results with: key: integration-test-postgres-${{ inputs.core_cache_key }} diff --git a/.github/workflows/core-unit-test.yml b/.github/workflows/core-unit-test.yml index c831758d4..3097cfd57 100644 --- a/.github/workflows/core-unit-test.yml +++ b/.github/workflows/core-unit-test.yml @@ -40,6 +40,7 @@ jobs: uses: actions/cache/restore@v3 id: cache timeout-minutes: 1 + continue-on-error: true name: restore previous results with: key: unit-test-${{ inputs.core_cache_key }} diff --git a/.github/workflows/core.yml b/.github/workflows/core.yml index c5d868533..45c4bbda0 100644 --- a/.github/workflows/core.yml +++ b/.github/workflows/core.yml @@ -41,6 +41,7 @@ jobs: - uses: actions/cache/restore@v3 timeout-minutes: 1 + continue-on-error: true id: cache with: key: core-${{ hashFiles( 'go.*', 'openapi', 'cmd', 'pkg/grpc/**/*.go', 'proto', 'internal') }} From c06dc106b81525e8ec6b3a929a100e2de661b5a5 Mon Sep 17 00:00:00 2001 From: Miguel Cabrerizo <30386061+doncicuto@users.noreply.github.com> Date: Wed, 18 Oct 2023 11:46:45 +0200 Subject: [PATCH 15/15] fix(Makefile): add -r to delete .artifacts/grpc (#6697) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6495993ed..dd07fe49c 100644 --- a/Makefile +++ b/Makefile @@ -83,7 +83,7 @@ console_build: console_dependencies console_client .PHONY: clean clean: - $(RM) .artifacts/grpc + $(RM) -r .artifacts/grpc $(RM) $(gen_authopt_path) $(RM) $(gen_zitadel_path)