From 5c0386db03d8d649cb9808dc3300ab1f98ae29b0 Mon Sep 17 00:00:00 2001 From: Abhishek Sah Date: Wed, 8 Apr 2026 15:58:21 +0530 Subject: [PATCH 1/4] feat: add audit logging to SetOrganizationMemberRole RPC SetOrganizationMemberRole had no audit logging unlike AddMember and RemoveUsers. This adds both structured audit records and event-based audit logging consistent with other org membership operations. Co-Authored-By: Claude Opus 4.6 (1M context) --- core/audit/audit.go | 1 + core/organization/service.go | 39 ++++++++++++++++++++++++++++++++++++ pkg/auditrecord/consts.go | 1 + 3 files changed, 41 insertions(+) diff --git a/core/audit/audit.go b/core/audit/audit.go index 2af240bf8..316dce88f 100644 --- a/core/audit/audit.go +++ b/core/audit/audit.go @@ -80,6 +80,7 @@ const ( OrgDisabledEvent EventName = "app.organization.disabled" OrgMemberCreatedEvent EventName = "app.organization.member.created" OrgMemberDeletedEvent EventName = "app.organization.member.deleted" + OrgMemberRoleSetEvent EventName = "app.organization.member.role.set" OrgKycUpdatedEvent EventName = "app.organization.kyc.updated" ProjectCreatedEvent EventName = "app.project.created" diff --git a/core/organization/service.go b/core/organization/service.go index efaf8b66f..f13f85793 100644 --- a/core/organization/service.go +++ b/core/organization/service.go @@ -393,6 +393,45 @@ func (s Service) SetMemberRole(ctx context.Context, orgID, userID, newRoleID str return err } + // audit logging + org, err := s.repository.GetByID(ctx, orgID) + if err != nil { + return err + } + + usr, err := s.userService.GetByID(ctx, userID) + if err != nil { + return err + } + + _, auditErr := s.auditRecordRepository.Create(ctx, auditrecord.AuditRecord{ + Event: pkgAuditRecord.OrganizationMemberRoleChangedEvent, + Resource: auditrecord.Resource{ + ID: orgID, + Type: pkgAuditRecord.OrganizationType, + Name: org.Title, + }, + Target: &auditrecord.Target{ + ID: userID, + Type: pkgAuditRecord.UserType, + Name: usr.Title, + Metadata: map[string]any{ + "email": usr.Email, + "role_id": newRoleID, + }, + }, + OrgID: orgID, + OccurredAt: time.Now(), + }) + if auditErr != nil { + return auditErr + } + + audit.GetAuditor(ctx, orgID).Log(audit.OrgMemberRoleSetEvent, audit.Target{ + ID: userID, + Type: schema.UserPrincipal, + }) + return nil } diff --git a/pkg/auditrecord/consts.go b/pkg/auditrecord/consts.go index e7185c689..247129ff8 100644 --- a/pkg/auditrecord/consts.go +++ b/pkg/auditrecord/consts.go @@ -36,6 +36,7 @@ const ( OrganizationInvitedEvent Event = "organization.invited" OrganizationMemberAddedEvent Event = "organization.added" OrganizationMemberRemovedEvent Event = "organization.removed" + OrganizationMemberRoleChangedEvent Event = "organization.role_changed" OrganizationInvitationAcceptedEvent Event = "organization.accepted" // KYC Events From 5b80d52941614cc50535ae1c5a424037b5e61b78 Mon Sep 17 00:00:00 2001 From: Abhishek Sah Date: Wed, 8 Apr 2026 16:36:50 +0530 Subject: [PATCH 2/4] fix: resolve gofmt alignment and update test mocks for audit logging Fix gofmt alignment in metadata map literal and update SetMemberRole test cases to mock the new audit record repository and user/org GetByID calls added by audit logging. Co-Authored-By: Claude Opus 4.6 (1M context) --- core/organization/service.go | 4 ++-- core/organization/service_test.go | 34 +++++++++++++++++-------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/core/organization/service.go b/core/organization/service.go index f13f85793..8346667a9 100644 --- a/core/organization/service.go +++ b/core/organization/service.go @@ -416,8 +416,8 @@ func (s Service) SetMemberRole(ctx context.Context, orgID, userID, newRoleID str Type: pkgAuditRecord.UserType, Name: usr.Title, Metadata: map[string]any{ - "email": usr.Email, - "role_id": newRoleID, + "email": usr.Email, + "role_id": newRoleID, }, }, OrgID: orgID, diff --git a/core/organization/service_test.go b/core/organization/service_test.go index dbcd47665..4e035fce9 100644 --- a/core/organization/service_test.go +++ b/core/organization/service_test.go @@ -379,7 +379,7 @@ func TestService_SetMemberRole(t *testing.T) { tests := []struct { name string - setup func(*mocks.Repository, *mocks.UserService, *mocks.RoleService, *mocks.PolicyService) + setup func(*mocks.Repository, *mocks.UserService, *mocks.RoleService, *mocks.PolicyService, *mocks.AuditRecordRepository) orgID string userID string newRoleID string @@ -387,7 +387,7 @@ func TestService_SetMemberRole(t *testing.T) { }{ { name: "should return error if org does not exist", - setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService) { + setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService, _ *mocks.AuditRecordRepository) { repo.EXPECT().GetByID(ctx, orgID).Return(organization.Organization{}, organization.ErrNotExist) }, orgID: orgID, @@ -397,7 +397,7 @@ func TestService_SetMemberRole(t *testing.T) { }, { name: "should return error if org is disabled", - setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService) { + setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService, _ *mocks.AuditRecordRepository) { repo.EXPECT().GetByID(ctx, orgID).Return(organization.Organization{State: organization.Disabled}, nil) }, orgID: orgID, @@ -407,7 +407,7 @@ func TestService_SetMemberRole(t *testing.T) { }, { name: "should return error if user does not exist", - setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService) { + setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService, _ *mocks.AuditRecordRepository) { repo.EXPECT().GetByID(ctx, orgID).Return(organization.Organization{ID: orgID, State: organization.Enabled}, nil) userSvc.EXPECT().GetByID(ctx, userID).Return(user.User{}, user.ErrNotExist) }, @@ -418,7 +418,7 @@ func TestService_SetMemberRole(t *testing.T) { }, { name: "should return error if role does not exist", - setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService) { + setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService, _ *mocks.AuditRecordRepository) { repo.EXPECT().GetByID(ctx, orgID).Return(organization.Organization{ID: orgID, State: organization.Enabled}, nil) userSvc.EXPECT().GetByID(ctx, userID).Return(user.User{ID: userID}, nil) roleSvc.EXPECT().Get(ctx, memberRoleID).Return(role.Role{}, role.ErrNotExist) @@ -430,7 +430,7 @@ func TestService_SetMemberRole(t *testing.T) { }, { name: "should return error if role is not valid for org scope", - setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService) { + setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService, _ *mocks.AuditRecordRepository) { repo.EXPECT().GetByID(ctx, orgID).Return(organization.Organization{ID: orgID, State: organization.Enabled}, nil) userSvc.EXPECT().GetByID(ctx, userID).Return(user.User{ID: userID}, nil) // role exists but has project scope, not org scope @@ -443,7 +443,7 @@ func TestService_SetMemberRole(t *testing.T) { }, { name: "should return error if user is not a member of the org", - setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService) { + setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService, _ *mocks.AuditRecordRepository) { repo.EXPECT().GetByID(ctx, orgID).Return(organization.Organization{ID: orgID, State: organization.Enabled}, nil) userSvc.EXPECT().GetByID(ctx, userID).Return(user.User{ID: userID}, nil) roleSvc.EXPECT().Get(ctx, memberRoleID).Return(role.Role{ID: memberRoleID, Name: "member", Scopes: []string{schema.OrganizationNamespace}}, nil) @@ -461,7 +461,7 @@ func TestService_SetMemberRole(t *testing.T) { }, { name: "should return error if demoting last owner", - setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService) { + setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService, _ *mocks.AuditRecordRepository) { repo.EXPECT().GetByID(ctx, orgID).Return(organization.Organization{ID: orgID, State: organization.Enabled}, nil) userSvc.EXPECT().GetByID(ctx, userID).Return(user.User{ID: userID}, nil) roleSvc.EXPECT().Get(ctx, memberRoleID).Return(role.Role{ID: memberRoleID, Name: "member", Scopes: []string{schema.OrganizationNamespace}}, nil) @@ -486,9 +486,9 @@ func TestService_SetMemberRole(t *testing.T) { }, { name: "should succeed when changing role with multiple owners", - setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService) { - repo.EXPECT().GetByID(ctx, orgID).Return(organization.Organization{ID: orgID, State: organization.Enabled}, nil) - userSvc.EXPECT().GetByID(ctx, userID).Return(user.User{ID: userID}, nil) + setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService, auditRepo *mocks.AuditRecordRepository) { + repo.EXPECT().GetByID(ctx, orgID).Return(organization.Organization{ID: orgID, State: organization.Enabled}, nil).Times(2) + userSvc.EXPECT().GetByID(ctx, userID).Return(user.User{ID: userID}, nil).Times(2) roleSvc.EXPECT().Get(ctx, memberRoleID).Return(role.Role{ID: memberRoleID, Name: "member", Scopes: []string{schema.OrganizationNamespace}}, nil) // get user's existing policies - user is owner policySvc.EXPECT().List(ctx, policy.Filter{ @@ -516,6 +516,8 @@ func TestService_SetMemberRole(t *testing.T) { PrincipalID: userID, PrincipalType: schema.UserPrincipal, }).Return(policy.Policy{}, nil) + // audit logging + auditRepo.EXPECT().Create(ctx, mock.Anything).Return(auditrecord.AuditRecord{}, nil) }, orgID: orgID, userID: userID, @@ -524,9 +526,9 @@ func TestService_SetMemberRole(t *testing.T) { }, { name: "should succeed when promoting to owner", - setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService) { - repo.EXPECT().GetByID(ctx, orgID).Return(organization.Organization{ID: orgID, State: organization.Enabled}, nil) - userSvc.EXPECT().GetByID(ctx, userID).Return(user.User{ID: userID}, nil) + setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService, auditRepo *mocks.AuditRecordRepository) { + repo.EXPECT().GetByID(ctx, orgID).Return(organization.Organization{ID: orgID, State: organization.Enabled}, nil).Times(2) + userSvc.EXPECT().GetByID(ctx, userID).Return(user.User{ID: userID}, nil).Times(2) roleSvc.EXPECT().Get(ctx, ownerRoleID).Return(role.Role{ID: ownerRoleID, Name: schema.RoleOrganizationOwner, Scopes: []string{schema.OrganizationNamespace}}, nil) // get user's existing policies - user is member policySvc.EXPECT().List(ctx, policy.Filter{ @@ -547,6 +549,8 @@ func TestService_SetMemberRole(t *testing.T) { PrincipalID: userID, PrincipalType: schema.UserPrincipal, }).Return(policy.Policy{}, nil) + // audit logging + auditRepo.EXPECT().Create(ctx, mock.Anything).Return(auditrecord.AuditRecord{}, nil) }, orgID: orgID, userID: userID, @@ -567,7 +571,7 @@ func TestService_SetMemberRole(t *testing.T) { mockRoleSvc := mocks.NewRoleService(t) if tt.setup != nil { - tt.setup(mockRepo, mockUserSvc, mockRoleSvc, mockPolicySvc) + tt.setup(mockRepo, mockUserSvc, mockRoleSvc, mockPolicySvc, mockAuditRecordRepo) } svc := organization.NewService(mockRepo, mockRelationSvc, mockUserSvc, mockAuthnSvc, mockPolicySvc, mockPrefSvc, mockAuditRecordRepo, mockRoleSvc) From 63a46750af06532f09e623e4fb928cddec62091c Mon Sep 17 00:00:00 2001 From: Abhishek Sah Date: Wed, 8 Apr 2026 16:45:20 +0530 Subject: [PATCH 3/4] fix: harden audit test assertions with specific field matching Replace mock.Anything with mock.MatchedBy to assert event type, resource ID, target ID, email, role_id, and org_id in audit records. Populate user mock with title and email for realistic assertions. Co-Authored-By: Claude Opus 4.6 (1M context) --- core/organization/service_test.go | 37 +++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/core/organization/service_test.go b/core/organization/service_test.go index 4e035fce9..ede2ae8a1 100644 --- a/core/organization/service_test.go +++ b/core/organization/service_test.go @@ -17,6 +17,7 @@ import ( "github.com/raystack/frontier/core/user" pat "github.com/raystack/frontier/core/userpat/models" "github.com/raystack/frontier/internal/bootstrap/schema" + pkgAuditRecord "github.com/raystack/frontier/pkg/auditrecord" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) @@ -488,7 +489,11 @@ func TestService_SetMemberRole(t *testing.T) { name: "should succeed when changing role with multiple owners", setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService, auditRepo *mocks.AuditRecordRepository) { repo.EXPECT().GetByID(ctx, orgID).Return(organization.Organization{ID: orgID, State: organization.Enabled}, nil).Times(2) - userSvc.EXPECT().GetByID(ctx, userID).Return(user.User{ID: userID}, nil).Times(2) + userSvc.EXPECT().GetByID(ctx, userID).Return(user.User{ + ID: userID, + Title: "test-user", + Email: "test-user@acme.dev", + }, nil).Times(2) roleSvc.EXPECT().Get(ctx, memberRoleID).Return(role.Role{ID: memberRoleID, Name: "member", Scopes: []string{schema.OrganizationNamespace}}, nil) // get user's existing policies - user is owner policySvc.EXPECT().List(ctx, policy.Filter{ @@ -517,7 +522,17 @@ func TestService_SetMemberRole(t *testing.T) { PrincipalType: schema.UserPrincipal, }).Return(policy.Policy{}, nil) // audit logging - auditRepo.EXPECT().Create(ctx, mock.Anything).Return(auditrecord.AuditRecord{}, nil) + auditRepo.EXPECT().Create(ctx, mock.MatchedBy(func(ar auditrecord.AuditRecord) bool { + if ar.Target == nil { + return false + } + return ar.Event == pkgAuditRecord.OrganizationMemberRoleChangedEvent && + ar.Resource.ID == orgID && + ar.Target.ID == userID && + ar.Target.Metadata["email"] == "test-user@acme.dev" && + ar.Target.Metadata["role_id"] == memberRoleID && + ar.OrgID == orgID + })).Return(auditrecord.AuditRecord{}, nil).Once() }, orgID: orgID, userID: userID, @@ -528,7 +543,11 @@ func TestService_SetMemberRole(t *testing.T) { name: "should succeed when promoting to owner", setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService, auditRepo *mocks.AuditRecordRepository) { repo.EXPECT().GetByID(ctx, orgID).Return(organization.Organization{ID: orgID, State: organization.Enabled}, nil).Times(2) - userSvc.EXPECT().GetByID(ctx, userID).Return(user.User{ID: userID}, nil).Times(2) + userSvc.EXPECT().GetByID(ctx, userID).Return(user.User{ + ID: userID, + Title: "test-user", + Email: "test-user@acme.dev", + }, nil).Times(2) roleSvc.EXPECT().Get(ctx, ownerRoleID).Return(role.Role{ID: ownerRoleID, Name: schema.RoleOrganizationOwner, Scopes: []string{schema.OrganizationNamespace}}, nil) // get user's existing policies - user is member policySvc.EXPECT().List(ctx, policy.Filter{ @@ -550,7 +569,17 @@ func TestService_SetMemberRole(t *testing.T) { PrincipalType: schema.UserPrincipal, }).Return(policy.Policy{}, nil) // audit logging - auditRepo.EXPECT().Create(ctx, mock.Anything).Return(auditrecord.AuditRecord{}, nil) + auditRepo.EXPECT().Create(ctx, mock.MatchedBy(func(ar auditrecord.AuditRecord) bool { + if ar.Target == nil { + return false + } + return ar.Event == pkgAuditRecord.OrganizationMemberRoleChangedEvent && + ar.Resource.ID == orgID && + ar.Target.ID == userID && + ar.Target.Metadata["email"] == "test-user@acme.dev" && + ar.Target.Metadata["role_id"] == ownerRoleID && + ar.OrgID == orgID + })).Return(auditrecord.AuditRecord{}, nil).Once() }, orgID: orgID, userID: userID, From 35f5b81c28ecaeb79e382784314e5d0790ef5ee3 Mon Sep 17 00:00:00 2001 From: Abhishek Sah Date: Thu, 9 Apr 2026 08:46:01 +0530 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20address=20review=20feedback=20?= =?UTF-8?q?=E2=80=94=20use=20LogWithAttrs,=20align=20event=20naming,=20har?= =?UTF-8?q?den=20test=20assertions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use LogWithAttrs with role_id attribute for richer event logging - Rename event to app.organization.member.role_changed to match structured audit record naming convention - Align project event from app.project.member.role.set to app.project.member.role_changed for consistency - Add org Name/Title to mock and verify Resource.Name in audit assertions Co-Authored-By: Claude Opus 4.6 (1M context) --- core/audit/audit.go | 28 +++++++++++++------------- core/organization/service.go | 4 +++- core/organization/service_test.go | 16 +++++++++++++-- internal/api/v1beta1connect/project.go | 2 +- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/core/audit/audit.go b/core/audit/audit.go index 316dce88f..c0ac6b898 100644 --- a/core/audit/audit.go +++ b/core/audit/audit.go @@ -74,20 +74,20 @@ const ( PolicyCreatedEvent EventName = "app.policy.created" PolicyDeletedEvent EventName = "app.policy.deleted" - OrgCreatedEvent EventName = "app.organization.created" - OrgUpdatedEvent EventName = "app.organization.updated" - OrgDeletedEvent EventName = "app.organization.deleted" - OrgDisabledEvent EventName = "app.organization.disabled" - OrgMemberCreatedEvent EventName = "app.organization.member.created" - OrgMemberDeletedEvent EventName = "app.organization.member.deleted" - OrgMemberRoleSetEvent EventName = "app.organization.member.role.set" - OrgKycUpdatedEvent EventName = "app.organization.kyc.updated" - - ProjectCreatedEvent EventName = "app.project.created" - ProjectUpdatedEvent EventName = "app.project.updated" - ProjectDeletedEvent EventName = "app.project.deleted" - ProjectMemberRoleSetEvent EventName = "app.project.member.role.set" - ProjectMemberRemovedEvent EventName = "app.project.member.removed" + OrgCreatedEvent EventName = "app.organization.created" + OrgUpdatedEvent EventName = "app.organization.updated" + OrgDeletedEvent EventName = "app.organization.deleted" + OrgDisabledEvent EventName = "app.organization.disabled" + OrgMemberCreatedEvent EventName = "app.organization.member.created" + OrgMemberDeletedEvent EventName = "app.organization.member.deleted" + OrgMemberRoleChangedEvent EventName = "app.organization.member.role_changed" + OrgKycUpdatedEvent EventName = "app.organization.kyc.updated" + + ProjectCreatedEvent EventName = "app.project.created" + ProjectUpdatedEvent EventName = "app.project.updated" + ProjectDeletedEvent EventName = "app.project.deleted" + ProjectMemberRoleChangedEvent EventName = "app.project.member.role_changed" + ProjectMemberRemovedEvent EventName = "app.project.member.removed" ResourceCreatedEvent EventName = "app.resource.created" ResourceUpdatedEvent EventName = "app.resource.updated" diff --git a/core/organization/service.go b/core/organization/service.go index 8346667a9..d5c54f61d 100644 --- a/core/organization/service.go +++ b/core/organization/service.go @@ -427,9 +427,11 @@ func (s Service) SetMemberRole(ctx context.Context, orgID, userID, newRoleID str return auditErr } - audit.GetAuditor(ctx, orgID).Log(audit.OrgMemberRoleSetEvent, audit.Target{ + audit.GetAuditor(ctx, orgID).LogWithAttrs(audit.OrgMemberRoleChangedEvent, audit.Target{ ID: userID, Type: schema.UserPrincipal, + }, map[string]string{ + "role_id": newRoleID, }) return nil diff --git a/core/organization/service_test.go b/core/organization/service_test.go index ede2ae8a1..0c564e0eb 100644 --- a/core/organization/service_test.go +++ b/core/organization/service_test.go @@ -488,7 +488,12 @@ func TestService_SetMemberRole(t *testing.T) { { name: "should succeed when changing role with multiple owners", setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService, auditRepo *mocks.AuditRecordRepository) { - repo.EXPECT().GetByID(ctx, orgID).Return(organization.Organization{ID: orgID, State: organization.Enabled}, nil).Times(2) + repo.EXPECT().GetByID(ctx, orgID).Return(organization.Organization{ + ID: orgID, + Name: "test-org", + Title: "Test Organization", + State: organization.Enabled, + }, nil).Times(2) userSvc.EXPECT().GetByID(ctx, userID).Return(user.User{ ID: userID, Title: "test-user", @@ -528,6 +533,7 @@ func TestService_SetMemberRole(t *testing.T) { } return ar.Event == pkgAuditRecord.OrganizationMemberRoleChangedEvent && ar.Resource.ID == orgID && + ar.Resource.Name == "Test Organization" && ar.Target.ID == userID && ar.Target.Metadata["email"] == "test-user@acme.dev" && ar.Target.Metadata["role_id"] == memberRoleID && @@ -542,7 +548,12 @@ func TestService_SetMemberRole(t *testing.T) { { name: "should succeed when promoting to owner", setup: func(repo *mocks.Repository, userSvc *mocks.UserService, roleSvc *mocks.RoleService, policySvc *mocks.PolicyService, auditRepo *mocks.AuditRecordRepository) { - repo.EXPECT().GetByID(ctx, orgID).Return(organization.Organization{ID: orgID, State: organization.Enabled}, nil).Times(2) + repo.EXPECT().GetByID(ctx, orgID).Return(organization.Organization{ + ID: orgID, + Name: "test-org", + Title: "Test Organization", + State: organization.Enabled, + }, nil).Times(2) userSvc.EXPECT().GetByID(ctx, userID).Return(user.User{ ID: userID, Title: "test-user", @@ -575,6 +586,7 @@ func TestService_SetMemberRole(t *testing.T) { } return ar.Event == pkgAuditRecord.OrganizationMemberRoleChangedEvent && ar.Resource.ID == orgID && + ar.Resource.Name == "Test Organization" && ar.Target.ID == userID && ar.Target.Metadata["email"] == "test-user@acme.dev" && ar.Target.Metadata["role_id"] == ownerRoleID && diff --git a/internal/api/v1beta1connect/project.go b/internal/api/v1beta1connect/project.go index 8ccd0dc89..93c45a895 100644 --- a/internal/api/v1beta1connect/project.go +++ b/internal/api/v1beta1connect/project.go @@ -401,7 +401,7 @@ func (h *ConnectHandler) SetProjectMemberRole(ctx context.Context, request *conn } } - audit.GetAuditor(ctx, "").LogWithAttrs(audit.ProjectMemberRoleSetEvent, audit.ProjectTarget(projectID), map[string]string{ + audit.GetAuditor(ctx, "").LogWithAttrs(audit.ProjectMemberRoleChangedEvent, audit.ProjectTarget(projectID), map[string]string{ "principal_id": principalID, "principal_type": principalType, "role_id": roleID,