From d4e9087f941a9e175651f391b3fc4929b3b2b123 Mon Sep 17 00:00:00 2001 From: Misha Bragin Date: Thu, 17 Aug 2023 14:04:04 +0200 Subject: [PATCH] Add peer login and expiration activity events (#1090) Track the even of a user logging in their peer. Track the event of a peer login expiration. --- management/server/account.go | 1 + management/server/activity/codes.go | 378 +++++------------------- management/server/http/api/openapi.yml | 4 +- management/server/http/api/types.gen.go | 2 + management/server/peer.go | 2 + 5 files changed, 82 insertions(+), 305 deletions(-) diff --git a/management/server/account.go b/management/server/account.go index 785058987..442066bf9 100644 --- a/management/server/account.go +++ b/management/server/account.go @@ -872,6 +872,7 @@ func (am *DefaultAccountManager) peerLoginExpirationJob(accountID string) func() log.Errorf("failed saving peer status while expiring peer %s", peer.ID) return account.GetNextPeerExpiration() } + am.storeEvent(peer.UserID, peer.ID, account.Id, activity.PeerLoginExpired, peer.EventMeta(am.GetDNSDomain())) } log.Debugf("discovered %d peers to expire for account %s", len(peerIDs), account.Id) diff --git a/management/server/activity/codes.go b/management/server/activity/codes.go index e571c3a0c..7c6b55218 100644 --- a/management/server/activity/codes.go +++ b/management/server/activity/codes.go @@ -1,5 +1,14 @@ package activity +// Activity that triggered an Event +type Activity int + +// Code is an activity string representation +type Code struct { + message string + code string +} + const ( // PeerAddedByUser indicates that a user added a new peer to the system PeerAddedByUser Activity = iota @@ -97,314 +106,77 @@ const ( UserUnblocked // GroupDeleted indicates that a user deleted group GroupDeleted + // UserLoggedInPeer indicates that user logged in their peer with an interactive SSO login + UserLoggedInPeer + // PeerLoginExpired indicates that the user peer login has been expired and peer disconnected + PeerLoginExpired ) -const ( - // PeerAddedByUserMessage is a human-readable text message of the PeerAddedByUser activity - PeerAddedByUserMessage string = "Peer added" - // PeerAddedWithSetupKeyMessage is a human-readable text message of the PeerAddedWithSetupKey activity - PeerAddedWithSetupKeyMessage = PeerAddedByUserMessage - // UserJoinedMessage is a human-readable text message of the UserJoined activity - UserJoinedMessage string = "User joined" - // UserInvitedMessage is a human-readable text message of the UserInvited activity - UserInvitedMessage string = "User invited" - // AccountCreatedMessage is a human-readable text message of the AccountCreated activity - AccountCreatedMessage string = "Account created" - // PeerRemovedByUserMessage is a human-readable text message of the PeerRemovedByUser activity - PeerRemovedByUserMessage string = "Peer deleted" - // RuleAddedMessage is a human-readable text message of the RuleAdded activity - RuleAddedMessage string = "Rule added" - // RuleRemovedMessage is a human-readable text message of the RuleRemoved activity - RuleRemovedMessage string = "Rule deleted" - // RuleUpdatedMessage is a human-readable text message of the RuleRemoved activity - RuleUpdatedMessage string = "Rule updated" - // PolicyAddedMessage is a human-readable text message of the PolicyAdded activity - PolicyAddedMessage string = "Policy added" - // PolicyRemovedMessage is a human-readable text message of the PolicyRemoved activity - PolicyRemovedMessage string = "Policy deleted" - // PolicyUpdatedMessage is a human-readable text message of the PolicyRemoved activity - PolicyUpdatedMessage string = "Policy updated" - // SetupKeyCreatedMessage is a human-readable text message of the SetupKeyCreated activity - SetupKeyCreatedMessage string = "Setup key created" - // SetupKeyUpdatedMessage is a human-readable text message of the SetupKeyUpdated activity - SetupKeyUpdatedMessage string = "Setup key updated" - // SetupKeyRevokedMessage is a human-readable text message of the SetupKeyRevoked activity - SetupKeyRevokedMessage string = "Setup key revoked" - // SetupKeyOverusedMessage is a human-readable text message of the SetupKeyOverused activity - SetupKeyOverusedMessage string = "Setup key overused" - // GroupCreatedMessage is a human-readable text message of the GroupCreated activity - GroupCreatedMessage string = "Group created" - // GroupUpdatedMessage is a human-readable text message of the GroupUpdated activity - GroupUpdatedMessage string = "Group updated" - // GroupAddedToPeerMessage is a human-readable text message of the GroupAddedToPeer activity - GroupAddedToPeerMessage string = "Group added to peer" - // GroupRemovedFromPeerMessage is a human-readable text message of the GroupRemovedFromPeer activity - GroupRemovedFromPeerMessage string = "Group removed from peer" - // GroupAddedToUserMessage is a human-readable text message of the GroupAddedToUser activity - GroupAddedToUserMessage string = "Group added to user" - // GroupRemovedFromUserMessage is a human-readable text message of the GroupRemovedFromUser activity - GroupRemovedFromUserMessage string = "Group removed from user" - // UserRoleUpdatedMessage is a human-readable text message of the UserRoleUpdatedMessage activity - UserRoleUpdatedMessage string = "User role updated" - // GroupAddedToSetupKeyMessage is a human-readable text message of the GroupAddedToSetupKey activity - GroupAddedToSetupKeyMessage string = "Group added to setup key" - // GroupRemovedFromSetupKeyMessage is a human-readable text message of the GroupRemovedFromSetupKey activity - GroupRemovedFromSetupKeyMessage string = "Group removed from user setup key" - // GroupAddedToDisabledManagementGroupsMessage is a human-readable text message of the GroupAddedToDisabledManagementGroups activity - GroupAddedToDisabledManagementGroupsMessage string = "Group added to disabled management DNS setting" - // GroupRemovedFromDisabledManagementGroupsMessage is a human-readable text message of the GroupRemovedFromDisabledManagementGroups activity - GroupRemovedFromDisabledManagementGroupsMessage string = "Group removed from disabled management DNS setting" - // RouteCreatedMessage is a human-readable text message of the RouteCreated activity - RouteCreatedMessage string = "Route created" - // RouteRemovedMessage is a human-readable text message of the RouteRemoved activity - RouteRemovedMessage string = "Route deleted" - // RouteUpdatedMessage is a human-readable text message of the RouteUpdated activity - RouteUpdatedMessage string = "Route updated" - // PeerSSHEnabledMessage is a human-readable text message of the PeerSSHEnabled activity - PeerSSHEnabledMessage string = "Peer SSH server enabled" - // PeerSSHDisabledMessage is a human-readable text message of the PeerSSHDisabled activity - PeerSSHDisabledMessage string = "Peer SSH server disabled" - // PeerRenamedMessage is a human-readable text message of the PeerRenamed activity - PeerRenamedMessage string = "Peer renamed" - // PeerLoginExpirationDisabledMessage is a human-readable text message of the PeerLoginExpirationDisabled activity - PeerLoginExpirationDisabledMessage string = "Peer login expiration disabled" - // PeerLoginExpirationEnabledMessage is a human-readable text message of the PeerLoginExpirationEnabled activity - PeerLoginExpirationEnabledMessage string = "Peer login expiration enabled" - // NameserverGroupCreatedMessage is a human-readable text message of the NameserverGroupCreated activity - NameserverGroupCreatedMessage string = "Nameserver group created" - // NameserverGroupDeletedMessage is a human-readable text message of the NameserverGroupDeleted activity - NameserverGroupDeletedMessage string = "Nameserver group deleted" - // NameserverGroupUpdatedMessage is a human-readable text message of the NameserverGroupUpdated activity - NameserverGroupUpdatedMessage string = "Nameserver group updated" - // AccountPeerLoginExpirationEnabledMessage is a human-readable text message of the AccountPeerLoginExpirationEnabled activity - AccountPeerLoginExpirationEnabledMessage string = "Peer login expiration enabled for the account" - // AccountPeerLoginExpirationDisabledMessage is a human-readable text message of the AccountPeerLoginExpirationDisabled activity - AccountPeerLoginExpirationDisabledMessage string = "Peer login expiration disabled for the account" - // AccountPeerLoginExpirationDurationUpdatedMessage is a human-readable text message of the AccountPeerLoginExpirationDurationUpdated activity - AccountPeerLoginExpirationDurationUpdatedMessage string = "Peer login expiration duration updated" - // PersonalAccessTokenCreatedMessage is a human-readable text message of the PersonalAccessTokenCreated activity - PersonalAccessTokenCreatedMessage string = "Personal access token created" - // PersonalAccessTokenDeletedMessage is a human-readable text message of the PersonalAccessTokenDeleted activity - PersonalAccessTokenDeletedMessage string = "Personal access token deleted" - // ServiceUserCreatedMessage is a human-readable text message of the ServiceUserCreated activity - ServiceUserCreatedMessage string = "Service user created" - // ServiceUserDeletedMessage is a human-readable text message of the ServiceUserDeleted activity - ServiceUserDeletedMessage string = "Service user deleted" - // UserBlockedMessage is a human-readable text message of the UserBlocked activity - UserBlockedMessage string = "User blocked" - // UserUnblockedMessage is a human-readable text message of the UserUnblocked activity - UserUnblockedMessage string = "User unblocked" - // GroupDeletedMessage is a human-readable text message of the GroupDeleted activity - GroupDeletedMessage string = "Group deleted" -) - -// Activity that triggered an Event -type Activity int - -// Message returns a string representation of an activity -func (a Activity) Message() string { - switch a { - case PeerAddedByUser: - return PeerAddedByUserMessage - case PeerRemovedByUser: - return PeerRemovedByUserMessage - case PeerAddedWithSetupKey: - return PeerAddedWithSetupKeyMessage - case UserJoined: - return UserJoinedMessage - case UserInvited: - return UserInvitedMessage - case AccountCreated: - return AccountCreatedMessage - case RuleAdded: - return RuleAddedMessage - case RuleRemoved: - return RuleRemovedMessage - case RuleUpdated: - return RuleUpdatedMessage - case PolicyAdded: - return PolicyAddedMessage - case PolicyRemoved: - return PolicyRemovedMessage - case PolicyUpdated: - return PolicyUpdatedMessage - case SetupKeyCreated: - return SetupKeyCreatedMessage - case SetupKeyUpdated: - return SetupKeyUpdatedMessage - case SetupKeyRevoked: - return SetupKeyRevokedMessage - case SetupKeyOverused: - return SetupKeyOverusedMessage - case GroupCreated: - return GroupCreatedMessage - case GroupUpdated: - return GroupUpdatedMessage - case GroupAddedToPeer: - return GroupAddedToPeerMessage - case GroupRemovedFromPeer: - return GroupRemovedFromPeerMessage - case GroupRemovedFromUser: - return GroupRemovedFromUserMessage - case GroupAddedToUser: - return GroupAddedToUserMessage - case UserRoleUpdated: - return UserRoleUpdatedMessage - case GroupAddedToSetupKey: - return GroupAddedToSetupKeyMessage - case GroupRemovedFromSetupKey: - return GroupRemovedFromSetupKeyMessage - case GroupAddedToDisabledManagementGroups: - return GroupAddedToDisabledManagementGroupsMessage - case GroupRemovedFromDisabledManagementGroups: - return GroupRemovedFromDisabledManagementGroupsMessage - case RouteCreated: - return RouteCreatedMessage - case RouteRemoved: - return RouteRemovedMessage - case RouteUpdated: - return RouteUpdatedMessage - case PeerSSHEnabled: - return PeerSSHEnabledMessage - case PeerSSHDisabled: - return PeerSSHDisabledMessage - case PeerLoginExpirationEnabled: - return PeerLoginExpirationEnabledMessage - case PeerLoginExpirationDisabled: - return PeerLoginExpirationDisabledMessage - case PeerRenamed: - return PeerRenamedMessage - case NameserverGroupCreated: - return NameserverGroupCreatedMessage - case NameserverGroupDeleted: - return NameserverGroupDeletedMessage - case NameserverGroupUpdated: - return NameserverGroupUpdatedMessage - case AccountPeerLoginExpirationEnabled: - return AccountPeerLoginExpirationEnabledMessage - case AccountPeerLoginExpirationDisabled: - return AccountPeerLoginExpirationDisabledMessage - case AccountPeerLoginExpirationDurationUpdated: - return AccountPeerLoginExpirationDurationUpdatedMessage - case PersonalAccessTokenCreated: - return PersonalAccessTokenCreatedMessage - case PersonalAccessTokenDeleted: - return PersonalAccessTokenDeletedMessage - case ServiceUserCreated: - return ServiceUserCreatedMessage - case ServiceUserDeleted: - return ServiceUserDeletedMessage - case UserBlocked: - return UserBlockedMessage - case UserUnblocked: - return UserUnblockedMessage - case GroupDeleted: - return GroupDeletedMessage - default: - return "UNKNOWN_ACTIVITY" - } +var activityMap = map[Activity]Code{ + PeerAddedByUser: {"Peer added", "user.peer.add"}, + PeerAddedWithSetupKey: {"Peer added", "setupkey.peer.add"}, + UserJoined: {"User joined", "user.join"}, + UserInvited: {"User invited", "user.invite"}, + AccountCreated: {"Account created", "account.create"}, + PeerRemovedByUser: {"Peer deleted", "user.peer.delete"}, + RuleAdded: {"Rule added", "rule.add"}, + RuleUpdated: {"Rule updated", "rule.update"}, + RuleRemoved: {"Rule deleted", "rule.delete"}, + PolicyAdded: {"Policy added", "policy.add"}, + PolicyUpdated: {"Policy updated", "policy.update"}, + PolicyRemoved: {"Policy deleted", "policy.delete"}, + SetupKeyCreated: {"Setup key created", "setupkey.add"}, + SetupKeyUpdated: {"Setup key updated", "setupkey.update"}, + SetupKeyRevoked: {"Setup key revoked", "setupkey.revoke"}, + SetupKeyOverused: {"Setup key overused", "setupkey.overuse"}, + GroupCreated: {"Group created", "group.add"}, + GroupUpdated: {"Group updated", "group.update"}, + GroupAddedToPeer: {"Group added to peer", "peer.group.add"}, + GroupRemovedFromPeer: {"Group removed from peer", "peer.group.delete"}, + GroupAddedToUser: {"Group added to user", "user.group.add"}, + GroupRemovedFromUser: {"Group removed from user", "user.group.delete"}, + UserRoleUpdated: {"User role updated", "user.role.update"}, + GroupAddedToSetupKey: {"Group added to setup key", "setupkey.group.add"}, + GroupRemovedFromSetupKey: {"Group removed from user setup key", "setupkey.group.delete"}, + GroupAddedToDisabledManagementGroups: {"Group added to disabled management DNS setting", "dns.setting.disabled.management.group.add"}, + GroupRemovedFromDisabledManagementGroups: {"Group removed from disabled management DNS setting", "dns.setting.disabled.management.group.delete"}, + RouteCreated: {"Route created", "route.add"}, + RouteRemoved: {"Route deleted", "route.delete"}, + RouteUpdated: {"Route updated", "route.update"}, + PeerSSHEnabled: {"Peer SSH server enabled", "peer.ssh.enable"}, + PeerSSHDisabled: {"Peer SSH server disabled", "peer.ssh.disable"}, + PeerRenamed: {"Peer renamed", "peer.rename"}, + PeerLoginExpirationEnabled: {"Peer login expiration enabled", "peer.login.expiration.enable"}, + PeerLoginExpirationDisabled: {"Peer login expiration disabled", "peer.login.expiration.disable"}, + NameserverGroupCreated: {"Nameserver group created", "nameserver.group.add"}, + NameserverGroupDeleted: {"Nameserver group deleted", "nameserver.group.delete"}, + NameserverGroupUpdated: {"Nameserver group updated", "nameserver.group.update"}, + AccountPeerLoginExpirationDurationUpdated: {"Account peer login expiration duration updated", "account.setting.peer.login.expiration.update"}, + AccountPeerLoginExpirationEnabled: {"Account peer login expiration enabled", "account.setting.peer.login.expiration.enable"}, + AccountPeerLoginExpirationDisabled: {"Account peer login expiration disabled", "account.setting.peer.login.expiration.disable"}, + PersonalAccessTokenCreated: {"Personal access token created", "personal.access.token.create"}, + PersonalAccessTokenDeleted: {"Personal access token deleted", "personal.access.token.delete"}, + ServiceUserCreated: {"Service user created", "service.user.create"}, + ServiceUserDeleted: {"Service user deleted", "service.user.delete"}, + UserBlocked: {"User blocked", "user.block"}, + UserUnblocked: {"User unblocked", "user.unblock"}, + GroupDeleted: {"Group deleted", "group.delete"}, + UserLoggedInPeer: {"User logged in peer", "user.peer.login"}, + PeerLoginExpired: {"Peer login expired", "peer.login.expire"}, } // StringCode returns a string code of the activity func (a Activity) StringCode() string { - switch a { - case PeerAddedByUser: - return "user.peer.add" - case PeerRemovedByUser: - return "user.peer.delete" - case PeerAddedWithSetupKey: - return "setupkey.peer.add" - case UserJoined: - return "user.join" - case UserInvited: - return "user.invite" - case UserBlocked: - return "user.block" - case UserUnblocked: - return "user.unblock" - case AccountCreated: - return "account.create" - case RuleAdded: - return "rule.add" - case RuleRemoved: - return "rule.delete" - case RuleUpdated: - return "rule.update" - case PolicyAdded: - return "policy.add" - case PolicyRemoved: - return "policy.delete" - case PolicyUpdated: - return "policy.update" - case SetupKeyCreated: - return "setupkey.add" - case SetupKeyRevoked: - return "setupkey.revoke" - case SetupKeyOverused: - return "setupkey.overuse" - case SetupKeyUpdated: - return "setupkey.update" - case GroupCreated: - return "group.add" - case GroupUpdated: - return "group.update" - case GroupDeleted: - return "group.delete" - case GroupRemovedFromPeer: - return "peer.group.delete" - case GroupAddedToPeer: - return "peer.group.add" - case GroupAddedToUser: - return "user.group.add" - case GroupRemovedFromUser: - return "user.group.delete" - case UserRoleUpdated: - return "user.role.update" - case GroupAddedToSetupKey: - return "setupkey.group.add" - case GroupRemovedFromSetupKey: - return "setupkey.group.delete" - case GroupAddedToDisabledManagementGroups: - return "dns.setting.disabled.management.group.add" - case GroupRemovedFromDisabledManagementGroups: - return "dns.setting.disabled.management.group.delete" - case RouteCreated: - return "route.add" - case RouteRemoved: - return "route.delete" - case RouteUpdated: - return "route.update" - case PeerRenamed: - return "peer.rename" - case PeerSSHEnabled: - return "peer.ssh.enable" - case PeerSSHDisabled: - return "peer.ssh.disable" - case PeerLoginExpirationDisabled: - return "peer.login.expiration.disable" - case PeerLoginExpirationEnabled: - return "peer.login.expiration.enable" - case NameserverGroupCreated: - return "nameserver.group.add" - case NameserverGroupDeleted: - return "nameserver.group.delete" - case NameserverGroupUpdated: - return "nameserver.group.update" - case AccountPeerLoginExpirationDurationUpdated: - return "account.setting.peer.login.expiration.update" - case AccountPeerLoginExpirationEnabled: - return "account.setting.peer.login.expiration.enable" - case AccountPeerLoginExpirationDisabled: - return "account.setting.peer.login.expiration.disable" - case PersonalAccessTokenCreated: - return "personal.access.token.create" - case PersonalAccessTokenDeleted: - return "personal.access.token.delete" - case ServiceUserCreated: - return "service.user.create" - case ServiceUserDeleted: - return "service.user.delete" - default: - return "UNKNOWN_ACTIVITY" + if code, ok := activityMap[a]; ok { + return code.code } + return "UNKNOWN_ACTIVITY" +} + +// Message returns a string representation of an activity +func (a Activity) Message() string { + if code, ok := activityMap[a]; ok { + return code.message + } + return "UNKNOWN_ACTIVITY" } diff --git a/management/server/http/api/openapi.yml b/management/server/http/api/openapi.yml index 2b18bc295..1fb54c4f7 100644 --- a/management/server/http/api/openapi.yml +++ b/management/server/http/api/openapi.yml @@ -892,7 +892,7 @@ components: description: The string code of the activity that occurred during the event type: string enum: [ "user.peer.delete", "user.join", "user.invite", "user.peer.add", "user.group.add", "user.group.delete", - "user.role.update", "user.block", "user.unblock", + "user.role.update", "user.block", "user.unblock", "user.peer.login", "setupkey.peer.add", "setupkey.add", "setupkey.update", "setupkey.revoke", "setupkey.overuse", "setupkey.group.delete", "setupkey.group.add", "rule.add", "rule.delete", "rule.update", @@ -901,7 +901,7 @@ components: "account.create", "account.setting.peer.login.expiration.update", "account.setting.peer.login.expiration.disable", "account.setting.peer.login.expiration.enable", "route.add", "route.delete", "route.update", "nameserver.group.add", "nameserver.group.delete", "nameserver.group.update", - "peer.ssh.disable", "peer.ssh.enable", "peer.rename", "peer.login.expiration.disable", "peer.login.expiration.enable", + "peer.ssh.disable", "peer.ssh.enable", "peer.rename", "peer.login.expiration.disable", "peer.login.expiration.enable", "peer.login.expire", "service.user.create", "personal.access.token.create", "service.user.delete", "personal.access.token.delete" ] example: route.add initiator_id: diff --git a/management/server/http/api/types.gen.go b/management/server/http/api/types.gen.go index c11ed9efa..93d371a17 100644 --- a/management/server/http/api/types.gen.go +++ b/management/server/http/api/types.gen.go @@ -27,6 +27,7 @@ const ( EventActivityCodeNameserverGroupUpdate EventActivityCode = "nameserver.group.update" EventActivityCodePeerLoginExpirationDisable EventActivityCode = "peer.login.expiration.disable" EventActivityCodePeerLoginExpirationEnable EventActivityCode = "peer.login.expiration.enable" + EventActivityCodePeerLoginExpire EventActivityCode = "peer.login.expire" EventActivityCodePeerRename EventActivityCode = "peer.rename" EventActivityCodePeerSshDisable EventActivityCode = "peer.ssh.disable" EventActivityCodePeerSshEnable EventActivityCode = "peer.ssh.enable" @@ -57,6 +58,7 @@ const ( EventActivityCodeUserJoin EventActivityCode = "user.join" EventActivityCodeUserPeerAdd EventActivityCode = "user.peer.add" EventActivityCodeUserPeerDelete EventActivityCode = "user.peer.delete" + EventActivityCodeUserPeerLogin EventActivityCode = "user.peer.login" EventActivityCodeUserRoleUpdate EventActivityCode = "user.role.update" EventActivityCodeUserUnblock EventActivityCode = "user.unblock" ) diff --git a/management/server/peer.go b/management/server/peer.go index b2fe0955a..b2d4e436f 100644 --- a/management/server/peer.go +++ b/management/server/peer.go @@ -695,6 +695,8 @@ func (am *DefaultAccountManager) LoginPeer(login PeerLogin) (*Peer, *NetworkMap, updatePeerLastLogin(peer, account) updateRemotePeers = true shouldStoreAccount = true + + am.storeEvent(login.UserID, peer.ID, account.Id, activity.UserLoggedInPeer, peer.EventMeta(am.GetDNSDomain())) } peer, updated := updatePeerMeta(peer, login.Meta, account)