diff --git a/backend/internal/actorprovider/service.go b/backend/internal/actorprovider/service.go index 41a2cd49d5..ba1525b7a4 100644 --- a/backend/internal/actorprovider/service.go +++ b/backend/internal/actorprovider/service.go @@ -127,13 +127,13 @@ func (p *actorProvider) AuthenticateActor( } // GetActor returns the backing entity record for the given actor ID. -func (p *actorProvider) GetActor(actorID string) (*providers.Entity, *tidcommon.ServiceError) { - entity, epErr := p.entityProvider.GetEntityProfile(actorID) +func (p *actorProvider) GetActor(ctx context.Context, actorID string) (*providers.Entity, *tidcommon.ServiceError) { + entity, epErr := p.entityProvider.GetEntityProfile(ctx, actorID) if epErr != nil { return nil, mapEntityProviderError(epErr) } if entity.Category == providers.EntityCategoryAgent { - ctx := security.WithRuntimeContext(context.Background()) + ctx := security.WithRuntimeContext(ctx) displayPaths := entitytype.ResolveDisplayAttributePaths( ctx, entitytype.TypeCategoryAgent, []string{entity.Type}, p.entityTypeSvc, p.logger) entity.Display = utils.ResolveDisplay(entity.ID, entity.Type, entity.Attributes, displayPaths) @@ -143,9 +143,9 @@ func (p *actorProvider) GetActor(actorID string) (*providers.Entity, *tidcommon. // GetActorGroups returns transitive group memberships for the given actor ID. func (p *actorProvider) GetActorGroups( - actorID string, + ctx context.Context, actorID string, ) ([]providers.EntityGroup, *tidcommon.ServiceError) { - groups, epErr := p.entityProvider.GetTransitiveEntityGroups(actorID) + groups, epErr := p.entityProvider.GetTransitiveEntityGroups(ctx, actorID) if epErr != nil { if epErr.Code == entityprovider.ErrorCodeNotImplemented { return nil, nil @@ -157,9 +157,9 @@ func (p *actorProvider) GetActorGroups( // GetTransitiveGroupAncestors returns the ancestor chain of a single group. func (p *actorProvider) GetTransitiveGroupAncestors( - groupID string, + ctx context.Context, groupID string, ) ([]string, *tidcommon.ServiceError) { - ancestors, epErr := p.entityProvider.GetTransitiveGroupAncestors(groupID) + ancestors, epErr := p.entityProvider.GetTransitiveGroupAncestors(ctx, groupID) if epErr != nil { if epErr.Code == entityprovider.ErrorCodeNotImplemented { return nil, nil @@ -171,12 +171,12 @@ func (p *actorProvider) GetTransitiveGroupAncestors( // GetActorRoles returns the roles assigned to the actor, directly and through the given groups. func (p *actorProvider) GetActorRoles( - actorID string, groupIDs []string, + ctx context.Context, actorID string, groupIDs []string, ) ([]string, *tidcommon.ServiceError) { if p.roleService == nil { return nil, nil } - return p.roleService.GetUserRoles(context.Background(), actorID, groupIDs) + return p.roleService.GetUserRoles(ctx, actorID, groupIDs) } func mapEntityProviderError(epErr *entityprovider.EntityProviderError) *tidcommon.ServiceError { diff --git a/backend/internal/actorprovider/service_test.go b/backend/internal/actorprovider/service_test.go index a7efd2c375..523a0caaa5 100644 --- a/backend/internal/actorprovider/service_test.go +++ b/backend/internal/actorprovider/service_test.go @@ -167,9 +167,9 @@ func (s *ActorProviderTestSuite) TestAuthenticateActor_Delegates_Failure() { func (s *ActorProviderTestSuite) TestGetActor_Delegates() { expected := &providers.Entity{ID: "app-1"} - s.mockEntity.On("GetEntityProfile", "app-1").Return(expected, (*entityprovider.EntityProviderError)(nil)) + s.mockEntity.On("GetEntityProfile", mock.Anything, "app-1").Return(expected, (*entityprovider.EntityProviderError)(nil)) - entity, err := s.provider.GetActor("app-1") + entity, err := s.provider.GetActor(context.Background(), "app-1") s.Nil(err) s.Equal(expected, entity) @@ -189,12 +189,12 @@ func (s *ActorProviderTestSuite) TestGetActor_AgentDisplayComesFromTheDisplayAtt []string{"default"}).Return(map[string]string{"default": tc.displayPath}, (*tidcommon.ServiceError)(nil)).Once() provider := Initialize(s.mockInbound, s.mockEntity, s.mockAuthn, s.mockRole, mockType) - s.mockEntity.On("GetEntityProfile", "agent-1").Return(&providers.Entity{ + s.mockEntity.On("GetEntityProfile", mock.Anything, "agent-1").Return(&providers.Entity{ ID: "agent-1", Category: providers.EntityCategoryAgent, Type: "default", Attributes: []byte(`{"name":"Ledger Agent"}`), }, (*entityprovider.EntityProviderError)(nil)).Once() - entity, err := provider.GetActor("agent-1") + entity, err := provider.GetActor(context.Background(), "agent-1") s.Nil(err) s.Equal(tc.want, entity.Display) @@ -204,9 +204,10 @@ func (s *ActorProviderTestSuite) TestGetActor_AgentDisplayComesFromTheDisplayAtt func (s *ActorProviderTestSuite) TestGetActorGroups_Delegates() { expected := []providers.EntityGroup{{ID: "group-1"}} - s.mockEntity.On("GetTransitiveEntityGroups", "app-1").Return(expected, (*entityprovider.EntityProviderError)(nil)) + s.mockEntity.On("GetTransitiveEntityGroups", mock.Anything, "app-1"). + Return(expected, (*entityprovider.EntityProviderError)(nil)) - groups, err := s.provider.GetActorGroups("app-1") + groups, err := s.provider.GetActorGroups(context.Background(), "app-1") s.Nil(err) s.Equal(expected, groups) @@ -218,7 +219,7 @@ func (s *ActorProviderTestSuite) TestGetActorRoles_Delegates() { s.mockRole.On("GetUserRoles", mock.Anything, "app-1", groupIDs). Return(expected, (*tidcommon.ServiceError)(nil)) - roles, err := s.provider.GetActorRoles("app-1", groupIDs) + roles, err := s.provider.GetActorRoles(context.Background(), "app-1", groupIDs) s.Nil(err) s.Equal(expected, roles) @@ -231,7 +232,7 @@ func (s *ActorProviderTestSuite) TestGetActorRoles_PropagatesError() { } s.mockRole.On("GetUserRoles", mock.Anything, "app-1", []string{"group-1"}).Return(nil, svcErr) - roles, err := s.provider.GetActorRoles("app-1", []string{"group-1"}) + roles, err := s.provider.GetActorRoles(context.Background(), "app-1", []string{"group-1"}) s.Nil(roles) s.Equal(svcErr, err) @@ -240,7 +241,7 @@ func (s *ActorProviderTestSuite) TestGetActorRoles_PropagatesError() { func (s *ActorProviderTestSuite) TestGetActorRoles_NilRoleService_ReturnsNil() { provider := Initialize(s.mockInbound, s.mockEntity, s.mockAuthn, nil, nil) - roles, err := provider.GetActorRoles("app-1", []string{"group-1"}) + roles, err := provider.GetActorRoles(context.Background(), "app-1", []string{"group-1"}) s.Nil(err) s.Nil(roles) diff --git a/backend/internal/actorprovider/utils.go b/backend/internal/actorprovider/utils.go index ffffc707fd..3a94696d58 100644 --- a/backend/internal/actorprovider/utils.go +++ b/backend/internal/actorprovider/utils.go @@ -24,7 +24,7 @@ func BuildApplication( return nil, &ErrorActorNotFound } - entity, entityErr := provider.GetActor(actorID) + entity, entityErr := provider.GetActor(ctx, actorID) if entityErr != nil && entityErr.Code != ErrorEntityNotFound.Code { return nil, &tidcommon.InternalServerError } diff --git a/backend/internal/actorprovider/utils_test.go b/backend/internal/actorprovider/utils_test.go index 79eac5f04a..4d4c9c060a 100644 --- a/backend/internal/actorprovider/utils_test.go +++ b/backend/internal/actorprovider/utils_test.go @@ -55,7 +55,7 @@ func (s *UtilsTestSuite) TestBuildApplication_Success() { entity := &providers.Entity{ID: "app-1", SystemAttributes: attrs} s.mockInbound.On("GetInboundClientByEntityID", mock.Anything, "app-1").Return(client, nil) - s.mockEntity.On("GetEntityProfile", "app-1").Return(entity, (*entityprovider.EntityProviderError)(nil)) + s.mockEntity.On("GetEntityProfile", mock.Anything, "app-1").Return(entity, (*entityprovider.EntityProviderError)(nil)) app, svcErr := BuildApplication(context.Background(), s.provider, "app-1") @@ -81,7 +81,7 @@ func (s *UtilsTestSuite) TestBuildApplication_NilClient() { func (s *UtilsTestSuite) TestBuildApplication_EntityLoadError() { client := &inboundmodel.InboundClient{ID: "app-1"} s.mockInbound.On("GetInboundClientByEntityID", mock.Anything, "app-1").Return(client, nil) - s.mockEntity.On("GetEntityProfile", "app-1").Return( + s.mockEntity.On("GetEntityProfile", mock.Anything, "app-1").Return( (*providers.Entity)(nil), entityprovider.NewEntityProviderError("INTERNAL_ERROR", "boom", "")) @@ -94,7 +94,7 @@ func (s *UtilsTestSuite) TestBuildApplication_EntityLoadError() { func (s *UtilsTestSuite) TestBuildApplication_EntityNotFound() { client := &inboundmodel.InboundClient{ID: "app-1", AllowedUserTypes: []string{"customer"}} s.mockInbound.On("GetInboundClientByEntityID", mock.Anything, "app-1").Return(client, nil) - s.mockEntity.On("GetEntityProfile", "app-1").Return( + s.mockEntity.On("GetEntityProfile", mock.Anything, "app-1").Return( (*providers.Entity)(nil), entityprovider.NewEntityProviderError(entityprovider.ErrorCodeEntityNotFound, "missing", "")) diff --git a/backend/internal/application/service.go b/backend/internal/application/service.go index b719c6e23b..40ebd2a04a 100644 --- a/backend/internal/application/service.go +++ b/backend/internal/application/service.go @@ -412,7 +412,7 @@ func (as *applicationService) GetOAuthApplication( appEntity, entErr := as.entityService.GetEntityProfile(ctx, client.ID) if entErr != nil && !errors.Is(entErr, entity.ErrEntityNotFound) { as.logger.Error(ctx, "Failed to load entity for OAuth client", - log.String("entityID", client.ID), log.Error(entErr)) + log.MaskedString("entityID", client.ID), log.Error(entErr)) return nil, &tidcommon.InternalServerError } if appEntity == nil || appEntity.Category != providers.EntityCategoryApp { diff --git a/backend/internal/authn/github/service.go b/backend/internal/authn/github/service.go index 7b56176527..32de562408 100644 --- a/backend/internal/authn/github/service.go +++ b/backend/internal/authn/github/service.go @@ -137,7 +137,7 @@ func (g *githubOAuthAuthnService) GetOAuthClientConfig(ctx context.Context, idpI // fetches user info, and builds the federated token. The entity is resolved later through recorded links. func (g *githubOAuthAuthnService) Authenticate(ctx context.Context, idpID string, authzData authncm.AuthorizationData) (*authncm.AuthnResult, *tidcommon.ServiceError) { - logger := g.logger.With(log.String("idpId", idpID)) + logger := g.logger.With(log.String(log.LoggerKeyIDPID, idpID)) logger.Debug(ctx, "Performing federated GitHub OAuth authentication") tokenResp, svcErr := g.ExchangeCodeForToken(ctx, idpID, authzData.Code, true) diff --git a/backend/internal/authn/google/service.go b/backend/internal/authn/google/service.go index 3b6deb2d82..d07f4449c8 100644 --- a/backend/internal/authn/google/service.go +++ b/backend/internal/authn/google/service.go @@ -89,7 +89,7 @@ func (g *googleOIDCAuthnService) ValidateTokenResponse(ctx context.Context, idpI // is called with validateResponse set to true. func (g *googleOIDCAuthnService) ValidateIDToken( ctx context.Context, idpID, idToken string) *tidcommon.ServiceError { - logger := g.logger.With(log.String("idpId", idpID)) + logger := g.logger.With(log.String(log.LoggerKeyIDPID, idpID)) logger.Debug(ctx, "Validating ID token") if strings.TrimSpace(idToken) == "" { @@ -137,7 +137,7 @@ func (g *googleOIDCAuthnService) ValidateIDToken( aud, ok := claims["aud"].(string) if !ok || aud != oAuthClientConfig.ClientID { logger.Debug(ctx, "Invalid ID token audience", log.String("audience", aud), - log.MaskedString("clientId", oAuthClientConfig.ClientID)) + log.MaskedString("clientID", oAuthClientConfig.ClientID)) return tidcommon.CustomServiceError(authnoidc.ErrorInvalidIDToken, tidcommon.I18nMessage{ Key: "error.authnservice.google.invalid_id_token_audience_description", DefaultValue: "The ID token audience does not match the expected client ID", @@ -224,7 +224,7 @@ func (g *googleOIDCAuthnService) GetOAuthClientConfig(ctx context.Context, idpID // resolved later through recorded links. func (g *googleOIDCAuthnService) Authenticate(ctx context.Context, idpID string, authzData common.AuthorizationData) (*common.AuthnResult, *tidcommon.ServiceError) { - logger := g.logger.With(log.String("idpId", idpID)) + logger := g.logger.With(log.String(log.LoggerKeyIDPID, idpID)) logger.Debug(ctx, "Performing federated Google OIDC authentication") tokenResp, svcErr := g.ExchangeCodeForToken(ctx, idpID, authzData.Code, true) diff --git a/backend/internal/authn/oauth/service.go b/backend/internal/authn/oauth/service.go index b071abbd6e..fd401c4110 100644 --- a/backend/internal/authn/oauth/service.go +++ b/backend/internal/authn/oauth/service.go @@ -68,7 +68,7 @@ func newOAuthAuthnService(httpClient syshttp.HTTPClientInterface, // GetOAuthClientConfig retrieves the OAuth client configuration for the given identity provider ID. func (s *oAuthAuthnService) GetOAuthClientConfig(ctx context.Context, idpID string) ( *OAuthClientConfig, *tidcommon.ServiceError) { - logger := s.logger.With(log.String("idpId", idpID)) + logger := s.logger.With(log.String(log.LoggerKeyIDPID, idpID)) if strings.TrimSpace(idpID) == "" { return nil, &ErrorEmptyIdpID } @@ -101,7 +101,7 @@ func (s *oAuthAuthnService) GetOAuthClientConfig(ctx context.Context, idpID stri // BuildAuthorizeURL constructs the authorization request URL for the external identity provider. func (s *oAuthAuthnService) BuildAuthorizeURL( ctx context.Context, idpID string) (string, map[string]string, *tidcommon.ServiceError) { - logger := s.logger.With(log.String("idpId", idpID)) + logger := s.logger.With(log.String(log.LoggerKeyIDPID, idpID)) logger.Debug(ctx, "Building authorize URL") oAuthClientConfig, svcErr := s.GetOAuthClientConfig(ctx, idpID) @@ -151,7 +151,7 @@ func (s *oAuthAuthnService) BuildAuthorizeURL( // and validates the token response if validateResponse is true. func (s *oAuthAuthnService) ExchangeCodeForToken(ctx context.Context, idpID, code string, validateResponse bool) ( *TokenResponse, *tidcommon.ServiceError) { - logger := s.logger.With(log.String("idpId", idpID)) + logger := s.logger.With(log.String(log.LoggerKeyIDPID, idpID)) logger.Debug(ctx, "Exchanging authorization code for token") if strings.TrimSpace(code) == "" { @@ -192,7 +192,7 @@ func (s *oAuthAuthnService) ExchangeCodeForToken(ctx context.Context, idpID, cod // to true. Hence generally you may not need to call this method explicitly. func (s *oAuthAuthnService) ValidateTokenResponse(ctx context.Context, idpID string, tokenResp *TokenResponse) *tidcommon.ServiceError { - logger := s.logger.With(log.String("idpId", idpID)) + logger := s.logger.With(log.String(log.LoggerKeyIDPID, idpID)) logger.Debug(ctx, "Validating token response") if tokenResp == nil { @@ -252,7 +252,7 @@ func (s *oAuthAuthnService) FetchUserInfoWithClientConfig(ctx context.Context, o // claim and builds the federated token. The entity is resolved later through recorded links. func (s *oAuthAuthnService) Authenticate(ctx context.Context, idpID string, authzData common.AuthorizationData) (*common.AuthnResult, *tidcommon.ServiceError) { - logger := s.logger.With(log.String("idpId", idpID)) + logger := s.logger.With(log.String(log.LoggerKeyIDPID, idpID)) logger.Debug(ctx, "Performing federated OAuth authentication") tokenResp, svcErr := s.ExchangeCodeForToken(ctx, idpID, authzData.Code, true) diff --git a/backend/internal/authn/oidc/service.go b/backend/internal/authn/oidc/service.go index 6e1e09c678..2f6b355054 100644 --- a/backend/internal/authn/oidc/service.go +++ b/backend/internal/authn/oidc/service.go @@ -134,7 +134,7 @@ func (s *oidcAuthnService) ValidateTokenResponse(ctx context.Context, idpID stri // to true. Hence generally you may not need to call this method explicitly if ExchangeCodeForToken method // is called with validateResponse set to true. func (s *oidcAuthnService) ValidateIDToken(ctx context.Context, idpID, idToken string) *tidcommon.ServiceError { - logger := s.logger.With(log.String("idpId", idpID)) + logger := s.logger.With(log.String(log.LoggerKeyIDPID, idpID)) logger.Debug(ctx, "Validating ID token") if strings.TrimSpace(idToken) == "" { @@ -197,7 +197,7 @@ func (s *oidcAuthnService) FetchUserInfo(ctx context.Context, idpID, accessToken // resolved later through recorded links. func (s *oidcAuthnService) Authenticate(ctx context.Context, idpID string, authzData authncm.AuthorizationData) (*authncm.AuthnResult, *tidcommon.ServiceError) { - logger := s.logger.With(log.String("idpId", idpID)) + logger := s.logger.With(log.String(log.LoggerKeyIDPID, idpID)) logger.Debug(ctx, "Performing federated OIDC authentication") tokenResp, svcErr := s.ExchangeCodeForToken(ctx, idpID, authzData.Code, true) diff --git a/backend/internal/authn/service.go b/backend/internal/authn/service.go index 42cd4b2cb1..cab8ae40fc 100644 --- a/backend/internal/authn/service.go +++ b/backend/internal/authn/service.go @@ -334,7 +334,7 @@ func (as *authenticationService) StartIDPAuthentication( ) ( *IDPAuthInitData, *tidcommon.ServiceError) { logger := log.GetLogger().With(log.String(log.LoggerKeyComponentName, svcLoggerComponentName)) - logger.Debug(ctx, "Starting IDP authentication", log.String("idpId", idpID)) + logger.Debug(ctx, "Starting IDP authentication", log.String(log.LoggerKeyIDPID, idpID)) if strings.TrimSpace(idpID) == "" { return nil, &common.ErrorInvalidIDPID @@ -363,7 +363,7 @@ func (as *authenticationService) StartIDPAuthentication( case providers.IDPTypeGitHub: redirectURL, _, buildURLErr = as.githubService.BuildAuthorizeURL(ctx, idpID) default: - logger.Error(ctx, "Unsupported IDP type", log.String("idpId", idpID), + logger.Error(ctx, "Unsupported IDP type", log.String(log.LoggerKeyIDPID, idpID), log.String("type", string(identityProvider.Type))) return nil, &tidcommon.InternalServerError } @@ -379,7 +379,7 @@ func (as *authenticationService) StartIDPAuthentication( } sessionToken, err := as.createSessionToken(ctx, idpID, identityProvider.Type, nonce) if err != nil { - logger.Error(ctx, "Failed to create session token", log.String("idpId", idpID), + logger.Error(ctx, "Failed to create session token", log.String(log.LoggerKeyIDPID, idpID), log.String("error", err.Error.DefaultValue)) return nil, &tidcommon.InternalServerError } @@ -738,7 +738,7 @@ func (as *authenticationService) handleIDPServiceError( } logger.Error(ctx, "Error occurred while retrieving IDP", - log.String("idpId", idpID), log.Any("error", svcErr)) + log.String(log.LoggerKeyIDPID, idpID), log.Any("error", svcErr)) return &tidcommon.InternalServerError } diff --git a/backend/internal/authnprovider/defaultprovider/default_authn_provider.go b/backend/internal/authnprovider/defaultprovider/default_authn_provider.go index 2f21f54f48..9ad2e40710 100644 --- a/backend/internal/authnprovider/defaultprovider/default_authn_provider.go +++ b/backend/internal/authnprovider/defaultprovider/default_authn_provider.go @@ -267,7 +267,7 @@ func (p *defaultAuthnProvider) StoreAccountLink(ctx context.Context, entityRefer "The user has reached the limit of linked accounts") } return p.logAndReturnServerError(ctx, "Failed to link account", - log.String("idpId", idpID), log.String("error", err.Error())) + log.String(log.LoggerKeyIDPID, idpID), log.String("error", err.Error())) } return nil } diff --git a/backend/internal/authnprovider/manager/manager.go b/backend/internal/authnprovider/manager/manager.go index 41be5a919a..0cce129b68 100644 --- a/backend/internal/authnprovider/manager/manager.go +++ b/backend/internal/authnprovider/manager/manager.go @@ -242,7 +242,7 @@ func (m *authnProviderManager) checkSubjectAllowed( return nil } m.logger.Debug(ctx, "resolved subject is not allowed for the application", - log.String("entityId", entityRef.EntityID), + log.MaskedString(log.LoggerKeyEntityID, entityRef.EntityID), log.String("entityCategory", entityRef.EntityCategory), log.String("entityType", entityRef.EntityType)) return &ErrorSubjectNotAllowed diff --git a/backend/internal/authz/engine/authzenpdpengine.go b/backend/internal/authz/engine/authzenpdpengine.go index 1793c592d7..ad600365aa 100644 --- a/backend/internal/authz/engine/authzenpdpengine.go +++ b/backend/internal/authz/engine/authzenpdpengine.go @@ -240,7 +240,7 @@ func (p *authZENPDPEngine) evaluateSingle( if err := p.post(ctx, settings, evaluationEndpoint, payload, &responseDecision); err != nil { p.logger.Error(ctx, "AuthZEN evaluation failed", log.String("pdp_endpoint", evaluationEndpoint), - log.String("resource_server_id", evaluation.ResourceServer.ID), + log.String("resourceServerID", evaluation.ResourceServer.ID), log.String("action", evaluation.Permission.Name), log.Error(err), ) diff --git a/backend/internal/authzen/service.go b/backend/internal/authzen/service.go index 56ad519714..e6642f84e4 100644 --- a/backend/internal/authzen/service.go +++ b/backend/internal/authzen/service.go @@ -439,7 +439,7 @@ func (s *authzenService) resolveSubject(ctx context.Context, subject Subject) (S if s.entityProvider == nil { return subject, nil } - entity, err := s.entityProvider.GetEntityProfile(subject.ID) + entity, err := s.entityProvider.GetEntityProfile(ctx, subject.ID) if err != nil { if err.Code == entityprovider.ErrorCodeNotImplemented { return subject, nil @@ -539,7 +539,7 @@ func (s *authzenService) resolveGroupIDs(ctx context.Context, entityID string) ( return []string{}, nil } - groups, err := s.entityProvider.GetTransitiveEntityGroups(entityID) + groups, err := s.entityProvider.GetTransitiveEntityGroups(ctx, entityID) if err != nil { if err.Code == entityprovider.ErrorCodeNotImplemented { return []string{}, nil diff --git a/backend/internal/authzen/service_test.go b/backend/internal/authzen/service_test.go index 66a4cb6a9b..da47f52a92 100644 --- a/backend/internal/authzen/service_test.go +++ b/backend/internal/authzen/service_test.go @@ -49,7 +49,7 @@ func (s *ServiceTestSuite) SetupTest() { } func (s *ServiceTestSuite) mockValidSubject() { - s.entityProviderMock.On("GetEntityProfile", testSubjectID).Return(&providers.Entity{ + s.entityProviderMock.On("GetEntityProfile", mock.Anything, testSubjectID).Return(&providers.Entity{ ID: testSubjectID, Category: providers.EntityCategory(testSubjectType), }, nil) @@ -76,7 +76,7 @@ func (s *ServiceTestSuite) TestEvaluateAccessAllowed() { s.mockResourceServerIdentifier("booking") s.mockValidAction(testBookingReadAction) s.mockValidSubject() - s.entityProviderMock.On("GetTransitiveEntityGroups", "user1").Return([]providers.EntityGroup{ + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, "user1").Return([]providers.EntityGroup{ {ID: "group1"}, {ID: "group1"}, {ID: "group2"}, @@ -123,7 +123,7 @@ func (s *ServiceTestSuite) TestEvaluateAccessPassesPropertiesToAuthz() { s.mockValidSubject() s.mockResourceServerIdentifier("booking") s.mockValidAction(testBookingReadAction) - s.entityProviderMock.On("GetTransitiveEntityGroups", "user1").Return([]providers.EntityGroup{}, nil) + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, "user1").Return([]providers.EntityGroup{}, nil) s.authzMock.On("EvaluateAccess", mock.Anything, providers.AccessEvaluationRequest{ Subject: providers.Subject{ Category: "user", @@ -159,7 +159,7 @@ func (s *ServiceTestSuite) TestEvaluateAccessDenied() { s.mockValidSubject() s.mockResourceServerIdentifier("booking") s.mockValidAction("booking:delete") - s.entityProviderMock.On("GetTransitiveEntityGroups", "user1").Return([]providers.EntityGroup{}, nil) + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, "user1").Return([]providers.EntityGroup{}, nil) s.authzMock.On("EvaluateAccess", mock.Anything, providers.AccessEvaluationRequest{ Subject: providers.Subject{Category: "user", ID: "user1", GroupIDs: []string{}}, ResourceServer: providers.AccessEvaluationResourceServer{ @@ -185,14 +185,14 @@ func (s *ServiceTestSuite) TestEvaluateAccessProviderNotImplementedUsesEmptyGrou Action: Action{Name: "report:read"}, } - s.entityProviderMock.On("GetEntityProfile", "app1").Return( + s.entityProviderMock.On("GetEntityProfile", mock.Anything, "app1").Return( (*providers.Entity)(nil), entityprovider.NewEntityProviderError( entityprovider.ErrorCodeNotImplemented, "not implemented", "not implemented"), ) s.mockResourceServerIdentifier("report") s.mockValidAction("report:read") - s.entityProviderMock.On("GetTransitiveEntityGroups", "app1").Return( + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, "app1").Return( []providers.EntityGroup(nil), entityprovider.NewEntityProviderError( entityprovider.ErrorCodeNotImplemented, "not implemented", "not implemented"), @@ -224,7 +224,7 @@ func (s *ServiceTestSuite) TestEvaluateAccessInfersSubjectTypeWhenTypeEmpty() { s.mockValidSubject() s.mockResourceServerIdentifier("booking") s.mockValidAction(testBookingReadAction) - s.entityProviderMock.On("GetTransitiveEntityGroups", "user1").Return([]providers.EntityGroup{}, nil) + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, "user1").Return([]providers.EntityGroup{}, nil) s.authzMock.On("EvaluateAccess", mock.Anything, providers.AccessEvaluationRequest{ Subject: providers.Subject{Category: "user", ID: "user1", GroupIDs: []string{}}, ResourceServer: providers.AccessEvaluationResourceServer{ @@ -252,7 +252,7 @@ func (s *ServiceTestSuite) TestEvaluateAccessGroupResolutionFailure() { s.mockValidSubject() s.mockResourceServerIdentifier("booking") s.mockValidAction(testBookingReadAction) - s.entityProviderMock.On("GetTransitiveEntityGroups", "user1").Return( + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, "user1").Return( []providers.EntityGroup(nil), entityprovider.NewEntityProviderError(entityprovider.ErrorCodeSystemError, "failed", "failed"), ) @@ -275,7 +275,7 @@ func (s *ServiceTestSuite) TestEvaluateAccessAuthorizationFailure() { s.mockValidSubject() s.mockResourceServerIdentifier("booking") s.mockValidAction(testBookingReadAction) - s.entityProviderMock.On("GetTransitiveEntityGroups", "user1").Return([]providers.EntityGroup{}, nil) + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, "user1").Return([]providers.EntityGroup{}, nil) s.authzMock.On("EvaluateAccess", mock.Anything, providers.AccessEvaluationRequest{ Subject: providers.Subject{Category: "user", ID: "user1", GroupIDs: []string{}}, ResourceServer: providers.AccessEvaluationResourceServer{ @@ -352,7 +352,7 @@ func (s *ServiceTestSuite) TestEvaluateAccessInvalidSubjectType() { Action: Action{Name: testBookingReadAction}, } - s.entityProviderMock.On("GetEntityProfile", "user1").Return(&providers.Entity{ + s.entityProviderMock.On("GetEntityProfile", mock.Anything, "user1").Return(&providers.Entity{ ID: "user1", Category: providers.EntityCategoryUser, }, nil) @@ -426,14 +426,14 @@ func (s *ServiceTestSuite) TestEvaluateAccessBatchPreservesOrder() { }, } - s.entityProviderMock.On("GetEntityProfile", testSubjectID).Return(&providers.Entity{ + s.entityProviderMock.On("GetEntityProfile", mock.Anything, testSubjectID).Return(&providers.Entity{ ID: testSubjectID, Category: providers.EntityCategoryUser, }, nil).Once() s.mockResourceServerIdentifier("booking") s.mockValidAction(testBookingReadAction) s.mockValidAction("booking:delete") - s.entityProviderMock.On("GetTransitiveEntityGroups", testSubjectID). + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, testSubjectID). Return([]providers.EntityGroup{}, nil).Once() s.authzMock.On("EvaluateAccessBatch", mock.Anything, mock.MatchedBy(func(req providers.AccessEvaluationsRequest) bool { @@ -482,7 +482,8 @@ func (s *ServiceTestSuite) TestEvaluateAccessBatchInfersSubjectTypeOnce() { s.mockResourceServerIdentifier("booking") s.mockValidAction(testBookingReadAction) s.mockValidAction("booking:create") - s.entityProviderMock.On("GetTransitiveEntityGroups", testSubjectID).Return([]providers.EntityGroup{}, nil).Once() + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, testSubjectID). + Return([]providers.EntityGroup{}, nil).Once() s.authzMock.On("EvaluateAccessBatch", mock.Anything, mock.MatchedBy(func(req providers.AccessEvaluationsRequest) bool { return len(req.Evaluations) == 2 && @@ -521,7 +522,7 @@ func (s *ServiceTestSuite) TestEvaluateAccessBatchInvalidActionReturnsFalse() { }, } - s.entityProviderMock.On("GetEntityProfile", "user1").Return(&providers.Entity{ + s.entityProviderMock.On("GetEntityProfile", mock.Anything, "user1").Return(&providers.Entity{ ID: "user1", Category: providers.EntityCategoryUser, }, nil).Once() @@ -530,7 +531,8 @@ func (s *ServiceTestSuite) TestEvaluateAccessBatchInvalidActionReturnsFalse() { s.resourceMock.On("ValidatePermissions", mock.Anything, testResourceServerID, []string{"booking:archive"}). Return([]string{"booking:archive"}, nil) s.mockValidAction("booking:delete") - s.entityProviderMock.On("GetTransitiveEntityGroups", "user1").Return([]providers.EntityGroup{}, nil).Once() + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, "user1"). + Return([]providers.EntityGroup{}, nil).Once() s.authzMock.On("EvaluateAccessBatch", mock.Anything, mock.MatchedBy(func(req providers.AccessEvaluationsRequest) bool { return len(req.Evaluations) == 2 && @@ -573,14 +575,15 @@ func (s *ServiceTestSuite) TestEvaluateAccessBatchInvalidSubjectReturnsItemError }, } - s.entityProviderMock.On("GetEntityProfile", "agent1").Return(&providers.Entity{ + s.entityProviderMock.On("GetEntityProfile", mock.Anything, "agent1").Return(&providers.Entity{ ID: "agent1", Category: providers.EntityCategoryUser, }, nil).Once() s.mockValidSubject() s.mockResourceServerIdentifier("booking") s.mockValidAction(testBookingReadAction) - s.entityProviderMock.On("GetTransitiveEntityGroups", "user1").Return([]providers.EntityGroup{}, nil).Once() + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, "user1"). + Return([]providers.EntityGroup{}, nil).Once() s.authzMock.On("EvaluateAccessBatch", mock.Anything, mock.MatchedBy(func(req providers.AccessEvaluationsRequest) bool { return len(req.Evaluations) == 1 && @@ -619,21 +622,21 @@ func (s *ServiceTestSuite) TestEvaluateAccessBatchGroupResolutionFailureReturnsI }, } - s.entityProviderMock.On("GetEntityProfile", "user1").Return(&providers.Entity{ + s.entityProviderMock.On("GetEntityProfile", mock.Anything, "user1").Return(&providers.Entity{ ID: "user1", Category: providers.EntityCategoryUser, }, nil).Once() - s.entityProviderMock.On("GetEntityProfile", "user2").Return(&providers.Entity{ + s.entityProviderMock.On("GetEntityProfile", mock.Anything, "user2").Return(&providers.Entity{ ID: "user2", Category: providers.EntityCategoryUser, }, nil).Once() s.mockResourceServerIdentifier("booking") s.mockValidAction(testBookingReadAction) - s.entityProviderMock.On("GetTransitiveEntityGroups", "user1").Return( + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, "user1").Return( []providers.EntityGroup(nil), entityprovider.NewEntityProviderError(entityprovider.ErrorCodeSystemError, "failed", "failed"), ).Once() - s.entityProviderMock.On("GetTransitiveEntityGroups", "user2").Return([]providers.EntityGroup{ + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, "user2").Return([]providers.EntityGroup{ {ID: "group1"}, }, nil).Once() s.authzMock.On("EvaluateAccessBatch", mock.Anything, @@ -674,13 +677,14 @@ func (s *ServiceTestSuite) TestEvaluateAccessBatchMissingActionReturnsItemError( }, } - s.entityProviderMock.On("GetEntityProfile", "user1").Return(&providers.Entity{ + s.entityProviderMock.On("GetEntityProfile", mock.Anything, "user1").Return(&providers.Entity{ ID: "user1", Category: providers.EntityCategoryUser, }, nil).Once() s.mockResourceServerIdentifier("booking") s.mockValidAction(testBookingReadAction) - s.entityProviderMock.On("GetTransitiveEntityGroups", "user1").Return([]providers.EntityGroup{}, nil).Once() + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, "user1"). + Return([]providers.EntityGroup{}, nil).Once() s.authzMock.On("EvaluateAccessBatch", mock.Anything, mock.MatchedBy(func(req providers.AccessEvaluationsRequest) bool { return len(req.Evaluations) == 1 && @@ -719,7 +723,7 @@ func (s *ServiceTestSuite) TestEvaluateAccessBatchAllInvalidActionsReturnsFalseW }, } - s.entityProviderMock.On("GetEntityProfile", "user1").Return(&providers.Entity{ + s.entityProviderMock.On("GetEntityProfile", mock.Anything, "user1").Return(&providers.Entity{ ID: "user1", Category: providers.EntityCategoryUser, }, nil).Once() @@ -757,7 +761,7 @@ func (s *ServiceTestSuite) TestSearchActionsReturnsAuthorizedActions() { } s.mockValidSubject() - s.entityProviderMock.On("GetTransitiveEntityGroups", "user1").Return([]providers.EntityGroup{ + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, "user1").Return([]providers.EntityGroup{ {ID: "group1"}, }, nil) s.mockResourceServerIdentifier("booking") @@ -826,7 +830,7 @@ func (s *ServiceTestSuite) TestSearchActionsRejectsMismatchedSubjectType() { Resource: Resource{Type: "booking", ID: testBookingResourceID}, } - s.entityProviderMock.On("GetEntityProfile", testSubjectID).Return(&providers.Entity{ + s.entityProviderMock.On("GetEntityProfile", mock.Anything, testSubjectID).Return(&providers.Entity{ ID: testSubjectID, Category: providers.EntityCategoryUser, }, nil) @@ -848,7 +852,7 @@ func (s *ServiceTestSuite) TestSearchActionsPaginatesResourceServerActions() { } s.mockValidSubject() - s.entityProviderMock.On("GetTransitiveEntityGroups", "user1").Return([]providers.EntityGroup{}, nil) + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, "user1").Return([]providers.EntityGroup{}, nil) s.mockResourceServerIdentifier("booking") s.resourceMock.On("GetActionList", mock.Anything, testResourceServerID, (*string)(nil), providers.ActionKind(""), serverconst.MaxPageSize, 0). @@ -900,7 +904,7 @@ func (s *ServiceTestSuite) TestSearchActionsReturnsEmptyResultsWhenDenied() { } s.mockValidSubject() - s.entityProviderMock.On("GetTransitiveEntityGroups", "user1").Return([]providers.EntityGroup{}, nil) + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, "user1").Return([]providers.EntityGroup{}, nil) s.mockResourceServerIdentifier("booking") s.resourceMock.On("GetActionList", mock.Anything, testResourceServerID, (*string)(nil), providers.ActionKind(""), mock.Anything, 0). @@ -980,7 +984,7 @@ func (s *ServiceTestSuite) TestSearchActionsResourceServiceError() { } s.mockValidSubject() - s.entityProviderMock.On("GetTransitiveEntityGroups", "user1").Return([]providers.EntityGroup{}, nil) + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, "user1").Return([]providers.EntityGroup{}, nil) s.mockResourceServerIdentifier("booking") s.resourceMock.On("GetActionList", mock.Anything, testResourceServerID, (*string)(nil), providers.ActionKind(""), mock.Anything, 0). @@ -1000,7 +1004,7 @@ func (s *ServiceTestSuite) TestSearchActionsAuthorizationServiceError() { } s.mockValidSubject() - s.entityProviderMock.On("GetTransitiveEntityGroups", "user1").Return([]providers.EntityGroup{}, nil) + s.entityProviderMock.On("GetTransitiveEntityGroups", mock.Anything, "user1").Return([]providers.EntityGroup{}, nil) s.mockResourceServerIdentifier("booking") s.resourceMock.On("GetActionList", mock.Anything, testResourceServerID, (*string)(nil), providers.ActionKind(""), mock.Anything, 0). diff --git a/backend/internal/connection/value_capture.go b/backend/internal/connection/value_capture.go index 9b1389d076..3d6d5eac49 100644 --- a/backend/internal/connection/value_capture.go +++ b/backend/internal/connection/value_capture.go @@ -28,7 +28,7 @@ func (s *service) captureIDPValues(ctx context.Context, dto *providers.IDPDTO) { if err != nil { log.GetLogger().With(log.String(log.LoggerKeyComponentName, valueCaptureLoggerComponentName)).Warn(ctx, "Failed to read a connection's values, so none were captured", - log.String("connectionId", dto.ID), log.Error(err)) + log.String("connectionID", dto.ID), log.Error(err)) return } s.valueCapturer.CaptureValues(ctx, resourceTypeConnection, &model) @@ -44,7 +44,7 @@ func (s *service) captureSenderValues(ctx context.Context, dto *ncommon.Notifica if err != nil { log.GetLogger().With(log.String(log.LoggerKeyComponentName, valueCaptureLoggerComponentName)).Warn(ctx, "Failed to read a connection's values, so none were captured", - log.String("connectionId", dto.ID), log.Error(err)) + log.String("connectionID", dto.ID), log.Error(err)) return } s.valueCapturer.CaptureValues(ctx, resourceTypeConnection, &model) diff --git a/backend/internal/design/resolve/service.go b/backend/internal/design/resolve/service.go index bb8419d712..f9252a7ee9 100644 --- a/backend/internal/design/resolve/service.go +++ b/backend/internal/design/resolve/service.go @@ -87,7 +87,7 @@ func (drs *designResolveService) ResolveDesign( // which application IDs exist. if svcErr.Code == application.ErrorApplicationNotFound.Code { drs.logger.Debug(ctx, "No design resolved; application does not exist", - log.String("applicationId", id)) + log.String("applicationID", id)) return nil, &common.ErrorApplicationHasNoDesign } return nil, svcErr @@ -113,8 +113,8 @@ func (drs *designResolveService) ResolveDesign( // The referenced theme has been deleted; fall back to the system default by leaving // the theme unset in the response. drs.logger.Warn(ctx, "Application references a deleted theme; falling back to default", - log.String("applicationId", id), - log.String("themeId", app.ThemeID)) + log.String("applicationID", id), + log.String("themeID", app.ThemeID)) } else { return nil, svcErr } @@ -136,8 +136,8 @@ func (drs *designResolveService) ResolveDesign( // The referenced layout has been deleted; fall back to the system default by leaving // the layout unset in the response. drs.logger.Warn(ctx, "Application references a deleted layout; falling back to default", - log.String("applicationId", id), - log.String("layoutId", app.LayoutID)) + log.String("applicationID", id), + log.String("layoutID", app.LayoutID)) } else { return nil, svcErr } @@ -149,8 +149,8 @@ func (drs *designResolveService) ResolveDesign( drs.logger.Debug(ctx, "Successfully resolved design configuration", log.String("type", string(resolveType)), log.String("id", id), - log.String("themeId", app.ThemeID), - log.String("layoutId", app.LayoutID)) + log.String("themeID", app.ThemeID), + log.String("layoutID", app.LayoutID)) return designResponse, nil } @@ -201,7 +201,7 @@ func (drs *designResolveService) resolveDesignTokens( applicableTheme, err := resolveApplicableTheme(theme.Theme, colorScheme) if err != nil { drs.logger.Error(ctx, "Failed to resolve applicable theme for design tokens", - log.String("themeId", themeID), log.Error(err)) + log.String("themeID", themeID), log.Error(err)) return nil, &tidcommon.InternalServerError } diff --git a/backend/internal/entity/cache_backed_store.go b/backend/internal/entity/cache_backed_store.go index 9ef8f0aa02..8c838c2afa 100644 --- a/backend/internal/entity/cache_backed_store.go +++ b/backend/internal/entity/cache_backed_store.go @@ -295,7 +295,7 @@ func (s *cacheBackedEntityStore) parseEntityAttributes( var attrs map[string]interface{} if err := json.Unmarshal(raw, &attrs); err != nil { s.logger.Warn(ctx, "Failed to unmarshal entity attributes for cache key resolution", - log.String("entityID", entity.ID), log.Error(err)) + log.MaskedString("entityID", entity.ID), log.Error(err)) continue } for k, v := range attrs { @@ -334,7 +334,7 @@ func (s *cacheBackedEntityStore) invalidateIdentifierCache(ctx context.Context, fetched, err := s.store.GetEntity(ctx, entityID) if err != nil { s.logger.Error(ctx, "Failed to fetch entity for identifier cache invalidation", - log.String("entityID", entityID), log.Error(err)) + log.MaskedString("entityID", entityID), log.Error(err)) return } entity = &fetched @@ -359,7 +359,7 @@ func (s *cacheBackedEntityStore) cacheEntityByID(ctx context.Context, entity *pr } if err := s.entityByIDCache.Set(ctx, cache.CacheKey{Key: entity.ID}, entity); err != nil { s.logger.Error(ctx, "Failed to cache entity by ID", - log.String("entityID", entity.ID), log.Error(err)) + log.MaskedString("entityID", entity.ID), log.Error(err)) } } @@ -371,7 +371,7 @@ func (s *cacheBackedEntityStore) cacheEntityWithCredentialsByID(ctx context.Cont if err := s.entityWithCredentialsByIDCache.Set(ctx, cache.CacheKey{Key: ewc.Entity.ID}, ewc); err != nil { s.logger.Error(ctx, "Failed to cache entity with credentials by ID", - log.String("entityID", ewc.Entity.ID), log.Error(err)) + log.MaskedString("entityID", ewc.Entity.ID), log.Error(err)) } } @@ -381,10 +381,10 @@ func (s *cacheBackedEntityStore) invalidateEntityByID(ctx context.Context, entit } if err := s.entityByIDCache.Delete(ctx, cache.CacheKey{Key: entityID}); err != nil { s.logger.Error(ctx, "Failed to invalidate entity cache by ID", - log.String("entityID", entityID), log.Error(err)) + log.MaskedString("entityID", entityID), log.Error(err)) } if err := s.entityWithCredentialsByIDCache.Delete(ctx, cache.CacheKey{Key: entityID}); err != nil { s.logger.Error(ctx, "Failed to invalidate entity with credentials cache by ID", - log.String("entityID", entityID), log.Error(err)) + log.MaskedString("entityID", entityID), log.Error(err)) } } diff --git a/backend/internal/entity/service.go b/backend/internal/entity/service.go index 0c540a3fd0..4f2323f4b6 100644 --- a/backend/internal/entity/service.go +++ b/backend/internal/entity/service.go @@ -531,7 +531,7 @@ func (s *entityService) LinkAccount(ctx context.Context, entityID, idpID, sub st return ErrBadAttributesInRequest } s.logger.Debug(ctx, "Linking account", log.MaskedString("id", entityID), - log.String("idpId", idpID)) + log.String(log.LoggerKeyIDPID, idpID)) return s.transactioner.Transact(ctx, func(txCtx context.Context) error { current, err := s.store.LockEntity(txCtx, entityID) diff --git a/backend/internal/entityprovider/default_entity_provider.go b/backend/internal/entityprovider/default_entity_provider.go index 84bfe42832..393334f136 100644 --- a/backend/internal/entityprovider/default_entity_provider.go +++ b/backend/internal/entityprovider/default_entity_provider.go @@ -75,9 +75,9 @@ func (p *defaultEntityProvider) GetLinkedEntities( // GetEntity retrieves an entity by ID. func (p *defaultEntityProvider) GetEntity( - entityID string, + ctx context.Context, entityID string, ) (*providers.Entity, *EntityProviderError) { - ctx := security.WithRuntimeContext(context.Background()) + ctx = security.WithRuntimeContext(ctx) result, err := p.entitySvc.GetEntity(ctx, entityID) if err != nil { return nil, mapEntityError(err) @@ -87,9 +87,9 @@ func (p *defaultEntityProvider) GetEntity( // GetEntityProfile retrieves an entity's profile by ID, without reading its runtime state. func (p *defaultEntityProvider) GetEntityProfile( - entityID string, + ctx context.Context, entityID string, ) (*providers.Entity, *EntityProviderError) { - ctx := security.WithRuntimeContext(context.Background()) + ctx = security.WithRuntimeContext(ctx) result, err := p.entitySvc.GetEntityProfile(ctx, entityID) if err != nil { return nil, mapEntityError(err) @@ -180,9 +180,9 @@ func (p *defaultEntityProvider) UpdateSystemCredentials( // GetTransitiveEntityGroups retrieves all groups an entity belongs to, including inherited groups. func (p *defaultEntityProvider) GetTransitiveEntityGroups( - entityID string, + ctx context.Context, entityID string, ) ([]providers.EntityGroup, *EntityProviderError) { - ctx := security.WithRuntimeContext(context.Background()) + ctx = security.WithRuntimeContext(ctx) groups, err := p.entitySvc.GetTransitiveEntityGroups(ctx, entityID) if err != nil { return nil, mapEntityError(err) @@ -195,9 +195,9 @@ func (p *defaultEntityProvider) GetTransitiveEntityGroups( // GetTransitiveGroupAncestors resolves the ancestor chain of a single group. func (p *defaultEntityProvider) GetTransitiveGroupAncestors( - groupID string, + ctx context.Context, groupID string, ) ([]string, *EntityProviderError) { - ctx := security.WithRuntimeContext(context.Background()) + ctx = security.WithRuntimeContext(ctx) ancestors, err := p.entitySvc.GetTransitiveGroupAncestors(ctx, groupID) if err != nil { return nil, mapEntityError(err) diff --git a/backend/internal/entityprovider/default_entity_provider_test.go b/backend/internal/entityprovider/default_entity_provider_test.go index 56215e2d9f..fa19f068ea 100644 --- a/backend/internal/entityprovider/default_entity_provider_test.go +++ b/backend/internal/entityprovider/default_entity_provider_test.go @@ -4,6 +4,7 @@ package entityprovider import ( + "context" "encoding/json" "errors" "testing" @@ -92,7 +93,7 @@ func (suite *DefaultEntityProviderTestSuite) TestGetEntity() { // Test Success suite.mockService.On("GetEntity", mock.Anything, testEntityID).Return(expected, nil).Once() - e, err := suite.provider.GetEntity(testEntityID) + e, err := suite.provider.GetEntity(context.Background(), testEntityID) suite.Nil(err) suite.Equal(testEntityID, e.ID) suite.Equal(providers.EntityCategory("user"), e.Category) @@ -101,7 +102,7 @@ func (suite *DefaultEntityProviderTestSuite) TestGetEntity() { suite.mockService.On("GetEntity", mock.Anything, testEntityID). Return(nil, entity.ErrEntityNotFound).Once() - e, err = suite.provider.GetEntity(testEntityID) + e, err = suite.provider.GetEntity(context.Background(), testEntityID) suite.Nil(e) suite.NotNil(err) suite.Equal(ErrorCodeEntityNotFound, err.Code) @@ -117,7 +118,7 @@ func (suite *DefaultEntityProviderTestSuite) TestGetEntityProfile() { suite.mockService.On("GetEntityProfile", mock.Anything, testEntityID).Return(expected, nil).Once() - e, err := suite.provider.GetEntityProfile(testEntityID) + e, err := suite.provider.GetEntityProfile(context.Background(), testEntityID) suite.Nil(err) suite.Equal(testEntityID, e.ID) suite.Equal(providers.EntityCategory("user"), e.Category) @@ -126,7 +127,7 @@ func (suite *DefaultEntityProviderTestSuite) TestGetEntityProfile() { suite.mockService.On("GetEntityProfile", mock.Anything, testEntityID). Return(nil, entity.ErrEntityNotFound).Once() - e, err = suite.provider.GetEntityProfile(testEntityID) + e, err = suite.provider.GetEntityProfile(context.Background(), testEntityID) suite.Nil(e) suite.NotNil(err) suite.Equal(ErrorCodeEntityNotFound, err.Code) @@ -338,7 +339,7 @@ func (suite *DefaultEntityProviderTestSuite) TestGetTransitiveEntityGroups() { suite.mockService.On("GetTransitiveEntityGroups", mock.Anything, testEntityID). Return(groups, nil).Once() - result, err := suite.provider.GetTransitiveEntityGroups(testEntityID) + result, err := suite.provider.GetTransitiveEntityGroups(context.Background(), testEntityID) suite.Nil(err) suite.Len(result, 2) suite.Equal("g1", result[0].ID) @@ -347,7 +348,7 @@ func (suite *DefaultEntityProviderTestSuite) TestGetTransitiveEntityGroups() { suite.mockService.On("GetTransitiveEntityGroups", mock.Anything, testEntityID). Return(nil, entity.ErrEntityNotFound).Once() - result, err = suite.provider.GetTransitiveEntityGroups(testEntityID) + result, err = suite.provider.GetTransitiveEntityGroups(context.Background(), testEntityID) suite.Nil(result) suite.NotNil(err) suite.Equal(ErrorCodeEntityNotFound, err.Code) @@ -356,7 +357,7 @@ func (suite *DefaultEntityProviderTestSuite) TestGetTransitiveEntityGroups() { suite.mockService.On("GetTransitiveEntityGroups", mock.Anything, testEntityID). Return(nil, errors.New("db error")).Once() - result, err = suite.provider.GetTransitiveEntityGroups(testEntityID) + result, err = suite.provider.GetTransitiveEntityGroups(context.Background(), testEntityID) suite.Nil(result) suite.NotNil(err) suite.Equal(ErrorCodeSystemError, err.Code) diff --git a/backend/internal/entityprovider/disabled_entity_provider.go b/backend/internal/entityprovider/disabled_entity_provider.go index 8ba06fbe71..c2f2b4b92e 100644 --- a/backend/internal/entityprovider/disabled_entity_provider.go +++ b/backend/internal/entityprovider/disabled_entity_provider.go @@ -4,6 +4,7 @@ package entityprovider import ( + "context" "encoding/json" "github.com/thunder-id/thunderid/pkg/thunderidengine/providers" @@ -40,13 +41,13 @@ func (p *disabledEntityProvider) GetLinkedEntities( } func (p *disabledEntityProvider) GetEntity( - _ string) (*providers.Entity, *EntityProviderError) { + _ context.Context, _ string) (*providers.Entity, *EntityProviderError) { return nil, errNotImplemented } // GetEntityProfile is not available without an entity provider. func (p *disabledEntityProvider) GetEntityProfile( - _ string) (*providers.Entity, *EntityProviderError) { + _ context.Context, _ string) (*providers.Entity, *EntityProviderError) { return nil, errNotImplemented } @@ -80,12 +81,12 @@ func (p *disabledEntityProvider) UpdateSystemCredentials(_ string, } func (p *disabledEntityProvider) GetTransitiveEntityGroups( - _ string) ([]providers.EntityGroup, *EntityProviderError) { + _ context.Context, _ string) ([]providers.EntityGroup, *EntityProviderError) { return nil, errNotImplemented } func (p *disabledEntityProvider) GetTransitiveGroupAncestors( - _ string) ([]string, *EntityProviderError) { + _ context.Context, _ string) ([]string, *EntityProviderError) { return nil, errNotImplemented } diff --git a/backend/internal/entityprovider/disabled_entity_provider_test.go b/backend/internal/entityprovider/disabled_entity_provider_test.go index 1505b2ec88..8b2ad4def7 100644 --- a/backend/internal/entityprovider/disabled_entity_provider_test.go +++ b/backend/internal/entityprovider/disabled_entity_provider_test.go @@ -4,6 +4,7 @@ package entityprovider import ( + "context" "encoding/json" "testing" @@ -38,13 +39,13 @@ func (suite *DisabledEntityProviderTestSuite) TestGetLinkedEntities() { } func (suite *DisabledEntityProviderTestSuite) TestGetEntity() { - e, err := suite.provider.GetEntity("entity-id") + e, err := suite.provider.GetEntity(context.Background(), "entity-id") suite.Nil(e) suite.Equal(errNotImplemented, err) } func (suite *DisabledEntityProviderTestSuite) TestGetEntityProfile() { - e, err := suite.provider.GetEntityProfile("entity-id") + e, err := suite.provider.GetEntityProfile(context.Background(), "entity-id") suite.Nil(e) suite.Equal(errNotImplemented, err) } @@ -76,7 +77,7 @@ func (suite *DisabledEntityProviderTestSuite) TestUpdateSystemCredentials() { } func (suite *DisabledEntityProviderTestSuite) TestGetTransitiveEntityGroups() { - groups, err := suite.provider.GetTransitiveEntityGroups("entity-id") + groups, err := suite.provider.GetTransitiveEntityGroups(context.Background(), "entity-id") suite.Nil(groups) suite.Equal(errNotImplemented, err) } diff --git a/backend/internal/entityprovider/interface.go b/backend/internal/entityprovider/interface.go index d3f539ba4a..0d9aa5d2dc 100644 --- a/backend/internal/entityprovider/interface.go +++ b/backend/internal/entityprovider/interface.go @@ -4,6 +4,7 @@ package entityprovider import ( + "context" "encoding/json" "github.com/thunder-id/thunderid/pkg/thunderidengine/providers" @@ -22,11 +23,11 @@ type EntityProviderInterface interface { GetLinkedEntities(idpID, sub string) ([]*providers.Entity, *EntityProviderError) // GetEntity retrieves an entity by ID. Credentials are never returned. - GetEntity(entityID string) (*providers.Entity, *EntityProviderError) + GetEntity(ctx context.Context, entityID string) (*providers.Entity, *EntityProviderError) // GetEntityProfile retrieves an entity's profile by ID, without its runtime state. State is empty. // Use it whenever the caller does not need the entity's status. - GetEntityProfile(entityID string) (*providers.Entity, *EntityProviderError) + GetEntityProfile(ctx context.Context, entityID string) (*providers.Entity, *EntityProviderError) // UpdateEntity updates an existing entity's core fields. The entity's state is not written. UpdateEntity(entityID string, entity *providers.Entity) (*providers.Entity, *EntityProviderError) @@ -51,10 +52,10 @@ type EntityProviderInterface interface { credentials json.RawMessage) *EntityProviderError // GetTransitiveEntityGroups retrieves all groups an entity belongs to, including inherited groups. - GetTransitiveEntityGroups(entityID string) ([]providers.EntityGroup, *EntityProviderError) + GetTransitiveEntityGroups(ctx context.Context, entityID string) ([]providers.EntityGroup, *EntityProviderError) // GetTransitiveGroupAncestors resolves the ancestor chain of a single group. - GetTransitiveGroupAncestors(groupID string) ([]string, *EntityProviderError) + GetTransitiveGroupAncestors(ctx context.Context, groupID string) ([]string, *EntityProviderError) // ValidateEntityIDs validates that the given entity IDs exist. Returns IDs that are invalid. ValidateEntityIDs(entityIDs []string) ([]string, *EntityProviderError) diff --git a/backend/internal/entitytype/service.go b/backend/internal/entitytype/service.go index 9f5708e7a2..50931dd8cb 100644 --- a/backend/internal/entitytype/service.go +++ b/backend/internal/entitytype/service.go @@ -842,13 +842,13 @@ func (us *entityTypeService) ensureOrganizationUnitExists( exists, svcErr := us.ouService.IsOrganizationUnitExists(ctx, oUID) if svcErr != nil { logger.Error(ctx, "Failed to verify organization unit existence", - log.String("oUID", oUID), log.Any("error", svcErr)) + log.String("ouID", oUID), log.Any("error", svcErr)) return &tidcommon.InternalServerError } if !exists { logger.Debug(ctx, "Organization unit does not exist", - log.String("oUID", oUID)) + log.String("ouID", oUID)) return invalidEntityTypeRequestErr(category, "organization unit id does not exist") } diff --git a/backend/internal/flow/executor/account_linking_executor.go b/backend/internal/flow/executor/account_linking_executor.go index 57e9e35bd5..58d57f0ab4 100644 --- a/backend/internal/flow/executor/account_linking_executor.go +++ b/backend/internal/flow/executor/account_linking_executor.go @@ -255,7 +255,7 @@ func (e *accountLinkingExecutor) writeLink(ctx *providers.NodeContext, execResp return fmt.Errorf("failed to link the federated identity: %s", svcErr.Code) } logger.Debug(ctx.Context, "The link write was rejected", - log.MaskedString(log.LoggerKeyEntityID, entityID), log.String("idpId", federated.IdpID), + log.MaskedString(log.LoggerKeyEntityID, entityID), log.String(log.LoggerKeyIDPID, federated.IdpID), log.String("errorCode", svcErr.Code)) execResp.Status = providers.ExecFailure execResp.Error = &ErrLinkingWriteFailed diff --git a/backend/internal/flow/executor/attribute_collector.go b/backend/internal/flow/executor/attribute_collector.go index f6eb35e5d1..55bde0c583 100644 --- a/backend/internal/flow/executor/attribute_collector.go +++ b/backend/internal/flow/executor/attribute_collector.go @@ -296,7 +296,7 @@ func (a *attributeCollector) getUserFromStore( return nil, errors.New("user ID is not available in the context") } - user, err := a.entityProvider.GetEntityProfile(userID) + user, err := a.entityProvider.GetEntityProfile(ctx.Context, userID) if err != nil { return nil, fmt.Errorf("failed to get user by ID: %s", err.Message) } diff --git a/backend/internal/flow/executor/attribute_collector_test.go b/backend/internal/flow/executor/attribute_collector_test.go index 34f2d44bc8..e4186dee7b 100644 --- a/backend/internal/flow/executor/attribute_collector_test.go +++ b/backend/internal/flow/executor/attribute_collector_test.go @@ -151,7 +151,7 @@ func (suite *AttributeCollectorTestSuite) TestExecute_UserInputRequired() { Attributes: attrsJSON, } - suite.mockEntityProvider.On("GetEntityProfile", testUserID).Return(existingUser, nil) + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, testUserID).Return(existingUser, nil) authUser := newAuthenticatedAuthUser() ctx := &providers.NodeContext{ @@ -198,7 +198,7 @@ func (suite *AttributeCollectorTestSuite) TestExecute_Success() { Attributes: json.RawMessage(`{}`), } - suite.mockEntityProvider.On("GetEntityProfile", testUserID).Return(existingUser, nil) + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, testUserID).Return(existingUser, nil) suite.mockEntityProvider.On("UpdateAttributes", testUserID, mock.MatchedBy(func(attrs json.RawMessage) bool { return attrs != nil })).Return(nil) @@ -233,7 +233,7 @@ func (suite *AttributeCollectorTestSuite) TestExecute_UpdateUserFails() { Attributes: json.RawMessage(`{}`), } - suite.mockEntityProvider.On("GetEntityProfile", testUserID).Return(existingUser, nil) + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, testUserID).Return(existingUser, nil) suite.mockEntityProvider.On("UpdateAttributes", testUserID, mock.Anything). Return(&entityprovider.EntityProviderError{Message: "update failed"}) @@ -306,7 +306,7 @@ func (suite *AttributeCollectorTestSuite) TestHasRequiredInputs_AttributesInUser Attributes: attrsJSON, } - suite.mockEntityProvider.On("GetEntityProfile", testUserID).Return(existingUser, nil) + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, testUserID).Return(existingUser, nil) result := suite.executor.HasRequiredInputs(ctx, execResp) @@ -333,7 +333,7 @@ func (suite *AttributeCollectorTestSuite) TestGetUserAttributes_Success() { Attributes: attrsJSON, } - suite.mockEntityProvider.On("GetEntityProfile", testUserID).Return(existingUser, nil) + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, testUserID).Return(existingUser, nil) result, err := suite.executor.getUserAttributes(ctx, execResp) @@ -353,7 +353,7 @@ func (suite *AttributeCollectorTestSuite) TestGetUserAttributes_UserNotFound() { RuntimeData: make(map[string]string), } - suite.mockEntityProvider.On("GetEntityProfile", testUserID). + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, testUserID). Return(nil, &entityprovider.EntityProviderError{Message: "user not found"}) result, err := suite.executor.getUserAttributes(ctx, execResp) @@ -377,7 +377,7 @@ func (suite *AttributeCollectorTestSuite) TestGetUserAttributes_InvalidJSON() { Attributes: json.RawMessage(`invalid json`), } - suite.mockEntityProvider.On("GetEntityProfile", testUserID).Return(existingUser, nil) + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, testUserID).Return(existingUser, nil) result, err := suite.executor.getUserAttributes(ctx, execResp) diff --git a/backend/internal/flow/executor/attribute_uniqueness_validator.go b/backend/internal/flow/executor/attribute_uniqueness_validator.go index 5191e9fdb1..a092e29467 100644 --- a/backend/internal/flow/executor/attribute_uniqueness_validator.go +++ b/backend/internal/flow/executor/attribute_uniqueness_validator.go @@ -4,7 +4,6 @@ package executor import ( - "context" "fmt" "github.com/thunder-id/thunderid/internal/entityprovider" @@ -85,7 +84,7 @@ func (e *attributeUniquenessValidator) Execute(ctx *providers.NodeContext) (*pro return execResp, nil } - svcCtx := security.WithRuntimeContext(context.Background()) + svcCtx := security.WithRuntimeContext(ctx.Context) uniqueAttrs, svcErr := e.entityTypeService.GetUniqueAttributes(svcCtx, category, entityType) if svcErr != nil { return nil, fmt.Errorf("failed to retrieve unique attributes from schema for %s type %s: %s", diff --git a/backend/internal/flow/executor/auth_assert_executor.go b/backend/internal/flow/executor/auth_assert_executor.go index e153fd274f..598438c60c 100644 --- a/backend/internal/flow/executor/auth_assert_executor.go +++ b/backend/internal/flow/executor/auth_assert_executor.go @@ -754,7 +754,7 @@ func (a *authAssertExecutor) fetchAllUserGroups( return nil, nil } - groups, err := a.entityProvider.GetTransitiveEntityGroups(userID) + groups, err := a.entityProvider.GetTransitiveEntityGroups(ctx, userID) if err != nil { a.logger.Error(ctx, "Failed to fetch transitive user groups", log.MaskedString(log.LoggerKeyUserID, userID), log.Any("error", err)) diff --git a/backend/internal/flow/executor/auth_assert_executor_test.go b/backend/internal/flow/executor/auth_assert_executor_test.go index 79d4ce13fe..1571ebcfab 100644 --- a/backend/internal/flow/executor/auth_assert_executor_test.go +++ b/backend/internal/flow/executor/auth_assert_executor_test.go @@ -922,7 +922,7 @@ func (suite *AuthAssertExecutorTestSuite) TestExecute_WithGroups() { {Name: "viewer"}, } - suite.mockEntityProvider.On("GetTransitiveEntityGroups", "user-123"). + suite.mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, "user-123"). Return(userGroups, nil) suite.mockJWTService.On("GenerateJWT", mock.Anything, "user-123", mock.Anything, mock.Anything, mock.MatchedBy(func(claims map[string]interface{}) bool { @@ -962,7 +962,7 @@ func (suite *AuthAssertExecutorTestSuite) TestExecute_WithGroups_EmptyGroups() { suite.setupGetEntityReference("", "") suite.setupGetUserAttributesEmpty() - suite.mockEntityProvider.On("GetTransitiveEntityGroups", "user-123"). + suite.mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, "user-123"). Return([]providers.EntityGroup{}, nil) suite.mockJWTService.On("GenerateJWT", mock.Anything, "user-123", mock.Anything, mock.Anything, mock.MatchedBy(func(claims map[string]interface{}) bool { @@ -999,7 +999,7 @@ func (suite *AuthAssertExecutorTestSuite) TestExecute_WithGroups_GetUserGroupsFa suite.setupGetEntityReference("", "") suite.setupGetUserAttributesEmpty() - suite.mockEntityProvider.On("GetTransitiveEntityGroups", "user-123").Return( + suite.mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, "user-123").Return( nil, &entityprovider.EntityProviderError{ Message: "failed to fetch groups", Description: "database error", }) @@ -1453,7 +1453,7 @@ func (suite *AuthAssertExecutorTestSuite) TestResolveUserAttributes_WithGroups() {Name: "developer"}, } - suite.mockEntityProvider.On("GetTransitiveEntityGroups", "user-123"). + suite.mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, "user-123"). Return(userGroups, nil) attrs, err := suite.executor.resolveUserAttributes(ctx, []string{oauth2const.UserAttributeGroups}, @@ -1474,7 +1474,7 @@ func (suite *AuthAssertExecutorTestSuite) TestResolveUserAttributes_WithGroups_F RuntimeData: map[string]string{}, } - suite.mockEntityProvider.On("GetTransitiveEntityGroups", "user-123"). + suite.mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, "user-123"). Return(nil, &entityprovider.EntityProviderError{Message: "groups_fetch_failed", Description: "database error"}) attrs, err := suite.executor.resolveUserAttributes(ctx, []string{oauth2const.UserAttributeGroups}, @@ -1754,7 +1754,7 @@ func (suite *AuthAssertExecutorTestSuite) TestExecute_WithAttributeCache_GroupsI {Name: "developer"}, } - suite.mockEntityProvider.On("GetTransitiveEntityGroups", "user-123"). + suite.mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, "user-123"). Return(userGroups, nil) suite.mockAttributeCacheSvc.On("CreateAttributeCache", mock.Anything, mock.MatchedBy(func(cache *attributecache.AttributeCache) bool { diff --git a/backend/internal/flow/executor/authz_executor.go b/backend/internal/flow/executor/authz_executor.go index a1dca082c4..03e6342b24 100644 --- a/backend/internal/flow/executor/authz_executor.go +++ b/backend/internal/flow/executor/authz_executor.go @@ -275,7 +275,7 @@ func (a *authorizationExecutor) extractGroupIDs(ctx *providers.NodeContext, user "Groups not found in context, fetching transitive groups from entity provider", log.MaskedString(log.LoggerKeyUserID, userID)) - groups, err := a.entityProvider.GetTransitiveEntityGroups(userID) + groups, err := a.entityProvider.GetTransitiveEntityGroups(ctx.Context, userID) if err != nil { return nil, err } @@ -300,10 +300,10 @@ func (a *authorizationExecutor) expandMappedGroupAncestors( } expanded := mappedGroupIDs for _, groupID := range mappedGroupIDs { - ancestors, err := a.entityProvider.GetTransitiveGroupAncestors(groupID) + ancestors, err := a.entityProvider.GetTransitiveGroupAncestors(ctx.Context, groupID) if err != nil { a.logger.Warn(ctx.Context, "Failed to resolve ancestors of a mapped group, continuing without them", - log.String("groupId", groupID), log.Error(err)) + log.String("groupID", groupID), log.Error(err)) continue } expanded = utils.MergeUniqueStrings(expanded, ancestors) diff --git a/backend/internal/flow/executor/authz_executor_test.go b/backend/internal/flow/executor/authz_executor_test.go index fc38fccf3b..7b4c310e24 100644 --- a/backend/internal/flow/executor/authz_executor_test.go +++ b/backend/internal/flow/executor/authz_executor_test.go @@ -164,7 +164,7 @@ func TestAuthorizationExecutor_Execute_ScopesEvaluationToResourceServer(t *testi mockAuthnProvider.On("GetEntityReference", mock.Anything, mock.Anything). Return(authUser, &providers.EntityReference{EntityID: testUser123ID}, nil) - mockEntityProvider.On("GetTransitiveEntityGroups", testUser123ID).Return( + mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, testUser123ID).Return( []providers.EntityGroup{}, nil) // The evaluation must be scoped to the requested resource server. @@ -282,7 +282,8 @@ func TestAuthorizationExecutor_Execute_ResourceServerFromUserInputFallback(t *te mockAuthnProvider.On("GetEntityReference", mock.Anything, mock.Anything). Return(authUser, &providers.EntityReference{EntityID: testUser123ID}, nil) - mockEntityProvider.On("GetTransitiveEntityGroups", testUser123ID).Return([]providers.EntityGroup{}, nil) + mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, testUser123ID). + Return([]providers.EntityGroup{}, nil) mockAuthzService.On("EvaluateAccessBatch", mock.Anything, mock.MatchedBy(func(req providers.AccessEvaluationsRequest) bool { return len(req.Evaluations) == 1 && req.Evaluations[0].ResourceServer.ID == "rs-input" @@ -322,7 +323,8 @@ func TestAuthorizationExecutor_Execute_DefaultResourceServerFallback(t *testing. mockAuthnProvider.On("GetEntityReference", mock.Anything, mock.Anything). Return(authUser, &providers.EntityReference{EntityID: testUser123ID}, nil) - mockEntityProvider.On("GetTransitiveEntityGroups", testUser123ID).Return([]providers.EntityGroup{}, nil) + mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, testUser123ID). + Return([]providers.EntityGroup{}, nil) mockAuthzService.On("EvaluateAccessBatch", mock.Anything, mock.MatchedBy(func(req providers.AccessEvaluationsRequest) bool { return len(req.Evaluations) == 1 && req.Evaluations[0].ResourceServer.ID == "rs-default" @@ -359,7 +361,7 @@ func TestAuthorizationExecutor_Execute_PartialPermissions(t *testing.T) { mockAuthnProvider.On("GetEntityReference", mock.Anything, mock.Anything). Return(authUser, &providers.EntityReference{EntityID: testUser123ID}, nil) - mockEntityProvider.On("GetTransitiveEntityGroups", testUser123ID).Return( + mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, testUser123ID).Return( []providers.EntityGroup{}, nil) // User only has read permission @@ -405,7 +407,7 @@ func TestAuthorizationExecutor_Execute_NoPermissions(t *testing.T) { mockAuthnProvider.On("GetEntityReference", mock.Anything, mock.Anything). Return(authUser, &providers.EntityReference{EntityID: testUser123ID}, nil) - mockEntityProvider.On("GetTransitiveEntityGroups", testUser123ID).Return( + mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, testUser123ID).Return( []providers.EntityGroup{}, nil) mockAuthzService.On("EvaluateAccessBatch", mock.Anything, mock.Anything).Return( @@ -474,7 +476,7 @@ func TestAuthorizationExecutor_Execute_ServiceError(t *testing.T) { mockAuthnProvider.On("GetEntityReference", mock.Anything, mock.Anything). Return(authUser, &providers.EntityReference{EntityID: testUser123ID}, nil) - mockEntityProvider.On("GetTransitiveEntityGroups", testUser123ID).Return( + mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, testUser123ID).Return( []providers.EntityGroup{}, nil) mockAuthzService.On("EvaluateAccessBatch", mock.Anything, mock.Anything).Return( @@ -514,7 +516,7 @@ func TestAuthorizationExecutor_Execute_GroupExtractionError(t *testing.T) { mockAuthnProvider.On("GetEntityReference", mock.Anything, mock.Anything). Return(authUser, &providers.EntityReference{EntityID: testUser123ID}, nil) - mockEntityProvider.On("GetTransitiveEntityGroups", testUser123ID).Return( + mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, testUser123ID).Return( nil, entityprovider.NewEntityProviderError( entityprovider.ErrorCodeSystemError, "failed to retrieve groups", @@ -573,7 +575,7 @@ func TestAuthorizationExecutor_ExtractGroupIDs_NoGroupsInContext(t *testing.T) { RuntimeData: make(map[string]string), } - mockEntityProvider.On("GetTransitiveEntityGroups", testUser123ID).Return( + mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, testUser123ID).Return( []providers.EntityGroup{}, nil) groupIDs, err := executor.extractGroupIDs(ctx, testUser123ID) @@ -674,7 +676,7 @@ func TestAuthorizationExecutor_ExtractGroupIDs_WithNoGroups(t *testing.T) { RuntimeData: make(map[string]string), } - mockEntityProvider.On("GetTransitiveEntityGroups", testUser123ID).Return( + mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, testUser123ID).Return( []providers.EntityGroup{}, nil) groupIDs, err := executor.extractGroupIDs(ctx, testUser123ID) @@ -922,7 +924,7 @@ func TestAuthorizationExecutor_ExtractGroupIDs_FromEntityProvider(t *testing.T) RuntimeData: make(map[string]string), // No groups in runtime data } - mockEntityProvider.On("GetTransitiveEntityGroups", "test-user-123").Return( + mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, "test-user-123").Return( []providers.EntityGroup{ {ID: "svc-group-1"}, {ID: "svc-group-2"}, @@ -945,7 +947,7 @@ func TestAuthorizationExecutor_ExtractGroupIDs_FromEntityProvider_Error(t *testi RuntimeData: make(map[string]string), // No groups in runtime data } - mockEntityProvider.On("GetTransitiveEntityGroups", "test-user-err").Return( + mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, "test-user-err").Return( nil, entityprovider.NewEntityProviderError( entityprovider.ErrorCodeSystemError, "failed to retrieve groups", @@ -1002,9 +1004,9 @@ func TestAuthorizationExecutor_Execute_MappedRoleAndGroupTargets(t *testing.T) { mockAuthnProvider.On("GetEntityReference", mock.Anything, mock.Anything). Return(authUser, &providers.EntityReference{EntityID: testUser123ID}, nil) - mockEntityProvider.On("GetTransitiveEntityGroups", testUser123ID).Return( + mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, testUser123ID).Return( []providers.EntityGroup{{ID: "group-real"}}, nil) - mockEntityProvider.On("GetTransitiveGroupAncestors", "group-mapped").Return([]string{}, nil) + mockEntityProvider.On("GetTransitiveGroupAncestors", mock.Anything, "group-mapped").Return([]string{}, nil) mockAuthzService.On("EvaluateAccessBatch", mock.Anything, @@ -1051,7 +1053,7 @@ func TestAuthorizationExecutor_Execute_MappedPermissionTargetUnionsDirectly(t *t mockAuthnProvider.On("GetEntityReference", mock.Anything, mock.Anything). Return(authUser, &providers.EntityReference{EntityID: testUser123ID}, nil) - mockEntityProvider.On("GetTransitiveEntityGroups", testUser123ID).Return( + mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, testUser123ID).Return( []providers.EntityGroup{}, nil) // The engine denies both; the mapped permission target still grants read:documents directly. @@ -1092,7 +1094,7 @@ func TestAuthorizationExecutor_Execute_MappedPermissionTargetWrongResourceServer mockAuthnProvider.On("GetEntityReference", mock.Anything, mock.Anything). Return(authUser, &providers.EntityReference{EntityID: testUser123ID}, nil) - mockEntityProvider.On("GetTransitiveEntityGroups", testUser123ID).Return( + mockEntityProvider.On("GetTransitiveEntityGroups", mock.Anything, testUser123ID).Return( []providers.EntityGroup{}, nil) mockAuthzService.On("EvaluateAccessBatch", mock.Anything, mock.Anything). Return(&providers.AccessEvaluationsResponse{ diff --git a/backend/internal/flow/executor/email_executor.go b/backend/internal/flow/executor/email_executor.go index 16dff7670a..fd9c3f2ed4 100644 --- a/backend/internal/flow/executor/email_executor.go +++ b/backend/internal/flow/executor/email_executor.go @@ -233,7 +233,7 @@ func (e *emailExecutor) resolveRecipientEmail(ctx *providers.NodeContext, logger if e.entityProvider == nil { return "", errors.New("entity provider is not configured for email resolution") } - user, providerErr := e.entityProvider.GetEntityProfile(userID) + user, providerErr := e.entityProvider.GetEntityProfile(ctx.Context, userID) if providerErr != nil { if providerErr.Code == entityprovider.ErrorCodeEntityNotFound { return "", nil diff --git a/backend/internal/flow/executor/email_executor_test.go b/backend/internal/flow/executor/email_executor_test.go index eba4f8f669..75caed9892 100644 --- a/backend/internal/flow/executor/email_executor_test.go +++ b/backend/internal/flow/executor/email_executor_test.go @@ -649,7 +649,7 @@ func (suite *EmailExecutorTestSuite) TestExecute_SendMode_BestEffortCompletesWhe lookupFails := bestEffortContext(sendable) lookupFails.UserInputs = nil lookupFails.RuntimeData = map[string]string{userAttributeUserID: "test-user-id"} - suite.mockEntityProvider.On("GetEntityProfile", "test-user-id").Return( + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, "test-user-id").Return( nil, entityprovider.NewEntityProviderError( entityprovider.ErrorCodeSystemError, "provider error", "system failure")).Once() noSender, noRenderer := *suite.executor, *suite.executor @@ -1218,7 +1218,7 @@ func (suite *EmailExecutorTestSuite) TestExecute_SendMode_ResolvesEmailFromEntit ID: "test-db-user-id", Attributes: []byte(`{"workEmail":"database-resolved@example.com"}`), } - suite.mockEntityProvider.On("GetEntityProfile", "test-db-user-id").Return(mockEntity, nil) + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, "test-db-user-id").Return(mockEntity, nil) suite.mockTemplateRenderer.On("Resolve", ctx.Context, @@ -1296,7 +1296,7 @@ func (suite *EmailExecutorTestSuite) TestExecute_SendMode_EntityProviderMissingE ID: "test-db-user-id", Attributes: []byte(`{"other":"data"}`), } - suite.mockEntityProvider.On("GetEntityProfile", "test-db-user-id").Return(mockEntity, nil) + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, "test-db-user-id").Return(mockEntity, nil) resp, err := suite.executor.Execute(ctx) @@ -1338,7 +1338,7 @@ func (suite *EmailExecutorTestSuite) TestExecute_SendMode_EntityProviderError() }, } - suite.mockEntityProvider.On("GetEntityProfile", "test-user-id").Return( + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, "test-user-id").Return( nil, entityprovider.NewEntityProviderError( entityprovider.ErrorCodeSystemError, "provider error", "system failure")) @@ -1362,7 +1362,7 @@ func (suite *EmailExecutorTestSuite) TestExecute_SendMode_EntityProviderUserNotF }, } - suite.mockEntityProvider.On("GetEntityProfile", "non-existent-user-id").Return( + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, "non-existent-user-id").Return( nil, entityprovider.NewEntityProviderError( entityprovider.ErrorCodeEntityNotFound, "user not found", "entity not found")) diff --git a/backend/internal/flow/executor/identifying_executor.go b/backend/internal/flow/executor/identifying_executor.go index 865e32e586..8f52151ef8 100644 --- a/backend/internal/flow/executor/identifying_executor.go +++ b/backend/internal/flow/executor/identifying_executor.go @@ -84,7 +84,7 @@ func (i *identifyingExecutor) IdentifyEntity(ctx context.Context, filters map[st logger.Debug(ctx, "Identifying entity with filters") if entityID, ok := filters[userAttributeUserID].(string); ok && entityID != "" { - entity, epErr := i.entityProvider.GetEntityProfile(entityID) + entity, epErr := i.entityProvider.GetEntityProfile(ctx, entityID) if epErr != nil { if epErr.Code == entityprovider.ErrorCodeEntityNotFound { execResp.Error = errForEntityCategory(ErrEntityNotFound, category) diff --git a/backend/internal/flow/executor/identifying_executor_test.go b/backend/internal/flow/executor/identifying_executor_test.go index 12dade6bf8..b1536451ff 100644 --- a/backend/internal/flow/executor/identifying_executor_test.go +++ b/backend/internal/flow/executor/identifying_executor_test.go @@ -1033,7 +1033,7 @@ func (suite *IdentifyingExecutorTestSuite) TestIdentifyEntity_WithEntityID_Succe filters := map[string]interface{}{userAttributeUserID: entityID} execResp := &providers.ExecutorResponse{RuntimeData: make(map[string]string)} - suite.mockEntityProvider.On("GetEntityProfile", entityID). + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, entityID). Return(&providers.Entity{ID: entityID}, nil) result, err := suite.executor.IdentifyEntity(context.Background(), filters, execResp, entitytype.TypeCategoryUser) @@ -1048,7 +1048,7 @@ func (suite *IdentifyingExecutorTestSuite) TestIdentifyEntity_WithEntityID_NotFo filters := map[string]interface{}{userAttributeUserID: "missing-id"} execResp := &providers.ExecutorResponse{RuntimeData: make(map[string]string)} - suite.mockEntityProvider.On("GetEntityProfile", "missing-id"). + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, "missing-id"). Return(nil, entityprovider.NewEntityProviderError(entityprovider.ErrorCodeEntityNotFound, "", "")) result, err := suite.executor.IdentifyEntity(context.Background(), filters, execResp, entitytype.TypeCategoryUser) @@ -1064,7 +1064,7 @@ func (suite *IdentifyingExecutorTestSuite) TestIdentifyEntity_WithEntityID_Syste filters := map[string]interface{}{userAttributeUserID: testUserID} execResp := &providers.ExecutorResponse{RuntimeData: make(map[string]string)} - suite.mockEntityProvider.On("GetEntityProfile", testUserID). + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, testUserID). Return(nil, entityprovider.NewEntityProviderError(entityprovider.ErrorCodeSystemError, "", "")) result, err := suite.executor.IdentifyEntity(context.Background(), filters, execResp, entitytype.TypeCategoryUser) diff --git a/backend/internal/flow/executor/owner_resolver.go b/backend/internal/flow/executor/owner_resolver.go index 84c44a30fb..5a4317e81e 100644 --- a/backend/internal/flow/executor/owner_resolver.go +++ b/backend/internal/flow/executor/owner_resolver.go @@ -94,7 +94,7 @@ func (e *ownerResolver) Execute(ctx *providers.NodeContext) (*providers.Executor func (e *ownerResolver) resolveSelectedOwner(ctx *providers.NodeContext, execResp *providers.ExecutorResponse, selected string, logger *log.Logger, ) (*providers.ExecutorResponse, error) { - entity, epErr := e.entityProvider.GetEntityProfile(selected) + entity, epErr := e.entityProvider.GetEntityProfile(ctx.Context, selected) if epErr != nil { if epErr.Code == entityprovider.ErrorCodeEntityNotFound { return e.rejectOwner(ctx, execResp, "Selected owner does not exist", logger), nil diff --git a/backend/internal/flow/executor/owner_resolver_test.go b/backend/internal/flow/executor/owner_resolver_test.go index fc8b326625..031240de31 100644 --- a/backend/internal/flow/executor/owner_resolver_test.go +++ b/backend/internal/flow/executor/owner_resolver_test.go @@ -117,7 +117,7 @@ func (suite *OwnerResolverTestSuite) TestSkippedPromptCompletesWithoutOwner() { func (suite *OwnerResolverTestSuite) TestSelectedOwnerIsRecorded() { ctx := ownerNodeContext() ctx.UserInputs[ownerKey] = testOwnerUserID - suite.mockEntityProvider.On("GetEntityProfile", testOwnerUserID). + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, testOwnerUserID). Return(&providers.Entity{Category: providers.EntityCategoryUser, ID: testOwnerUserID}, nil).Once() resp, err := suite.executor.Execute(ctx) @@ -132,7 +132,7 @@ func (suite *OwnerResolverTestSuite) TestSelectedOwnerIsRecorded() { func (suite *OwnerResolverTestSuite) TestUnknownOwnerIsRePrompted() { ctx := ownerNodeContext() ctx.UserInputs[ownerKey] = "does-not-exist" - suite.mockEntityProvider.On("GetEntityProfile", "does-not-exist"). + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, "does-not-exist"). Return(nil, entityprovider.NewEntityProviderError(entityprovider.ErrorCodeEntityNotFound, "", "")).Once() resp, err := suite.executor.Execute(ctx) @@ -150,7 +150,7 @@ func (suite *OwnerResolverTestSuite) TestUnknownOwnerIsRePrompted() { func (suite *OwnerResolverTestSuite) TestNonUserEntityIsRejected() { ctx := ownerNodeContext() ctx.UserInputs[ownerKey] = testOtherUserID - suite.mockEntityProvider.On("GetEntityProfile", testOtherUserID). + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, testOtherUserID). Return(&providers.Entity{Category: providers.EntityCategoryAgent, ID: testOtherUserID}, nil).Once() resp, err := suite.executor.Execute(ctx) @@ -168,7 +168,7 @@ func (suite *OwnerResolverTestSuite) TestNonUserEntityIsRejected() { func (suite *OwnerResolverTestSuite) TestEntityLookupFailurePropagates() { ctx := ownerNodeContext() ctx.UserInputs[ownerKey] = testOwnerUserID - suite.mockEntityProvider.On("GetEntityProfile", testOwnerUserID). + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, testOwnerUserID). Return(nil, entityprovider.NewEntityProviderError(entityprovider.ErrorCodeSystemError, "", "")).Once() resp, err := suite.executor.Execute(ctx) diff --git a/backend/internal/flow/executor/provisioning_executor.go b/backend/internal/flow/executor/provisioning_executor.go index aaa99e2d43..7fd9e81dc5 100644 --- a/backend/internal/flow/executor/provisioning_executor.go +++ b/backend/internal/flow/executor/provisioning_executor.go @@ -549,7 +549,7 @@ func (p *provisioningExecutor) handleExistingEntity(ctx *providers.NodeContext, return false, nil } - existingEntity, getEntityErr := p.entityProvider.GetEntityProfile(entityID) + existingEntity, getEntityErr := p.entityProvider.GetEntityProfile(ctx.Context, entityID) if getEntityErr != nil { return false, errors.New("failed to retrieve the existing entity") } diff --git a/backend/internal/flow/executor/provisioning_executor_test.go b/backend/internal/flow/executor/provisioning_executor_test.go index fef106143b..3e35b24d40 100644 --- a/backend/internal/flow/executor/provisioning_executor_test.go +++ b/backend/internal/flow/executor/provisioning_executor_test.go @@ -2694,7 +2694,7 @@ func (suite *ProvisioningExecutorTestSuite) TestExecute_CrossOU_Success() { } suite.mockEntityProvider.On("IdentifyEntity", attrs).Return(&existingUserID, nil) - suite.mockEntityProvider.On("GetEntityProfile", existingUserID).Return(existingUser, nil) + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, existingUserID).Return(existingUser, nil) suite.mockUserMgtProvider.On("CreateUser", mock.Anything, mock.MatchedBy(func(u *providers.User) bool { return u.OUID == testOUID @@ -2761,7 +2761,7 @@ func (suite *ProvisioningExecutorTestSuite) TestExecute_CrossOU_SameOU_Fails() { } suite.mockEntityProvider.On("IdentifyEntity", attrs).Return(&existingUserID, nil) - suite.mockEntityProvider.On("GetEntityProfile", existingUserID).Return(existingUser, nil) + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, existingUserID).Return(existingUser, nil) resp, err := suite.executor.Execute(ctx) @@ -2957,7 +2957,7 @@ func (suite *ProvisioningExecutorTestSuite) TestExecute_CrossOU_SameOU_AuthnFlow } suite.mockEntityProvider.On("IdentifyEntity", attrs).Return(&existingUserID, nil) - suite.mockEntityProvider.On("GetEntityProfile", existingUserID).Return(existingUser, nil) + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, existingUserID).Return(existingUser, nil) resp, err := suite.executor.Execute(ctx) @@ -3007,7 +3007,7 @@ func (suite *ProvisioningExecutorTestSuite) TestExecute_CrossOU_SameOU_Registrat provMock.On(methodGetRequiredInputs, mock.Anything).Return(nodeInputs).Maybe() suite.mockEntityProvider.On("IdentifyEntity", attrs).Return(&existingUserID, nil) - suite.mockEntityProvider.On("GetEntityProfile", existingUserID).Return(existingUser, nil) + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, existingUserID).Return(existingUser, nil) resp, err := suite.executor.Execute(ctx) @@ -3039,7 +3039,7 @@ func (suite *ProvisioningExecutorTestSuite) TestExecute_CrossOU_GetUserError() { } suite.mockEntityProvider.On("IdentifyEntity", attrs).Return(&existingUserID, nil) - suite.mockEntityProvider.On("GetEntityProfile", existingUserID).Return(nil, + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, existingUserID).Return(nil, entityprovider.NewEntityProviderError(entityprovider.ErrorCodeSystemError, "db error", "")) resp, err := suite.executor.Execute(ctx) @@ -4534,7 +4534,7 @@ func (suite *ProvisioningExecutorTestSuite) TestExecute_CrossOU_AmbiguousUser_Ma {ID: testExistingUserID, OUID: testOUID}, {ID: "other-user-id", OUID: "ou-honda"}, }, nil) - suite.mockEntityProvider.On("GetEntityProfile", testExistingUserID). + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, testExistingUserID). Return(&providers.Entity{ID: testExistingUserID, OUID: testOUID}, nil) resp, err := suite.executor.Execute(ctx) @@ -4986,7 +4986,7 @@ func (suite *ProvisioningExecutorTestSuite) TestExecute_Federated_CrossOURegistr ctx.NodeProperties = map[string]interface{}{common.NodePropertyAllowCrossOUProvisioning: true} ctx.NodeInputs = []providers.Input{} suite.expectSchemaForProvisioning() - suite.mockEntityProvider.On("GetEntityProfile", testExistingUser123ID). + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, testExistingUser123ID). Return(&providers.Entity{ID: testExistingUser123ID, OUID: "ou-source"}, nil).Once() suite.mockUserMgtProvider.On("CreateUser", mock.Anything, mock.MatchedBy(func(u *providers.User) bool { diff --git a/backend/internal/flow/executor/register.go b/backend/internal/flow/executor/register.go index 153bd40391..dbdc9eb3f6 100644 --- a/backend/internal/flow/executor/register.go +++ b/backend/internal/flow/executor/register.go @@ -115,12 +115,12 @@ func (r *executorRegistry) RegisterExecutor(name string, exec providers.Executor return } - logger.Debug(ctx, "Registering executor", log.String("executorName", name)) + logger.Debug(ctx, "Registering executor", log.String(log.LoggerKeyExecutorName, name)) r.mu.Lock() defer r.mu.Unlock() if _, ok := r.executors[name]; ok { - logger.Warn(ctx, "Executor already registered", log.String("executorName", name)) + logger.Warn(ctx, "Executor already registered", log.String(log.LoggerKeyExecutorName, name)) return } r.executors[name] = exec diff --git a/backend/internal/flow/executor/session_executor.go b/backend/internal/flow/executor/session_executor.go index 598a235d26..79c5a9dd0d 100644 --- a/backend/internal/flow/executor/session_executor.go +++ b/backend/internal/flow/executor/session_executor.go @@ -299,7 +299,7 @@ func (e *sessionExecutor) loadCheckpoint(ctx *providers.NodeContext, execResp *p } logger.Debug(ctx.Context, "Loaded SSO checkpoint", - log.String("flowId", session.SSOInputsFrom(ctx.Context).FlowID), + log.String("flowID", session.SSOInputsFrom(ctx.Context).FlowID), log.String("checkpoint", checkpoint)) return nil } diff --git a/backend/internal/flow/executor/session_signout_executor.go b/backend/internal/flow/executor/session_signout_executor.go index e9a5982328..b3064d000a 100644 --- a/backend/internal/flow/executor/session_signout_executor.go +++ b/backend/internal/flow/executor/session_signout_executor.go @@ -80,7 +80,7 @@ func (e *sessionSignOutExecutor) Execute(ctx *providers.NodeContext) (*providers // concern — the OAuth layer resolves it on the sign-out completion callback. execResp.EngineData[common.RuntimeKeySSOSessionCleared] = dataValueTrue - logger.Debug(ctx.Context, "Terminated SSO session on sign-out", log.String("flowId", in.FlowID)) + logger.Debug(ctx.Context, "Terminated SSO session on sign-out", log.String("flowID", in.FlowID)) return execResp, nil } diff --git a/backend/internal/flow/executor/sms_executor.go b/backend/internal/flow/executor/sms_executor.go index 46ab835b6c..80f3bcd83f 100644 --- a/backend/internal/flow/executor/sms_executor.go +++ b/backend/internal/flow/executor/sms_executor.go @@ -204,7 +204,7 @@ func (e *smsExecutor) resolveRecipientMobile(ctx *providers.NodeContext, phoneAt return mobile } if userID, ok := ctx.RuntimeData[userAttributeUserID]; ok && userID != "" && e.entityProvider != nil { - user, err := e.entityProvider.GetEntityProfile(userID) + user, err := e.entityProvider.GetEntityProfile(ctx.Context, userID) if err == nil { if mobile, attrErr := GetUserAttribute(user, phoneAttr); attrErr == nil { return mobile diff --git a/backend/internal/flow/executor/sso_check_executor.go b/backend/internal/flow/executor/sso_check_executor.go index 7184311745..6a6f1e080a 100644 --- a/backend/internal/flow/executor/sso_check_executor.go +++ b/backend/internal/flow/executor/sso_check_executor.go @@ -102,7 +102,7 @@ func (e *ssoCheckExecutor) Execute(ctx *providers.NodeContext) (*providers.Execu common.ForwardedDataKeySSOSessionContext: snapshot, } logger.Debug(ctx.Context, "Live SSO checkpoint present; routing to the Skip outcome", - log.String("flowId", in.FlowID), + log.String("flowID", in.FlowID), log.String("checkpoint", checkpoint)) } else { execResp.Status = providers.ExecFailure diff --git a/backend/internal/flow/executor/utils.go b/backend/internal/flow/executor/utils.go index 9827d6b44d..d0dbe7806f 100644 --- a/backend/internal/flow/executor/utils.go +++ b/backend/internal/flow/executor/utils.go @@ -330,7 +330,7 @@ func resolveAndSetMappedAuthorizationTargets( directTargets, svcErr := idpService.GetDirectAuthorizationTargets(ctx, idpDTO, federatedAttributes) if svcErr != nil { logger.Warn(ctx, "Failed to resolve direct authorization targets, continuing with rule-based targets only", - log.String("idpId", idpDTO.ID), log.String("error", svcErr.Error.DefaultValue)) + log.String(log.LoggerKeyIDPID, idpDTO.ID), log.String("error", svcErr.Error.DefaultValue)) } else { targets = append(targets, directTargets...) } diff --git a/backend/internal/flow/flowexec/engine.go b/backend/internal/flow/flowexec/engine.go index 8948de8d99..77db7e979a 100644 --- a/backend/internal/flow/flowexec/engine.go +++ b/backend/internal/flow/flowexec/engine.go @@ -154,7 +154,7 @@ func (fe *flowEngine) executeNodePackage(ctx *EngineContext, currentNode core.NodeInterface, flowStep *FlowStep, flowStartTime int64) ( core.NodeInterface, bool, *tidcommon.ServiceError) { logger := fe.logger.With(log.String(log.LoggerKeyExecutionID, ctx.ExecutionID), - log.String("nodeID", currentNode.GetID()), log.String("nodeType", string(currentNode.GetType()))) + log.String(log.LoggerKeyNodeID, currentNode.GetID()), log.String("nodeType", string(currentNode.GetType()))) logger.Debug(ctx.Context, "Executing node") @@ -219,8 +219,7 @@ func (fe *flowEngine) executeNodePackage(ctx *EngineContext, // Check if the node should be executed based on its condition if !currentNode.ShouldExecute(nodeCtx) { - logger.Debug(ctx.Context, "Skipping node due to unmet condition", - log.String("nodeID", currentNode.GetID())) + logger.Debug(ctx.Context, "Skipping node due to unmet condition") nextNode, svcErr := fe.skipToNextNode(ctx, currentNode, logger) if svcErr != nil { return nil, false, svcErr @@ -520,8 +519,7 @@ func (fe *flowEngine) setNodeExecutor( } executableNode, ok := node.(core.ExecutorBackedNodeInterface) if !ok { - logger.Error(ctx, "Task execution node does not implement ExecutorBackedNodeInterface", - log.String("nodeID", node.GetID())) + logger.Error(ctx, "Task execution node does not implement ExecutorBackedNodeInterface") return &tidcommon.InternalServerError } @@ -530,20 +528,18 @@ func (fe *flowEngine) setNodeExecutor( return nil } - logger.Debug(ctx, "Executor not set for the node. Constructing executor.", - log.String("nodeID", node.GetID())) + logger.Debug(ctx, "Executor not set for the node. Constructing executor.") executorName := executableNode.GetExecutorName() if executorName == "" { - logger.Error(ctx, "Executor name not configured for executable node", - log.String("nodeID", node.GetID())) + logger.Error(ctx, "Executor name not configured for executable node") return &tidcommon.InternalServerError } executor, err := fe.getExecutorByName(executorName) if err != nil { - logger.Error(ctx, "Error constructing executor for node", log.String("nodeID", node.GetID()), - log.String("executorName", executorName), log.Error(err)) + logger.Error(ctx, "Error constructing executor for node", + log.String(log.LoggerKeyExecutorName, executorName), log.Error(err)) return &tidcommon.InternalServerError } @@ -1161,13 +1157,12 @@ func (fe *flowEngine) skipToNextNode(ctx *EngineContext, currentNode core.NodeIn // Condition must specify where to skip to if condition == nil || condition.OnSkip == "" { - logger.Error(ctx.Context, "Node has condition but onSkip is not specified", - log.String("nodeID", currentNode.GetID())) + logger.Error(ctx.Context, "Node has condition but onSkip is not specified") return nil, &tidcommon.InternalServerError } logger.Debug(ctx.Context, "Using condition's onSkip for skipped node", - log.String("nodeID", currentNode.GetID()), log.String("onSkip", condition.OnSkip)) + log.String("onSkip", condition.OnSkip)) nodeResp := &common.NodeResponse{NextNodeID: condition.OnSkip} @@ -1342,7 +1337,8 @@ func (fe *flowEngine) isSegmentRestartAllowed(ctx *EngineContext, logger *log.Lo return false } - if svcErr := fe.setNodeExecutor(ctx.Context, segStartNode, logger); svcErr != nil { + nodeLogger := logger.With(log.String(log.LoggerKeyNodeID, seg.StartNodeID)) + if svcErr := fe.setNodeExecutor(ctx.Context, segStartNode, nodeLogger); svcErr != nil { return false } @@ -1446,7 +1442,7 @@ func publishNodeExecutionStartedEvent( } evt := event.NewEvent( - ctx.ExecutionID, // Use ExecutionID as TraceID + ctx.TraceID, string(event.EventTypeFlowNodeExecutionStarted), event.ComponentFlowEngine, ). @@ -1517,7 +1513,7 @@ func publishNodeExecutionCompletedEvent(ctx *EngineContext, node core.NodeInterf durationMs := executionEndTime - executionStartTime evt := event.NewEvent( - ctx.ExecutionID, // Use ExecutionID as TraceID + ctx.TraceID, string(eventType), event.ComponentFlowEngine, ). @@ -1554,7 +1550,7 @@ func publishFlowStartedEvent(ctx *EngineContext, obsSvc providers.ObservabilityP } evt := event.NewEvent( - ctx.ExecutionID, // Use ExecutionID as TraceID, so the whole flow shares one trace + ctx.TraceID, string(event.EventTypeFlowStarted), event.ComponentFlowEngine, ). @@ -1581,7 +1577,7 @@ func publishFlowCompletedEvent( durationMs := flowEndTime - flowStartTime evt := event.NewEvent( - ctx.ExecutionID, // Use ExecutionID as TraceID + ctx.TraceID, string(event.EventTypeFlowCompleted), event.ComponentFlowEngine, ). @@ -1605,7 +1601,7 @@ func publishFlowFailedEvent(ctx *EngineContext, svcErr *tidcommon.ServiceError, durationMs := flowEndTime - flowStartTime evt := event.NewEvent( - ctx.ExecutionID, // Use ExecutionID as TraceID, so the whole flow shares one trace + ctx.TraceID, string(event.EventTypeFlowFailed), event.ComponentFlowEngine, ). diff --git a/backend/internal/flow/flowexec/engine_test.go b/backend/internal/flow/flowexec/engine_test.go index 9a19ec859d..04a566b36e 100644 --- a/backend/internal/flow/flowexec/engine_test.go +++ b/backend/internal/flow/flowexec/engine_test.go @@ -2153,7 +2153,6 @@ func (s *EngineTestSuite) TestSkipToNextNode_NoCondition() { t := s.T() mockNode := coremock.NewNodeInterfaceMock(t) mockNode.On("GetCondition").Return((*core.NodeCondition)(nil)) - mockNode.On("GetID").Return("node-1") fe := &flowEngine{logger: log.GetLogger()} ctx := &EngineContext{Context: context.Background()} @@ -2168,7 +2167,6 @@ func (s *EngineTestSuite) TestSkipToNextNode_EmptyOnSkip() { cond := &core.NodeCondition{OnSkip: ""} mockNode := coremock.NewNodeInterfaceMock(t) mockNode.On("GetCondition").Return(cond) - mockNode.On("GetID").Return("node-1") fe := &flowEngine{logger: log.GetLogger()} ctx := &EngineContext{Context: context.Background()} @@ -2183,7 +2181,6 @@ func (s *EngineTestSuite) TestSkipToNextNode_NodeNotFound() { cond := &core.NodeCondition{OnSkip: "skip-target"} mockNode := coremock.NewNodeInterfaceMock(t) mockNode.On("GetCondition").Return(cond) - mockNode.On("GetID").Return("node-1") mockGraph := coremock.NewGraphInterfaceMock(t) mockGraph.On("GetNode", "skip-target").Return(nil, false) @@ -2396,7 +2393,6 @@ func (s *EngineTestSuite) TestSetNodeExecutor_NotExecutorBacked() { t := s.T() mockNode := coremock.NewNodeInterfaceMock(t) mockNode.On("GetType").Return(common.NodeTypeTaskExecution) - mockNode.On("GetID").Return("node-1") fe := &flowEngine{logger: log.GetLogger()} err := fe.setNodeExecutor(context.Background(), mockNode, log.GetLogger()) @@ -2421,7 +2417,6 @@ func (s *EngineTestSuite) TestSetNodeExecutor_ExecutorNameEmpty() { mockNode.On("GetType").Return(common.NodeTypeTaskExecution) mockNode.On("GetExecutor").Return(nil) mockNode.On("GetExecutorName").Return("") - mockNode.On("GetID").Return("node-1") fe := &flowEngine{logger: log.GetLogger()} err := fe.setNodeExecutor(context.Background(), mockNode, log.GetLogger()) @@ -2437,7 +2432,6 @@ func (s *EngineTestSuite) TestSetNodeExecutor_RegistryError() { mockNode.On("GetType").Return(common.NodeTypeTaskExecution) mockNode.On("GetExecutor").Return(nil) mockNode.On("GetExecutorName").Return("myExec") - mockNode.On("GetID").Return("node-1") fe := &flowEngine{executorRegistry: mockRegistry, logger: log.GetLogger()} err := fe.setNodeExecutor(context.Background(), mockNode, log.GetLogger()) @@ -4613,6 +4607,8 @@ func setupCapturingObservability(t *testing.T) ( return mockObs, captured } +const testRequestTraceID = "request-trace-1" + // agentFlowContext returns an engine context for an authentication flow driven by an agent that has // authenticated a user. The subject is recorded on AuthUser, which is where the authentication // executors put it — EngineContext.AuthenticatedUser is never written during execution, so a test @@ -4620,7 +4616,7 @@ func setupCapturingObservability(t *testing.T) ( func agentFlowContext() *EngineContext { ctx := &EngineContext{ ExecutionID: "flow-exec-1", - TraceID: "request-trace-1", + TraceID: testRequestTraceID, FlowType: providers.FlowTypeAuthentication, AppID: "agent-entity-1", Application: providers.Application{ @@ -4656,10 +4652,8 @@ func TestFlowStartedEvent_ReportsPrincipalAndCorrelation(t *testing.T) { } evt := (*captured)[0] - // The whole flow must share one trace, keyed on the execution id, so FLOW_STARTED stitches to - // its own child events. - if evt.TraceID != "flow-exec-1" { - t.Errorf("TraceID = %q, want the execution id %q", evt.TraceID, "flow-exec-1") + if evt.TraceID != testRequestTraceID { + t.Errorf("TraceID = %q, want the request trace id %q", evt.TraceID, testRequestTraceID) } assertEventData(t, evt, map[string]interface{}{ @@ -4786,6 +4780,9 @@ func TestNodeExecutionStartedEvent_ReportsSubjectAndPrincipal(t *testing.T) { publishNodeExecutionStartedEvent(agentFlowContext(), node, mockObs) + if evt := (*captured)[0]; evt.TraceID != testRequestTraceID { + t.Errorf("TraceID = %q, want the request trace id %q", evt.TraceID, testRequestTraceID) + } assertEventData(t, (*captured)[0], map[string]interface{}{ event.DataKey.ActorType: string(providers.EntityCategoryAgent), event.DataKey.ClientID: "agent-client-id", @@ -4846,15 +4843,15 @@ func TestFlowCompletedEvent_ReportsPrincipalAndCorrelation(t *testing.T) { }) } -func TestFlowFailedEvent_SharesTheFlowTrace(t *testing.T) { +func TestFlowFailedEvent_CarriesTheRequestTrace(t *testing.T) { mockObs, captured := setupCapturingObservability(t) defer config.ResetServerRuntime() publishFlowFailedEvent(agentFlowContext(), nil, 0, 5, mockObs) evt := (*captured)[0] - if evt.TraceID != "flow-exec-1" { - t.Errorf("TraceID = %q, want the execution id %q", evt.TraceID, "flow-exec-1") + if evt.TraceID != testRequestTraceID { + t.Errorf("TraceID = %q, want the request trace id %q", evt.TraceID, testRequestTraceID) } assertEventData(t, evt, map[string]interface{}{ event.DataKey.ActorType: string(providers.EntityCategoryAgent), diff --git a/backend/internal/flow/flowexec/interceptor_runner.go b/backend/internal/flow/flowexec/interceptor_runner.go index 3238ac71fb..6e847f643e 100644 --- a/backend/internal/flow/flowexec/interceptor_runner.go +++ b/backend/internal/flow/flowexec/interceptor_runner.go @@ -159,7 +159,7 @@ func (s *interceptorRunner) executeInterceptor( logger.Debug(execCtx.Ctx, "Running interceptor", log.String("interceptorName", name), log.String("mode", string(mode)), - log.String("nodeID", execCtx.CurrentNodeID)) + log.String(log.LoggerKeyNodeID, execCtx.CurrentNodeID)) ctx := &core.InterceptorContext{ Context: execCtx.Ctx, diff --git a/backend/internal/flow/flowexec/service_test.go b/backend/internal/flow/flowexec/service_test.go index 826d7991f4..a804ca5ba7 100644 --- a/backend/internal/flow/flowexec/service_test.go +++ b/backend/internal/flow/flowexec/service_test.go @@ -307,7 +307,7 @@ func TestInitiateFlowSuccessScenarios(t *testing.T) { } else { mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, appID). Return(mockClient, nil) - mockEntityProvider.EXPECT().GetEntityProfile(appID). + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, appID). Return(mockEntity, (*entityprovider.EntityProviderError)(nil)) mockFlowProvider.EXPECT().GetFlow(mock.Anything, "auth-graph-1"). Return(&providers.CompleteFlowDefinition{ID: "auth-graph-1"}, nil) @@ -408,7 +408,7 @@ func TestInitiateFlowErrorScenarios(t *testing.T) { ) { mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, appID). Return(&inboundmodel.InboundClient{ID: appID, AuthFlowID: "auth-graph-1"}, nil) - mockEntityProvider.EXPECT().GetEntityProfile(appID).Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, appID).Return( &providers.Entity{ID: appID, Category: providers.EntityCategoryApp}, (*entityprovider.EntityProviderError)(nil)) @@ -523,7 +523,7 @@ func TestInitiateFlowFallsBackToDefaultFlow(t *testing.T) { mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, appID). Return(&inboundmodel.InboundClient{ID: appID, AuthFlowID: "stale-auth-graph"}, nil) - mockEntityProvider.EXPECT().GetEntityProfile(appID). + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, appID). Return(&providers.Entity{ID: appID, Category: providers.EntityCategoryApp}, (*entityprovider.EntityProviderError)(nil)) @@ -683,7 +683,7 @@ func TestEncryptedPayloadStoredBeforeWrite(t *testing.T) { mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, "test-app").Return( &inboundmodel.InboundClient{ID: "test-app", AuthFlowID: "auth-graph-1"}, nil) - mockEntityProvider.EXPECT().GetEntityProfile("test-app").Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, "test-app").Return( &providers.Entity{ID: "test-app", Category: providers.EntityCategoryApp}, (*entityprovider.EntityProviderError)(nil)) mockFlowProvider.EXPECT(). @@ -765,7 +765,7 @@ func TestDecryptCalledForEncryptedStoredContext(t *testing.T) { mockGraphBuilder.EXPECT().GetGraph(mock.Anything, mock.Anything).Return(testGraph, nil) mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, "test-app-id").Return( &inboundmodel.InboundClient{ID: "test-app-id", AuthFlowID: "test-graph-id"}, nil) - mockEntityProvider.EXPECT().GetEntityProfile("test-app-id").Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, "test-app-id").Return( &providers.Entity{ID: "test-app-id", Category: providers.EntityCategoryApp}, (*entityprovider.EntityProviderError)(nil)) @@ -1065,7 +1065,7 @@ func TestExecute_ContextDecryptionSuccess(t *testing.T) { mockGraphBuilder.EXPECT().GetGraph(mock.Anything, mock.Anything).Return(testGraph, nil) mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, "test-app-id").Return( &inboundmodel.InboundClient{ID: "test-app-id", AuthFlowID: "test-graph-id"}, nil) - mockEntityProvider.EXPECT().GetEntityProfile("test-app-id").Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, "test-app-id").Return( &providers.Entity{ID: "test-app-id", Category: providers.EntityCategoryApp}, (*entityprovider.EntityProviderError)(nil)) challengeToken := "test-challenge-token" @@ -1129,7 +1129,7 @@ func TestExecute_ExistingFlowWithoutChallengeToken(t *testing.T) { mockGraphBuilder.EXPECT().GetGraph(mock.Anything, mock.Anything).Return(testGraph, nil) mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, "test-app-id").Return( &inboundmodel.InboundClient{ID: "test-app-id", AuthFlowID: "test-graph-id"}, nil) - mockEntityProvider.EXPECT().GetEntityProfile("test-app-id").Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, "test-app-id").Return( &providers.Entity{ID: "test-app-id", Category: providers.EntityCategoryApp}, (*entityprovider.EntityProviderError)(nil)) @@ -1224,7 +1224,7 @@ func TestExecute_ExistingFlowWithDifferentChallengeTokens(t *testing.T) { mockGraphBuilder.EXPECT().GetGraph(mock.Anything, mock.Anything).Return(testGraph, nil) mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, "test-app-id").Return( &inboundmodel.InboundClient{ID: "test-app-id", AuthFlowID: "test-graph-id"}, nil) - mockEntityProvider.EXPECT().GetEntityProfile("test-app-id").Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, "test-app-id").Return( &providers.Entity{ID: "test-app-id", Category: providers.EntityCategoryApp}, (*entityprovider.EntityProviderError)(nil)) @@ -1301,7 +1301,7 @@ func TestExecute_EngineError_InvalidChallengeToken_PreservesContext(t *testing.T mockGraphBuilder.EXPECT().GetGraph(mock.Anything, mock.Anything).Return(testGraph, nil) mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, "test-app-id").Return( &inboundmodel.InboundClient{ID: "test-app-id", AuthFlowID: "test-graph-id"}, nil) - mockEntityProvider.EXPECT().GetEntityProfile("test-app-id").Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, "test-app-id").Return( &providers.Entity{ID: "test-app-id", Category: providers.EntityCategoryApp}, (*entityprovider.EntityProviderError)(nil)) mockCrypto.EXPECT().Encrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). @@ -1372,7 +1372,7 @@ func TestExecute_EngineError_NonChallengeToken_RemovesContext(t *testing.T) { mockGraphBuilder.EXPECT().GetGraph(mock.Anything, mock.Anything).Return(testGraph, nil) mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, "test-app-id").Return( &inboundmodel.InboundClient{ID: "test-app-id", AuthFlowID: "test-graph-id"}, nil) - mockEntityProvider.EXPECT().GetEntityProfile("test-app-id").Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, "test-app-id").Return( &providers.Entity{ID: "test-app-id", Category: providers.EntityCategoryApp}, (*entityprovider.EntityProviderError)(nil)) @@ -1435,7 +1435,7 @@ func TestExecute_EngineError_NewFlow_ContextNeverRemoved(t *testing.T) { Return(providers.AuthUser{}, nil, nil) mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, "test-app").Return( &inboundmodel.InboundClient{ID: "test-app", AuthFlowID: "auth-graph-1"}, nil).Times(3) - mockEntityProvider.EXPECT().GetEntityProfile("test-app").Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, "test-app").Return( &providers.Entity{ID: "test-app", Category: providers.EntityCategoryApp}, (*entityprovider.EntityProviderError)(nil)) mockFlowProvider.EXPECT(). @@ -1515,7 +1515,7 @@ func TestBuildApplication_EntityLoadError(t *testing.T) { provider, mockInbound, mockEP := newBuildAppProvider(t) mockInbound.EXPECT().GetInboundClientByEntityID(mock.Anything, "app-x"). Return(&inboundmodel.InboundClient{ID: "app-x"}, nil) - mockEP.EXPECT().GetEntityProfile("app-x").Return( + mockEP.EXPECT().GetEntityProfile(mock.Anything, "app-x").Return( (*providers.Entity)(nil), entityprovider.NewEntityProviderError("INTERNAL_ERROR", "boom", "")) @@ -1532,7 +1532,7 @@ func TestBuildApplication_EntityNotFound_ReturnsAppWithoutEntityFields(t *testin ID: "app-x", AllowedUserTypes: []string{"customer"}, }, nil) - mockEP.EXPECT().GetEntityProfile("app-x").Return( + mockEP.EXPECT().GetEntityProfile(mock.Anything, "app-x").Return( (*providers.Entity)(nil), entityprovider.NewEntityProviderError(entityprovider.ErrorCodeEntityNotFound, "missing", "")) @@ -1556,7 +1556,7 @@ func TestBuildApplication_Success_WithMetadataAndClientID(t *testing.T) { }, }, nil) sysAttrs := []byte(`{"name":"Acme","clientId":"client-1"}`) - mockEP.EXPECT().GetEntityProfile("app-x").Return( + mockEP.EXPECT().GetEntityProfile(mock.Anything, "app-x").Return( &providers.Entity{ ID: "app-x", Category: providers.EntityCategoryApp, @@ -1678,7 +1678,7 @@ func TestInitiateAndExecute_CustomExpiryUsed(t *testing.T) { mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, appID).Return( &inboundmodel.InboundClient{ID: appID, AuthFlowID: "auth-graph-expiry"}, nil) - mockEntityProvider.EXPECT().GetEntityProfile(appID).Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, appID).Return( &providers.Entity{ID: appID, Category: providers.EntityCategoryApp}, nil) mockFlowProvider.EXPECT(). GetFlow(mock.Anything, "auth-graph-expiry"). @@ -1735,7 +1735,7 @@ func TestInitiateAndExecute_ZeroExpiryUsesDefault(t *testing.T) { mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, appID).Return( &inboundmodel.InboundClient{ID: appID, AuthFlowID: "auth-graph-defexp"}, nil) - mockEntityProvider.EXPECT().GetEntityProfile(appID).Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, appID).Return( &providers.Entity{ID: appID, Category: providers.EntityCategoryApp}, nil) mockFlowProvider.EXPECT(). GetFlow(mock.Anything, "auth-graph-defexp"). @@ -1800,7 +1800,7 @@ func TestInitiateAndExecute_InitialInputsAndRuntimeData(t *testing.T) { mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, appID).Return( &inboundmodel.InboundClient{ID: appID, AuthFlowID: "auth-graph-ia"}, nil) - mockEntityProvider.EXPECT().GetEntityProfile(appID).Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, appID).Return( &providers.Entity{ID: appID, Category: providers.EntityCategoryApp}, nil) mockFlowProvider.EXPECT(). GetFlow(mock.Anything, "auth-graph-ia"). @@ -1861,7 +1861,7 @@ func TestInitiateAndExecute_FlowComplete_ContextNotStored(t *testing.T) { mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, appID).Return( &inboundmodel.InboundClient{ID: appID, AuthFlowID: "auth-graph-complete"}, nil) - mockEntityProvider.EXPECT().GetEntityProfile(appID).Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, appID).Return( &providers.Entity{ID: appID, Category: providers.EntityCategoryApp}, nil) mockFlowProvider.EXPECT(). GetFlow(mock.Anything, "auth-graph-complete"). @@ -1914,7 +1914,7 @@ func TestInitiateAndExecute_EngineError(t *testing.T) { mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, appID).Return( &inboundmodel.InboundClient{ID: appID, AuthFlowID: "auth-graph-ee"}, nil) - mockEntityProvider.EXPECT().GetEntityProfile(appID).Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, appID).Return( &providers.Entity{ID: appID, Category: providers.EntityCategoryApp}, nil) mockFlowProvider.EXPECT(). GetFlow(mock.Anything, "auth-graph-ee"). @@ -1965,7 +1965,7 @@ func TestInitiateAndExecute_StoreError_ReturnsError(t *testing.T) { mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, appID).Return( &inboundmodel.InboundClient{ID: appID, AuthFlowID: "auth-graph-se"}, nil) - mockEntityProvider.EXPECT().GetEntityProfile(appID).Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, appID).Return( &providers.Entity{ID: appID, Category: providers.EntityCategoryApp}, nil) mockFlowProvider.EXPECT(). GetFlow(mock.Anything, "auth-graph-se"). @@ -2178,7 +2178,7 @@ func (s *ServiceTestSuite) TestExecute_NewFlow_IncompleteStoresContext() { Return(providers.AuthUser{}, nil, nil) mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, appID).Return( &inboundmodel.InboundClient{ID: appID, AuthFlowID: "auth-graph-new"}, nil) - mockEntityProvider.EXPECT().GetEntityProfile(appID).Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, appID).Return( &providers.Entity{ID: appID, Category: providers.EntityCategoryApp}, nil) mockFlowProvider.EXPECT(). GetFlow(mock.Anything, "auth-graph-new"). @@ -2246,7 +2246,7 @@ func (s *ServiceTestSuite) TestExecute_ExistingFlow_CompleteRemovesContext() { mockGraphBuilder.EXPECT().GetGraph(mock.Anything, mock.Anything).Return(testGraph, nil) mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, "test-app-id").Return( &inboundmodel.InboundClient{ID: "test-app-id", AuthFlowID: "test-graph-id"}, nil) - mockEntityProvider.EXPECT().GetEntityProfile("test-app-id").Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, "test-app-id").Return( &providers.Entity{ID: "test-app-id", Category: providers.EntityCategoryApp}, nil) mockEngine.EXPECT().Execute(mock.Anything). Return(FlowStep{Status: providers.FlowStatusComplete}, nil) @@ -2872,7 +2872,7 @@ func (s *ServiceTestSuite) TestExecute_NewFlow_BackendApp_ValidSecret_Allowed() Return(providers.AuthUser{}, nil, nil) mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, "test-app").Return( &inboundmodel.InboundClient{ID: "test-app", AuthFlowID: "auth-graph-1"}, nil).Times(3) - mockEntityProvider.EXPECT().GetEntityProfile("test-app").Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, "test-app").Return( &providers.Entity{ID: "test-app", Category: providers.EntityCategoryApp}, (*entityprovider.EntityProviderError)(nil)) mockFlowProvider.EXPECT(). @@ -2988,7 +2988,7 @@ func (s *ServiceTestSuite) TestExecute_NewFlow_EmbeddedApp_ValidSecret_Allowed() Return(providers.AuthUser{}, nil, nil) mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, "test-app").Return( &inboundmodel.InboundClient{ID: "test-app", AuthFlowID: "auth-graph-1"}, nil).Times(3) - mockEntityProvider.EXPECT().GetEntityProfile("test-app").Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, "test-app").Return( &providers.Entity{ID: "test-app", Category: providers.EntityCategoryApp}, (*entityprovider.EntityProviderError)(nil)) mockFlowProvider.EXPECT(). @@ -3081,7 +3081,7 @@ func (s *ServiceTestSuite) TestExecute_ContinuationFlow_AuthCodeApp_NotBlocked() mockGraphBuilder.EXPECT().GetGraph(mock.Anything, mock.Anything).Return(testGraph, nil) mockInboundClient.EXPECT().GetInboundClientByEntityID(mock.Anything, "test-app").Return( &inboundmodel.InboundClient{ID: "test-app", AuthFlowID: "auth-graph-1"}, nil) - mockEntityProvider.EXPECT().GetEntityProfile("test-app").Return( + mockEntityProvider.EXPECT().GetEntityProfile(mock.Anything, "test-app").Return( &providers.Entity{ID: "test-app", Category: providers.EntityCategoryApp}, (*entityprovider.EntityProviderError)(nil)) diff --git a/backend/internal/flow/flowmeta/service.go b/backend/internal/flow/flowmeta/service.go index 511828525f..931b9f2998 100644 --- a/backend/internal/flow/flowmeta/service.go +++ b/backend/internal/flow/flowmeta/service.go @@ -162,7 +162,7 @@ func (fms *flowMetaService) populateTypeMetadata( return "", &ErrorApplicationNotFound } - entity, epErr := fms.actorProvider.GetActor(id) + entity, epErr := fms.actorProvider.GetActor(ctx, id) if epErr != nil && epErr.Code != string(entityprovider.ErrorCodeEntityNotFound) { fms.logger.Error(ctx, "Failed to get actor", log.String("appID", id), log.String("error", epErr.Error.DefaultValue)) diff --git a/backend/internal/flow/flowmeta/service_test.go b/backend/internal/flow/flowmeta/service_test.go index ac8aaaee15..65afc884d4 100644 --- a/backend/internal/flow/flowmeta/service_test.go +++ b/backend/internal/flow/flowmeta/service_test.go @@ -88,7 +88,7 @@ func (suite *FlowMetaServiceTestSuite) expectInboundLookup( SystemAttributes: sysAttrs, } suite.mockInboundClient.On("GetInboundClientByEntityID", mock.Anything, appID).Return(client, nil) - suite.mockEntityProvider.On("GetEntityProfile", appID). + suite.mockEntityProvider.On("GetEntityProfile", mock.Anything, appID). Return(entity, (*entityprovider.EntityProviderError)(nil)) } diff --git a/backend/internal/flow/graphbuilder/graph_builder.go b/backend/internal/flow/graphbuilder/graph_builder.go index a0f4223cbd..b77620a060 100644 --- a/backend/internal/flow/graphbuilder/graph_builder.go +++ b/backend/internal/flow/graphbuilder/graph_builder.go @@ -332,7 +332,7 @@ func (b *graphBuilder) configureNodeInputs( nodeDef *providers.NodeDefinition, node core.NodeInterface, ) { - logger := b.logger.With(log.String("nodeID", nodeDef.ID)) + logger := b.logger.With(log.String(log.LoggerKeyNodeID, nodeDef.ID)) executorNode, ok := node.(core.ExecutorBackedNodeInterface) if !ok { @@ -419,7 +419,7 @@ func (b *graphBuilder) configureNodePrompts( node core.NodeInterface, edges map[string][]string, ) error { - logger := b.logger.With(log.String("nodeID", nodeDef.ID)) + logger := b.logger.With(log.String(log.LoggerKeyNodeID, nodeDef.ID)) if len(nodeDef.Prompts) == 0 { logger.Debug(ctx, "No prompts to configure for this node") @@ -479,7 +479,7 @@ func (b *graphBuilder) configureNodePrompts( func (b *graphBuilder) configureDisplayOnlyProperties( ctx context.Context, nodeDef *providers.NodeDefinition, node core.NodeInterface, edges map[string][]string, boundaries *[]segmentBoundary) error { - logger := b.logger.With(log.String("nodeID", nodeDef.ID)) + logger := b.logger.With(log.String(log.LoggerKeyNodeID, nodeDef.ID)) if nodeDef.Next == "" { return nil @@ -548,7 +548,7 @@ func (b *graphBuilder) computeSegments(g core.GraphInterface, boundaries []segme // configureNodeExecutor configures the executor for a node. func (b *graphBuilder) configureNodeExecutor( ctx context.Context, nodeDef *providers.NodeDefinition, node core.NodeInterface) error { - logger := b.logger.With(log.String("nodeID", nodeDef.ID)) + logger := b.logger.With(log.String(log.LoggerKeyNodeID, nodeDef.ID)) if nodeDef.Executor == nil { logger.Debug(ctx, "No executor to configure for this node") diff --git a/backend/internal/flow/mgt/inference.go b/backend/internal/flow/mgt/inference.go index 6d5eb0e878..1be89304ef 100644 --- a/backend/internal/flow/mgt/inference.go +++ b/backend/internal/flow/mgt/inference.go @@ -591,7 +591,7 @@ func (s *flowInferenceService) insertPhoneInputPromptIfNeeded( err := s.insertNodeBefore(nodes, phonePromptNode, otpGenerateNodeID) if err != nil { s.logger.Warn(ctx, "Failed to insert phone input prompt before OTP generate node", - log.String("nodeID", otpGenerateNodeID), log.Error(err)) + log.String(log.LoggerKeyNodeID, otpGenerateNodeID), log.Error(err)) return } diff --git a/backend/internal/flow/session/service.go b/backend/internal/flow/session/service.go index 1cbf1fd707..c564953c8e 100644 --- a/backend/internal/flow/session/service.go +++ b/backend/internal/flow/session/service.go @@ -375,7 +375,7 @@ func (s *service) Terminate(ctx context.Context, handle, flowID string) (*Sessio return nil, fmt.Errorf("failed to terminate session: %w", txErr) } - s.logger.Debug(ctx, "Terminated SSO session", log.String("flowId", sess.FlowID)) + s.logger.Debug(ctx, "Terminated SSO session", log.String("flowID", sess.FlowID)) if notify { s.terminationTopic.Notify(ctx, TerminatedSession{ SessionID: sess.SessionID, @@ -618,7 +618,7 @@ func (s *service) establishSession(ctx context.Context, in SaveCheckpointInput) } created := established.HandleID == handle if created { - s.logger.Debug(ctx, "Established SSO session", log.String("flowId", in.FlowID)) + s.logger.Debug(ctx, "Established SSO session", log.String("flowID", in.FlowID)) } return established, created, nil } diff --git a/backend/internal/gateway/apply_lease.go b/backend/internal/gateway/apply_lease.go index e069f8eb9d..0ccf62478c 100644 --- a/backend/internal/gateway/apply_lease.go +++ b/backend/internal/gateway/apply_lease.go @@ -79,7 +79,7 @@ func (s *versionService) lease(ctx context.Context, gatewayID string, coalesce b } if queued { s.logger.Info(ctx, "Queued the latest version behind the running apply", - log.String("gatewayId", gatewayID)) + log.String("gatewayID", gatewayID)) return nil, "", time.Time{}, true, nil } // Released between the claim and the ask; claim again. @@ -101,13 +101,13 @@ func (s *versionService) releaser(ctx context.Context, gatewayID, token string) // The release outlives the request that applied, which may be gone by now. ctx := context.WithoutCancel(ctx) if err := s.versions.ReleaseLease(ctx, gatewayID, token); err != nil { - s.logger.Error(ctx, "Failed to release the gateway's apply lease", log.String("gatewayId", gatewayID), + s.logger.Error(ctx, "Failed to release the gateway's apply lease", log.String("gatewayID", gatewayID), log.Error(err)) } by, pending, err := s.versions.TakePendingLatest(ctx, gatewayID) if err != nil { s.logger.Error(ctx, "Failed to read whether the latest version is to be applied again", - log.String("gatewayId", gatewayID), log.Error(err)) + log.String("gatewayID", gatewayID), log.Error(err)) return } if pending { @@ -124,12 +124,12 @@ func (s *versionService) applyLatestAgain(ctx context.Context, gatewayID string) switch { case svcErr != nil: s.logger.Warn(ctx, "The latest version queued behind an apply could not be applied", - log.String("gatewayId", gatewayID), log.String("code", svcErr.Code)) + log.String("gatewayID", gatewayID), log.String("code", svcErr.Code)) case result.Queued: s.logger.Info(ctx, "The latest version is queued once more behind another apply", - log.String("gatewayId", gatewayID)) + log.String("gatewayID", gatewayID)) default: - s.logger.Info(ctx, "Applied the latest version queued behind an apply", log.String("gatewayId", gatewayID), + s.logger.Info(ctx, "Applied the latest version queued behind an apply", log.String("gatewayID", gatewayID), log.String("version", result.Diff.ToVersion)) } } diff --git a/backend/internal/gateway/service.go b/backend/internal/gateway/service.go index d2f118f43e..41823d670d 100644 --- a/backend/internal/gateway/service.go +++ b/backend/internal/gateway/service.go @@ -183,7 +183,7 @@ func (s *service) Register(ctx context.Context, return nil, &ErrorGatewayLimitReached } - s.logger.Info(ctx, "Registered a gateway", log.String("gatewayId", registered.ID), + s.logger.Info(ctx, "Registered a gateway", log.String("gatewayID", registered.ID), log.String("baseUrl", registered.BaseURL)) registered.Key = "" // The generated key travels in the response and is not kept anywhere readable. @@ -286,7 +286,7 @@ func (s *service) Update(ctx context.Context, id string, return nil, &tidcommon.InternalServerError } - s.logger.Info(ctx, "Updated a gateway", log.String("gatewayId", existing.ID)) + s.logger.Info(ctx, "Updated a gateway", log.String("gatewayID", existing.ID)) existing.Key = "" return existing, nil } @@ -310,7 +310,7 @@ func (s *service) Delete(ctx context.Context, id string) *tidcommon.ServiceError s.logger.Error(ctx, "Failed to remove the gateway", log.Error(err)) return &tidcommon.InternalServerError } - s.logger.Info(ctx, "Removed a gateway", log.String("gatewayId", id)) + s.logger.Info(ctx, "Removed a gateway", log.String("gatewayID", id)) return nil } diff --git a/backend/internal/gateway/store_service.go b/backend/internal/gateway/store_service.go index 2c9fac367c..b5ae9524be 100644 --- a/backend/internal/gateway/store_service.go +++ b/backend/internal/gateway/store_service.go @@ -157,7 +157,7 @@ func callGatewayStore[T any](ctx context.Context, s *storeService, gatewayID str if errors.As(err, &refusal) && json.Valid(refusal.Body) { return &StoreAnswer[T]{Refusal: refusal}, nil } - s.logger.Error(ctx, "Failed to reach a gateway's store", log.String("gatewayId", gw.ID), log.Error(err)) + s.logger.Error(ctx, "Failed to reach a gateway's store", log.String("gatewayID", gw.ID), log.Error(err)) return nil, unreachable(err) } return &StoreAnswer[T]{Value: value, Created: created}, nil diff --git a/backend/internal/gateway/value_capture.go b/backend/internal/gateway/value_capture.go index 826afd9c4a..ddf6f620d1 100644 --- a/backend/internal/gateway/value_capture.go +++ b/backend/internal/gateway/value_capture.go @@ -196,19 +196,19 @@ func (c *ValueCapture) push(ctx context.Context, key string) { case svcErr != nil && p.failures+1 < c.attempts: p.failures++ c.logger.Warn(ctx, "Failed to capture a value in the default gateway's store; it will be tried again", - log.String("gatewayId", p.gatewayID), log.String("collection", p.collection), + log.String("gatewayID", p.gatewayID), log.String("collection", p.collection), log.String("name", p.name), log.Int("failures", p.failures), log.String("error", svcErr.Error.DefaultValue)) p.timer = time.AfterFunc(c.pushDelay(p.failures), func() { c.push(ctx, key) }) case svcErr != nil: c.logger.Error(ctx, "Gave up capturing a value in the default gateway's store", - log.String("gatewayId", p.gatewayID), log.String("collection", p.collection), + log.String("gatewayID", p.gatewayID), log.String("collection", p.collection), log.String("name", p.name), log.Int("failures", p.failures+1), log.String("error", svcErr.Error.DefaultValue)) delete(c.pending, key) case refusal != nil: c.logger.Warn(ctx, "The default gateway's store refused a captured value", - log.String("gatewayId", p.gatewayID), log.String("collection", p.collection), + log.String("gatewayID", p.gatewayID), log.String("collection", p.collection), log.String("name", p.name), log.Int("status", refusal.Status)) delete(c.pending, key) default: diff --git a/backend/internal/gateway/version_service.go b/backend/internal/gateway/version_service.go index f4c9125259..d303c92a38 100644 --- a/backend/internal/gateway/version_service.go +++ b/backend/internal/gateway/version_service.go @@ -125,7 +125,7 @@ func (s *versionService) capture(ctx context.Context, req CaptureRequest) (*Vers } for _, failed := range skipped { s.logger.Warn(ctx, "A resource the export could not write is left out of the version", - log.String("resourceType", failed.ResourceType), log.MaskedString("resourceId", failed.ResourceID), + log.String("resourceType", failed.ResourceType), log.MaskedString("resourceID", failed.ResourceID), log.String("error", failed.Error)) } @@ -579,7 +579,7 @@ func (s *versionService) write(ctx context.Context, gw *Gateway, target *Version // Once the gateway may have written any of it, the version is kept as it is. delivered = mayHaveWritten(err) if err != nil { - s.logger.Error(ctx, "Failed to apply a version to a gateway", log.String("gatewayId", gw.ID), + s.logger.Error(ctx, "Failed to apply a version to a gateway", log.String("gatewayID", gw.ID), log.Int("version", target.Seq), log.Error(err)) if kept && errors.Is(err, errImportNotWritten) { s.restoreExclusions(ctx, gw.ID, before, exclude, include) @@ -600,7 +600,7 @@ func (s *versionService) write(ctx context.Context, gw *Gateway, target *Version if len(request.Deletions) > 0 { if failed, ok := failedDeletions(answer); !ok || failed > 0 { s.logger.Warn(ctx, "The gateway did not complete the removals, so the version is not recorded as applied", - log.String("gatewayId", gw.ID), log.Int("version", target.Seq), log.Int("failed", failed)) + log.String("gatewayID", gw.ID), log.Int("version", target.Seq), log.Int("failed", failed)) return result, nil } } @@ -609,7 +609,7 @@ func (s *versionService) write(ctx context.Context, gw *Gateway, target *Version return nil, svcErr } result.Recorded = true - s.logger.Info(ctx, "Applied a configuration version to a gateway", log.String("gatewayId", gw.ID), + s.logger.Info(ctx, "Applied a configuration version to a gateway", log.String("gatewayID", gw.ID), log.Int("version", target.Seq)) s.clearOwedTaken(ctx, gw.ID, owed, choice.leftAlone) return result, nil @@ -623,7 +623,7 @@ func (s *versionService) write(ctx context.Context, gw *Gateway, target *Version func (s *versionService) mayStillSend(ctx context.Context, gw *Gateway, target *Version, token string, prepared time.Time) *tidcommon.ServiceError { if time.Since(prepared) > prepareBudget { - s.logger.Warn(ctx, "An apply took too long to prepare and sends nothing", log.String("gatewayId", gw.ID), + s.logger.Warn(ctx, "An apply took too long to prepare and sends nothing", log.String("gatewayID", gw.ID), log.Int("version", target.Seq)) return &ErrorApplyTookTooLong } @@ -634,7 +634,7 @@ func (s *versionService) mayStillSend(ctx context.Context, gw *Gateway, target * } if !holds { s.logger.Warn(ctx, "Another apply took over the gateway before the import was sent", - log.String("gatewayId", gw.ID), log.Int("version", target.Seq)) + log.String("gatewayID", gw.ID), log.Int("version", target.Seq)) return &ErrorAppliedChanged } return nil @@ -651,7 +651,7 @@ func (s *versionService) clearOwedTaken(ctx context.Context, gatewayID string, o } if err := s.versions.SetExcluded(ctx, gatewayID, nil, taken); err != nil { s.logger.Error(ctx, "Failed to clear what the gateway was owed after it was applied", - log.String("gatewayId", gatewayID), log.Error(err)) + log.String("gatewayID", gatewayID), log.Error(err)) } } @@ -679,10 +679,10 @@ func (s *versionService) record(ctx context.Context, gw *Gateway, target *Versio return nil case errors.Is(err, errVersionRemoved): s.logger.Warn(ctx, "A version was removed or replaced while it was applied to a gateway", - log.String("gatewayId", gw.ID), log.Int("version", target.Seq)) + log.String("gatewayID", gw.ID), log.Int("version", target.Seq)) return &ErrorVersionRemoved case errors.Is(err, errAppliedChanged): - s.logger.Warn(ctx, "Another apply to the gateway finished first", log.String("gatewayId", gw.ID), + s.logger.Warn(ctx, "Another apply to the gateway finished first", log.String("gatewayID", gw.ID), log.Int("version", target.Seq)) return &ErrorAppliedChanged default: @@ -705,7 +705,7 @@ func (s *versionService) refuseUnconfirmedRemovals(ctx context.Context, gw *Gate return nil } s.logger.Info(ctx, "Refused an apply that removes more than the threshold until it is confirmed", - log.String("gatewayId", gw.ID), log.Int("removals", removals), log.Int("threshold", limit)) + log.String("gatewayID", gw.ID), log.Int("removals", removals), log.Int("threshold", limit)) return &ErrorRemovalsNeedConfirmation } @@ -756,7 +756,7 @@ func (s *versionService) requiredValues(ctx context.Context, gw *Gateway, key, c variables, secrets := referencesIn(content) held, err := s.client.HeldValues(ctx, gw, key, variables, secrets) if err != nil { - s.logger.Error(ctx, "Failed to read which values a gateway holds", log.String("gatewayId", gw.ID), + s.logger.Error(ctx, "Failed to read which values a gateway holds", log.String("gatewayID", gw.ID), log.Error(err)) return nil, nil, "", unreachable(err) } @@ -824,7 +824,7 @@ func (s *versionService) restoreExclusions(ctx context.Context, gatewayID string } if err := s.versions.SetExcluded(ctx, gatewayID, reexclude, touched); err != nil { s.logger.Error(ctx, "Failed to put back what the gateway leaves alone after a failed apply", - log.String("gatewayId", gatewayID), log.Error(err)) + log.String("gatewayID", gatewayID), log.Error(err)) } } @@ -850,7 +850,7 @@ func (s *versionService) plan(ctx context.Context, gatewayID string, target *Ver // is always there. Were it not, the deletions could not be worked out, and applying without // them would leave behind what the new version dropped. if heldVersion == nil { - s.logger.Error(ctx, "The version a gateway holds is not kept", log.String("gatewayId", gatewayID), + s.logger.Error(ctx, "The version a gateway holds is not kept", log.String("gatewayID", gatewayID), log.Int("version", applied.AppliedVersion)) return nil, nil, &tidcommon.InternalServerError } diff --git a/backend/internal/idp/cache_backed_store.go b/backend/internal/idp/cache_backed_store.go index 975f57393e..635ed04dcf 100644 --- a/backend/internal/idp/cache_backed_store.go +++ b/backend/internal/idp/cache_backed_store.go @@ -158,7 +158,7 @@ func (s *cacheBackedIDPStore) cacheIDP(ctx context.Context, idp *providers.IDPDT idKey := cache.CacheKey{Key: idp.ID} if err := s.idpByIDCache.Set(ctx, idKey, idp); err != nil { - logger.Error(ctx, "Failed to cache IDP by ID", log.Error(err), log.String("idpID", idp.ID)) + logger.Error(ctx, "Failed to cache IDP by ID", log.Error(err), log.String(log.LoggerKeyIDPID, idp.ID)) } } @@ -172,7 +172,7 @@ func (s *cacheBackedIDPStore) invalidateIDP(ctx context.Context, idp *providers. idKey := cache.CacheKey{Key: idp.ID} if err := s.idpByIDCache.Delete(ctx, idKey); err != nil { logger.Error(ctx, "Failed to invalidate IDP cache by ID", - log.Error(err), log.String("idpID", idp.ID)) + log.Error(err), log.String(log.LoggerKeyIDPID, idp.ID)) } } for _, prop := range idp.Properties { diff --git a/backend/internal/idp/service.go b/backend/internal/idp/service.go index 2695b63609..1d7fb5f557 100644 --- a/backend/internal/idp/service.go +++ b/backend/internal/idp/service.go @@ -188,7 +188,7 @@ func (is *idpService) GetIdentityProvider( if errors.Is(err, ErrIDPNotFound) { return nil, &ErrorIDPNotFound } - logger.Error(ctx, "Failed to get identity provider", log.String("idpID", idpID), log.Error(err)) + logger.Error(ctx, "Failed to get identity provider", log.String(log.LoggerKeyIDPID, idpID), log.Error(err)) return nil, &tidcommon.InternalServerError } @@ -306,7 +306,7 @@ func (is *idpService) UpdateIdentityProvider( return nil, svcErr } if err != nil { - logger.Error(ctx, "Failed to update identity provider", log.Error(err), log.String("idpID", idpID)) + logger.Error(ctx, "Failed to update identity provider", log.Error(err), log.String(log.LoggerKeyIDPID, idpID)) return nil, &tidcommon.InternalServerError } @@ -358,7 +358,7 @@ func (is *idpService) DeleteIdentityProvider(ctx context.Context, idpID string) return svcErr } if err != nil { - logger.Error(ctx, "Failed to delete identity provider", log.Error(err), log.String("idpID", idpID)) + logger.Error(ctx, "Failed to delete identity provider", log.Error(err), log.String(log.LoggerKeyIDPID, idpID)) return &tidcommon.InternalServerError } @@ -553,13 +553,14 @@ func (is *idpService) GetIDPUsages( if errors.Is(err, ErrIDPNotFound) { return nil, &ErrorIDPNotFound } - is.logger.Error(ctx, "Failed to retrieve identity provider", log.Error(err), log.String("idpID", idpID)) + is.logger.Error(ctx, "Failed to retrieve identity provider", log.Error(err), + log.String(log.LoggerKeyIDPID, idpID)) return nil, &tidcommon.InternalServerError } if is.dependencyRegistry == nil { is.logger.Warn(ctx, "Dependency registry not set; returning unknown dependencies", - log.String("idpID", idpID)) + log.String(log.LoggerKeyIDPID, idpID)) return &resourcedependency.DependenciesResponse{ TotalResults: nil, Count: 0, @@ -570,7 +571,8 @@ func (is *idpService) GetIDPUsages( result, err := is.dependencyRegistry.GetDependencies(ctx, resourcedependency.ResourceTypeIDP, idpID) if err != nil { - is.logger.Error(ctx, "Failed to get identity provider usages", log.Error(err), log.String("idpID", idpID)) + is.logger.Error(ctx, "Failed to get identity provider usages", log.Error(err), + log.String(log.LoggerKeyIDPID, idpID)) return nil, &tidcommon.InternalServerError } @@ -584,20 +586,20 @@ func (is *idpService) GetIDPUsages( func (is *idpService) ensureNoBlockingDependencies(ctx context.Context, idpID string) *tidcommon.ServiceError { if is.dependencyRegistry == nil { is.logger.Error(ctx, "Dependency registry not set; refusing to delete identity provider", - log.String("idpID", idpID)) + log.String(log.LoggerKeyIDPID, idpID)) return &tidcommon.InternalServerError } deps, err := is.dependencyRegistry.GetDependencies(ctx, resourcedependency.ResourceTypeIDP, idpID) if err != nil { is.logger.Error(ctx, "Failed to evaluate identity provider dependencies", - log.Error(err), log.String("idpID", idpID)) + log.Error(err), log.String(log.LoggerKeyIDPID, idpID)) return &tidcommon.InternalServerError } // Fail closed: nil TotalResults means a provider failed to report, so usage is unknown. if deps == nil || deps.TotalResults == nil { is.logger.Error(ctx, "Identity provider dependency data unavailable; refusing to delete", - log.String("idpID", idpID)) + log.String(log.LoggerKeyIDPID, idpID)) return &tidcommon.InternalServerError } @@ -607,7 +609,7 @@ func (is *idpService) ensureNoBlockingDependencies(ctx context.Context, idpID st } is.logger.Debug(ctx, "Identity provider has blocking dependencies; deletion refused", - log.String("idpID", idpID), log.Int("blockingCount", len(blocking))) + log.String(log.LoggerKeyIDPID, idpID), log.Int("blockingCount", len(blocking))) return tidcommon.CustomServiceError(ErrorIDPHasBlockingDependencies, tidcommon.I18nMessage{ Key: "error.idpservice.idp_has_blocking_dependencies_description", DefaultValue: fmt.Sprintf( diff --git a/backend/internal/idp/store.go b/backend/internal/idp/store.go index c4a657a2f5..9ce9ce4485 100644 --- a/backend/internal/idp/store.go +++ b/backend/internal/idp/store.go @@ -374,7 +374,7 @@ func idJagEnabledFromRow(ctx context.Context, logger *log.Logger, idpID string, properties, err := cmodels.DeserializePropertiesFromJSONObject(propertiesJSON) if err != nil { logger.Warn(ctx, "Failed to deserialize IDP properties; omitting idJagEnabled flag", - log.String("idpID", idpID), log.Error(err)) + log.String(log.LoggerKeyIDPID, idpID), log.Error(err)) return nil } return idJagEnabledFromProperties(properties) diff --git a/backend/internal/inboundclient/cache_backed_store.go b/backend/internal/inboundclient/cache_backed_store.go index 37569df9e7..fdb39ff0e8 100644 --- a/backend/internal/inboundclient/cache_backed_store.go +++ b/backend/internal/inboundclient/cache_backed_store.go @@ -146,7 +146,7 @@ func (c *cachedBackStore) cacheInboundClient(ctx context.Context, client *inboun logger := log.GetLogger().With(log.String(log.LoggerKeyComponentName, "InboundClientCachedBackStore")) if err := c.inboundClientCache.Set(ctx, cache.CacheKey{Key: client.ID}, client); err != nil { logger.Error(ctx, "Failed to cache inbound client", - log.String("entityID", client.ID), log.Error(err)) + log.MaskedString("entityID", client.ID), log.Error(err)) } } @@ -156,7 +156,7 @@ func (c *cachedBackStore) cacheOAuthProfile(ctx context.Context, entityID string } logger := log.GetLogger().With(log.String(log.LoggerKeyComponentName, "InboundClientCachedBackStore")) if err := c.oauthProfileCache.Set(ctx, cache.CacheKey{Key: entityID}, profile); err != nil { - logger.Error(ctx, "Failed to cache OAuth profile", log.String("entityID", entityID), log.Error(err)) + logger.Error(ctx, "Failed to cache OAuth profile", log.MaskedString("entityID", entityID), log.Error(err)) } } @@ -167,7 +167,7 @@ func (c *cachedBackStore) invalidateInboundClient(ctx context.Context, entityID logger := log.GetLogger().With(log.String(log.LoggerKeyComponentName, "InboundClientCachedBackStore")) if err := c.inboundClientCache.Delete(ctx, cache.CacheKey{Key: entityID}); err != nil { logger.Error(ctx, "Failed to invalidate inbound client cache", - log.String("entityID", entityID), log.Error(err)) + log.MaskedString("entityID", entityID), log.Error(err)) } } @@ -178,6 +178,6 @@ func (c *cachedBackStore) invalidateOAuthProfile(ctx context.Context, entityID s logger := log.GetLogger().With(log.String(log.LoggerKeyComponentName, "InboundClientCachedBackStore")) if err := c.oauthProfileCache.Delete(ctx, cache.CacheKey{Key: entityID}); err != nil { logger.Error(ctx, "Failed to invalidate OAuth profile cache", - log.String("entityID", entityID), log.Error(err)) + log.MaskedString("entityID", entityID), log.Error(err)) } } diff --git a/backend/internal/inboundclient/service.go b/backend/internal/inboundclient/service.go index 6305cf3be8..f188f53779 100644 --- a/backend/internal/inboundclient/service.go +++ b/backend/internal/inboundclient/service.go @@ -425,10 +425,10 @@ func (s *inboundClientService) resolveClientID(ctx context.Context, entityID str if s.entityProvider == nil { return "" } - e, epErr := s.entityProvider.GetEntityProfile(entityID) + e, epErr := s.entityProvider.GetEntityProfile(ctx, entityID) if epErr != nil { s.logger.Warn(ctx, "Failed to resolve OAuth client_id from entity provider", - log.String("entityID", entityID), log.Error(epErr)) + log.MaskedString("entityID", entityID), log.Error(epErr)) return "" } return clientIDFromEntity(e) @@ -600,7 +600,7 @@ func (s *inboundClientService) GetOAuthClientByEntityID(ctx context.Context, ent // is missing. func (s *inboundClientService) oauthClientForEntity(ctx context.Context, entityID, clientID string) ( *providers.OAuthClient, error) { - e, epErr := s.entityProvider.GetEntityProfile(entityID) + e, epErr := s.entityProvider.GetEntityProfile(ctx, entityID) if epErr != nil { if epErr.Code == entityprovider.ErrorCodeEntityNotFound { return nil, nil @@ -664,7 +664,7 @@ func (s *inboundClientService) IsClientAccessibleFromOU( accessible, svcErr := s.sharingService.IsVisible(ctx, rt, client.ID, accessingOUID) if svcErr != nil { s.logger.Error(ctx, "Failed to resolve client access for an organization unit", - log.String("clientID", client.ID), log.Any("error", svcErr)) + log.MaskedString(log.LoggerKeyEntityID, client.ID), log.Any("error", svcErr)) return false, svcErr } return accessible, nil @@ -730,7 +730,7 @@ func (s *inboundClientService) resolveFlowDefaults(ctx context.Context, c *inbou ouID := "" if s.entityProvider != nil && c.ID != "" { - if e, epErr := s.entityProvider.GetEntityProfile(c.ID); epErr == nil && e != nil { + if e, epErr := s.entityProvider.GetEntityProfile(ctx, c.ID); epErr == nil && e != nil { ouID = e.OUID } } diff --git a/backend/internal/inboundclient/service_test.go b/backend/internal/inboundclient/service_test.go index 187fbdf207..fdcc607acd 100644 --- a/backend/internal/inboundclient/service_test.go +++ b/backend/internal/inboundclient/service_test.go @@ -1008,7 +1008,7 @@ const testCIMDClientID = "https://client.example.com/oauth/client.json" func (suite *InboundClientServiceTestSuite) cimdEntityProvider( clientID string) *entityprovidermock.EntityProviderInterfaceMock { ep := entityprovidermock.NewEntityProviderInterfaceMock(suite.T()) - ep.EXPECT().GetEntityProfile("p1").Return(&providers.Entity{ + ep.EXPECT().GetEntityProfile(mock.Anything, "p1").Return(&providers.Entity{ ID: "p1", SystemAttributes: json.RawMessage(`{"clientId":"` + clientID + `"}`), }, nil) return ep @@ -3079,7 +3079,7 @@ func (suite *InboundClientServiceTestSuite) TestGetOAuthClientByClientID_GetEnti id := testServiceEntityID ep := entityprovidermock.NewEntityProviderInterfaceMock(suite.T()) ep.EXPECT().IdentifyEntity(mock.Anything).Return(&id, nil) - ep.EXPECT().GetEntityProfile(id).Return(nil, &entityprovider.EntityProviderError{ + ep.EXPECT().GetEntityProfile(mock.Anything, id).Return(nil, &entityprovider.EntityProviderError{ Code: entityprovider.ErrorCodeEntityNotFound, }) svc := &inboundClientService{entityProvider: ep, store: newInboundClientStoreInterfaceMock(suite.T())} @@ -3092,7 +3092,7 @@ func (suite *InboundClientServiceTestSuite) TestGetOAuthClientByClientID_OAuthPr id := testServiceEntityID ep := entityprovidermock.NewEntityProviderInterfaceMock(suite.T()) ep.EXPECT().IdentifyEntity(mock.Anything).Return(&id, nil) - ep.EXPECT().GetEntityProfile(id).Return(&providers.Entity{ID: id, OUID: "ou-1"}, nil) + ep.EXPECT().GetEntityProfile(mock.Anything, id).Return(&providers.Entity{ID: id, OUID: "ou-1"}, nil) store := newInboundClientStoreInterfaceMock(suite.T()) store.EXPECT().GetOAuthProfileByEntityID(mock.Anything, id).Return(nil, ErrInboundClientNotFound) @@ -3109,7 +3109,7 @@ func (suite *InboundClientServiceTestSuite) TestGetOAuthClientByClientID_CIMDCli id := testServiceEntityID ep := entityprovidermock.NewEntityProviderInterfaceMock(suite.T()) ep.EXPECT().IdentifyEntity(mock.Anything).Return(&id, nil) - ep.EXPECT().GetEntityProfile(id).Return(&providers.Entity{ID: id, OUID: "ou-1"}, nil) + ep.EXPECT().GetEntityProfile(mock.Anything, id).Return(&providers.Entity{ID: id, OUID: "ou-1"}, nil) store := newInboundClientStoreInterfaceMock(suite.T()) store.EXPECT().GetOAuthProfileByEntityID(mock.Anything, id).Return(&providers.OAuthProfile{ ClientIDMetadataDocument: true, @@ -3132,7 +3132,7 @@ func (suite *InboundClientServiceTestSuite) TestGetOAuthClientByClientID_StoreEr id := testServiceEntityID ep := entityprovidermock.NewEntityProviderInterfaceMock(suite.T()) ep.EXPECT().IdentifyEntity(mock.Anything).Return(&id, nil) - ep.EXPECT().GetEntityProfile(id).Return(&providers.Entity{ID: id, OUID: "ou-1"}, nil) + ep.EXPECT().GetEntityProfile(mock.Anything, id).Return(&providers.Entity{ID: id, OUID: "ou-1"}, nil) storeErr := errors.New("db down") store := newInboundClientStoreInterfaceMock(suite.T()) @@ -3165,7 +3165,7 @@ func (suite *InboundClientServiceTestSuite) TestGetOAuthClientByEntityID_EmptyEn func (suite *InboundClientServiceTestSuite) TestGetOAuthClientByEntityID_EntityNotFound() { ep := entityprovidermock.NewEntityProviderInterfaceMock(suite.T()) - ep.EXPECT().GetEntityProfile(testServiceEntityID).Return(nil, &entityprovider.EntityProviderError{ + ep.EXPECT().GetEntityProfile(mock.Anything, testServiceEntityID).Return(nil, &entityprovider.EntityProviderError{ Code: entityprovider.ErrorCodeEntityNotFound, }) svc := &inboundClientService{entityProvider: ep, store: newInboundClientStoreInterfaceMock(suite.T())} @@ -3176,7 +3176,7 @@ func (suite *InboundClientServiceTestSuite) TestGetOAuthClientByEntityID_EntityN func (suite *InboundClientServiceTestSuite) TestGetOAuthClientByEntityID_NoClientIDReturnsNil() { ep := entityprovidermock.NewEntityProviderInterfaceMock(suite.T()) - ep.EXPECT().GetEntityProfile(testServiceEntityID).Return(&providers.Entity{ID: testServiceEntityID}, nil) + ep.EXPECT().GetEntityProfile(mock.Anything, testServiceEntityID).Return(&providers.Entity{ID: testServiceEntityID}, nil) svc := &inboundClientService{entityProvider: ep, store: newInboundClientStoreInterfaceMock(suite.T())} got, err := svc.GetOAuthClientByEntityID(context.Background(), testServiceEntityID) assert.NoError(suite.T(), err) @@ -3185,7 +3185,7 @@ func (suite *InboundClientServiceTestSuite) TestGetOAuthClientByEntityID_NoClien func (suite *InboundClientServiceTestSuite) TestGetOAuthClientByEntityID_BuildsClient() { ep := entityprovidermock.NewEntityProviderInterfaceMock(suite.T()) - ep.EXPECT().GetEntityProfile(testServiceEntityID).Return(&providers.Entity{ + ep.EXPECT().GetEntityProfile(mock.Anything, testServiceEntityID).Return(&providers.Entity{ ID: testServiceEntityID, OUID: "ou-1", SystemAttributes: json.RawMessage(`{"clientId":"client-1"}`), diff --git a/backend/internal/notificationtemplate/service.go b/backend/internal/notificationtemplate/service.go index 7c6f6f13b5..2efba74687 100644 --- a/backend/internal/notificationtemplate/service.go +++ b/backend/internal/notificationtemplate/service.go @@ -504,7 +504,7 @@ func (ts *notificationTemplateService) resolveOU(ctx context.Context, ouID strin } exists, svcErr := ts.ouService.IsOrganizationUnitExists(ctx, ouID) if svcErr != nil { - ts.logger.Error(ctx, "Failed to verify organization unit", log.String("ouId", ouID), + ts.logger.Error(ctx, "Failed to verify organization unit", log.String("ouID", ouID), log.Any("error", svcErr)) return &tidcommon.InternalServerError } diff --git a/backend/internal/oauth/oauth2/authz/service.go b/backend/internal/oauth/oauth2/authz/service.go index e91a3afa36..7e81abe07e 100644 --- a/backend/internal/oauth/oauth2/authz/service.go +++ b/backend/internal/oauth/oauth2/authz/service.go @@ -508,7 +508,7 @@ func (as *authorizeService) handleStandardAuthorizationRequest( if redirectURI == "" { if len(app.RedirectURIs) == 0 { as.logger.Error(ctx, "OAuth application has no registered redirect URIs", - log.String("client_id", app.ClientID)) + log.String("clientID", app.ClientID)) return nil, &AuthorizationError{ Code: oauth2const.ErrorServerError, Message: "Failed to process authorization request", diff --git a/backend/internal/oauth/oauth2/clientauth/clientouadmission.go b/backend/internal/oauth/oauth2/clientauth/clientouadmission.go index 8ea2dca74e..b6eecc4338 100644 --- a/backend/internal/oauth/oauth2/clientauth/clientouadmission.go +++ b/backend/internal/oauth/oauth2/clientauth/clientouadmission.go @@ -36,13 +36,13 @@ func ClientOUAdmissionMiddleware(actorProvider providers.ActorProvider) func(htt if svcErr != nil { log.GetLogger().Error(ctx, "Failed to resolve client access for an organization unit", log.MaskedString("clientID", clientInfo.ClientID), - log.String("ouId", accessingOUID), log.Any("error", svcErr)) + log.String("ouID", accessingOUID), log.Any("error", svcErr)) writeAuthError(ctx, w, errOUAccessUnresolved) return } if !accessible { log.GetLogger().Debug(ctx, "Client is not authorized for the requested organization unit", - log.MaskedString("clientID", clientInfo.ClientID), log.String("ouId", accessingOUID)) + log.MaskedString("clientID", clientInfo.ClientID), log.String("ouID", accessingOUID)) writeAuthError(ctx, w, errClientNotAuthorizedForOU) return } diff --git a/backend/internal/oauth/oauth2/granthandlers/client_credentials.go b/backend/internal/oauth/oauth2/granthandlers/client_credentials.go index 5ec391067b..ab6ce80c5d 100644 --- a/backend/internal/oauth/oauth2/granthandlers/client_credentials.go +++ b/backend/internal/oauth/oauth2/granthandlers/client_credentials.go @@ -91,7 +91,7 @@ func (h *clientCredentialsGrantHandler) HandleGrant(ctx context.Context, tokenRe if len(scopes) > 0 { var groupIDs []string if h.actorProvider != nil { - groups, groupErr := h.actorProvider.GetActorGroups(oauthApp.ID) + groups, groupErr := h.actorProvider.GetActorGroups(ctx, oauthApp.ID) if groupErr != nil { logger.Error(ctx, "Failed to resolve app group memberships", log.String("appID", oauthApp.ID), log.String("error", groupErr.Error.DefaultValue)) @@ -124,7 +124,7 @@ func (h *clientCredentialsGrantHandler) HandleGrant(ctx context.Context, tokenRe } } - clientAttributes, clientAttrErr := tokenservice.BuildClientAttributes(oauthApp, h.actorProvider) + clientAttributes, clientAttrErr := tokenservice.BuildClientAttributes(ctx, oauthApp, h.actorProvider) if clientAttrErr != nil { return nil, &model.ErrorResponse{ Error: constants.ErrorServerError, diff --git a/backend/internal/oauth/oauth2/granthandlers/client_credentials_test.go b/backend/internal/oauth/oauth2/granthandlers/client_credentials_test.go index 2aa5a07c25..403d428afd 100644 --- a/backend/internal/oauth/oauth2/granthandlers/client_credentials_test.go +++ b/backend/internal/oauth/oauth2/granthandlers/client_credentials_test.go @@ -95,7 +95,7 @@ func (suite *ClientCredentialsGrantHandlerTestSuite) SetupTest() { actorProvider: suite.mockEntityProvider, resourceService: suite.mockResourceService, } - suite.mockEntityProvider.On("GetActorGroups", mock.Anything). + suite.mockEntityProvider.On("GetActorGroups", mock.Anything, mock.Anything). Return([]providers.EntityGroup{}, nil).Maybe() suite.oauthApp = &providers.OAuthClient{ @@ -694,7 +694,7 @@ func (suite *ClientCredentialsGrantHandlerTestSuite) TestHandleGrant_AgentOwnAtt }, } - suite.mockEntityProvider.On("GetActor", agentApp.ID).Return(&providers.Entity{ + suite.mockEntityProvider.On("GetActor", mock.Anything, agentApp.ID).Return(&providers.Entity{ ID: agentApp.ID, Attributes: []byte(`{"modelProvider":"anthropic"}`), }, (*tidcommon.ServiceError)(nil)) @@ -739,7 +739,7 @@ func (suite *ClientCredentialsGrantHandlerTestSuite) TestHandleGrant_AgentSystem }, } - suite.mockEntityProvider.On("GetActor", agentApp.ID).Return(&providers.Entity{ + suite.mockEntityProvider.On("GetActor", mock.Anything, agentApp.ID).Return(&providers.Entity{ ID: agentApp.ID, Category: providers.EntityCategoryAgent, Attributes: []byte(`{"name":"Ledger Agent"}`), @@ -789,7 +789,7 @@ func (suite *ClientCredentialsGrantHandlerTestSuite) TestHandleGrant_Application } // Applications store name in SystemAttributes too; the category gate must keep it out of the token. - suite.mockEntityProvider.On("GetActor", appApp.ID).Return(&providers.Entity{ + suite.mockEntityProvider.On("GetActor", mock.Anything, appApp.ID).Return(&providers.Entity{ ID: appApp.ID, Category: providers.EntityCategoryApp, SystemAttributes: []byte(`{"name":"My Application","clientId":"cid"}`), diff --git a/backend/internal/oauth/oauth2/granthandlers/refresh_token.go b/backend/internal/oauth/oauth2/granthandlers/refresh_token.go index 0a75a5bc48..03020b9600 100644 --- a/backend/internal/oauth/oauth2/granthandlers/refresh_token.go +++ b/backend/internal/oauth/oauth2/granthandlers/refresh_token.go @@ -311,7 +311,7 @@ func (h *refreshTokenGrantHandler) HandleGrant(ctx context.Context, tokenRequest // Issue a new refresh token if renew_on_grant is enabled; otherwise reuse the existing one. // The new refresh token carries the same single resource server audience. if renewRefreshToken { - logger.Debug(ctx, "Renewing refresh token", log.String("client_id", tokenRequest.ClientID)) + logger.Debug(ctx, "Renewing refresh token", log.String("clientID", tokenRequest.ClientID)) errResp := h.IssueRefreshToken(ctx, tokenResponse, oauthApp, refreshTokenClaims.Sub, audiences, refreshTokenClaims.GrantType, newTokenScopes, @@ -498,7 +498,7 @@ func (h *refreshTokenGrantHandler) verifyCredentialsUnchanged(ctx context.Contex if oauthApp == nil || oauthApp.ID == "" || oauthApp.ID == claims.Sub { return subjectEntity, nil } - clientEntity, svcErr := h.actorProvider.GetActor(oauthApp.ID) + clientEntity, svcErr := h.actorProvider.GetActor(ctx, oauthApp.ID) if svcErr != nil { logger.Error(ctx, "Failed to resolve the refresh token client", log.String("error", svcErr.Error.DefaultValue)) @@ -551,7 +551,7 @@ func (h *refreshTokenGrantHandler) resolveSubjectEntity(ctx context.Context, sub return nil, nil } - entity, svcErr := h.actorProvider.GetActor(subject) + entity, svcErr := h.actorProvider.GetActor(ctx, subject) if svcErr == nil { return entity, nil } @@ -645,7 +645,7 @@ func (h *refreshTokenGrantHandler) reauthorizeScopes(ctx context.Context, subjec subject := subjectEntity.ID // Roles reach a subject directly and through their groups, so both are evaluated together. - groups, groupErr := h.actorProvider.GetActorGroups(subject) + groups, groupErr := h.actorProvider.GetActorGroups(ctx, subject) if groupErr != nil { logger.Error(ctx, "Failed to resolve group memberships for refresh token subject", log.MaskedString(log.LoggerKeyUserID, subject), diff --git a/backend/internal/oauth/oauth2/granthandlers/refresh_token_test.go b/backend/internal/oauth/oauth2/granthandlers/refresh_token_test.go index 54ab6c41cc..e4e8ca9720 100644 --- a/backend/internal/oauth/oauth2/granthandlers/refresh_token_test.go +++ b/backend/internal/oauth/oauth2/granthandlers/refresh_token_test.go @@ -167,11 +167,11 @@ func allowAllEvaluations(_ context.Context, // change, and still holds every permission scope on the refresh token, so tests that are not about // re-authorization or credential changes keep exercising the scopes they set up. func (suite *RefreshTokenGrantHandlerTestSuite) installPermissiveAuthzStubs() { - suite.mockActorProvider.On("GetActor", mock.Anything). - Return(func(actorID string) *providers.Entity { + suite.mockActorProvider.On("GetActor", mock.Anything, mock.Anything). + Return(func(_ context.Context, actorID string) *providers.Entity { return &providers.Entity{ID: actorID} }, nil).Maybe() - suite.mockActorProvider.On("GetActorGroups", mock.Anything). + suite.mockActorProvider.On("GetActorGroups", mock.Anything, mock.Anything). Return([]providers.EntityGroup{}, nil).Maybe() suite.mockAuthzService.On("EvaluateAccessBatch", mock.Anything, mock.Anything). Return(allowAllEvaluations, nil).Maybe() @@ -2182,8 +2182,8 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_DownscopeValidat func (suite *RefreshTokenGrantHandlerTestSuite) resetAuthzMocks() { suite.mockAuthzService = authzmock.NewAuthorizationProviderMock(suite.T()) suite.mockActorProvider = actorprovidermock.NewActorProviderMock(suite.T()) - suite.mockActorProvider.On("GetActor", mock.Anything). - Return(func(actorID string) *providers.Entity { + suite.mockActorProvider.On("GetActor", mock.Anything, mock.Anything). + Return(func(_ context.Context, actorID string) *providers.Entity { return &providers.Entity{ID: actorID} }, nil).Maybe() suite.rebuildHandlerWithConfig() @@ -2195,7 +2195,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_DropsScopesNoLon suite.resetAuthzMocks() suite.refreshClaimsValid() - suite.mockActorProvider.On("GetActorGroups", testRefreshTokenUserID). + suite.mockActorProvider.On("GetActorGroups", mock.Anything, testRefreshTokenUserID). Return([]providers.EntityGroup{}, nil) mockEvaluateAccessBatch(suite.mockAuthzService, testRefreshTokenUserID, testRefreshTokenAudience, []string{"read", "write"}, []string{"read"}) @@ -2229,7 +2229,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_RotatedRefreshTo suite.resetAuthzMocks() suite.refreshClaimsValid() - suite.mockActorProvider.On("GetActorGroups", testRefreshTokenUserID). + suite.mockActorProvider.On("GetActorGroups", mock.Anything, testRefreshTokenUserID). Return([]providers.EntityGroup{}, nil) mockEvaluateAccessBatch(suite.mockAuthzService, testRefreshTokenUserID, testRefreshTokenAudience, []string{"read", "write"}, []string{"read"}) @@ -2264,7 +2264,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_EvaluatesWithSub suite.resetAuthzMocks() suite.refreshClaimsValid() - suite.mockActorProvider.On("GetActorGroups", testRefreshTokenUserID). + suite.mockActorProvider.On("GetActorGroups", mock.Anything, testRefreshTokenUserID). Return([]providers.EntityGroup{{ID: "group-1"}, {ID: "group-2"}, {ID: ""}}, nil) var evaluatedGroupIDs []string @@ -2300,7 +2300,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_OIDCScopesSurviv Iat: int64(suite.validClaims["iat"].(float64)), }, nil) - suite.mockActorProvider.On("GetActorGroups", testRefreshTokenUserID). + suite.mockActorProvider.On("GetActorGroups", mock.Anything, testRefreshTokenUserID). Return([]providers.EntityGroup{}, nil) mockEvaluateAccessBatch(suite.mockAuthzService, testRefreshTokenUserID, testRefreshTokenAudience, []string{"read"}, []string{}) @@ -2369,7 +2369,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_AuthorizationFai suite.resetAuthzMocks() suite.refreshClaimsValid() - suite.mockActorProvider.On("GetActorGroups", testRefreshTokenUserID). + suite.mockActorProvider.On("GetActorGroups", mock.Anything, testRefreshTokenUserID). Return([]providers.EntityGroup{}, nil) suite.mockAuthzService.On("EvaluateAccessBatch", mock.Anything, mock.Anything). Return(nil, &tidcommon.ServiceError{ @@ -2390,7 +2390,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_GroupResolutionF suite.resetAuthzMocks() suite.refreshClaimsValid() - suite.mockActorProvider.On("GetActorGroups", testRefreshTokenUserID). + suite.mockActorProvider.On("GetActorGroups", mock.Anything, testRefreshTokenUserID). Return(nil, &tidcommon.ServiceError{ Type: tidcommon.ServerErrorType, Code: "ENTITY-5000", @@ -2409,7 +2409,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_GroupResolutionF func (suite *RefreshTokenGrantHandlerTestSuite) resetActorMocks() { suite.mockAuthzService = authzmock.NewAuthorizationProviderMock(suite.T()) suite.mockActorProvider = actorprovidermock.NewActorProviderMock(suite.T()) - suite.mockActorProvider.On("GetActorGroups", mock.Anything). + suite.mockActorProvider.On("GetActorGroups", mock.Anything, mock.Anything). Return([]providers.EntityGroup{}, nil).Maybe() suite.mockAuthzService.On("EvaluateAccessBatch", mock.Anything, mock.Anything). Return(allowAllEvaluations, nil).Maybe() @@ -2428,7 +2428,7 @@ func entityMarkedAt(id string, at time.Time) *providers.Entity { func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_RejectsTokenPredatingPasswordReset() { suite.resetActorMocks() suite.refreshClaimsValid() - suite.mockActorProvider.On("GetActor", testRefreshTokenUserID). + suite.mockActorProvider.On("GetActor", mock.Anything, testRefreshTokenUserID). Return(entityMarkedAt(testRefreshTokenUserID, time.Now()), nil) response, err := suite.handler.HandleGrant(context.Background(), suite.testTokenReq, suite.oauthApp) @@ -2442,7 +2442,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_RejectsTokenPred func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_AllowsTokenIssuedAfterPasswordReset() { suite.resetActorMocks() suite.refreshClaimsValid() - suite.mockActorProvider.On("GetActor", testRefreshTokenUserID). + suite.mockActorProvider.On("GetActor", mock.Anything, testRefreshTokenUserID). Return(entityMarkedAt(testRefreshTokenUserID, time.Now().Add(-2*time.Hour)), nil) suite.mockTokenBuilder.On("BuildAccessToken", mock.Anything, mock.Anything).Return(&model.TokenDTO{ Token: "new.access.token", IssuedAt: time.Now().Unix(), ExpiresIn: 3600, @@ -2460,9 +2460,9 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_RejectsTokenPred suite.refreshClaimsValid() appWithID := *suite.oauthApp appWithID.ID = testAppEntityID - suite.mockActorProvider.On("GetActor", testRefreshTokenUserID). + suite.mockActorProvider.On("GetActor", mock.Anything, testRefreshTokenUserID). Return(&providers.Entity{ID: testRefreshTokenUserID}, nil) - suite.mockActorProvider.On("GetActor", appWithID.ID). + suite.mockActorProvider.On("GetActor", mock.Anything, appWithID.ID). Return(entityMarkedAt(appWithID.ID, time.Now()), nil) response, err := suite.handler.HandleGrant(context.Background(), suite.testTokenReq, &appWithID) @@ -2478,7 +2478,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_RejectsTokenPred func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_SkipsChecksForMappedSubject() { suite.resetActorMocks() suite.refreshClaimsValid() - suite.mockActorProvider.On("GetActor", testRefreshTokenUserID). + suite.mockActorProvider.On("GetActor", mock.Anything, testRefreshTokenUserID). Return(nil, &tidcommon.ServiceError{ Type: tidcommon.ClientErrorType, Code: "ACP-1002", @@ -2488,7 +2488,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_SkipsChecksForMa Return(&providers.InboundClient{ SubjectAttribute: map[string]string{"employee": "external_id"}, }, nil) - suite.mockActorProvider.On("GetActor", testAppEntityID). + suite.mockActorProvider.On("GetActor", mock.Anything, testAppEntityID). Return(&providers.Entity{ID: testAppEntityID}, nil) suite.mockTokenBuilder.On("BuildAccessToken", mock.Anything, mock.Anything).Return(&model.TokenDTO{ Token: "new.access.token", IssuedAt: time.Now().Unix(), ExpiresIn: 3600, @@ -2508,7 +2508,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_SkipsChecksForMa func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_RejectsWhenSubjectNoLongerExists() { suite.resetActorMocks() suite.refreshClaimsValid() - suite.mockActorProvider.On("GetActor", testRefreshTokenUserID). + suite.mockActorProvider.On("GetActor", mock.Anything, testRefreshTokenUserID). Return(nil, &tidcommon.ServiceError{ Type: tidcommon.ClientErrorType, Code: "ACP-1002", @@ -2516,7 +2516,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_RejectsWhenSubje }) suite.mockActorProvider.On("GetInboundClientByID", mock.Anything, mock.Anything). Return(&providers.InboundClient{}, nil) - suite.mockActorProvider.On("GetActor", testAppEntityID). + suite.mockActorProvider.On("GetActor", mock.Anything, testAppEntityID). Return(&providers.Entity{ID: testAppEntityID}, nil).Maybe() appWithID := *suite.oauthApp @@ -2532,7 +2532,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_RejectsWhenSubje func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_CredentialLookupFailureFailsClosed() { suite.resetActorMocks() suite.refreshClaimsValid() - suite.mockActorProvider.On("GetActor", testRefreshTokenUserID). + suite.mockActorProvider.On("GetActor", mock.Anything, testRefreshTokenUserID). Return(nil, &tidcommon.ServiceError{ Type: tidcommon.ServerErrorType, Code: "ACP-5000", @@ -2557,7 +2557,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_UnreadableCreden } { suite.resetActorMocks() suite.refreshClaimsValid() - suite.mockActorProvider.On("GetActor", testRefreshTokenUserID). + suite.mockActorProvider.On("GetActor", mock.Anything, testRefreshTokenUserID). Return(&providers.Entity{ ID: testRefreshTokenUserID, SystemAttributes: json.RawMessage(systemAttributes), @@ -2578,7 +2578,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_UnreadableCreden func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_SkipsReauthorizationForSubjectWithoutID() { suite.resetActorMocks() suite.refreshClaimsValid() - suite.mockActorProvider.On("GetActor", testRefreshTokenUserID). + suite.mockActorProvider.On("GetActor", mock.Anything, testRefreshTokenUserID). Return(&providers.Entity{}, nil) var grantedScopes []string @@ -2642,7 +2642,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_EmptySubjectSkip assert.Nil(suite.T(), err) assert.NotNil(suite.T(), response) - suite.mockActorProvider.AssertNotCalled(suite.T(), "GetActor", mock.Anything) + suite.mockActorProvider.AssertNotCalled(suite.T(), "GetActor", mock.Anything, mock.Anything) } // The client authenticated moments ago, so a failed client lookup is an outage rather than a deleted @@ -2652,9 +2652,9 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_ClientLookupFail suite.refreshClaimsValid() appWithID := *suite.oauthApp appWithID.ID = testAppEntityID - suite.mockActorProvider.On("GetActor", testRefreshTokenUserID). + suite.mockActorProvider.On("GetActor", mock.Anything, testRefreshTokenUserID). Return(&providers.Entity{ID: testRefreshTokenUserID}, nil) - suite.mockActorProvider.On("GetActor", testAppEntityID). + suite.mockActorProvider.On("GetActor", mock.Anything, testAppEntityID). Return(nil, &tidcommon.ServiceError{ Type: tidcommon.ServerErrorType, Code: "ACP-5000", @@ -2675,7 +2675,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_SubjectMappingLo suite.refreshClaimsValid() appWithID := *suite.oauthApp appWithID.ID = testAppEntityID - suite.mockActorProvider.On("GetActor", testRefreshTokenUserID). + suite.mockActorProvider.On("GetActor", mock.Anything, testRefreshTokenUserID). Return(nil, &tidcommon.ServiceError{ Type: tidcommon.ClientErrorType, Code: "ACP-1002", @@ -2700,7 +2700,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_SubjectMappingLo func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_UnidentifiableClientSkipsSubjectChecks() { suite.resetActorMocks() suite.refreshClaimsValid() - suite.mockActorProvider.On("GetActor", testRefreshTokenUserID). + suite.mockActorProvider.On("GetActor", mock.Anything, testRefreshTokenUserID). Return(nil, &tidcommon.ServiceError{ Type: tidcommon.ClientErrorType, Code: "ACP-1002", @@ -2722,7 +2722,7 @@ func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_UnidentifiableCl func (suite *RefreshTokenGrantHandlerTestSuite) TestHandleGrant_SystemAttributesWithoutMarkerAllowRefresh() { suite.resetActorMocks() suite.refreshClaimsValid() - suite.mockActorProvider.On("GetActor", testRefreshTokenUserID). + suite.mockActorProvider.On("GetActor", mock.Anything, testRefreshTokenUserID). Return(&providers.Entity{ ID: testRefreshTokenUserID, SystemAttributes: json.RawMessage(`{"name":"Some App","clientId":"abc"}`), diff --git a/backend/internal/oauth/oauth2/logout/service.go b/backend/internal/oauth/oauth2/logout/service.go index f9ed7c8741..73a0ced299 100644 --- a/backend/internal/oauth/oauth2/logout/service.go +++ b/backend/internal/oauth/oauth2/logout/service.go @@ -198,9 +198,9 @@ func (s *logoutService) Resolve(ctx context.Context, req LogoutRequest) (*Logout if svcErr != nil { // An unresolvable client is the caller's fault (unknown client id); log at debug, not error. if svcErr.Type == tidcommon.ClientErrorType { - s.logger.Debug(ctx, "Client not found for logout", log.String("clientId", clientID)) + s.logger.Debug(ctx, "Client not found for logout", log.String("clientID", clientID)) } else { - s.logger.Error(ctx, "Failed to resolve client for logout", log.String("clientId", clientID)) + s.logger.Error(ctx, "Failed to resolve client for logout", log.String("clientID", clientID)) } return nil, errInvalidClient } diff --git a/backend/internal/oauth/oauth2/token/handler.go b/backend/internal/oauth/oauth2/token/handler.go index d82ff0e8c7..79ab8af6b6 100644 --- a/backend/internal/oauth/oauth2/token/handler.go +++ b/backend/internal/oauth/oauth2/token/handler.go @@ -139,7 +139,7 @@ func (th *tokenHandler) HandleTokenRequest(w http.ResponseWriter, r *http.Reques return } - logger.Debug(ctx, "Token response sending", log.String("client_id", clientInfo.ClientID)) + logger.Debug(ctx, "Token response sending", log.String("clientID", clientInfo.ClientID)) // Must include the following headers when sensitive data is returned. w.Header().Set(sysconst.CacheControlHeaderName, sysconst.CacheControlNoStore) diff --git a/backend/internal/oauth/oauth2/token/service.go b/backend/internal/oauth/oauth2/token/service.go index ca8dd31eee..ecb12bf80f 100644 --- a/backend/internal/oauth/oauth2/token/service.go +++ b/backend/internal/oauth/oauth2/token/service.go @@ -183,7 +183,7 @@ func (ts *tokenService) ProcessTokenRequest( if grantType.IssuesRefreshToken() && oauthApp.IsAllowedGrantType(providers.GrantTypeRefreshToken) { logger.Debug(ctx, "Issuing refresh token for the token request", - log.String("client_id", clientID), log.String("grant_type", grantTypeStr)) + log.String("clientID", clientID), log.String("grant_type", grantTypeStr)) refreshGrantHandler, handlerErr := ts.grantHandlerProvider.GetGrantHandler(providers.GrantTypeRefreshToken) if handlerErr != nil { @@ -198,7 +198,7 @@ func (ts *tokenService) ProcessTokenRequest( refreshGrantHandlerTyped, ok := refreshGrantHandler.(granthandlers.RefreshTokenGrantHandlerInterface) if !ok { logger.Error(ctx, "Failed to cast refresh grant handler", - log.String("client_id", clientID), log.String("grant_type", grantTypeStr)) + log.String("clientID", clientID), log.String("grant_type", grantTypeStr)) publishTokenIssuanceFailedEvent(ts.observabilitySvc, ctx, oauthApp, clientID, grantTypeStr, scopeStr, 500, "Internal Server Error", startTime) return nil, &model.ErrorResponse{ @@ -255,7 +255,7 @@ func (ts *tokenService) ProcessTokenRequest( } logger.Debug(ctx, "Token generated successfully", - log.String("client_id", clientID), log.String("grant_type", grantTypeStr)) + log.String("clientID", clientID), log.String("grant_type", grantTypeStr)) ts.publishTokenIssuedEvent(ctx, oauthApp, tokenRespDTO, clientID, grantTypeStr, scopes, startTime) diff --git a/backend/internal/oauth/oauth2/tokenservice/builder.go b/backend/internal/oauth/oauth2/tokenservice/builder.go index 11039072c0..10dfcd052a 100644 --- a/backend/internal/oauth/oauth2/tokenservice/builder.go +++ b/backend/internal/oauth/oauth2/tokenservice/builder.go @@ -93,9 +93,9 @@ func (tb *tokenBuilder) BuildAccessToken( } if tokenCtx.ActorClaims != nil { tokenDTO.Delegated = true - tokenDTO.ActorSub = tb.resolveActorIdentity(tokenCtx, tokenCtx.ActorClaims.Sub) + tokenDTO.ActorSub = tb.resolveActorIdentity(ctx, tokenCtx, tokenCtx.ActorClaims.Sub) } - tokenDTO.SubjectID, tokenDTO.SubjectCategory = tb.resolveSubjectIdentity(tokenCtx) + tokenDTO.SubjectID, tokenDTO.SubjectCategory = tb.resolveSubjectIdentity(ctx, tokenCtx) token, iat, err := tb.jwtService.GenerateJWT( ctx, @@ -125,13 +125,15 @@ func (tb *tokenBuilder) BuildAccessToken( // // Every grant reaches this function, so none can omit the fields by forgetting to set them, but a // grant whose upstream layer already knows the answer supplies it and skips the lookup entirely. -func (tb *tokenBuilder) resolveSubjectIdentity(tokenCtx *AccessTokenBuildContext) (id, category string) { +func (tb *tokenBuilder) resolveSubjectIdentity( + ctx context.Context, tokenCtx *AccessTokenBuildContext, +) (id, category string) { // authorization_code: carried on the flow assertion, which resolved the entity during login. if tokenCtx.SubjectEntityID != "" { if tokenCtx.SubjectCategory != "" { return tokenCtx.SubjectEntityID, tokenCtx.SubjectCategory } - return tokenCtx.SubjectEntityID, tb.lookupCategory(tokenCtx.SubjectEntityID) + return tokenCtx.SubjectEntityID, tb.lookupCategory(ctx, tokenCtx.SubjectEntityID) } if tokenCtx.Subject == "" { @@ -148,7 +150,7 @@ func (tb *tokenBuilder) resolveSubjectIdentity(tokenCtx *AccessTokenBuildContext // Resolving it decides which: a mapped attribute matches no entity, so an unresolvable subject is // reported as no subject rather than published as-is. This is what keeps a mapped attribute, which // may be an email address, off the events. - category = tb.lookupCategory(tokenCtx.Subject) + category = tb.lookupCategory(ctx, tokenCtx.Subject) if category == "" { return "", "" } @@ -162,7 +164,9 @@ func (tb *tokenBuilder) resolveSubjectIdentity(tokenCtx *AccessTokenBuildContext // issuing application may have mapped to an attribute such as an email address, and reporting no // actor is preferable to publishing one that identifies a person. Delegation itself stays visible // regardless, because the token DTO records it separately from the actor's identifier. -func (tb *tokenBuilder) resolveActorIdentity(tokenCtx *AccessTokenBuildContext, actorSub string) string { +func (tb *tokenBuilder) resolveActorIdentity( + ctx context.Context, tokenCtx *AccessTokenBuildContext, actorSub string, +) string { if actorSub == "" { return "" } @@ -173,7 +177,7 @@ func (tb *tokenBuilder) resolveActorIdentity(tokenCtx *AccessTokenBuildContext, return actorSub } - if tb.lookupCategory(actorSub) == "" { + if tb.lookupCategory(ctx, actorSub) == "" { return "" } return actorSub @@ -182,11 +186,11 @@ func (tb *tokenBuilder) resolveActorIdentity(tokenCtx *AccessTokenBuildContext, // lookupCategory returns the entity category of the given resource ID, or an empty string when the // provider is absent or the ID resolves to no entity. Reads are served by the cache-backed entity // store, so this is normally an in-memory hit. -func (tb *tokenBuilder) lookupCategory(entityID string) string { +func (tb *tokenBuilder) lookupCategory(ctx context.Context, entityID string) string { if tb.actorProvider == nil { return "" } - entity, svcErr := tb.actorProvider.GetActor(entityID) + entity, svcErr := tb.actorProvider.GetActor(ctx, entityID) if svcErr != nil || entity == nil { return "" } diff --git a/backend/internal/oauth/oauth2/tokenservice/builder_test.go b/backend/internal/oauth/oauth2/tokenservice/builder_test.go index 94c40fbd51..818c74a0fa 100644 --- a/backend/internal/oauth/oauth2/tokenservice/builder_test.go +++ b/backend/internal/oauth/oauth2/tokenservice/builder_test.go @@ -2600,7 +2600,7 @@ const ( func TestResolveSubjectIdentity_CarriedFromTheAssertion(t *testing.T) { tb := &tokenBuilder{} - id, category := tb.resolveSubjectIdentity(&AccessTokenBuildContext{ + id, category := tb.resolveSubjectIdentity(context.Background(), &AccessTokenBuildContext{ Subject: "alice@example.com", SubjectEntityID: subjectIdentityUserID, SubjectCategory: string(providers.EntityCategoryUser), @@ -2615,12 +2615,12 @@ func TestResolveSubjectIdentity_CarriedFromTheAssertion(t *testing.T) { // resolved. func TestResolveSubjectIdentity_AssertionIDWithoutCategory(t *testing.T) { actors := actorprovidermock.NewActorProviderMock(t) - actors.On("GetActor", subjectIdentityUserID). + actors.On("GetActor", mock.Anything, subjectIdentityUserID). Return(&providers.Entity{ID: subjectIdentityUserID, Category: providers.EntityCategoryUser}, (*tidcommon.ServiceError)(nil)) tb := &tokenBuilder{actorProvider: actors} - id, category := tb.resolveSubjectIdentity(&AccessTokenBuildContext{ + id, category := tb.resolveSubjectIdentity(context.Background(), &AccessTokenBuildContext{ SubjectEntityID: subjectIdentityUserID, }) @@ -2633,7 +2633,7 @@ func TestResolveSubjectIdentity_AssertionIDWithoutCategory(t *testing.T) { func TestResolveSubjectIdentity_SubjectIsTheClient(t *testing.T) { tb := &tokenBuilder{} - id, category := tb.resolveSubjectIdentity(&AccessTokenBuildContext{ + id, category := tb.resolveSubjectIdentity(context.Background(), &AccessTokenBuildContext{ Subject: subjectIdentityClientID, OAuthApp: &providers.OAuthClient{ ID: subjectIdentityClientID, @@ -2649,12 +2649,12 @@ func TestResolveSubjectIdentity_SubjectIsTheClient(t *testing.T) { // minted for agent B must report an agent subject, not a user. func TestResolveSubjectIdentity_AgentSubjectOfAnExchange(t *testing.T) { actors := actorprovidermock.NewActorProviderMock(t) - actors.On("GetActor", "agent-b"). + actors.On("GetActor", mock.Anything, "agent-b"). Return(&providers.Entity{ID: "agent-b", Category: providers.EntityCategoryAgent}, (*tidcommon.ServiceError)(nil)) tb := &tokenBuilder{actorProvider: actors} - id, category := tb.resolveSubjectIdentity(&AccessTokenBuildContext{ + id, category := tb.resolveSubjectIdentity(context.Background(), &AccessTokenBuildContext{ Subject: "agent-b", OAuthApp: &providers.OAuthClient{ID: subjectIdentityClientID, EntityCategory: providers.EntityCategoryAgent}, }) @@ -2668,11 +2668,11 @@ func TestResolveSubjectIdentity_AgentSubjectOfAnExchange(t *testing.T) { // so the attribute — an email address here — is never published. func TestResolveSubjectIdentity_MappedAttributeIsNotReported(t *testing.T) { actors := actorprovidermock.NewActorProviderMock(t) - actors.On("GetActor", "alice@example.com"). + actors.On("GetActor", mock.Anything, "alice@example.com"). Return((*providers.Entity)(nil), &tidcommon.ServiceError{Code: "ENTITY-404"}) tb := &tokenBuilder{actorProvider: actors} - id, category := tb.resolveSubjectIdentity(&AccessTokenBuildContext{ + id, category := tb.resolveSubjectIdentity(context.Background(), &AccessTokenBuildContext{ Subject: "alice@example.com", OAuthApp: &providers.OAuthClient{ID: subjectIdentityClientID}, }) @@ -2685,7 +2685,7 @@ func TestResolveSubjectIdentity_NoProviderOrNoSubject(t *testing.T) { tb := &tokenBuilder{} // A subject that is not the client cannot be resolved without a provider, so it is not reported. - id, category := tb.resolveSubjectIdentity(&AccessTokenBuildContext{ + id, category := tb.resolveSubjectIdentity(context.Background(), &AccessTokenBuildContext{ Subject: subjectIdentityUserID, OAuthApp: &providers.OAuthClient{ID: subjectIdentityClientID}, }) @@ -2693,7 +2693,7 @@ func TestResolveSubjectIdentity_NoProviderOrNoSubject(t *testing.T) { assert.Empty(t, category) // No subject at all. - id, category = tb.resolveSubjectIdentity(&AccessTokenBuildContext{}) + id, category = tb.resolveSubjectIdentity(context.Background(), &AccessTokenBuildContext{}) assert.Empty(t, id) assert.Empty(t, category) } @@ -2704,7 +2704,7 @@ func TestResolveSubjectIdentity_NoProviderOrNoSubject(t *testing.T) { func TestResolveActorIdentity_ActorIsTheClient(t *testing.T) { tb := &tokenBuilder{} - id := tb.resolveActorIdentity(&AccessTokenBuildContext{ + id := tb.resolveActorIdentity(context.Background(), &AccessTokenBuildContext{ OAuthApp: &providers.OAuthClient{ ID: subjectIdentityClientID, EntityCategory: providers.EntityCategoryAgent, @@ -2718,12 +2718,12 @@ func TestResolveActorIdentity_ActorIsTheClient(t *testing.T) { // entity is reported. func TestResolveActorIdentity_ActorTokenNamesAnEntity(t *testing.T) { actors := actorprovidermock.NewActorProviderMock(t) - actors.On("GetActor", "agent-b"). + actors.On("GetActor", mock.Anything, "agent-b"). Return(&providers.Entity{ID: "agent-b", Category: providers.EntityCategoryAgent}, (*tidcommon.ServiceError)(nil)) tb := &tokenBuilder{actorProvider: actors} - id := tb.resolveActorIdentity(&AccessTokenBuildContext{ + id := tb.resolveActorIdentity(context.Background(), &AccessTokenBuildContext{ OAuthApp: &providers.OAuthClient{ID: subjectIdentityClientID}, }, "agent-b") @@ -2735,11 +2735,11 @@ func TestResolveActorIdentity_ActorTokenNamesAnEntity(t *testing.T) { // address here, is never published. func TestResolveActorIdentity_MappedAttributeIsNotReported(t *testing.T) { actors := actorprovidermock.NewActorProviderMock(t) - actors.On("GetActor", "svc@example.com"). + actors.On("GetActor", mock.Anything, "svc@example.com"). Return((*providers.Entity)(nil), &tidcommon.ServiceError{Code: "ENTITY-404"}) tb := &tokenBuilder{actorProvider: actors} - id := tb.resolveActorIdentity(&AccessTokenBuildContext{ + id := tb.resolveActorIdentity(context.Background(), &AccessTokenBuildContext{ OAuthApp: &providers.OAuthClient{ID: subjectIdentityClientID}, }, "svc@example.com") @@ -2750,13 +2750,13 @@ func TestResolveActorIdentity_NoProviderOrNoActor(t *testing.T) { tb := &tokenBuilder{} // An actor that is not the client cannot be resolved without a provider, so it is not reported. - id := tb.resolveActorIdentity(&AccessTokenBuildContext{ + id := tb.resolveActorIdentity(context.Background(), &AccessTokenBuildContext{ OAuthApp: &providers.OAuthClient{ID: subjectIdentityClientID}, }, "agent-b") assert.Empty(t, id) // No actor at all. - id = tb.resolveActorIdentity(&AccessTokenBuildContext{}, "") + id = tb.resolveActorIdentity(context.Background(), &AccessTokenBuildContext{}, "") assert.Empty(t, id) } diff --git a/backend/internal/oauth/oauth2/tokenservice/utils.go b/backend/internal/oauth/oauth2/tokenservice/utils.go index a94c820c71..f044359371 100644 --- a/backend/internal/oauth/oauth2/tokenservice/utils.go +++ b/backend/internal/oauth/oauth2/tokenservice/utils.go @@ -475,12 +475,13 @@ func FilterAttributesByAllowList( // The organization claims are not among them: BuildClientEffectiveOUAttributes resolves those, and // they travel in a field of their own on the build context. func BuildClientAttributes( + ctx context.Context, oauthApp *providers.OAuthClient, actorProvider providers.ActorProvider, ) (map[string]interface{}, error) { claims := make(map[string]interface{}) - entity, err := fetchClientEntity(oauthApp, actorProvider) + entity, err := fetchClientEntity(ctx, oauthApp, actorProvider) if err != nil { return nil, err } @@ -502,7 +503,7 @@ func BuildClientAttributes( claims[k] = v } - groupRoleClaims, err := resolveClientGroupRoleClaims(oauthApp, actorProvider) + groupRoleClaims, err := resolveClientGroupRoleClaims(ctx, oauthApp, actorProvider) if err != nil { return nil, err } @@ -533,6 +534,7 @@ func resolvedWithoutEntity(name string) bool { // system-attribute resolvers can share it. Returns nil when no requested attribute needs the // entity: an empty allow-list, or one that lists only claims resolved elsewhere (OU, groups, roles). func fetchClientEntity( + ctx context.Context, oauthApp *providers.OAuthClient, actorProvider providers.ActorProvider, ) (*providers.Entity, error) { @@ -551,7 +553,7 @@ func fetchClientEntity( return nil, nil } - entity, svcErr := actorProvider.GetActor(oauthApp.ID) + entity, svcErr := actorProvider.GetActor(ctx, oauthApp.ID) if svcErr != nil { return nil, fmt.Errorf("failed to fetch entity %s for client attributes: %s", oauthApp.ID, svcErr.Error) } @@ -677,6 +679,7 @@ func resolveClientSystemAttributes( // ClientConfig.Attributes. Groups come from the actor's transitive memberships; roles are resolved // from those groups plus direct assignments. The shared group lookup runs once for both. func resolveClientGroupRoleClaims( + ctx context.Context, oauthApp *providers.OAuthClient, actorProvider providers.ActorProvider, ) (map[string]interface{}, error) { @@ -691,7 +694,7 @@ func resolveClientGroupRoleClaims( return nil, nil } - groups, svcErr := actorProvider.GetActorGroups(oauthApp.ID) + groups, svcErr := actorProvider.GetActorGroups(ctx, oauthApp.ID) if svcErr != nil { return nil, fmt.Errorf("failed to fetch groups for client %s: %s", oauthApp.ID, svcErr.Error) } @@ -715,7 +718,7 @@ func resolveClientGroupRoleClaims( groupIDs = append(groupIDs, g.ID) } } - roles, roleErr := actorProvider.GetActorRoles(oauthApp.ID, groupIDs) + roles, roleErr := actorProvider.GetActorRoles(ctx, oauthApp.ID, groupIDs) if roleErr != nil { return nil, fmt.Errorf("failed to fetch roles for client %s: %s", oauthApp.ID, roleErr.Error) } @@ -814,7 +817,7 @@ func ApplyMappedAuthorization( } roleIDs, groupIDs, mappedPermissions := idp.SplitAuthorizationTargets(authorizationTargets) - groupIDs, err := expandMappedGroupAncestors(actorProvider, groupIDs) + groupIDs, err := expandMappedGroupAncestors(ctx, actorProvider, groupIDs) if err != nil { logger.Error(ctx, "Failed to resolve ancestors of a mapped group", log.Error(err)) return nil, &model.ErrorResponse{ @@ -855,14 +858,14 @@ func ApplyMappedAuthorization( // expandMappedGroupAncestors adds each mapped group's ancestor groups. Fails closed, like // resolveMappedAuthorization above. func expandMappedGroupAncestors( - actorProvider providers.ActorProvider, groupIDs []string, + ctx context.Context, actorProvider providers.ActorProvider, groupIDs []string, ) ([]string, error) { if actorProvider == nil || len(groupIDs) == 0 { return groupIDs, nil } expanded := groupIDs for _, groupID := range groupIDs { - ancestors, svcErr := actorProvider.GetTransitiveGroupAncestors(groupID) + ancestors, svcErr := actorProvider.GetTransitiveGroupAncestors(ctx, groupID) if svcErr != nil { return nil, fmt.Errorf( "%w: failed to resolve ancestors of group %q: %s", diff --git a/backend/internal/oauth/oauth2/tokenservice/utils_test.go b/backend/internal/oauth/oauth2/tokenservice/utils_test.go index 645a5af4d1..d1839cff1d 100644 --- a/backend/internal/oauth/oauth2/tokenservice/utils_test.go +++ b/backend/internal/oauth/oauth2/tokenservice/utils_test.go @@ -906,11 +906,11 @@ func (suite *UtilsTestSuite) TestBuildClientAttributes_OUOnly_SkipsEntityFetch() app := newOAuthAppForClientAttributesWith(testBCCOUID, []string{constants.ClaimOUID, constants.ClaimOUName, constants.ClaimOUHandle}) - claims, err := BuildClientAttributes(app, actors) + claims, err := BuildClientAttributes(context.Background(), app, actors) assert.NoError(suite.T(), err) assert.Nil(suite.T(), claims, "the organization claims are not this function's to return") - actors.AssertNotCalled(suite.T(), "GetActor") + actors.AssertNotCalled(suite.T(), "GetActor", mock.Anything, mock.Anything) } func (suite *UtilsTestSuite) TestBuildClientAttributes_OUAttributes_PartialSelection() { @@ -945,14 +945,14 @@ func newOAuthAppForOwnAttributes(clientAttributes []string) *providers.OAuthClie func (suite *UtilsTestSuite) TestBuildClientAttributes_ResolvesRegardlessOfEntityCategory() { actors := actorprovidermock.NewActorProviderMock(suite.T()) - actors.On("GetActor", testBCCAppID).Return(&providers.Entity{ + actors.On("GetActor", mock.Anything, testBCCAppID).Return(&providers.Entity{ ID: testBCCAppID, Attributes: []byte(`{"modelProvider":"anthropic"}`), }, (*tidcommon.ServiceError)(nil)) app := newOAuthAppForOwnAttributes([]string{"modelProvider"}) app.EntityCategory = providers.EntityCategoryUser - claims, err := BuildClientAttributes(app, actors) + claims, err := BuildClientAttributes(context.Background(), app, actors) assert.NoError(suite.T(), err) assert.Equal(suite.T(), "anthropic", claims["modelProvider"]) @@ -962,7 +962,7 @@ func (suite *UtilsTestSuite) TestBuildClientAttributes_NoClientAttributesConfigu actors := actorprovidermock.NewActorProviderMock(suite.T()) app := newOAuthAppForOwnAttributes(nil) - claims, err := BuildClientAttributes(app, actors) + claims, err := BuildClientAttributes(context.Background(), app, actors) assert.NoError(suite.T(), err) assert.Nil(suite.T(), claims) @@ -970,13 +970,13 @@ func (suite *UtilsTestSuite) TestBuildClientAttributes_NoClientAttributesConfigu func (suite *UtilsTestSuite) TestBuildClientAttributes_AgentOwnAttributes_HappyPath() { actors := actorprovidermock.NewActorProviderMock(suite.T()) - actors.On("GetActor", testBCCAppID).Return(&providers.Entity{ + actors.On("GetActor", mock.Anything, testBCCAppID).Return(&providers.Entity{ ID: testBCCAppID, Attributes: []byte(`{"modelProvider":"anthropic","model":"claude","unrequested":"x"}`), }, (*tidcommon.ServiceError)(nil)) app := newOAuthAppForOwnAttributes([]string{"modelProvider", "model"}) - claims, err := BuildClientAttributes(app, actors) + claims, err := BuildClientAttributes(context.Background(), app, actors) assert.NoError(suite.T(), err) assert.Equal(suite.T(), "anthropic", claims["modelProvider"]) @@ -986,13 +986,13 @@ func (suite *UtilsTestSuite) TestBuildClientAttributes_AgentOwnAttributes_HappyP func (suite *UtilsTestSuite) TestBuildClientAttributes_AgentOwnAttributes_SkipsReservedClaimNames() { actors := actorprovidermock.NewActorProviderMock(suite.T()) - actors.On("GetActor", testBCCAppID).Return(&providers.Entity{ + actors.On("GetActor", mock.Anything, testBCCAppID).Return(&providers.Entity{ ID: testBCCAppID, Attributes: []byte(`{"scope":"malicious-override","modelProvider":"anthropic"}`), }, (*tidcommon.ServiceError)(nil)) app := newOAuthAppForOwnAttributes([]string{"scope", "modelProvider"}) - claims, err := BuildClientAttributes(app, actors) + claims, err := BuildClientAttributes(context.Background(), app, actors) assert.NoError(suite.T(), err) assert.Equal(suite.T(), "anthropic", claims["modelProvider"]) @@ -1002,13 +1002,13 @@ func (suite *UtilsTestSuite) TestBuildClientAttributes_AgentOwnAttributes_SkipsR // sub_type is reserved, so an agent cannot surface a schema attribute of that name. func (suite *UtilsTestSuite) TestBuildClientAttributes_AgentOwnAttributes_SkipsSubType() { actors := actorprovidermock.NewActorProviderMock(suite.T()) - actors.On("GetActor", testBCCAppID).Return(&providers.Entity{ + actors.On("GetActor", mock.Anything, testBCCAppID).Return(&providers.Entity{ ID: testBCCAppID, Attributes: []byte(`{"sub_type":"app","modelProvider":"anthropic"}`), }, (*tidcommon.ServiceError)(nil)) app := newOAuthAppForOwnAttributes([]string{"sub_type", "modelProvider"}) - claims, err := BuildClientAttributes(app, actors) + claims, err := BuildClientAttributes(context.Background(), app, actors) assert.NoError(suite.T(), err) assert.Equal(suite.T(), "anthropic", claims["modelProvider"]) @@ -1017,7 +1017,7 @@ func (suite *UtilsTestSuite) TestBuildClientAttributes_AgentOwnAttributes_SkipsS func (suite *UtilsTestSuite) TestBuildClientAttributes_AgentSystemAttributes_HappyPath() { actors := actorprovidermock.NewActorProviderMock(suite.T()) - actors.On("GetActor", testBCCAppID).Return(&providers.Entity{ + actors.On("GetActor", mock.Anything, testBCCAppID).Return(&providers.Entity{ ID: testBCCAppID, Category: providers.EntityCategoryAgent, Attributes: []byte(`{"modelProvider":"anthropic","name":"Ledger Agent"}`), @@ -1025,7 +1025,7 @@ func (suite *UtilsTestSuite) TestBuildClientAttributes_AgentSystemAttributes_Hap }, (*tidcommon.ServiceError)(nil)) app := newOAuthAppForOwnAttributes([]string{"modelProvider", "name", "owner"}) - claims, err := BuildClientAttributes(app, actors) + claims, err := BuildClientAttributes(context.Background(), app, actors) assert.NoError(suite.T(), err) assert.Equal(suite.T(), "anthropic", claims["modelProvider"]) @@ -1037,66 +1037,66 @@ func (suite *UtilsTestSuite) TestBuildClientAttributes_AgentSystemAttributes_Hap func (suite *UtilsTestSuite) TestBuildClientAttributes_GroupsAndRoles_Resolved() { actors := actorprovidermock.NewActorProviderMock(suite.T()) - actors.On("GetActorGroups", testBCCAppID).Return([]providers.EntityGroup{ + actors.On("GetActorGroups", mock.Anything, testBCCAppID).Return([]providers.EntityGroup{ {ID: "g1", Name: "engineering"}, {ID: "g2", Name: "admins"}, }, (*tidcommon.ServiceError)(nil)) - actors.On("GetActorRoles", testBCCAppID, []string{"g1", "g2"}). + actors.On("GetActorRoles", mock.Anything, testBCCAppID, []string{"g1", "g2"}). Return([]string{"admin", "editor"}, (*tidcommon.ServiceError)(nil)) app := newOAuthAppForOwnAttributes([]string{"groups", "roles"}) - claims, err := BuildClientAttributes(app, actors) + claims, err := BuildClientAttributes(context.Background(), app, actors) assert.NoError(suite.T(), err) assert.ElementsMatch(suite.T(), []string{"engineering", "admins"}, claims["groups"]) assert.ElementsMatch(suite.T(), []string{"admin", "editor"}, claims["roles"]) - actors.AssertNotCalled(suite.T(), "GetActor") + actors.AssertNotCalled(suite.T(), "GetActor", mock.Anything, mock.Anything) } func (suite *UtilsTestSuite) TestBuildClientAttributes_GroupsOnly_DoesNotResolveRoles() { actors := actorprovidermock.NewActorProviderMock(suite.T()) - actors.On("GetActorGroups", testBCCAppID).Return([]providers.EntityGroup{ + actors.On("GetActorGroups", mock.Anything, testBCCAppID).Return([]providers.EntityGroup{ {ID: "g1", Name: "engineering"}, }, (*tidcommon.ServiceError)(nil)) app := newOAuthAppForOwnAttributes([]string{"groups"}) - claims, err := BuildClientAttributes(app, actors) + claims, err := BuildClientAttributes(context.Background(), app, actors) assert.NoError(suite.T(), err) assert.ElementsMatch(suite.T(), []string{"engineering"}, claims["groups"]) assert.NotContains(suite.T(), claims, "roles") - actors.AssertNotCalled(suite.T(), "GetActorRoles") + actors.AssertNotCalled(suite.T(), "GetActorRoles", mock.Anything, mock.Anything, mock.Anything) } func (suite *UtilsTestSuite) TestBuildClientAttributes_GroupRoles_SkippedWhenNotRequested() { actors := actorprovidermock.NewActorProviderMock(suite.T()) - actors.On("GetActor", testBCCAppID).Return(&providers.Entity{ + actors.On("GetActor", mock.Anything, testBCCAppID).Return(&providers.Entity{ ID: testBCCAppID, Category: providers.EntityCategoryAgent, Attributes: []byte(`{"modelProvider":"anthropic"}`), }, (*tidcommon.ServiceError)(nil)) app := newOAuthAppForOwnAttributes([]string{"modelProvider"}) - claims, err := BuildClientAttributes(app, actors) + claims, err := BuildClientAttributes(context.Background(), app, actors) assert.NoError(suite.T(), err) assert.Equal(suite.T(), "anthropic", claims["modelProvider"]) assert.NotContains(suite.T(), claims, "groups") assert.NotContains(suite.T(), claims, "roles") - actors.AssertNotCalled(suite.T(), "GetActorGroups") - actors.AssertNotCalled(suite.T(), "GetActorRoles") + actors.AssertNotCalled(suite.T(), "GetActorGroups", mock.Anything, mock.Anything) + actors.AssertNotCalled(suite.T(), "GetActorRoles", mock.Anything, mock.Anything, mock.Anything) } func (suite *UtilsTestSuite) TestBuildClientAttributes_SystemAttributes_SkippedForNonAgentEntity() { actors := actorprovidermock.NewActorProviderMock(suite.T()) - actors.On("GetActor", testBCCAppID).Return(&providers.Entity{ + actors.On("GetActor", mock.Anything, testBCCAppID).Return(&providers.Entity{ ID: testBCCAppID, Category: providers.EntityCategoryApp, SystemAttributes: []byte(`{"name":"My App"}`), }, (*tidcommon.ServiceError)(nil)) app := newOAuthAppForOwnAttributes([]string{"name"}) - claims, err := BuildClientAttributes(app, actors) + claims, err := BuildClientAttributes(context.Background(), app, actors) assert.NoError(suite.T(), err) assert.Nil(suite.T(), claims) @@ -1104,13 +1104,13 @@ func (suite *UtilsTestSuite) TestBuildClientAttributes_SystemAttributes_SkippedF func (suite *UtilsTestSuite) TestBuildClientAttributes_SystemAttributes_EmptyWhenNotStored() { actors := actorprovidermock.NewActorProviderMock(suite.T()) - actors.On("GetActor", testBCCAppID).Return(&providers.Entity{ + actors.On("GetActor", mock.Anything, testBCCAppID).Return(&providers.Entity{ ID: testBCCAppID, Category: providers.EntityCategoryAgent, }, (*tidcommon.ServiceError)(nil)) app := newOAuthAppForOwnAttributes([]string{"name", "owner"}) - claims, err := BuildClientAttributes(app, actors) + claims, err := BuildClientAttributes(context.Background(), app, actors) assert.NoError(suite.T(), err) assert.Nil(suite.T(), claims) @@ -1118,7 +1118,7 @@ func (suite *UtilsTestSuite) TestBuildClientAttributes_SystemAttributes_EmptyWhe func (suite *UtilsTestSuite) TestBuildClientAttributes_StaleSystemNameDoesNotOverrideSchemaName() { actors := actorprovidermock.NewActorProviderMock(suite.T()) - actors.On("GetActor", testBCCAppID).Return(&providers.Entity{ + actors.On("GetActor", mock.Anything, testBCCAppID).Return(&providers.Entity{ ID: testBCCAppID, Category: providers.EntityCategoryAgent, Attributes: []byte(`{"name":"schema-name"}`), @@ -1126,7 +1126,7 @@ func (suite *UtilsTestSuite) TestBuildClientAttributes_StaleSystemNameDoesNotOve }, (*tidcommon.ServiceError)(nil)) app := newOAuthAppForOwnAttributes([]string{"name"}) - claims, err := BuildClientAttributes(app, actors) + claims, err := BuildClientAttributes(context.Background(), app, actors) assert.NoError(suite.T(), err) assert.Equal(suite.T(), "schema-name", claims["name"]) @@ -1134,7 +1134,7 @@ func (suite *UtilsTestSuite) TestBuildClientAttributes_StaleSystemNameDoesNotOve func (suite *UtilsTestSuite) TestBuildClientAttributes_AgentGetActorError_ReturnsError() { actors := actorprovidermock.NewActorProviderMock(suite.T()) - actors.On("GetActor", testBCCAppID).Return( + actors.On("GetActor", mock.Anything, testBCCAppID).Return( (*providers.Entity)(nil), &tidcommon.ServiceError{ Code: "AGT-0001", @@ -1143,7 +1143,7 @@ func (suite *UtilsTestSuite) TestBuildClientAttributes_AgentGetActorError_Return ) app := newOAuthAppForOwnAttributes([]string{"modelProvider"}) - claims, err := BuildClientAttributes(app, actors) + claims, err := BuildClientAttributes(context.Background(), app, actors) assert.Error(suite.T(), err) assert.Nil(suite.T(), claims) diff --git a/backend/internal/ou/handler.go b/backend/internal/ou/handler.go index 86144d89a5..8500fc76f5 100644 --- a/backend/internal/ou/handler.go +++ b/backend/internal/ou/handler.go @@ -98,7 +98,7 @@ func (ouh *organizationUnitHandler) HandleOUPostRequest(w http.ResponseWriter, r sysutils.WriteSuccessResponse(ctx, w, http.StatusCreated, createdOU) - logger.Debug(ctx, "Successfully created organization unit", log.String("ouId", createdOU.ID)) + logger.Debug(ctx, "Successfully created organization unit", log.String("ouID", createdOU.ID)) } // HandleOUGetRequest handles the get organization unit by id request. @@ -119,7 +119,7 @@ func (ouh *organizationUnitHandler) HandleOUGetRequest(w http.ResponseWriter, r sysutils.WriteSuccessResponse(ctx, w, http.StatusOK, ou) - logger.Debug(ctx, "Successfully retrieved organization unit", log.String("ouId", id)) + logger.Debug(ctx, "Successfully retrieved organization unit", log.String("ouID", id)) } // HandleOUPutRequest handles the update organization unit request. @@ -155,7 +155,7 @@ func (ouh *organizationUnitHandler) HandleOUPutRequest(w http.ResponseWriter, r sysutils.WriteSuccessResponse(ctx, w, http.StatusOK, ou) - logger.Debug(ctx, "Successfully updated organization unit", log.String("ouId", id)) + logger.Debug(ctx, "Successfully updated organization unit", log.String("ouID", id)) } // HandleOUDeleteRequest handles the delete organization unit request. @@ -175,7 +175,7 @@ func (ouh *organizationUnitHandler) HandleOUDeleteRequest(w http.ResponseWriter, } sysutils.WriteSuccessResponse(ctx, w, http.StatusNoContent, nil) - logger.Debug(ctx, "Successfully deleted organization unit", log.String("ouId", id)) + logger.Debug(ctx, "Successfully deleted organization unit", log.String("ouID", id)) } // HandleOUChildrenListRequest handles the list child organization units request. diff --git a/backend/internal/resource/service.go b/backend/internal/resource/service.go index c7ae6144f7..9da8564e2a 100644 --- a/backend/internal/resource/service.go +++ b/backend/internal/resource/service.go @@ -810,7 +810,7 @@ func (rs *resourceService) UpdateResource( if rs.IsResourceServerDeclarative(resourceServerID) { rs.logger.Debug(ctx, "Cannot modify resource in declarative resource server", - log.String("resource_server_id", resourceServerID), + log.String("resourceServerID", resourceServerID), ) return nil, ErrorImmutableResource.WithParams(map[string]string{"id": id}) } @@ -874,7 +874,7 @@ func (rs *resourceService) DeleteResource( if rs.IsResourceServerDeclarative(resourceServerID) { rs.logger.Debug(ctx, "Cannot delete resource in declarative resource server", - log.String("resource_server_id", resourceServerID), + log.String("resourceServerID", resourceServerID), ) return ErrorImmutableResource.WithParams(map[string]string{"id": id}) } @@ -1304,7 +1304,7 @@ func (rs *resourceService) ValidatePermissions( permissions []string, ) ([]string, *tidcommon.ServiceError) { rs.logger.Debug(ctx, "Validating permissions", - log.String("resourceServerId", resourceServerID), + log.String("resourceServerID", resourceServerID), log.Int("permissionCount", len(permissions))) if len(permissions) == 0 { @@ -1316,12 +1316,12 @@ func (rs *resourceService) ValidatePermissions( if err != nil { if !errors.Is(err, errResourceServerNotFound) { rs.logger.Error(ctx, "Failed to validate resource server existence", - log.String("resourceServerId", resourceServerID), + log.String("resourceServerID", resourceServerID), log.Error(err)) return nil, &tidcommon.InternalServerError } rs.logger.Debug(ctx, "Resource server not found", - log.String("resourceServerId", resourceServerID)) + log.String("resourceServerID", resourceServerID)) // Return all permissions as invalid if resource server doesn't exist return permissions, nil } @@ -1330,7 +1330,7 @@ func (rs *resourceService) ValidatePermissions( invalidPermissions, storeErr := rs.resourceStore.ValidatePermissions(ctx, resourceServerID, permissions) if storeErr != nil { rs.logger.Error(ctx, "Failed to validate permissions in store", - log.String("resourceServerId", resourceServerID), + log.String("resourceServerID", resourceServerID), log.Error(storeErr)) return nil, &tidcommon.InternalServerError } @@ -1544,7 +1544,7 @@ func (rs *resourceService) validateActionDelete( if rs.IsResourceServerDeclarative(resourceServerID) { rs.logger.Debug(ctx, "Cannot delete action in declarative resource server", - log.String("resource_server_id", resourceServerID), + log.String("resourceServerID", resourceServerID), ) return ErrorImmutableAction.WithParams(map[string]string{"id": id}) } diff --git a/backend/internal/role/handler.go b/backend/internal/role/handler.go index 1dfcb64bed..20ff4873f5 100644 --- a/backend/internal/role/handler.go +++ b/backend/internal/role/handler.go @@ -106,7 +106,7 @@ func (rh *roleHandler) HandleRolePostRequest(w http.ResponseWriter, r *http.Requ sysutils.WriteSuccessResponse(ctx, w, http.StatusCreated, createdRole) - logger.Debug(ctx, "Successfully created role", log.String("roleId", createdRole.ID)) + logger.Debug(ctx, "Successfully created role", log.String("roleID", createdRole.ID)) } // HandleRoleGetRequest handles the get role by id request. diff --git a/backend/internal/role/service.go b/backend/internal/role/service.go index b0dba40beb..0af156808a 100644 --- a/backend/internal/role/service.go +++ b/backend/internal/role/service.go @@ -792,7 +792,7 @@ func (rs *roleService) validatePermissions( if svcErr != nil { logger.Error(ctx, "Failed to validate permissions", - log.String("resourceServerId", resPerm.ResourceServerID), + log.String("resourceServerID", resPerm.ResourceServerID), log.String("error", svcErr.Error.DefaultValue)) return &tidcommon.InternalServerError } @@ -800,7 +800,7 @@ func (rs *roleService) validatePermissions( // If any permissions are invalid, return error if len(invalidPerms) > 0 { logger.Debug(ctx, "Invalid permissions found", - log.String("resourceServerId", resPerm.ResourceServerID), + log.String("resourceServerID", resPerm.ResourceServerID), log.Any("invalidPermissions", invalidPerms), log.Int("count", len(invalidPerms))) return &ErrorInvalidPermissions diff --git a/backend/internal/system/importer/delete_runtime.go b/backend/internal/system/importer/delete_runtime.go index dbaf100430..68b874dc81 100644 --- a/backend/internal/system/importer/delete_runtime.go +++ b/backend/internal/system/importer/delete_runtime.go @@ -52,7 +52,7 @@ func (s *importService) logDeletionFailure( ctx context.Context, deletion ResourceDeletion, outcome ImportItemOutcome) { fields := []log.Field{ log.String("resourceType", deletion.ResourceType), - log.String("resourceId", deletion.ID), + log.String("resourceID", deletion.ID), log.String("code", outcome.Code), } if outcome.Message != "" { diff --git a/backend/internal/system/log/constants.go b/backend/internal/system/log/constants.go index 73e399a3b2..fb50b8d5a0 100644 --- a/backend/internal/system/log/constants.go +++ b/backend/internal/system/log/constants.go @@ -11,7 +11,9 @@ const ( // LoggerKeyExecutionID is the key used to identify the flow execution ID in the logger. LoggerKeyExecutionID = "executionID" // LoggerKeyNodeID is the key used to identify the node ID in the logger. - LoggerKeyNodeID = "nodeId" + LoggerKeyNodeID = "nodeID" + // LoggerKeyIDPID is the key used to identify the identity provider ID in the logger. + LoggerKeyIDPID = "idpID" // LoggerKeyTraceID is the key used to identify the trace ID (correlation ID) in the logger. LoggerKeyTraceID = "trace_id" // LoggerKeyUserID is the key used to identify the user ID in the logger. diff --git a/backend/internal/user/service.go b/backend/internal/user/service.go index 515cb63588..da945d319f 100644 --- a/backend/internal/user/service.go +++ b/backend/internal/user/service.go @@ -249,7 +249,7 @@ func (us *userService) GetUsersByPath( oupkg.ErrorInvalidLimit.Code: &ErrorInvalidLimit, oupkg.ErrorInvalidOffset.Code: &ErrorInvalidOffset, }, - log.String("oUID", oUID), + log.String("ouID", oUID), log.Int("limit", limit), log.Int("offset", offset), ) @@ -1110,7 +1110,7 @@ func (us *userService) validateOrganizationUnitForUserType( oupkg.ErrorInvalidRequestFormat.Code: &ErrorInvalidOUID, oupkg.ErrorMissingOUID.Code: &ErrorInvalidOUID, }, - log.String("oUID", oUID), + log.String("ouID", oUID), ) } if !exists { @@ -1152,7 +1152,7 @@ func (us *userService) validateOrganizationUnitForUserType( oupkg.ErrorOrganizationUnitNotFound.Code: &ErrorOrganizationUnitNotFound, }, log.String("userType", userType), - log.String("oUID", oUID), + log.String("ouID", oUID), log.String("schemaOUID", entityType.OUID), ) } @@ -1160,7 +1160,7 @@ func (us *userService) validateOrganizationUnitForUserType( if !isParent { logger.Debug(ctx, "Organization unit mismatch for user type", log.String("userType", userType), - log.String("oUID", oUID), + log.String("ouID", oUID), log.String("schemaOUID", entityType.OUID)) return &ErrorOrganizationUnitMismatch } diff --git a/backend/pkg/thunderidengine/providers/interface.go b/backend/pkg/thunderidengine/providers/interface.go index a9dd6a9d86..9433ed42cb 100644 --- a/backend/pkg/thunderidengine/providers/interface.go +++ b/backend/pkg/thunderidengine/providers/interface.go @@ -89,10 +89,10 @@ type ActorProvider interface { AuthenticateActor( ctx context.Context, identifiers, credentials map[string]interface{}, ) *common.ServiceError - GetActor(actorID string) (*Entity, *common.ServiceError) - GetActorGroups(actorID string) ([]EntityGroup, *common.ServiceError) - GetActorRoles(actorID string, groupIDs []string) ([]string, *common.ServiceError) - GetTransitiveGroupAncestors(groupID string) ([]string, *common.ServiceError) + GetActor(ctx context.Context, actorID string) (*Entity, *common.ServiceError) + GetActorGroups(ctx context.Context, actorID string) ([]EntityGroup, *common.ServiceError) + GetActorRoles(ctx context.Context, actorID string, groupIDs []string) ([]string, *common.ServiceError) + GetTransitiveGroupAncestors(ctx context.Context, groupID string) ([]string, *common.ServiceError) } // AgentMgtProvider provisions agents on behalf of runtime capabilities. The rules and semantics of an diff --git a/backend/tests/mocks/actorprovidermock/ActorProvider_mock.go b/backend/tests/mocks/actorprovidermock/ActorProvider_mock.go index 3926f2fedf..a55df664cf 100644 --- a/backend/tests/mocks/actorprovidermock/ActorProvider_mock.go +++ b/backend/tests/mocks/actorprovidermock/ActorProvider_mock.go @@ -114,8 +114,8 @@ func (_c *ActorProviderMock_AuthenticateActor_Call) RunAndReturn(run func(ctx co } // GetActor provides a mock function for the type ActorProviderMock -func (_mock *ActorProviderMock) GetActor(actorID string) (*providers.Entity, *common.ServiceError) { - ret := _mock.Called(actorID) +func (_mock *ActorProviderMock) GetActor(ctx context.Context, actorID string) (*providers.Entity, *common.ServiceError) { + ret := _mock.Called(ctx, actorID) if len(ret) == 0 { panic("no return value specified for GetActor") @@ -123,18 +123,18 @@ func (_mock *ActorProviderMock) GetActor(actorID string) (*providers.Entity, *co var r0 *providers.Entity var r1 *common.ServiceError - if returnFunc, ok := ret.Get(0).(func(string) (*providers.Entity, *common.ServiceError)); ok { - return returnFunc(actorID) + if returnFunc, ok := ret.Get(0).(func(context.Context, string) (*providers.Entity, *common.ServiceError)); ok { + return returnFunc(ctx, actorID) } - if returnFunc, ok := ret.Get(0).(func(string) *providers.Entity); ok { - r0 = returnFunc(actorID) + if returnFunc, ok := ret.Get(0).(func(context.Context, string) *providers.Entity); ok { + r0 = returnFunc(ctx, actorID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*providers.Entity) } } - if returnFunc, ok := ret.Get(1).(func(string) *common.ServiceError); ok { - r1 = returnFunc(actorID) + if returnFunc, ok := ret.Get(1).(func(context.Context, string) *common.ServiceError); ok { + r1 = returnFunc(ctx, actorID) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*common.ServiceError) @@ -149,19 +149,25 @@ type ActorProviderMock_GetActor_Call struct { } // GetActor is a helper method to define mock.On call +// - ctx context.Context // - actorID string -func (_e *ActorProviderMock_Expecter) GetActor(actorID any) *ActorProviderMock_GetActor_Call { - return &ActorProviderMock_GetActor_Call{Call: _e.mock.On("GetActor", actorID)} +func (_e *ActorProviderMock_Expecter) GetActor(ctx any, actorID any) *ActorProviderMock_GetActor_Call { + return &ActorProviderMock_GetActor_Call{Call: _e.mock.On("GetActor", ctx, actorID)} } -func (_c *ActorProviderMock_GetActor_Call) Run(run func(actorID string)) *ActorProviderMock_GetActor_Call { +func (_c *ActorProviderMock_GetActor_Call) Run(run func(ctx context.Context, actorID string)) *ActorProviderMock_GetActor_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string + var arg0 context.Context if args[0] != nil { - arg0 = args[0].(string) + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) } run( arg0, + arg1, ) }) return _c @@ -172,14 +178,14 @@ func (_c *ActorProviderMock_GetActor_Call) Return(entity *providers.Entity, serv return _c } -func (_c *ActorProviderMock_GetActor_Call) RunAndReturn(run func(actorID string) (*providers.Entity, *common.ServiceError)) *ActorProviderMock_GetActor_Call { +func (_c *ActorProviderMock_GetActor_Call) RunAndReturn(run func(ctx context.Context, actorID string) (*providers.Entity, *common.ServiceError)) *ActorProviderMock_GetActor_Call { _c.Call.Return(run) return _c } // GetActorGroups provides a mock function for the type ActorProviderMock -func (_mock *ActorProviderMock) GetActorGroups(actorID string) ([]providers.EntityGroup, *common.ServiceError) { - ret := _mock.Called(actorID) +func (_mock *ActorProviderMock) GetActorGroups(ctx context.Context, actorID string) ([]providers.EntityGroup, *common.ServiceError) { + ret := _mock.Called(ctx, actorID) if len(ret) == 0 { panic("no return value specified for GetActorGroups") @@ -187,18 +193,18 @@ func (_mock *ActorProviderMock) GetActorGroups(actorID string) ([]providers.Enti var r0 []providers.EntityGroup var r1 *common.ServiceError - if returnFunc, ok := ret.Get(0).(func(string) ([]providers.EntityGroup, *common.ServiceError)); ok { - return returnFunc(actorID) + if returnFunc, ok := ret.Get(0).(func(context.Context, string) ([]providers.EntityGroup, *common.ServiceError)); ok { + return returnFunc(ctx, actorID) } - if returnFunc, ok := ret.Get(0).(func(string) []providers.EntityGroup); ok { - r0 = returnFunc(actorID) + if returnFunc, ok := ret.Get(0).(func(context.Context, string) []providers.EntityGroup); ok { + r0 = returnFunc(ctx, actorID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]providers.EntityGroup) } } - if returnFunc, ok := ret.Get(1).(func(string) *common.ServiceError); ok { - r1 = returnFunc(actorID) + if returnFunc, ok := ret.Get(1).(func(context.Context, string) *common.ServiceError); ok { + r1 = returnFunc(ctx, actorID) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*common.ServiceError) @@ -213,19 +219,25 @@ type ActorProviderMock_GetActorGroups_Call struct { } // GetActorGroups is a helper method to define mock.On call +// - ctx context.Context // - actorID string -func (_e *ActorProviderMock_Expecter) GetActorGroups(actorID any) *ActorProviderMock_GetActorGroups_Call { - return &ActorProviderMock_GetActorGroups_Call{Call: _e.mock.On("GetActorGroups", actorID)} +func (_e *ActorProviderMock_Expecter) GetActorGroups(ctx any, actorID any) *ActorProviderMock_GetActorGroups_Call { + return &ActorProviderMock_GetActorGroups_Call{Call: _e.mock.On("GetActorGroups", ctx, actorID)} } -func (_c *ActorProviderMock_GetActorGroups_Call) Run(run func(actorID string)) *ActorProviderMock_GetActorGroups_Call { +func (_c *ActorProviderMock_GetActorGroups_Call) Run(run func(ctx context.Context, actorID string)) *ActorProviderMock_GetActorGroups_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string + var arg0 context.Context if args[0] != nil { - arg0 = args[0].(string) + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) } run( arg0, + arg1, ) }) return _c @@ -236,14 +248,14 @@ func (_c *ActorProviderMock_GetActorGroups_Call) Return(entityGroups []providers return _c } -func (_c *ActorProviderMock_GetActorGroups_Call) RunAndReturn(run func(actorID string) ([]providers.EntityGroup, *common.ServiceError)) *ActorProviderMock_GetActorGroups_Call { +func (_c *ActorProviderMock_GetActorGroups_Call) RunAndReturn(run func(ctx context.Context, actorID string) ([]providers.EntityGroup, *common.ServiceError)) *ActorProviderMock_GetActorGroups_Call { _c.Call.Return(run) return _c } // GetActorRoles provides a mock function for the type ActorProviderMock -func (_mock *ActorProviderMock) GetActorRoles(actorID string, groupIDs []string) ([]string, *common.ServiceError) { - ret := _mock.Called(actorID, groupIDs) +func (_mock *ActorProviderMock) GetActorRoles(ctx context.Context, actorID string, groupIDs []string) ([]string, *common.ServiceError) { + ret := _mock.Called(ctx, actorID, groupIDs) if len(ret) == 0 { panic("no return value specified for GetActorRoles") @@ -251,18 +263,18 @@ func (_mock *ActorProviderMock) GetActorRoles(actorID string, groupIDs []string) var r0 []string var r1 *common.ServiceError - if returnFunc, ok := ret.Get(0).(func(string, []string) ([]string, *common.ServiceError)); ok { - return returnFunc(actorID, groupIDs) + if returnFunc, ok := ret.Get(0).(func(context.Context, string, []string) ([]string, *common.ServiceError)); ok { + return returnFunc(ctx, actorID, groupIDs) } - if returnFunc, ok := ret.Get(0).(func(string, []string) []string); ok { - r0 = returnFunc(actorID, groupIDs) + if returnFunc, ok := ret.Get(0).(func(context.Context, string, []string) []string); ok { + r0 = returnFunc(ctx, actorID, groupIDs) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]string) } } - if returnFunc, ok := ret.Get(1).(func(string, []string) *common.ServiceError); ok { - r1 = returnFunc(actorID, groupIDs) + if returnFunc, ok := ret.Get(1).(func(context.Context, string, []string) *common.ServiceError); ok { + r1 = returnFunc(ctx, actorID, groupIDs) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*common.ServiceError) @@ -277,25 +289,31 @@ type ActorProviderMock_GetActorRoles_Call struct { } // GetActorRoles is a helper method to define mock.On call +// - ctx context.Context // - actorID string // - groupIDs []string -func (_e *ActorProviderMock_Expecter) GetActorRoles(actorID any, groupIDs any) *ActorProviderMock_GetActorRoles_Call { - return &ActorProviderMock_GetActorRoles_Call{Call: _e.mock.On("GetActorRoles", actorID, groupIDs)} +func (_e *ActorProviderMock_Expecter) GetActorRoles(ctx any, actorID any, groupIDs any) *ActorProviderMock_GetActorRoles_Call { + return &ActorProviderMock_GetActorRoles_Call{Call: _e.mock.On("GetActorRoles", ctx, actorID, groupIDs)} } -func (_c *ActorProviderMock_GetActorRoles_Call) Run(run func(actorID string, groupIDs []string)) *ActorProviderMock_GetActorRoles_Call { +func (_c *ActorProviderMock_GetActorRoles_Call) Run(run func(ctx context.Context, actorID string, groupIDs []string)) *ActorProviderMock_GetActorRoles_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string + var arg0 context.Context if args[0] != nil { - arg0 = args[0].(string) + arg0 = args[0].(context.Context) } - var arg1 []string + var arg1 string if args[1] != nil { - arg1 = args[1].([]string) + arg1 = args[1].(string) + } + var arg2 []string + if args[2] != nil { + arg2 = args[2].([]string) } run( arg0, arg1, + arg2, ) }) return _c @@ -306,7 +324,7 @@ func (_c *ActorProviderMock_GetActorRoles_Call) Return(strings []string, service return _c } -func (_c *ActorProviderMock_GetActorRoles_Call) RunAndReturn(run func(actorID string, groupIDs []string) ([]string, *common.ServiceError)) *ActorProviderMock_GetActorRoles_Call { +func (_c *ActorProviderMock_GetActorRoles_Call) RunAndReturn(run func(ctx context.Context, actorID string, groupIDs []string) ([]string, *common.ServiceError)) *ActorProviderMock_GetActorRoles_Call { _c.Call.Return(run) return _c } @@ -592,8 +610,8 @@ func (_c *ActorProviderMock_GetOAuthProfileByID_Call) RunAndReturn(run func(ctx } // GetTransitiveGroupAncestors provides a mock function for the type ActorProviderMock -func (_mock *ActorProviderMock) GetTransitiveGroupAncestors(groupID string) ([]string, *common.ServiceError) { - ret := _mock.Called(groupID) +func (_mock *ActorProviderMock) GetTransitiveGroupAncestors(ctx context.Context, groupID string) ([]string, *common.ServiceError) { + ret := _mock.Called(ctx, groupID) if len(ret) == 0 { panic("no return value specified for GetTransitiveGroupAncestors") @@ -601,18 +619,18 @@ func (_mock *ActorProviderMock) GetTransitiveGroupAncestors(groupID string) ([]s var r0 []string var r1 *common.ServiceError - if returnFunc, ok := ret.Get(0).(func(string) ([]string, *common.ServiceError)); ok { - return returnFunc(groupID) + if returnFunc, ok := ret.Get(0).(func(context.Context, string) ([]string, *common.ServiceError)); ok { + return returnFunc(ctx, groupID) } - if returnFunc, ok := ret.Get(0).(func(string) []string); ok { - r0 = returnFunc(groupID) + if returnFunc, ok := ret.Get(0).(func(context.Context, string) []string); ok { + r0 = returnFunc(ctx, groupID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]string) } } - if returnFunc, ok := ret.Get(1).(func(string) *common.ServiceError); ok { - r1 = returnFunc(groupID) + if returnFunc, ok := ret.Get(1).(func(context.Context, string) *common.ServiceError); ok { + r1 = returnFunc(ctx, groupID) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*common.ServiceError) @@ -627,19 +645,25 @@ type ActorProviderMock_GetTransitiveGroupAncestors_Call struct { } // GetTransitiveGroupAncestors is a helper method to define mock.On call +// - ctx context.Context // - groupID string -func (_e *ActorProviderMock_Expecter) GetTransitiveGroupAncestors(groupID any) *ActorProviderMock_GetTransitiveGroupAncestors_Call { - return &ActorProviderMock_GetTransitiveGroupAncestors_Call{Call: _e.mock.On("GetTransitiveGroupAncestors", groupID)} +func (_e *ActorProviderMock_Expecter) GetTransitiveGroupAncestors(ctx any, groupID any) *ActorProviderMock_GetTransitiveGroupAncestors_Call { + return &ActorProviderMock_GetTransitiveGroupAncestors_Call{Call: _e.mock.On("GetTransitiveGroupAncestors", ctx, groupID)} } -func (_c *ActorProviderMock_GetTransitiveGroupAncestors_Call) Run(run func(groupID string)) *ActorProviderMock_GetTransitiveGroupAncestors_Call { +func (_c *ActorProviderMock_GetTransitiveGroupAncestors_Call) Run(run func(ctx context.Context, groupID string)) *ActorProviderMock_GetTransitiveGroupAncestors_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string + var arg0 context.Context if args[0] != nil { - arg0 = args[0].(string) + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) } run( arg0, + arg1, ) }) return _c @@ -650,7 +674,7 @@ func (_c *ActorProviderMock_GetTransitiveGroupAncestors_Call) Return(strings []s return _c } -func (_c *ActorProviderMock_GetTransitiveGroupAncestors_Call) RunAndReturn(run func(groupID string) ([]string, *common.ServiceError)) *ActorProviderMock_GetTransitiveGroupAncestors_Call { +func (_c *ActorProviderMock_GetTransitiveGroupAncestors_Call) RunAndReturn(run func(ctx context.Context, groupID string) ([]string, *common.ServiceError)) *ActorProviderMock_GetTransitiveGroupAncestors_Call { _c.Call.Return(run) return _c } diff --git a/backend/tests/mocks/entityprovidermock/EntityProviderInterface_mock.go b/backend/tests/mocks/entityprovidermock/EntityProviderInterface_mock.go index b7a89d3154..a818da2449 100644 --- a/backend/tests/mocks/entityprovidermock/EntityProviderInterface_mock.go +++ b/backend/tests/mocks/entityprovidermock/EntityProviderInterface_mock.go @@ -5,6 +5,7 @@ package entityprovidermock import ( + "context" "encoding/json" mock "github.com/stretchr/testify/mock" @@ -166,8 +167,8 @@ func (_c *EntityProviderInterfaceMock_GetEntitiesByIDs_Call) RunAndReturn(run fu } // GetEntity provides a mock function for the type EntityProviderInterfaceMock -func (_mock *EntityProviderInterfaceMock) GetEntity(entityID string) (*providers.Entity, *entityprovider.EntityProviderError) { - ret := _mock.Called(entityID) +func (_mock *EntityProviderInterfaceMock) GetEntity(ctx context.Context, entityID string) (*providers.Entity, *entityprovider.EntityProviderError) { + ret := _mock.Called(ctx, entityID) if len(ret) == 0 { panic("no return value specified for GetEntity") @@ -175,18 +176,18 @@ func (_mock *EntityProviderInterfaceMock) GetEntity(entityID string) (*providers var r0 *providers.Entity var r1 *entityprovider.EntityProviderError - if returnFunc, ok := ret.Get(0).(func(string) (*providers.Entity, *entityprovider.EntityProviderError)); ok { - return returnFunc(entityID) + if returnFunc, ok := ret.Get(0).(func(context.Context, string) (*providers.Entity, *entityprovider.EntityProviderError)); ok { + return returnFunc(ctx, entityID) } - if returnFunc, ok := ret.Get(0).(func(string) *providers.Entity); ok { - r0 = returnFunc(entityID) + if returnFunc, ok := ret.Get(0).(func(context.Context, string) *providers.Entity); ok { + r0 = returnFunc(ctx, entityID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*providers.Entity) } } - if returnFunc, ok := ret.Get(1).(func(string) *entityprovider.EntityProviderError); ok { - r1 = returnFunc(entityID) + if returnFunc, ok := ret.Get(1).(func(context.Context, string) *entityprovider.EntityProviderError); ok { + r1 = returnFunc(ctx, entityID) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*entityprovider.EntityProviderError) @@ -201,19 +202,25 @@ type EntityProviderInterfaceMock_GetEntity_Call struct { } // GetEntity is a helper method to define mock.On call +// - ctx context.Context // - entityID string -func (_e *EntityProviderInterfaceMock_Expecter) GetEntity(entityID any) *EntityProviderInterfaceMock_GetEntity_Call { - return &EntityProviderInterfaceMock_GetEntity_Call{Call: _e.mock.On("GetEntity", entityID)} +func (_e *EntityProviderInterfaceMock_Expecter) GetEntity(ctx any, entityID any) *EntityProviderInterfaceMock_GetEntity_Call { + return &EntityProviderInterfaceMock_GetEntity_Call{Call: _e.mock.On("GetEntity", ctx, entityID)} } -func (_c *EntityProviderInterfaceMock_GetEntity_Call) Run(run func(entityID string)) *EntityProviderInterfaceMock_GetEntity_Call { +func (_c *EntityProviderInterfaceMock_GetEntity_Call) Run(run func(ctx context.Context, entityID string)) *EntityProviderInterfaceMock_GetEntity_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string + var arg0 context.Context if args[0] != nil { - arg0 = args[0].(string) + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) } run( arg0, + arg1, ) }) return _c @@ -224,7 +231,7 @@ func (_c *EntityProviderInterfaceMock_GetEntity_Call) Return(entity *providers.E return _c } -func (_c *EntityProviderInterfaceMock_GetEntity_Call) RunAndReturn(run func(entityID string) (*providers.Entity, *entityprovider.EntityProviderError)) *EntityProviderInterfaceMock_GetEntity_Call { +func (_c *EntityProviderInterfaceMock_GetEntity_Call) RunAndReturn(run func(ctx context.Context, entityID string) (*providers.Entity, *entityprovider.EntityProviderError)) *EntityProviderInterfaceMock_GetEntity_Call { _c.Call.Return(run) return _c } @@ -380,8 +387,8 @@ func (_c *EntityProviderInterfaceMock_GetEntityListCount_Call) RunAndReturn(run } // GetEntityProfile provides a mock function for the type EntityProviderInterfaceMock -func (_mock *EntityProviderInterfaceMock) GetEntityProfile(entityID string) (*providers.Entity, *entityprovider.EntityProviderError) { - ret := _mock.Called(entityID) +func (_mock *EntityProviderInterfaceMock) GetEntityProfile(ctx context.Context, entityID string) (*providers.Entity, *entityprovider.EntityProviderError) { + ret := _mock.Called(ctx, entityID) if len(ret) == 0 { panic("no return value specified for GetEntityProfile") @@ -389,18 +396,18 @@ func (_mock *EntityProviderInterfaceMock) GetEntityProfile(entityID string) (*pr var r0 *providers.Entity var r1 *entityprovider.EntityProviderError - if returnFunc, ok := ret.Get(0).(func(string) (*providers.Entity, *entityprovider.EntityProviderError)); ok { - return returnFunc(entityID) + if returnFunc, ok := ret.Get(0).(func(context.Context, string) (*providers.Entity, *entityprovider.EntityProviderError)); ok { + return returnFunc(ctx, entityID) } - if returnFunc, ok := ret.Get(0).(func(string) *providers.Entity); ok { - r0 = returnFunc(entityID) + if returnFunc, ok := ret.Get(0).(func(context.Context, string) *providers.Entity); ok { + r0 = returnFunc(ctx, entityID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*providers.Entity) } } - if returnFunc, ok := ret.Get(1).(func(string) *entityprovider.EntityProviderError); ok { - r1 = returnFunc(entityID) + if returnFunc, ok := ret.Get(1).(func(context.Context, string) *entityprovider.EntityProviderError); ok { + r1 = returnFunc(ctx, entityID) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*entityprovider.EntityProviderError) @@ -415,19 +422,25 @@ type EntityProviderInterfaceMock_GetEntityProfile_Call struct { } // GetEntityProfile is a helper method to define mock.On call +// - ctx context.Context // - entityID string -func (_e *EntityProviderInterfaceMock_Expecter) GetEntityProfile(entityID any) *EntityProviderInterfaceMock_GetEntityProfile_Call { - return &EntityProviderInterfaceMock_GetEntityProfile_Call{Call: _e.mock.On("GetEntityProfile", entityID)} +func (_e *EntityProviderInterfaceMock_Expecter) GetEntityProfile(ctx any, entityID any) *EntityProviderInterfaceMock_GetEntityProfile_Call { + return &EntityProviderInterfaceMock_GetEntityProfile_Call{Call: _e.mock.On("GetEntityProfile", ctx, entityID)} } -func (_c *EntityProviderInterfaceMock_GetEntityProfile_Call) Run(run func(entityID string)) *EntityProviderInterfaceMock_GetEntityProfile_Call { +func (_c *EntityProviderInterfaceMock_GetEntityProfile_Call) Run(run func(ctx context.Context, entityID string)) *EntityProviderInterfaceMock_GetEntityProfile_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string + var arg0 context.Context if args[0] != nil { - arg0 = args[0].(string) + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) } run( arg0, + arg1, ) }) return _c @@ -438,7 +451,7 @@ func (_c *EntityProviderInterfaceMock_GetEntityProfile_Call) Return(entity *prov return _c } -func (_c *EntityProviderInterfaceMock_GetEntityProfile_Call) RunAndReturn(run func(entityID string) (*providers.Entity, *entityprovider.EntityProviderError)) *EntityProviderInterfaceMock_GetEntityProfile_Call { +func (_c *EntityProviderInterfaceMock_GetEntityProfile_Call) RunAndReturn(run func(ctx context.Context, entityID string) (*providers.Entity, *entityprovider.EntityProviderError)) *EntityProviderInterfaceMock_GetEntityProfile_Call { _c.Call.Return(run) return _c } @@ -514,8 +527,8 @@ func (_c *EntityProviderInterfaceMock_GetLinkedEntities_Call) RunAndReturn(run f } // GetTransitiveEntityGroups provides a mock function for the type EntityProviderInterfaceMock -func (_mock *EntityProviderInterfaceMock) GetTransitiveEntityGroups(entityID string) ([]providers.EntityGroup, *entityprovider.EntityProviderError) { - ret := _mock.Called(entityID) +func (_mock *EntityProviderInterfaceMock) GetTransitiveEntityGroups(ctx context.Context, entityID string) ([]providers.EntityGroup, *entityprovider.EntityProviderError) { + ret := _mock.Called(ctx, entityID) if len(ret) == 0 { panic("no return value specified for GetTransitiveEntityGroups") @@ -523,18 +536,18 @@ func (_mock *EntityProviderInterfaceMock) GetTransitiveEntityGroups(entityID str var r0 []providers.EntityGroup var r1 *entityprovider.EntityProviderError - if returnFunc, ok := ret.Get(0).(func(string) ([]providers.EntityGroup, *entityprovider.EntityProviderError)); ok { - return returnFunc(entityID) + if returnFunc, ok := ret.Get(0).(func(context.Context, string) ([]providers.EntityGroup, *entityprovider.EntityProviderError)); ok { + return returnFunc(ctx, entityID) } - if returnFunc, ok := ret.Get(0).(func(string) []providers.EntityGroup); ok { - r0 = returnFunc(entityID) + if returnFunc, ok := ret.Get(0).(func(context.Context, string) []providers.EntityGroup); ok { + r0 = returnFunc(ctx, entityID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]providers.EntityGroup) } } - if returnFunc, ok := ret.Get(1).(func(string) *entityprovider.EntityProviderError); ok { - r1 = returnFunc(entityID) + if returnFunc, ok := ret.Get(1).(func(context.Context, string) *entityprovider.EntityProviderError); ok { + r1 = returnFunc(ctx, entityID) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*entityprovider.EntityProviderError) @@ -549,19 +562,25 @@ type EntityProviderInterfaceMock_GetTransitiveEntityGroups_Call struct { } // GetTransitiveEntityGroups is a helper method to define mock.On call +// - ctx context.Context // - entityID string -func (_e *EntityProviderInterfaceMock_Expecter) GetTransitiveEntityGroups(entityID any) *EntityProviderInterfaceMock_GetTransitiveEntityGroups_Call { - return &EntityProviderInterfaceMock_GetTransitiveEntityGroups_Call{Call: _e.mock.On("GetTransitiveEntityGroups", entityID)} +func (_e *EntityProviderInterfaceMock_Expecter) GetTransitiveEntityGroups(ctx any, entityID any) *EntityProviderInterfaceMock_GetTransitiveEntityGroups_Call { + return &EntityProviderInterfaceMock_GetTransitiveEntityGroups_Call{Call: _e.mock.On("GetTransitiveEntityGroups", ctx, entityID)} } -func (_c *EntityProviderInterfaceMock_GetTransitiveEntityGroups_Call) Run(run func(entityID string)) *EntityProviderInterfaceMock_GetTransitiveEntityGroups_Call { +func (_c *EntityProviderInterfaceMock_GetTransitiveEntityGroups_Call) Run(run func(ctx context.Context, entityID string)) *EntityProviderInterfaceMock_GetTransitiveEntityGroups_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string + var arg0 context.Context if args[0] != nil { - arg0 = args[0].(string) + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) } run( arg0, + arg1, ) }) return _c @@ -572,14 +591,14 @@ func (_c *EntityProviderInterfaceMock_GetTransitiveEntityGroups_Call) Return(ent return _c } -func (_c *EntityProviderInterfaceMock_GetTransitiveEntityGroups_Call) RunAndReturn(run func(entityID string) ([]providers.EntityGroup, *entityprovider.EntityProviderError)) *EntityProviderInterfaceMock_GetTransitiveEntityGroups_Call { +func (_c *EntityProviderInterfaceMock_GetTransitiveEntityGroups_Call) RunAndReturn(run func(ctx context.Context, entityID string) ([]providers.EntityGroup, *entityprovider.EntityProviderError)) *EntityProviderInterfaceMock_GetTransitiveEntityGroups_Call { _c.Call.Return(run) return _c } // GetTransitiveGroupAncestors provides a mock function for the type EntityProviderInterfaceMock -func (_mock *EntityProviderInterfaceMock) GetTransitiveGroupAncestors(groupID string) ([]string, *entityprovider.EntityProviderError) { - ret := _mock.Called(groupID) +func (_mock *EntityProviderInterfaceMock) GetTransitiveGroupAncestors(ctx context.Context, groupID string) ([]string, *entityprovider.EntityProviderError) { + ret := _mock.Called(ctx, groupID) if len(ret) == 0 { panic("no return value specified for GetTransitiveGroupAncestors") @@ -587,18 +606,18 @@ func (_mock *EntityProviderInterfaceMock) GetTransitiveGroupAncestors(groupID st var r0 []string var r1 *entityprovider.EntityProviderError - if returnFunc, ok := ret.Get(0).(func(string) ([]string, *entityprovider.EntityProviderError)); ok { - return returnFunc(groupID) + if returnFunc, ok := ret.Get(0).(func(context.Context, string) ([]string, *entityprovider.EntityProviderError)); ok { + return returnFunc(ctx, groupID) } - if returnFunc, ok := ret.Get(0).(func(string) []string); ok { - r0 = returnFunc(groupID) + if returnFunc, ok := ret.Get(0).(func(context.Context, string) []string); ok { + r0 = returnFunc(ctx, groupID) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]string) } } - if returnFunc, ok := ret.Get(1).(func(string) *entityprovider.EntityProviderError); ok { - r1 = returnFunc(groupID) + if returnFunc, ok := ret.Get(1).(func(context.Context, string) *entityprovider.EntityProviderError); ok { + r1 = returnFunc(ctx, groupID) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*entityprovider.EntityProviderError) @@ -613,19 +632,25 @@ type EntityProviderInterfaceMock_GetTransitiveGroupAncestors_Call struct { } // GetTransitiveGroupAncestors is a helper method to define mock.On call +// - ctx context.Context // - groupID string -func (_e *EntityProviderInterfaceMock_Expecter) GetTransitiveGroupAncestors(groupID any) *EntityProviderInterfaceMock_GetTransitiveGroupAncestors_Call { - return &EntityProviderInterfaceMock_GetTransitiveGroupAncestors_Call{Call: _e.mock.On("GetTransitiveGroupAncestors", groupID)} +func (_e *EntityProviderInterfaceMock_Expecter) GetTransitiveGroupAncestors(ctx any, groupID any) *EntityProviderInterfaceMock_GetTransitiveGroupAncestors_Call { + return &EntityProviderInterfaceMock_GetTransitiveGroupAncestors_Call{Call: _e.mock.On("GetTransitiveGroupAncestors", ctx, groupID)} } -func (_c *EntityProviderInterfaceMock_GetTransitiveGroupAncestors_Call) Run(run func(groupID string)) *EntityProviderInterfaceMock_GetTransitiveGroupAncestors_Call { +func (_c *EntityProviderInterfaceMock_GetTransitiveGroupAncestors_Call) Run(run func(ctx context.Context, groupID string)) *EntityProviderInterfaceMock_GetTransitiveGroupAncestors_Call { _c.Call.Run(func(args mock.Arguments) { - var arg0 string + var arg0 context.Context if args[0] != nil { - arg0 = args[0].(string) + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) } run( arg0, + arg1, ) }) return _c @@ -636,7 +661,7 @@ func (_c *EntityProviderInterfaceMock_GetTransitiveGroupAncestors_Call) Return(s return _c } -func (_c *EntityProviderInterfaceMock_GetTransitiveGroupAncestors_Call) RunAndReturn(run func(groupID string) ([]string, *entityprovider.EntityProviderError)) *EntityProviderInterfaceMock_GetTransitiveGroupAncestors_Call { +func (_c *EntityProviderInterfaceMock_GetTransitiveGroupAncestors_Call) RunAndReturn(run func(ctx context.Context, groupID string) ([]string, *entityprovider.EntityProviderError)) *EntityProviderInterfaceMock_GetTransitiveGroupAncestors_Call { _c.Call.Return(run) return _c }