Add more activity events (#663)

This commit is contained in:
Misha Bragin 2023-01-25 16:29:59 +01:00 committed by GitHub
parent a0de9aa345
commit 9e408b5bbc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 252 additions and 105 deletions

View File

@ -77,6 +77,11 @@ type NameServer struct {
Port int
}
// EventMeta returns activity event meta related to the nameserver group
func (g *NameServerGroup) EventMeta() map[string]any {
return map[string]any{"name": g.Name}
}
// Copy copies a nameserver object
func (n *NameServer) Copy() *NameServer {
return &NameServer{

View File

@ -55,7 +55,7 @@ type AccountManager interface {
MarkPeerConnected(peerKey string, connected bool) error
DeletePeer(accountID, peerKey, userID string) (*Peer, error)
GetPeerByIP(accountId string, peerIP string) (*Peer, error)
UpdatePeer(accountID string, peer *Peer) (*Peer, error)
UpdatePeer(accountID, userID string, peer *Peer) (*Peer, error)
GetNetworkMap(peerKey string) (*NetworkMap, error)
GetPeerNetwork(peerKey string) (*Network, error)
AddPeer(setupKey, userID string, peer *Peer) (*Peer, error)
@ -76,16 +76,16 @@ type AccountManager interface {
DeleteRule(accountID, ruleID, userID string) error
ListRules(accountID, userID string) ([]*Rule, error)
GetRoute(accountID, routeID, userID string) (*route.Route, error)
CreateRoute(accountID string, prefix, peer, description, netID string, masquerade bool, metric int, groups []string, enabled bool) (*route.Route, error)
SaveRoute(accountID string, route *route.Route) error
UpdateRoute(accountID string, routeID string, operations []RouteUpdateOperation) (*route.Route, error)
DeleteRoute(accountID, routeID string) error
CreateRoute(accountID string, prefix, peerIP, description, netID string, masquerade bool, metric int, groups []string, enabled bool, userID string) (*route.Route, error)
SaveRoute(accountID, userID string, route *route.Route) error
UpdateRoute(accountID, routeID string, operations []RouteUpdateOperation) (*route.Route, error)
DeleteRoute(accountID, routeID, userID string) error
ListRoutes(accountID, userID string) ([]*route.Route, error)
GetNameServerGroup(accountID, nsGroupID string) (*nbdns.NameServerGroup, error)
CreateNameServerGroup(accountID string, name, description string, nameServerList []nbdns.NameServer, groups []string, primary bool, domains []string, enabled bool) (*nbdns.NameServerGroup, error)
SaveNameServerGroup(accountID string, nsGroupToSave *nbdns.NameServerGroup) error
UpdateNameServerGroup(accountID, nsGroupID string, operations []NameServerGroupUpdateOperation) (*nbdns.NameServerGroup, error)
DeleteNameServerGroup(accountID, nsGroupID string) error
CreateNameServerGroup(accountID string, name, description string, nameServerList []nbdns.NameServer, groups []string, primary bool, domains []string, enabled bool, userID string) (*nbdns.NameServerGroup, error)
SaveNameServerGroup(accountID, userID string, nsGroupToSave *nbdns.NameServerGroup) error
UpdateNameServerGroup(accountID, nsGroupID, userID string, operations []NameServerGroupUpdateOperation) (*nbdns.NameServerGroup, error)
DeleteNameServerGroup(accountID, nsGroupID, userID string) error
ListNameServerGroups(accountID string) ([]*nbdns.NameServerGroup, error)
GetDNSDomain() string
GetEvents(accountID, userID string) ([]*activity.Event, error)
@ -220,6 +220,17 @@ func (a *Account) GetRoutesByPrefix(prefix netip.Prefix) []*route.Route {
return routes
}
// GetPeerByIP returns peer by it's IP if exists under account or nil otherwise
func (a *Account) GetPeerByIP(peerIP string) *Peer {
for _, peer := range a.Peers {
if peerIP == peer.IP.String() {
return peer
}
}
return nil
}
// GetPeerRules returns a list of source or destination rules of a given peer.
func (a *Account) GetPeerRules(peerPubKey string) (srcRules []*Rule, dstRules []*Rule) {

View File

@ -49,6 +49,24 @@ const (
GroupAddedToDisabledManagementGroups
// GroupRemovedFromDisabledManagementGroups indicates that a user removed a group from the DNS setting Disabled management groups
GroupRemovedFromDisabledManagementGroups
// RouteCreated indicates that a user created a route
RouteCreated
// RouteRemoved indicates that a user deleted a route
RouteRemoved
// RouteUpdated indicates that a user updated a route
RouteUpdated
// PeerSSHEnabled indicates that a user enabled SSH server on a peer
PeerSSHEnabled
// PeerSSHDisabled indicates that a user disabled SSH server on a peer
PeerSSHDisabled
// PeerRenamed indicates that a user renamed a peer
PeerRenamed
// NameserverGroupCreated indicates that a user created a nameservers group
NameserverGroupCreated
// NameserverGroupDeleted indicates that a user deleted a nameservers group
NameserverGroupDeleted
// NameserverGroupUpdated indicates that a user updated a nameservers group
NameserverGroupUpdated
)
const (
@ -100,6 +118,24 @@ const (
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"
// 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"
)
// Activity that triggered an Event
@ -156,6 +192,24 @@ func (a Activity) Message() string {
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 PeerRenamed:
return PeerRenamedMessage
case NameserverGroupCreated:
return NameserverGroupCreatedMessage
case NameserverGroupDeleted:
return NameserverGroupDeletedMessage
case NameserverGroupUpdated:
return NameserverGroupUpdatedMessage
default:
return "UNKNOWN_ACTIVITY"
}
@ -212,6 +266,24 @@ func (a Activity) StringCode() string {
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 NameserverGroupCreated:
return "nameserver.group.add"
case NameserverGroupDeleted:
return "nameserver.group.delete"
case NameserverGroupUpdated:
return "nameserver.group.update"
default:
return "UNKNOWN_ACTIVITY"
}

View File

@ -535,7 +535,10 @@ components:
"setupkey.group.delete", "setupkey.group.add",
"rule.add", "rule.delete", "rule.update",
"group.add", "group.update", "dns.setting.disabled.management.group.add",
"account.create", "dns.setting.disabled.management.group.delete"
"account.create", "dns.setting.disabled.management.group.delete",
"route.add", "route.delete", "route.update",
"nameserver.group.add", "nameserver.group.delete", "nameserver.group.update",
"peer.ssh.disable", "peer.ssh.enable", "peer.rename"
]
initiator_id:
description: The ID of the initiator of the event. E.g., an ID of a user that triggered the event.

View File

@ -18,6 +18,15 @@ const (
EventActivityCodeDnsSettingDisabledManagementGroupDelete EventActivityCode = "dns.setting.disabled.management.group.delete"
EventActivityCodeGroupAdd EventActivityCode = "group.add"
EventActivityCodeGroupUpdate EventActivityCode = "group.update"
EventActivityCodeNameserverGroupAdd EventActivityCode = "nameserver.group.add"
EventActivityCodeNameserverGroupDelete EventActivityCode = "nameserver.group.delete"
EventActivityCodeNameserverGroupUpdate EventActivityCode = "nameserver.group.update"
EventActivityCodePeerRename EventActivityCode = "peer.rename"
EventActivityCodePeerSshDisable EventActivityCode = "peer.ssh.disable"
EventActivityCodePeerSshEnable EventActivityCode = "peer.ssh.enable"
EventActivityCodeRouteAdd EventActivityCode = "route.add"
EventActivityCodeRouteDelete EventActivityCode = "route.delete"
EventActivityCodeRouteUpdate EventActivityCode = "route.update"
EventActivityCodeRuleAdd EventActivityCode = "rule.add"
EventActivityCodeRuleDelete EventActivityCode = "rule.delete"
EventActivityCodeRuleUpdate EventActivityCode = "rule.update"

View File

@ -57,7 +57,7 @@ func (h *Nameservers) GetAllNameserversHandler(w http.ResponseWriter, r *http.Re
// CreateNameserverGroupHandler handles nameserver group creation request
func (h *Nameservers) CreateNameserverGroupHandler(w http.ResponseWriter, r *http.Request) {
claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience)
account, _, err := h.accountManager.GetAccountFromToken(claims)
account, user, err := h.accountManager.GetAccountFromToken(claims)
if err != nil {
util.WriteError(err, w)
return
@ -76,7 +76,7 @@ func (h *Nameservers) CreateNameserverGroupHandler(w http.ResponseWriter, r *htt
return
}
nsGroup, err := h.accountManager.CreateNameServerGroup(account.Id, req.Name, req.Description, nsList, req.Groups, req.Primary, req.Domains, req.Enabled)
nsGroup, err := h.accountManager.CreateNameServerGroup(account.Id, req.Name, req.Description, nsList, req.Groups, req.Primary, req.Domains, req.Enabled, user.Id)
if err != nil {
util.WriteError(err, w)
return
@ -90,7 +90,7 @@ func (h *Nameservers) CreateNameserverGroupHandler(w http.ResponseWriter, r *htt
// UpdateNameserverGroupHandler handles update to a nameserver group identified by a given ID
func (h *Nameservers) UpdateNameserverGroupHandler(w http.ResponseWriter, r *http.Request) {
claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience)
account, _, err := h.accountManager.GetAccountFromToken(claims)
account, user, err := h.accountManager.GetAccountFromToken(claims)
if err != nil {
util.WriteError(err, w)
return
@ -126,7 +126,7 @@ func (h *Nameservers) UpdateNameserverGroupHandler(w http.ResponseWriter, r *htt
Enabled: req.Enabled,
}
err = h.accountManager.SaveNameServerGroup(account.Id, updatedNSGroup)
err = h.accountManager.SaveNameServerGroup(account.Id, user.Id, updatedNSGroup)
if err != nil {
util.WriteError(err, w)
return
@ -140,7 +140,7 @@ func (h *Nameservers) UpdateNameserverGroupHandler(w http.ResponseWriter, r *htt
// PatchNameserverGroupHandler handles patch updates to a nameserver group identified by a given ID
func (h *Nameservers) PatchNameserverGroupHandler(w http.ResponseWriter, r *http.Request) {
claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience)
account, _, err := h.accountManager.GetAccountFromToken(claims)
account, user, err := h.accountManager.GetAccountFromToken(claims)
if err != nil {
util.WriteError(err, w)
return
@ -208,7 +208,7 @@ func (h *Nameservers) PatchNameserverGroupHandler(w http.ResponseWriter, r *http
}
}
updatedNSGroup, err := h.accountManager.UpdateNameServerGroup(account.Id, nsGroupID, operations)
updatedNSGroup, err := h.accountManager.UpdateNameServerGroup(account.Id, nsGroupID, user.Id, operations)
if err != nil {
util.WriteError(err, w)
return
@ -222,7 +222,7 @@ func (h *Nameservers) PatchNameserverGroupHandler(w http.ResponseWriter, r *http
// DeleteNameserverGroupHandler handles nameserver group deletion request
func (h *Nameservers) DeleteNameserverGroupHandler(w http.ResponseWriter, r *http.Request) {
claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience)
account, _, err := h.accountManager.GetAccountFromToken(claims)
account, user, err := h.accountManager.GetAccountFromToken(claims)
if err != nil {
util.WriteError(err, w)
return
@ -234,7 +234,7 @@ func (h *Nameservers) DeleteNameserverGroupHandler(w http.ResponseWriter, r *htt
return
}
err = h.accountManager.DeleteNameServerGroup(account.Id, nsGroupID)
err = h.accountManager.DeleteNameServerGroup(account.Id, nsGroupID, user.Id)
if err != nil {
util.WriteError(err, w)
return

View File

@ -63,7 +63,7 @@ func initNameserversTestData() *Nameservers {
}
return nil, status.Errorf(status.NotFound, "nameserver group with ID %s not found", nsGroupID)
},
CreateNameServerGroupFunc: func(accountID string, name, description string, nameServerList []nbdns.NameServer, groups []string, primary bool, domains []string, enabled bool) (*nbdns.NameServerGroup, error) {
CreateNameServerGroupFunc: func(accountID string, name, description string, nameServerList []nbdns.NameServer, groups []string, primary bool, domains []string, enabled bool, _ string) (*nbdns.NameServerGroup, error) {
return &nbdns.NameServerGroup{
ID: existingNSGroupID,
Name: name,
@ -75,16 +75,16 @@ func initNameserversTestData() *Nameservers {
Domains: domains,
}, nil
},
DeleteNameServerGroupFunc: func(accountID, nsGroupID string) error {
DeleteNameServerGroupFunc: func(accountID, nsGroupID, _ string) error {
return nil
},
SaveNameServerGroupFunc: func(accountID string, nsGroupToSave *nbdns.NameServerGroup) error {
SaveNameServerGroupFunc: func(accountID, _ string, nsGroupToSave *nbdns.NameServerGroup) error {
if nsGroupToSave.ID == existingNSGroupID {
return nil
}
return status.Errorf(status.NotFound, "nameserver group with ID %s was not found", nsGroupToSave.ID)
},
UpdateNameServerGroupFunc: func(accountID, nsGroupID string, operations []server.NameServerGroupUpdateOperation) (*nbdns.NameServerGroup, error) {
UpdateNameServerGroupFunc: func(accountID, nsGroupID, _ string, operations []server.NameServerGroupUpdateOperation) (*nbdns.NameServerGroup, error) {
nsGroupToUpdate := baseExistingNSGroup.Copy()
if nsGroupID != nsGroupToUpdate.ID {
return nil, status.Errorf(status.NotFound, "nameserver group ID %s no longer exists", nsGroupID)
@ -110,7 +110,7 @@ func initNameserversTestData() *Nameservers {
return nsGroupToUpdate, nil
},
GetAccountFromTokenFunc: func(_ jwtclaims.AuthorizationClaims) (*server.Account, *server.User, error) {
return testingNSAccount, nil, nil
return testingNSAccount, testingAccount.Users["test_user"], nil
},
},
authAudience: "",

View File

@ -27,7 +27,7 @@ func NewPeers(accountManager server.AccountManager, authAudience string) *Peers
}
}
func (h *Peers) updatePeer(account *server.Account, peer *server.Peer, w http.ResponseWriter, r *http.Request) {
func (h *Peers) updatePeer(account *server.Account, user *server.User, peer *server.Peer, w http.ResponseWriter, r *http.Request) {
req := &api.PutApiPeersIdJSONBody{}
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
@ -36,7 +36,7 @@ func (h *Peers) updatePeer(account *server.Account, peer *server.Peer, w http.Re
}
update := &server.Peer{Key: peer.Key, SSHEnabled: req.SshEnabled, Name: req.Name}
peer, err = h.accountManager.UpdatePeer(account.Id, update)
peer, err = h.accountManager.UpdatePeer(account.Id, user.Id, update)
if err != nil {
util.WriteError(err, w)
return
@ -81,7 +81,7 @@ func (h *Peers) HandlePeer(w http.ResponseWriter, r *http.Request) {
h.deletePeer(account.Id, user.Id, peer, w, r)
return
case http.MethodPut:
h.updatePeer(account, peer, w, r)
h.updatePeer(account, user, peer, w, r)
return
case http.MethodGet:
util.WriteJSONObject(w, toPeerResponse(peer, account, dnsDomain))

View File

@ -54,7 +54,7 @@ func (h *Routes) GetAllRoutesHandler(w http.ResponseWriter, r *http.Request) {
// CreateRouteHandler handles route creation request
func (h *Routes) CreateRouteHandler(w http.ResponseWriter, r *http.Request) {
claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience)
account, _, err := h.accountManager.GetAccountFromToken(claims)
account, user, err := h.accountManager.GetAccountFromToken(claims)
if err != nil {
util.WriteError(err, w)
return
@ -67,16 +67,6 @@ func (h *Routes) CreateRouteHandler(w http.ResponseWriter, r *http.Request) {
return
}
peerKey := req.Peer
if req.Peer != "" {
peer, err := h.accountManager.GetPeerByIP(account.Id, req.Peer)
if err != nil {
util.WriteError(err, w)
return
}
peerKey = peer.Key
}
_, newPrefix, err := route.ParseNetwork(req.Network)
if err != nil {
util.WriteError(err, w)
@ -89,7 +79,7 @@ func (h *Routes) CreateRouteHandler(w http.ResponseWriter, r *http.Request) {
return
}
newRoute, err := h.accountManager.CreateRoute(account.Id, newPrefix.String(), peerKey, req.Description, req.NetworkId, req.Masquerade, req.Metric, req.Groups, req.Enabled)
newRoute, err := h.accountManager.CreateRoute(account.Id, newPrefix.String(), req.Peer, req.Description, req.NetworkId, req.Masquerade, req.Metric, req.Groups, req.Enabled, user.Id)
if err != nil {
util.WriteError(err, w)
return
@ -138,9 +128,9 @@ func (h *Routes) UpdateRouteHandler(w http.ResponseWriter, r *http.Request) {
peerKey := req.Peer
if req.Peer != "" {
peer, err := h.accountManager.GetPeerByIP(account.Id, req.Peer)
if err != nil {
util.WriteError(err, w)
peer := account.GetPeerByIP(req.Peer)
if peer == nil {
util.WriteError(status.Errorf(status.NotFound, "peer %s not found", req.Peer), w)
return
}
peerKey = peer.Key
@ -165,7 +155,7 @@ func (h *Routes) UpdateRouteHandler(w http.ResponseWriter, r *http.Request) {
Groups: req.Groups,
}
err = h.accountManager.SaveRoute(account.Id, newRoute)
err = h.accountManager.SaveRoute(account.Id, user.Id, newRoute)
if err != nil {
util.WriteError(err, w)
return
@ -329,7 +319,7 @@ func (h *Routes) PatchRouteHandler(w http.ResponseWriter, r *http.Request) {
// DeleteRouteHandler handles route deletion request
func (h *Routes) DeleteRouteHandler(w http.ResponseWriter, r *http.Request) {
claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience)
account, _, err := h.accountManager.GetAccountFromToken(claims)
account, user, err := h.accountManager.GetAccountFromToken(claims)
if err != nil {
util.WriteError(err, w)
return
@ -341,7 +331,7 @@ func (h *Routes) DeleteRouteHandler(w http.ResponseWriter, r *http.Request) {
return
}
err = h.accountManager.DeleteRoute(account.Id, routeID)
err = h.accountManager.DeleteRoute(account.Id, routeID, user.Id)
if err != nil {
util.WriteError(err, w)
return

View File

@ -48,7 +48,7 @@ var testingAccount = &server.Account{
Domain: "hotmail.com",
Peers: map[string]*server.Peer{
existingPeerKey: {
Key: existingPeerID,
Key: existingPeerKey,
IP: netip.MustParseAddr(existingPeerID).AsSlice(),
},
},
@ -66,12 +66,18 @@ func initRoutesTestData() *Routes {
}
return nil, status.Errorf(status.NotFound, "route with ID %s not found", routeID)
},
CreateRouteFunc: func(accountID string, network, peer, description, netID string, masquerade bool, metric int, groups []string, enabled bool) (*route.Route, error) {
CreateRouteFunc: func(accountID string, network, peerIP, description, netID string, masquerade bool, metric int, groups []string, enabled bool, _ string) (*route.Route, error) {
peer := testingAccount.GetPeerByIP(peerIP)
if peer == nil {
return nil, status.Errorf(status.NotFound, "peer %s not found", peerIP)
}
networkType, p, _ := route.ParseNetwork(network)
return &route.Route{
ID: existingRouteID,
NetID: netID,
Peer: peer,
Peer: peer.Key,
Network: p,
NetworkType: networkType,
Description: description,
@ -80,12 +86,12 @@ func initRoutesTestData() *Routes {
Groups: groups,
}, nil
},
SaveRouteFunc: func(_ string, _ *route.Route) error {
SaveRouteFunc: func(_, _ string, _ *route.Route) error {
return nil
},
DeleteRouteFunc: func(_ string, peerIP string) error {
if peerIP != existingRouteID {
return status.Errorf(status.NotFound, "Peer with ID %s not found", peerIP)
DeleteRouteFunc: func(_ string, routeID string, _ string) error {
if routeID != existingRouteID {
return status.Errorf(status.NotFound, "Peer with ID %s not found", routeID)
}
return nil
},

View File

@ -44,21 +44,21 @@ type MockAccountManager struct {
GetUsersFromAccountFunc func(accountID, userID string) ([]*server.UserInfo, error)
UpdatePeerMetaFunc func(peerKey string, meta server.PeerSystemMeta) error
UpdatePeerSSHKeyFunc func(peerKey string, sshKey string) error
UpdatePeerFunc func(accountID string, peer *server.Peer) (*server.Peer, error)
CreateRouteFunc func(accountID string, prefix, peer, description, netID string, masquerade bool, metric int, groups []string, enabled bool) (*route.Route, error)
UpdatePeerFunc func(accountID, userID string, peer *server.Peer) (*server.Peer, error)
CreateRouteFunc func(accountID string, prefix, peer, description, netID string, masquerade bool, metric int, groups []string, enabled bool, userID string) (*route.Route, error)
GetRouteFunc func(accountID, routeID, userID string) (*route.Route, error)
SaveRouteFunc func(accountID string, route *route.Route) error
SaveRouteFunc func(accountID, userID string, route *route.Route) error
UpdateRouteFunc func(accountID string, routeID string, operations []server.RouteUpdateOperation) (*route.Route, error)
DeleteRouteFunc func(accountID, routeID string) error
DeleteRouteFunc func(accountID, routeID, userID string) error
ListRoutesFunc func(accountID, userID string) ([]*route.Route, error)
SaveSetupKeyFunc func(accountID string, key *server.SetupKey, userID string) (*server.SetupKey, error)
ListSetupKeysFunc func(accountID, userID string) ([]*server.SetupKey, error)
SaveUserFunc func(accountID, userID string, user *server.User) (*server.UserInfo, error)
GetNameServerGroupFunc func(accountID, nsGroupID string) (*nbdns.NameServerGroup, error)
CreateNameServerGroupFunc func(accountID string, name, description string, nameServerList []nbdns.NameServer, groups []string, primary bool, domains []string, enabled bool) (*nbdns.NameServerGroup, error)
SaveNameServerGroupFunc func(accountID string, nsGroupToSave *nbdns.NameServerGroup) error
UpdateNameServerGroupFunc func(accountID, nsGroupID string, operations []server.NameServerGroupUpdateOperation) (*nbdns.NameServerGroup, error)
DeleteNameServerGroupFunc func(accountID, nsGroupID string) error
CreateNameServerGroupFunc func(accountID string, name, description string, nameServerList []nbdns.NameServer, groups []string, primary bool, domains []string, enabled bool, userID string) (*nbdns.NameServerGroup, error)
SaveNameServerGroupFunc func(accountID, userID string, nsGroupToSave *nbdns.NameServerGroup) error
UpdateNameServerGroupFunc func(accountID, nsGroupID, userID string, operations []server.NameServerGroupUpdateOperation) (*nbdns.NameServerGroup, error)
DeleteNameServerGroupFunc func(accountID, nsGroupID, userID string) error
ListNameServerGroupsFunc func(accountID string) ([]*nbdns.NameServerGroup, error)
CreateUserFunc func(accountID, userID string, key *server.UserInfo) (*server.UserInfo, error)
GetAccountFromTokenFunc func(claims jwtclaims.AuthorizationClaims) (*server.Account, *server.User, error)
@ -323,17 +323,17 @@ func (am *MockAccountManager) UpdatePeerSSHKey(peerKey string, sshKey string) er
}
// UpdatePeer mocks UpdatePeerFunc function of the account manager
func (am *MockAccountManager) UpdatePeer(accountID string, peer *server.Peer) (*server.Peer, error) {
func (am *MockAccountManager) UpdatePeer(accountID, userID string, peer *server.Peer) (*server.Peer, error) {
if am.UpdatePeerFunc != nil {
return am.UpdatePeerFunc(accountID, peer)
return am.UpdatePeerFunc(accountID, userID, peer)
}
return nil, status.Errorf(codes.Unimplemented, "method UpdatePeerFunc is is not implemented")
}
// CreateRoute mock implementation of CreateRoute from server.AccountManager interface
func (am *MockAccountManager) CreateRoute(accountID string, network, peer, description, netID string, masquerade bool, metric int, groups []string, enabled bool) (*route.Route, error) {
func (am *MockAccountManager) CreateRoute(accountID string, network, peerIP, description, netID string, masquerade bool, metric int, groups []string, enabled bool, userID string) (*route.Route, error) {
if am.CreateRouteFunc != nil {
return am.CreateRouteFunc(accountID, network, peer, description, netID, masquerade, metric, groups, enabled)
return am.CreateRouteFunc(accountID, network, peerIP, description, netID, masquerade, metric, groups, enabled, userID)
}
return nil, status.Errorf(codes.Unimplemented, "method CreateRoute is not implemented")
}
@ -347,15 +347,15 @@ func (am *MockAccountManager) GetRoute(accountID, routeID, userID string) (*rout
}
// SaveRoute mock implementation of SaveRoute from server.AccountManager interface
func (am *MockAccountManager) SaveRoute(accountID string, route *route.Route) error {
func (am *MockAccountManager) SaveRoute(accountID, userID string, route *route.Route) error {
if am.SaveRouteFunc != nil {
return am.SaveRouteFunc(accountID, route)
return am.SaveRouteFunc(accountID, userID, route)
}
return status.Errorf(codes.Unimplemented, "method SaveRoute is not implemented")
}
// UpdateRoute mock implementation of UpdateRoute from server.AccountManager interface
func (am *MockAccountManager) UpdateRoute(accountID string, ruleID string, operations []server.RouteUpdateOperation) (*route.Route, error) {
func (am *MockAccountManager) UpdateRoute(accountID, ruleID string, operations []server.RouteUpdateOperation) (*route.Route, error) {
if am.UpdateRouteFunc != nil {
return am.UpdateRouteFunc(accountID, ruleID, operations)
}
@ -363,9 +363,9 @@ func (am *MockAccountManager) UpdateRoute(accountID string, ruleID string, opera
}
// DeleteRoute mock implementation of DeleteRoute from server.AccountManager interface
func (am *MockAccountManager) DeleteRoute(accountID, routeID string) error {
func (am *MockAccountManager) DeleteRoute(accountID, routeID, userID string) error {
if am.DeleteRouteFunc != nil {
return am.DeleteRouteFunc(accountID, routeID)
return am.DeleteRouteFunc(accountID, routeID, userID)
}
return status.Errorf(codes.Unimplemented, "method DeleteRoute is not implemented")
}
@ -422,33 +422,33 @@ func (am *MockAccountManager) GetNameServerGroup(accountID, nsGroupID string) (*
}
// CreateNameServerGroup mocks CreateNameServerGroup of the AccountManager interface
func (am *MockAccountManager) CreateNameServerGroup(accountID string, name, description string, nameServerList []nbdns.NameServer, groups []string, primary bool, domains []string, enabled bool) (*nbdns.NameServerGroup, error) {
func (am *MockAccountManager) CreateNameServerGroup(accountID string, name, description string, nameServerList []nbdns.NameServer, groups []string, primary bool, domains []string, enabled bool, userID string) (*nbdns.NameServerGroup, error) {
if am.CreateNameServerGroupFunc != nil {
return am.CreateNameServerGroupFunc(accountID, name, description, nameServerList, groups, primary, domains, enabled)
return am.CreateNameServerGroupFunc(accountID, name, description, nameServerList, groups, primary, domains, enabled, userID)
}
return nil, nil
}
// SaveNameServerGroup mocks SaveNameServerGroup of the AccountManager interface
func (am *MockAccountManager) SaveNameServerGroup(accountID string, nsGroupToSave *nbdns.NameServerGroup) error {
func (am *MockAccountManager) SaveNameServerGroup(accountID, userID string, nsGroupToSave *nbdns.NameServerGroup) error {
if am.SaveNameServerGroupFunc != nil {
return am.SaveNameServerGroupFunc(accountID, nsGroupToSave)
return am.SaveNameServerGroupFunc(accountID, userID, nsGroupToSave)
}
return nil
}
// UpdateNameServerGroup mocks UpdateNameServerGroup of the AccountManager interface
func (am *MockAccountManager) UpdateNameServerGroup(accountID, nsGroupID string, operations []server.NameServerGroupUpdateOperation) (*nbdns.NameServerGroup, error) {
func (am *MockAccountManager) UpdateNameServerGroup(accountID, nsGroupID, userID string, operations []server.NameServerGroupUpdateOperation) (*nbdns.NameServerGroup, error) {
if am.UpdateNameServerGroupFunc != nil {
return am.UpdateNameServerGroupFunc(accountID, nsGroupID, operations)
return am.UpdateNameServerGroupFunc(accountID, nsGroupID, userID, operations)
}
return nil, nil
}
// DeleteNameServerGroup mocks DeleteNameServerGroup of the AccountManager interface
func (am *MockAccountManager) DeleteNameServerGroup(accountID, nsGroupID string) error {
func (am *MockAccountManager) DeleteNameServerGroup(accountID, nsGroupID, userID string) error {
if am.DeleteNameServerGroupFunc != nil {
return am.DeleteNameServerGroupFunc(accountID, nsGroupID)
return am.DeleteNameServerGroupFunc(accountID, nsGroupID, userID)
}
return nil
}

View File

@ -3,6 +3,7 @@ package server
import (
"github.com/miekg/dns"
nbdns "github.com/netbirdio/netbird/dns"
"github.com/netbirdio/netbird/management/server/activity"
"github.com/netbirdio/netbird/management/server/status"
"github.com/rs/xid"
log "github.com/sirupsen/logrus"
@ -77,7 +78,7 @@ func (am *DefaultAccountManager) GetNameServerGroup(accountID, nsGroupID string)
}
// CreateNameServerGroup creates and saves a new nameserver group
func (am *DefaultAccountManager) CreateNameServerGroup(accountID string, name, description string, nameServerList []nbdns.NameServer, groups []string, primary bool, domains []string, enabled bool) (*nbdns.NameServerGroup, error) {
func (am *DefaultAccountManager) CreateNameServerGroup(accountID string, name, description string, nameServerList []nbdns.NameServer, groups []string, primary bool, domains []string, enabled bool, userID string) (*nbdns.NameServerGroup, error) {
unlock := am.Store.AcquireAccountLock(accountID)
defer unlock()
@ -121,11 +122,13 @@ func (am *DefaultAccountManager) CreateNameServerGroup(accountID string, name, d
return newNSGroup.Copy(), status.Errorf(status.Internal, "failed to update peers after create nameserver %s", name)
}
am.storeEvent(userID, newNSGroup.ID, accountID, activity.NameserverGroupCreated, newNSGroup.EventMeta())
return newNSGroup.Copy(), nil
}
// SaveNameServerGroup saves nameserver group
func (am *DefaultAccountManager) SaveNameServerGroup(accountID string, nsGroupToSave *nbdns.NameServerGroup) error {
func (am *DefaultAccountManager) SaveNameServerGroup(accountID, userID string, nsGroupToSave *nbdns.NameServerGroup) error {
unlock := am.Store.AcquireAccountLock(accountID)
defer unlock()
@ -158,11 +161,13 @@ func (am *DefaultAccountManager) SaveNameServerGroup(accountID string, nsGroupTo
return status.Errorf(status.Internal, "failed to update peers after update nameserver %s", nsGroupToSave.Name)
}
am.storeEvent(userID, nsGroupToSave.ID, accountID, activity.NameserverGroupUpdated, nsGroupToSave.EventMeta())
return nil
}
// UpdateNameServerGroup updates existing nameserver group with set of operations
func (am *DefaultAccountManager) UpdateNameServerGroup(accountID, nsGroupID string, operations []NameServerGroupUpdateOperation) (*nbdns.NameServerGroup, error) {
func (am *DefaultAccountManager) UpdateNameServerGroup(accountID, nsGroupID, userID string, operations []NameServerGroupUpdateOperation) (*nbdns.NameServerGroup, error) {
unlock := am.Store.AcquireAccountLock(accountID)
defer unlock()
@ -265,7 +270,7 @@ func (am *DefaultAccountManager) UpdateNameServerGroup(accountID, nsGroupID stri
}
// DeleteNameServerGroup deletes nameserver group with nsGroupID
func (am *DefaultAccountManager) DeleteNameServerGroup(accountID, nsGroupID string) error {
func (am *DefaultAccountManager) DeleteNameServerGroup(accountID, nsGroupID, userID string) error {
unlock := am.Store.AcquireAccountLock(accountID)
defer unlock()
@ -275,6 +280,10 @@ func (am *DefaultAccountManager) DeleteNameServerGroup(accountID, nsGroupID stri
return err
}
nsGroup := account.NameServerGroups[nsGroupID]
if nsGroup == nil {
return status.Errorf(status.NotFound, "nameserver group %s wasn't found", nsGroupID)
}
delete(account.NameServerGroups, nsGroupID)
account.Network.IncSerial()
@ -285,10 +294,11 @@ func (am *DefaultAccountManager) DeleteNameServerGroup(accountID, nsGroupID stri
err = am.updateAccountPeers(account)
if err != nil {
log.Error(err)
return status.Errorf(status.Internal, "failed to update peers after deleting nameserver %s", nsGroupID)
}
am.storeEvent(userID, nsGroup.ID, accountID, activity.NameserverGroupDeleted, nsGroup.EventMeta())
return nil
}

View File

@ -380,6 +380,7 @@ func TestCreateNameServerGroup(t *testing.T) {
testCase.inputArgs.primary,
testCase.inputArgs.domains,
testCase.inputArgs.enabled,
userID,
)
testCase.errFunc(t, err)
@ -628,7 +629,7 @@ func TestSaveNameServerGroup(t *testing.T) {
}
}
err = am.SaveNameServerGroup(account.Id, nsGroupToSave)
err = am.SaveNameServerGroup(account.Id, userID, nsGroupToSave)
testCase.errFunc(t, err)
@ -952,7 +953,7 @@ func TestUpdateNameServerGroup(t *testing.T) {
t.Error("account should be saved")
}
updatedRoute, err := am.UpdateNameServerGroup(account.Id, testCase.nsGroupID, testCase.operations)
updatedRoute, err := am.UpdateNameServerGroup(account.Id, testCase.nsGroupID, userID, testCase.operations)
testCase.errFunc(t, err)
if !testCase.shouldCreate {
@ -1009,7 +1010,7 @@ func TestDeleteNameServerGroup(t *testing.T) {
t.Error("failed to save account")
}
err = am.DeleteNameServerGroup(account.Id, testingNSGroup.ID)
err = am.DeleteNameServerGroup(account.Id, testingNSGroup.ID, userID)
if err != nil {
t.Error("deleting nameserver group failed with error: ", err)
}

View File

@ -185,7 +185,7 @@ func (am *DefaultAccountManager) MarkPeerConnected(peerPubKey string, connected
}
// UpdatePeer updates peer. Only Peer.Name and Peer.SSHEnabled can be updated.
func (am *DefaultAccountManager) UpdatePeer(accountID string, update *Peer) (*Peer, error) {
func (am *DefaultAccountManager) UpdatePeer(accountID, userID string, update *Peer) (*Peer, error) {
unlock := am.Store.AcquireAccountLock(accountID)
defer unlock()
@ -201,7 +201,14 @@ func (am *DefaultAccountManager) UpdatePeer(accountID string, update *Peer) (*Pe
return nil, err
}
peer.SSHEnabled = update.SSHEnabled
if peer.SSHEnabled != update.SSHEnabled {
peer.SSHEnabled = update.SSHEnabled
event := activity.PeerSSHEnabled
if !update.SSHEnabled {
event = activity.PeerSSHDisabled
}
am.storeEvent(userID, peer.IP.String(), accountID, event, peer.EventMeta(am.GetDNSDomain()))
}
if peer.Name != update.Name {
peer.Name = update.Name
@ -214,6 +221,8 @@ func (am *DefaultAccountManager) UpdatePeer(accountID string, update *Peer) (*Pe
}
peer.DNSLabel = newLabel
am.storeEvent(userID, peer.IP.String(), accountID, activity.PeerRenamed, peer.EventMeta(am.GetDNSDomain()))
}
account.UpdatePeer(peer)

View File

@ -2,6 +2,7 @@ package server
import (
"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"
@ -118,7 +119,7 @@ func (am *DefaultAccountManager) checkPrefixPeerExists(accountID, peer string, p
}
// CreateRoute creates and saves a new route
func (am *DefaultAccountManager) CreateRoute(accountID string, network, peer, description, netID string, masquerade bool, metric int, groups []string, enabled bool) (*route.Route, error) {
func (am *DefaultAccountManager) CreateRoute(accountID string, network, peerIP, description, netID string, masquerade bool, metric int, groups []string, enabled bool, userID string) (*route.Route, error) {
unlock := am.Store.AcquireAccountLock(accountID)
defer unlock()
@ -127,23 +128,25 @@ func (am *DefaultAccountManager) CreateRoute(accountID string, network, peer, de
return nil, err
}
peerKey := ""
if peerIP != "" {
peer := account.GetPeerByIP(peerIP)
if peer == nil {
return nil, status.Errorf(status.NotFound, "peer %s not found", peerIP)
}
peerKey = peer.Key
}
var newRoute route.Route
prefixType, newPrefix, err := route.ParseNetwork(network)
if err != nil {
return nil, status.Errorf(status.InvalidArgument, "failed to parse IP %s", network)
}
err = am.checkPrefixPeerExists(accountID, peer, newPrefix)
err = am.checkPrefixPeerExists(accountID, peerKey, newPrefix)
if err != nil {
return nil, err
}
if peer != "" {
_, peerExist := account.Peers[peer]
if !peerExist {
return nil, status.Errorf(status.InvalidArgument, "failed to find Peer %s", peer)
}
}
if metric < route.MinMetric || metric > route.MaxMetric {
return nil, status.Errorf(status.InvalidArgument, "metric should be between %d and %d", route.MinMetric, route.MaxMetric)
}
@ -157,7 +160,7 @@ func (am *DefaultAccountManager) CreateRoute(accountID string, network, peer, de
return nil, err
}
newRoute.Peer = peer
newRoute.Peer = peerKey
newRoute.ID = xid.New().String()
newRoute.Network = newPrefix
newRoute.NetworkType = prefixType
@ -184,11 +187,14 @@ func (am *DefaultAccountManager) CreateRoute(accountID string, network, peer, de
log.Error(err)
return &newRoute, status.Errorf(status.Internal, "failed to update peers after create route %s", newPrefix)
}
am.storeEvent(userID, newRoute.ID, accountID, activity.RouteCreated, newRoute.EventMeta())
return &newRoute, nil
}
// SaveRoute saves route
func (am *DefaultAccountManager) SaveRoute(accountID string, routeToSave *route.Route) error {
func (am *DefaultAccountManager) SaveRoute(accountID, userID string, routeToSave *route.Route) error {
unlock := am.Store.AcquireAccountLock(accountID)
defer unlock()
@ -232,6 +238,8 @@ func (am *DefaultAccountManager) SaveRoute(accountID string, routeToSave *route.
return err
}
am.storeEvent(userID, routeToSave.ID, accountID, activity.RouteUpdated, routeToSave.EventMeta())
return am.updateAccountPeers(account)
}
@ -339,7 +347,7 @@ func (am *DefaultAccountManager) UpdateRoute(accountID, routeID string, operatio
}
// DeleteRoute deletes route with routeID
func (am *DefaultAccountManager) DeleteRoute(accountID, routeID string) error {
func (am *DefaultAccountManager) DeleteRoute(accountID, routeID, userID string) error {
unlock := am.Store.AcquireAccountLock(accountID)
defer unlock()
@ -348,6 +356,10 @@ func (am *DefaultAccountManager) DeleteRoute(accountID, routeID string) error {
return err
}
routy := account.Routes[routeID]
if routy == nil {
return status.Errorf(status.NotFound, "route with ID %s doesn't exist", routeID)
}
delete(account.Routes, routeID)
account.Network.IncSerial()
@ -355,6 +367,8 @@ func (am *DefaultAccountManager) DeleteRoute(accountID, routeID string) error {
return err
}
am.storeEvent(userID, routy.ID, accountID, activity.RouteRemoved, routy.EventMeta())
return am.updateAccountPeers(account)
}

View File

@ -238,16 +238,25 @@ func TestCreateRoute(t *testing.T) {
t.Error("failed to init testing account")
}
peerIP := "99.99.99.99"
peer := account.Peers[testCase.inputArgs.peer]
if testCase.inputArgs.peer == "" {
peerIP = ""
} else if peer != nil {
peerIP = peer.IP.String()
}
outRoute, err := am.CreateRoute(
account.Id,
testCase.inputArgs.network,
testCase.inputArgs.peer,
peerIP,
testCase.inputArgs.description,
testCase.inputArgs.netID,
testCase.inputArgs.masquerade,
testCase.inputArgs.metric,
testCase.inputArgs.groups,
testCase.inputArgs.enabled,
userID,
)
testCase.errFunc(t, err)
@ -500,7 +509,7 @@ func TestSaveRoute(t *testing.T) {
}
}
err = am.SaveRoute(account.Id, routeToSave)
err = am.SaveRoute(account.Id, userID, routeToSave)
testCase.errFunc(t, err)
@ -814,7 +823,7 @@ func TestDeleteRoute(t *testing.T) {
t.Error("failed to save account")
}
err = am.DeleteRoute(account.Id, testingRoute.ID)
err = am.DeleteRoute(account.Id, testingRoute.ID, userID)
if err != nil {
t.Error("deleting route failed with error: ", err)
}
@ -859,9 +868,11 @@ func TestGetNetworkMap_RouteSync(t *testing.T) {
newAccountRoutes, err := am.GetNetworkMap(peer1Key)
require.NoError(t, err)
require.Len(t, newAccountRoutes.Routes, 0, "new accounts should have no routes")
peer := account.Peers[baseRoute.Peer]
createdRoute, err := am.CreateRoute(account.Id, baseRoute.Network.String(), baseRoute.Peer,
baseRoute.Description, baseRoute.NetID, baseRoute.Masquerade, baseRoute.Metric, baseRoute.Groups, false)
createdRoute, err := am.CreateRoute(account.Id, baseRoute.Network.String(), peer.IP.String(),
baseRoute.Description, baseRoute.NetID, baseRoute.Masquerade, baseRoute.Metric, baseRoute.Groups, false,
userID)
require.NoError(t, err)
noDisabledRoutes, err := am.GetNetworkMap(peer1Key)
@ -871,7 +882,7 @@ func TestGetNetworkMap_RouteSync(t *testing.T) {
enabledRoute := createdRoute.Copy()
enabledRoute.Enabled = true
err = am.SaveRoute(account.Id, enabledRoute)
err = am.SaveRoute(account.Id, userID, enabledRoute)
require.NoError(t, err)
peer1Routes, err := am.GetNetworkMap(peer1Key)
@ -923,7 +934,7 @@ func TestGetNetworkMap_RouteSync(t *testing.T) {
require.NoError(t, err)
require.Len(t, peer2GroupRoutes.Routes, 0, "we should not receive routes for peer2")
err = am.DeleteRoute(account.Id, enabledRoute.ID)
err = am.DeleteRoute(account.Id, enabledRoute.ID, userID)
require.NoError(t, err)
peer1DeletedRoute, err := am.GetNetworkMap(peer1Key)
@ -952,6 +963,7 @@ func createRouterStore(t *testing.T) (Store, error) {
}
func initTestRouteAccount(t *testing.T, am *DefaultAccountManager) (*Account, error) {
peer1 := &Peer{
Key: peer1Key,
Name: "test-host1@netbird.io",

View File

@ -76,6 +76,11 @@ type Route struct {
Groups []string
}
// EventMeta returns activity event meta related to the route
func (r *Route) EventMeta() map[string]any {
return map[string]any{"name": r.NetID, "network_range": r.Network.String()}
}
// Copy copies a route object
func (r *Route) Copy() *Route {
return &Route{