Export account manager events store (#1295)

* Expose account manager StoreEvent to integrations

* Add account manager StoreEvent mock
This commit is contained in:
Bethuel Mmbaga 2023-11-08 13:35:37 +03:00 committed by GitHub
parent 9f7e13fc87
commit 89e8540531
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 58 additions and 48 deletions

View File

@ -97,6 +97,7 @@ type AccountManager interface {
DeleteNameServerGroup(accountID, nsGroupID, userID string) error
ListNameServerGroups(accountID string) ([]*nbdns.NameServerGroup, error)
GetDNSDomain() string
StoreEvent(initiatorID, targetID, accountID string, activityID activity.Activity, meta map[string]any)
GetEvents(accountID, userID string) ([]*activity.Event, error)
GetDNSSettings(accountID string, userID string) (*DNSSettings, error)
SaveDNSSettings(accountID string, userID string, dnsSettingsToSave *DNSSettings) error
@ -873,11 +874,11 @@ func (am *DefaultAccountManager) UpdateAccountSettings(accountID, userID string,
} else {
am.checkAndSchedulePeerLoginExpiration(account)
}
am.storeEvent(userID, accountID, accountID, event, nil)
am.StoreEvent(userID, accountID, accountID, event, nil)
}
if oldSettings.PeerLoginExpiration != newSettings.PeerLoginExpiration {
am.storeEvent(userID, accountID, accountID, activity.AccountPeerLoginExpirationDurationUpdated, nil)
am.StoreEvent(userID, accountID, accountID, activity.AccountPeerLoginExpirationDurationUpdated, nil)
am.checkAndSchedulePeerLoginExpiration(account)
}
@ -939,7 +940,7 @@ func (am *DefaultAccountManager) newAccount(userID, domain string) (*Account, er
continue
} else if statusErr.Type() == status.NotFound {
newAccount := newAccountWithId(accountId, userID, domain)
am.storeEvent(userID, newAccount.Id, accountId, activity.AccountCreated, nil)
am.StoreEvent(userID, newAccount.Id, accountId, activity.AccountCreated, nil)
return newAccount, nil
} else {
return nil, err
@ -1280,7 +1281,7 @@ func (am *DefaultAccountManager) handleNewUserAccount(domainAcc *Account, claims
return nil, err
}
am.storeEvent(claims.UserId, claims.UserId, account.Id, activity.UserJoined, nil)
am.StoreEvent(claims.UserId, claims.UserId, account.Id, activity.UserJoined, nil)
return account, nil
}
@ -1313,7 +1314,7 @@ func (am *DefaultAccountManager) redeemInvite(account *Account, userID string) e
return
}
log.Debugf("user %s of account %s redeemed invite", user.ID, account.Id)
am.storeEvent(userID, userID, account.Id, activity.UserJoined, nil)
am.StoreEvent(userID, userID, account.Id, activity.UserJoined, nil)
}()
}
@ -1463,7 +1464,7 @@ func (am *DefaultAccountManager) GetAccountFromToken(claims jwtclaims.Authorizat
am.updateAccountPeers(account)
for _, g := range addNewGroups {
if group := account.GetGroup(g); group != nil {
am.storeEvent(user.Id, user.Id, account.Id, activity.GroupAddedToUser,
am.StoreEvent(user.Id, user.Id, account.Id, activity.GroupAddedToUser,
map[string]any{
"group": group.Name,
"group_id": group.ID,
@ -1473,7 +1474,7 @@ func (am *DefaultAccountManager) GetAccountFromToken(claims jwtclaims.Authorizat
}
for _, g := range removeOldGroups {
if group := account.GetGroup(g); group != nil {
am.storeEvent(user.Id, user.Id, account.Id, activity.GroupRemovedFromUser,
am.StoreEvent(user.Id, user.Id, account.Id, activity.GroupRemovedFromUser,
map[string]any{
"group": group.Name,
"group_id": group.ID,

View File

@ -96,14 +96,14 @@ func (am *DefaultAccountManager) SaveDNSSettings(accountID string, userID string
for _, id := range addedGroups {
group := account.GetGroup(id)
meta := map[string]any{"group": group.Name, "group_id": group.ID}
am.storeEvent(userID, accountID, accountID, activity.GroupAddedToDisabledManagementGroups, meta)
am.StoreEvent(userID, accountID, accountID, activity.GroupAddedToDisabledManagementGroups, meta)
}
removedGroups := difference(oldSettings.DisabledManagementGroups, dnsSettingsToSave.DisabledManagementGroups)
for _, id := range removedGroups {
group := account.GetGroup(id)
meta := map[string]any{"group": group.Name, "group_id": group.ID}
am.storeEvent(userID, accountID, accountID, activity.GroupRemovedFromDisabledManagementGroups, meta)
am.StoreEvent(userID, accountID, accountID, activity.GroupRemovedFromDisabledManagementGroups, meta)
}
am.updateAccountPeers(account)

View File

@ -36,7 +36,7 @@ func (am *DefaultAccountManager) GetEvents(accountID, userID string) ([]*activit
return filtered, nil
}
func (am *DefaultAccountManager) storeEvent(initiatorID, targetID, accountID string, activityID activity.Activity,
func (am *DefaultAccountManager) StoreEvent(initiatorID, targetID, accountID string, activityID activity.Activity,
meta map[string]any) {
go func() {

View File

@ -101,7 +101,7 @@ func (am *DefaultAccountManager) SaveGroup(accountID, userID string, newGroup *G
removedPeers = difference(oldGroup.Peers, newGroup.Peers)
} else {
addedPeers = append(addedPeers, newGroup.Peers...)
am.storeEvent(userID, newGroup.ID, accountID, activity.GroupCreated, newGroup.EventMeta())
am.StoreEvent(userID, newGroup.ID, accountID, activity.GroupCreated, newGroup.EventMeta())
}
for _, p := range addedPeers {
@ -110,7 +110,7 @@ func (am *DefaultAccountManager) SaveGroup(accountID, userID string, newGroup *G
log.Errorf("peer %s not found under account %s while saving group", p, accountID)
continue
}
am.storeEvent(userID, peer.ID, accountID, activity.GroupAddedToPeer,
am.StoreEvent(userID, peer.ID, accountID, activity.GroupAddedToPeer,
map[string]any{
"group": newGroup.Name, "group_id": newGroup.ID, "peer_ip": peer.IP.String(),
"peer_fqdn": peer.FQDN(am.GetDNSDomain()),
@ -123,7 +123,7 @@ func (am *DefaultAccountManager) SaveGroup(accountID, userID string, newGroup *G
log.Errorf("peer %s not found under account %s while saving group", p, accountID)
continue
}
am.storeEvent(userID, peer.ID, accountID, activity.GroupRemovedFromPeer,
am.StoreEvent(userID, peer.ID, accountID, activity.GroupRemovedFromPeer,
map[string]any{
"group": newGroup.Name, "group_id": newGroup.ID, "peer_ip": peer.IP.String(),
"peer_fqdn": peer.FQDN(am.GetDNSDomain()),
@ -241,7 +241,7 @@ func (am *DefaultAccountManager) DeleteGroup(accountId, userId, groupID string)
return err
}
am.storeEvent(userId, groupID, accountId, activity.GroupDeleted, g.EventMeta())
am.StoreEvent(userId, groupID, accountId, activity.GroupDeleted, g.EventMeta())
am.updateAccountPeers(account)

View File

@ -67,6 +67,7 @@ type MockAccountManager struct {
CreateUserFunc func(accountID, userID string, key *server.UserInfo) (*server.UserInfo, error)
GetAccountFromTokenFunc func(claims jwtclaims.AuthorizationClaims) (*server.Account, *server.User, error)
GetDNSDomainFunc func() string
StoreEventFunc func(initiatorID, targetID, accountID string, activityID activity.Activity, meta map[string]any)
GetEventsFunc func(accountID, userID string) ([]*activity.Event, error)
GetDNSSettingsFunc func(accountID, userID string) (*server.DNSSettings, error)
SaveDNSSettingsFunc func(accountID, userID string, dnsSettingsToSave *server.DNSSettings) error
@ -592,3 +593,10 @@ func (am *MockAccountManager) GetAllConnectedPeers() (map[string]struct{}, error
}
return nil, status.Errorf(codes.Unimplemented, "method GetAllConnectedPeers is not implemented")
}
// StoreEvent mocks StoreEvent of the AccountManager interface
func (am *MockAccountManager) StoreEvent(initiatorID, targetID, accountID string, activityID activity.Activity, meta map[string]any) {
if am.StoreEventFunc != nil {
am.StoreEventFunc(initiatorID, targetID, accountID, activityID, meta)
}
}

View File

@ -76,7 +76,7 @@ func (am *DefaultAccountManager) CreateNameServerGroup(accountID string, name, d
am.updateAccountPeers(account)
am.storeEvent(userID, newNSGroup.ID, accountID, activity.NameserverGroupCreated, newNSGroup.EventMeta())
am.StoreEvent(userID, newNSGroup.ID, accountID, activity.NameserverGroupCreated, newNSGroup.EventMeta())
return newNSGroup.Copy(), nil
}
@ -111,7 +111,7 @@ func (am *DefaultAccountManager) SaveNameServerGroup(accountID, userID string, n
am.updateAccountPeers(account)
am.storeEvent(userID, nsGroupToSave.ID, accountID, activity.NameserverGroupUpdated, nsGroupToSave.EventMeta())
am.StoreEvent(userID, nsGroupToSave.ID, accountID, activity.NameserverGroupUpdated, nsGroupToSave.EventMeta())
return nil
}
@ -141,7 +141,7 @@ func (am *DefaultAccountManager) DeleteNameServerGroup(accountID, nsGroupID, use
am.updateAccountPeers(account)
am.storeEvent(userID, nsGroup.ID, accountID, activity.NameserverGroupDeleted, nsGroup.EventMeta())
am.StoreEvent(userID, nsGroup.ID, accountID, activity.NameserverGroupDeleted, nsGroup.EventMeta())
return nil
}

View File

@ -310,7 +310,7 @@ func (am *DefaultAccountManager) UpdatePeer(accountID, userID string, update *Pe
if !update.SSHEnabled {
event = activity.PeerSSHDisabled
}
am.storeEvent(userID, peer.IP.String(), accountID, event, peer.EventMeta(am.GetDNSDomain()))
am.StoreEvent(userID, peer.IP.String(), accountID, event, peer.EventMeta(am.GetDNSDomain()))
}
if peer.Name != update.Name {
@ -325,7 +325,7 @@ func (am *DefaultAccountManager) UpdatePeer(accountID, userID string, update *Pe
peer.DNSLabel = newLabel
am.storeEvent(userID, peer.ID, accountID, activity.PeerRenamed, peer.EventMeta(am.GetDNSDomain()))
am.StoreEvent(userID, peer.ID, accountID, activity.PeerRenamed, peer.EventMeta(am.GetDNSDomain()))
}
if peer.LoginExpirationEnabled != update.LoginExpirationEnabled {
@ -340,7 +340,7 @@ func (am *DefaultAccountManager) UpdatePeer(accountID, userID string, update *Pe
if !update.LoginExpirationEnabled {
event = activity.PeerLoginExpirationDisabled
}
am.storeEvent(userID, peer.IP.String(), accountID, event, peer.EventMeta(am.GetDNSDomain()))
am.StoreEvent(userID, peer.IP.String(), accountID, event, peer.EventMeta(am.GetDNSDomain()))
if peer.AddedWithSSOLogin() && peer.LoginExpirationEnabled && account.Settings.PeerLoginExpirationEnabled {
am.checkAndSchedulePeerLoginExpiration(account)
@ -394,7 +394,7 @@ func (am *DefaultAccountManager) deletePeers(account *Account, peerIDs []string,
},
})
am.peersUpdateManager.CloseChannel(peer.ID)
am.storeEvent(userID, peer.ID, account.Id, activity.PeerRemovedByUser, peer.EventMeta(am.GetDNSDomain()))
am.StoreEvent(userID, peer.ID, account.Id, activity.PeerRemovedByUser, peer.EventMeta(am.GetDNSDomain()))
}
return nil
@ -590,7 +590,7 @@ func (am *DefaultAccountManager) AddPeer(setupKey, userID string, peer *Peer) (*
opEvent.TargetID = newPeer.ID
opEvent.Meta = newPeer.EventMeta(am.GetDNSDomain())
am.storeEvent(opEvent.InitiatorID, opEvent.TargetID, opEvent.AccountID, opEvent.Activity, opEvent.Meta)
am.StoreEvent(opEvent.InitiatorID, opEvent.TargetID, opEvent.AccountID, opEvent.Activity, opEvent.Meta)
am.updateAccountPeers(account)
@ -686,7 +686,7 @@ func (am *DefaultAccountManager) LoginPeer(login PeerLogin) (*Peer, *NetworkMap,
updateRemotePeers = true
shouldStoreAccount = true
am.storeEvent(login.UserID, peer.ID, account.Id, activity.UserLoggedInPeer, peer.EventMeta(am.GetDNSDomain()))
am.StoreEvent(login.UserID, peer.ID, account.Id, activity.UserLoggedInPeer, peer.EventMeta(am.GetDNSDomain()))
}
peer, updated := updatePeerMeta(peer, login.Meta, account)

View File

@ -353,7 +353,7 @@ func (am *DefaultAccountManager) SavePolicy(accountID, userID string, policy *Po
if exists {
action = activity.PolicyUpdated
}
am.storeEvent(userID, policy.ID, accountID, action, policy.EventMeta())
am.StoreEvent(userID, policy.ID, accountID, action, policy.EventMeta())
am.updateAccountPeers(account)
@ -380,7 +380,7 @@ func (am *DefaultAccountManager) DeletePolicy(accountID, policyID, userID string
return err
}
am.storeEvent(userID, policy.ID, accountID, activity.PolicyRemoved, policy.EventMeta())
am.StoreEvent(userID, policy.ID, accountID, activity.PolicyRemoved, policy.EventMeta())
am.updateAccountPeers(account)

View File

@ -4,11 +4,12 @@ import (
"net/netip"
"unicode/utf8"
"github.com/rs/xid"
"github.com/netbirdio/netbird/management/proto"
"github.com/netbirdio/netbird/management/server/activity"
"github.com/netbirdio/netbird/management/server/status"
"github.com/netbirdio/netbird/route"
"github.com/rs/xid"
)
// GetRoute gets a route object from account and route IDs
@ -186,7 +187,7 @@ func (am *DefaultAccountManager) CreateRoute(accountID, network, peerID string,
am.updateAccountPeers(account)
am.storeEvent(userID, newRoute.ID, accountID, activity.RouteCreated, newRoute.EventMeta())
am.StoreEvent(userID, newRoute.ID, accountID, activity.RouteCreated, newRoute.EventMeta())
return &newRoute, nil
}
@ -247,7 +248,7 @@ func (am *DefaultAccountManager) SaveRoute(accountID, userID string, routeToSave
am.updateAccountPeers(account)
am.storeEvent(userID, routeToSave.ID, accountID, activity.RouteUpdated, routeToSave.EventMeta())
am.StoreEvent(userID, routeToSave.ID, accountID, activity.RouteUpdated, routeToSave.EventMeta())
return nil
}
@ -273,7 +274,7 @@ func (am *DefaultAccountManager) DeleteRoute(accountID, routeID, userID string)
return err
}
am.storeEvent(userID, routy.ID, accountID, activity.RouteRemoved, routy.EventMeta())
am.StoreEvent(userID, routy.ID, accountID, activity.RouteRemoved, routy.EventMeta())
am.updateAccountPeers(account)

View File

@ -235,12 +235,12 @@ func (am *DefaultAccountManager) CreateSetupKey(accountID string, keyName string
return nil, status.Errorf(status.Internal, "failed adding account key")
}
am.storeEvent(userID, setupKey.Id, accountID, activity.SetupKeyCreated, setupKey.EventMeta())
am.StoreEvent(userID, setupKey.Id, accountID, activity.SetupKeyCreated, setupKey.EventMeta())
for _, g := range setupKey.AutoGroups {
group := account.GetGroup(g)
if group != nil {
am.storeEvent(userID, setupKey.Id, accountID, activity.GroupAddedToSetupKey,
am.StoreEvent(userID, setupKey.Id, accountID, activity.GroupAddedToSetupKey,
map[string]any{"group": group.Name, "group_id": group.ID, "setupkey": setupKey.Name})
} else {
log.Errorf("group %s not found while saving setup key activity event of account %s", g, account.Id)
@ -292,7 +292,7 @@ func (am *DefaultAccountManager) SaveSetupKey(accountID string, keyToSave *Setup
}
if !oldKey.Revoked && newKey.Revoked {
am.storeEvent(userID, newKey.Id, accountID, activity.SetupKeyRevoked, newKey.EventMeta())
am.StoreEvent(userID, newKey.Id, accountID, activity.SetupKeyRevoked, newKey.EventMeta())
}
defer func() {
@ -301,7 +301,7 @@ func (am *DefaultAccountManager) SaveSetupKey(accountID string, keyToSave *Setup
for _, g := range removedGroups {
group := account.GetGroup(g)
if group != nil {
am.storeEvent(userID, oldKey.Id, accountID, activity.GroupRemovedFromSetupKey,
am.StoreEvent(userID, oldKey.Id, accountID, activity.GroupRemovedFromSetupKey,
map[string]any{"group": group.Name, "group_id": group.ID, "setupkey": newKey.Name})
} else {
log.Errorf("group %s not found while saving setup key activity event of account %s", g, account.Id)
@ -312,7 +312,7 @@ func (am *DefaultAccountManager) SaveSetupKey(accountID string, keyToSave *Setup
for _, g := range addedGroups {
group := account.GetGroup(g)
if group != nil {
am.storeEvent(userID, oldKey.Id, accountID, activity.GroupAddedToSetupKey,
am.StoreEvent(userID, oldKey.Id, accountID, activity.GroupAddedToSetupKey,
map[string]any{"group": group.Name, "group_id": group.ID, "setupkey": newKey.Name})
} else {
log.Errorf("group %s not found while saving setup key activity event of account %s", g, account.Id)

View File

@ -211,7 +211,7 @@ func (am *DefaultAccountManager) createServiceUser(accountID string, initiatorUs
}
meta := map[string]any{"name": newUser.ServiceUserName}
am.storeEvent(initiatorUserID, newUser.Id, accountID, activity.ServiceUserCreated, meta)
am.StoreEvent(initiatorUserID, newUser.Id, accountID, activity.ServiceUserCreated, meta)
return &UserInfo{
ID: newUser.Id,
@ -312,7 +312,7 @@ func (am *DefaultAccountManager) inviteNewUser(accountID, userID string, invite
return nil, err
}
am.storeEvent(userID, newUser.Id, accountID, activity.UserInvited, nil)
am.StoreEvent(userID, newUser.Id, accountID, activity.UserInvited, nil)
return newUser.ToUserInfo(idpUser)
}
@ -349,7 +349,7 @@ func (am *DefaultAccountManager) GetUser(claims jwtclaims.AuthorizationClaims) (
if newLogin {
meta := map[string]any{"timestamp": claims.LastLogin}
am.storeEvent(claims.UserId, claims.UserId, account.Id, activity.DashboardLogin, meta)
am.StoreEvent(claims.UserId, claims.UserId, account.Id, activity.DashboardLogin, meta)
}
return user, nil
@ -357,7 +357,7 @@ func (am *DefaultAccountManager) GetUser(claims jwtclaims.AuthorizationClaims) (
func (am *DefaultAccountManager) deleteServiceUser(account *Account, initiatorUserID string, targetUser *User) {
meta := map[string]any{"name": targetUser.ServiceUserName}
am.storeEvent(initiatorUserID, targetUser.Id, account.Id, activity.ServiceUserDeleted, meta)
am.StoreEvent(initiatorUserID, targetUser.Id, account.Id, activity.ServiceUserDeleted, meta)
delete(account.Users, targetUser.Id)
}
@ -428,7 +428,7 @@ func (am *DefaultAccountManager) deleteRegularUser(account *Account, initiatorUs
}
meta := map[string]any{"name": tuName, "email": tuEmail}
am.storeEvent(initiatorUserID, targetUserID, account.Id, activity.UserDeleted, meta)
am.StoreEvent(initiatorUserID, targetUserID, account.Id, activity.UserDeleted, meta)
am.updateAccountPeers(account)
@ -484,7 +484,7 @@ func (am *DefaultAccountManager) InviteUser(accountID string, initiatorUserID st
return err
}
am.storeEvent(initiatorUserID, user.ID, accountID, activity.UserInvited, nil)
am.StoreEvent(initiatorUserID, user.ID, accountID, activity.UserInvited, nil)
return nil
}
@ -534,7 +534,7 @@ func (am *DefaultAccountManager) CreatePAT(accountID string, initiatorUserID str
}
meta := map[string]any{"name": pat.Name, "is_service_user": targetUser.IsServiceUser, "user_name": targetUser.ServiceUserName}
am.storeEvent(initiatorUserID, targetUserID, accountID, activity.PersonalAccessTokenCreated, meta)
am.StoreEvent(initiatorUserID, targetUserID, accountID, activity.PersonalAccessTokenCreated, meta)
return pat, nil
}
@ -578,7 +578,7 @@ func (am *DefaultAccountManager) DeletePAT(accountID string, initiatorUserID str
}
meta := map[string]any{"name": pat.Name, "is_service_user": targetUser.IsServiceUser, "user_name": targetUser.ServiceUserName}
am.storeEvent(initiatorUserID, targetUserID, accountID, activity.PersonalAccessTokenDeleted, meta)
am.StoreEvent(initiatorUserID, targetUserID, accountID, activity.PersonalAccessTokenDeleted, meta)
delete(targetUser.PATs, tokenID)
@ -739,15 +739,15 @@ func (am *DefaultAccountManager) SaveUser(accountID, initiatorUserID string, upd
defer func() {
if oldUser.IsBlocked() != update.IsBlocked() {
if update.IsBlocked() {
am.storeEvent(initiatorUserID, oldUser.Id, accountID, activity.UserBlocked, nil)
am.StoreEvent(initiatorUserID, oldUser.Id, accountID, activity.UserBlocked, nil)
} else {
am.storeEvent(initiatorUserID, oldUser.Id, accountID, activity.UserUnblocked, nil)
am.StoreEvent(initiatorUserID, oldUser.Id, accountID, activity.UserUnblocked, nil)
}
}
// store activity logs
if oldUser.Role != newUser.Role {
am.storeEvent(initiatorUserID, oldUser.Id, accountID, activity.UserRoleUpdated, map[string]any{"role": newUser.Role})
am.StoreEvent(initiatorUserID, oldUser.Id, accountID, activity.UserRoleUpdated, map[string]any{"role": newUser.Role})
}
if update.AutoGroups != nil {
@ -756,7 +756,7 @@ func (am *DefaultAccountManager) SaveUser(accountID, initiatorUserID string, upd
for _, g := range removedGroups {
group := account.GetGroup(g)
if group != nil {
am.storeEvent(initiatorUserID, oldUser.Id, accountID, activity.GroupRemovedFromUser,
am.StoreEvent(initiatorUserID, oldUser.Id, accountID, activity.GroupRemovedFromUser,
map[string]any{"group": group.Name, "group_id": group.ID, "is_service_user": newUser.IsServiceUser, "user_name": newUser.ServiceUserName})
} else {
log.Errorf("group %s not found while saving user activity event of account %s", g, account.Id)
@ -766,7 +766,7 @@ func (am *DefaultAccountManager) SaveUser(accountID, initiatorUserID string, upd
for _, g := range addedGroups {
group := account.GetGroup(g)
if group != nil {
am.storeEvent(initiatorUserID, oldUser.Id, accountID, activity.GroupAddedToUser,
am.StoreEvent(initiatorUserID, oldUser.Id, accountID, activity.GroupAddedToUser,
map[string]any{"group": group.Name, "group_id": group.ID, "is_service_user": newUser.IsServiceUser, "user_name": newUser.ServiceUserName})
}
}
@ -914,7 +914,7 @@ func (am *DefaultAccountManager) expireAndUpdatePeers(account *Account, peers []
if err := am.Store.SavePeerStatus(account.Id, peer.ID, *peer.Status); err != nil {
return err
}
am.storeEvent(
am.StoreEvent(
peer.UserID, peer.ID, account.Id,
activity.PeerLoginExpired, peer.EventMeta(am.GetDNSDomain()),
)