diff --git a/management/server/activity/codes.go b/management/server/activity/codes.go index 5c5989f84..2e3be1ef5 100644 --- a/management/server/activity/codes.go +++ b/management/server/activity/codes.go @@ -179,6 +179,7 @@ const ( PeerIPUpdated Activity = 88 UserApproved Activity = 89 UserRejected Activity = 90 + UserCreated Activity = 91 AccountDeleted Activity = 99999 ) @@ -288,6 +289,7 @@ var activityMap = map[Activity]Code{ PeerIPUpdated: {"Peer IP updated", "peer.ip.update"}, UserApproved: {"User approved", "user.approve"}, UserRejected: {"User rejected", "user.reject"}, + UserCreated: {"User created", "user.create"}, } // StringCode returns a string code of the activity diff --git a/management/server/user.go b/management/server/user.go index 6b8bcbcad..cefc4d1a5 100644 --- a/management/server/user.go +++ b/management/server/user.go @@ -596,9 +596,15 @@ func (am *DefaultAccountManager) SaveOrAddUsers(ctx context.Context, accountID, } // prepareUserUpdateEvents prepares a list user update events based on the changes between the old and new user data. -func (am *DefaultAccountManager) prepareUserUpdateEvents(ctx context.Context, accountID string, initiatorUserID string, oldUser, newUser *types.User, transferredOwnerRole bool, removedGroupIDs, addedGroupIDs []string, tx store.Store) []func() { +func (am *DefaultAccountManager) prepareUserUpdateEvents(ctx context.Context, accountID string, initiatorUserID string, oldUser, newUser *types.User, transferredOwnerRole bool, isNewUser bool, removedGroupIDs, addedGroupIDs []string, tx store.Store) []func() { var eventsToStore []func() + if isNewUser { + eventsToStore = append(eventsToStore, func() { + am.StoreEvent(ctx, initiatorUserID, newUser.Id, accountID, activity.UserCreated, nil) + }) + } + if oldUser.IsBlocked() != newUser.IsBlocked() { if newUser.IsBlocked() { eventsToStore = append(eventsToStore, func() { @@ -661,7 +667,7 @@ func (am *DefaultAccountManager) processUserUpdate(ctx context.Context, transact return false, nil, nil, nil, status.Errorf(status.InvalidArgument, "provided user update is nil") } - oldUser, err := getUserOrCreateIfNotExists(ctx, transaction, accountID, update, addIfNotExists) + oldUser, isNewUser, err := getUserOrCreateIfNotExists(ctx, transaction, accountID, update, addIfNotExists) if err != nil { return false, nil, nil, nil, err } @@ -716,30 +722,30 @@ func (am *DefaultAccountManager) processUserUpdate(ctx context.Context, transact } updateAccountPeers := len(userPeers) > 0 - userEventsToAdd := am.prepareUserUpdateEvents(ctx, updatedUser.AccountID, initiatorUserId, oldUser, updatedUser, transferredOwnerRole, removedGroups, addedGroups, transaction) + userEventsToAdd := am.prepareUserUpdateEvents(ctx, updatedUser.AccountID, initiatorUserId, oldUser, updatedUser, transferredOwnerRole, isNewUser, removedGroups, addedGroups, transaction) return updateAccountPeers, updatedUser, peersToExpire, userEventsToAdd, nil } // getUserOrCreateIfNotExists retrieves the existing user or creates a new one if it doesn't exist. -func getUserOrCreateIfNotExists(ctx context.Context, transaction store.Store, accountID string, update *types.User, addIfNotExists bool) (*types.User, error) { +func getUserOrCreateIfNotExists(ctx context.Context, transaction store.Store, accountID string, update *types.User, addIfNotExists bool) (*types.User, bool, error) { existingUser, err := transaction.GetUserByUserID(ctx, store.LockingStrengthNone, update.Id) if err != nil { if sErr, ok := status.FromError(err); ok && sErr.Type() == status.NotFound { if !addIfNotExists { - return nil, status.Errorf(status.NotFound, "user to update doesn't exist: %s", update.Id) + return nil, false, status.Errorf(status.NotFound, "user to update doesn't exist: %s", update.Id) } update.AccountID = accountID - return update, nil // use all fields from update if addIfNotExists is true + return update, true, nil // use all fields from update if addIfNotExists is true } - return nil, err + return nil, false, err } if existingUser.AccountID != accountID { - return nil, status.Errorf(status.InvalidArgument, "user account ID mismatch") + return nil, false, status.Errorf(status.InvalidArgument, "user account ID mismatch") } - return existingUser, nil + return existingUser, false, nil } func handleOwnerRoleTransfer(ctx context.Context, transaction store.Store, initiatorUser, update *types.User) (bool, error) {