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 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 // Copy copies a nameserver object
func (n *NameServer) Copy() *NameServer { func (n *NameServer) Copy() *NameServer {
return &NameServer{ return &NameServer{

View File

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

View File

@ -49,6 +49,24 @@ const (
GroupAddedToDisabledManagementGroups GroupAddedToDisabledManagementGroups
// GroupRemovedFromDisabledManagementGroups indicates that a user removed a group from the DNS setting Disabled management groups // GroupRemovedFromDisabledManagementGroups indicates that a user removed a group from the DNS setting Disabled management groups
GroupRemovedFromDisabledManagementGroups 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 ( const (
@ -100,6 +118,24 @@ const (
GroupAddedToDisabledManagementGroupsMessage string = "Group added to disabled management DNS setting" GroupAddedToDisabledManagementGroupsMessage string = "Group added to disabled management DNS setting"
// GroupRemovedFromDisabledManagementGroupsMessage is a human-readable text message of the GroupRemovedFromDisabledManagementGroups activity // GroupRemovedFromDisabledManagementGroupsMessage is a human-readable text message of the GroupRemovedFromDisabledManagementGroups activity
GroupRemovedFromDisabledManagementGroupsMessage string = "Group removed from disabled management DNS setting" 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 // Activity that triggered an Event
@ -156,6 +192,24 @@ func (a Activity) Message() string {
return GroupAddedToDisabledManagementGroupsMessage return GroupAddedToDisabledManagementGroupsMessage
case GroupRemovedFromDisabledManagementGroups: case GroupRemovedFromDisabledManagementGroups:
return GroupRemovedFromDisabledManagementGroupsMessage 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: default:
return "UNKNOWN_ACTIVITY" return "UNKNOWN_ACTIVITY"
} }
@ -212,6 +266,24 @@ func (a Activity) StringCode() string {
return "dns.setting.disabled.management.group.add" return "dns.setting.disabled.management.group.add"
case GroupRemovedFromDisabledManagementGroups: case GroupRemovedFromDisabledManagementGroups:
return "dns.setting.disabled.management.group.delete" 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: default:
return "UNKNOWN_ACTIVITY" return "UNKNOWN_ACTIVITY"
} }

View File

@ -535,7 +535,10 @@ components:
"setupkey.group.delete", "setupkey.group.add", "setupkey.group.delete", "setupkey.group.add",
"rule.add", "rule.delete", "rule.update", "rule.add", "rule.delete", "rule.update",
"group.add", "group.update", "dns.setting.disabled.management.group.add", "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: initiator_id:
description: The ID of the initiator of the event. E.g., an ID of a user that triggered the event. 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" EventActivityCodeDnsSettingDisabledManagementGroupDelete EventActivityCode = "dns.setting.disabled.management.group.delete"
EventActivityCodeGroupAdd EventActivityCode = "group.add" EventActivityCodeGroupAdd EventActivityCode = "group.add"
EventActivityCodeGroupUpdate EventActivityCode = "group.update" 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" EventActivityCodeRuleAdd EventActivityCode = "rule.add"
EventActivityCodeRuleDelete EventActivityCode = "rule.delete" EventActivityCodeRuleDelete EventActivityCode = "rule.delete"
EventActivityCodeRuleUpdate EventActivityCode = "rule.update" 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 // CreateNameserverGroupHandler handles nameserver group creation request
func (h *Nameservers) CreateNameserverGroupHandler(w http.ResponseWriter, r *http.Request) { func (h *Nameservers) CreateNameserverGroupHandler(w http.ResponseWriter, r *http.Request) {
claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience) claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience)
account, _, err := h.accountManager.GetAccountFromToken(claims) account, user, err := h.accountManager.GetAccountFromToken(claims)
if err != nil { if err != nil {
util.WriteError(err, w) util.WriteError(err, w)
return return
@ -76,7 +76,7 @@ func (h *Nameservers) CreateNameserverGroupHandler(w http.ResponseWriter, r *htt
return 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 { if err != nil {
util.WriteError(err, w) util.WriteError(err, w)
return 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 // UpdateNameserverGroupHandler handles update to a nameserver group identified by a given ID
func (h *Nameservers) UpdateNameserverGroupHandler(w http.ResponseWriter, r *http.Request) { func (h *Nameservers) UpdateNameserverGroupHandler(w http.ResponseWriter, r *http.Request) {
claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience) claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience)
account, _, err := h.accountManager.GetAccountFromToken(claims) account, user, err := h.accountManager.GetAccountFromToken(claims)
if err != nil { if err != nil {
util.WriteError(err, w) util.WriteError(err, w)
return return
@ -126,7 +126,7 @@ func (h *Nameservers) UpdateNameserverGroupHandler(w http.ResponseWriter, r *htt
Enabled: req.Enabled, Enabled: req.Enabled,
} }
err = h.accountManager.SaveNameServerGroup(account.Id, updatedNSGroup) err = h.accountManager.SaveNameServerGroup(account.Id, user.Id, updatedNSGroup)
if err != nil { if err != nil {
util.WriteError(err, w) util.WriteError(err, w)
return 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 // PatchNameserverGroupHandler handles patch updates to a nameserver group identified by a given ID
func (h *Nameservers) PatchNameserverGroupHandler(w http.ResponseWriter, r *http.Request) { func (h *Nameservers) PatchNameserverGroupHandler(w http.ResponseWriter, r *http.Request) {
claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience) claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience)
account, _, err := h.accountManager.GetAccountFromToken(claims) account, user, err := h.accountManager.GetAccountFromToken(claims)
if err != nil { if err != nil {
util.WriteError(err, w) util.WriteError(err, w)
return 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 { if err != nil {
util.WriteError(err, w) util.WriteError(err, w)
return return
@ -222,7 +222,7 @@ func (h *Nameservers) PatchNameserverGroupHandler(w http.ResponseWriter, r *http
// DeleteNameserverGroupHandler handles nameserver group deletion request // DeleteNameserverGroupHandler handles nameserver group deletion request
func (h *Nameservers) DeleteNameserverGroupHandler(w http.ResponseWriter, r *http.Request) { func (h *Nameservers) DeleteNameserverGroupHandler(w http.ResponseWriter, r *http.Request) {
claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience) claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience)
account, _, err := h.accountManager.GetAccountFromToken(claims) account, user, err := h.accountManager.GetAccountFromToken(claims)
if err != nil { if err != nil {
util.WriteError(err, w) util.WriteError(err, w)
return return
@ -234,7 +234,7 @@ func (h *Nameservers) DeleteNameserverGroupHandler(w http.ResponseWriter, r *htt
return return
} }
err = h.accountManager.DeleteNameServerGroup(account.Id, nsGroupID) err = h.accountManager.DeleteNameServerGroup(account.Id, nsGroupID, user.Id)
if err != nil { if err != nil {
util.WriteError(err, w) util.WriteError(err, w)
return return

View File

@ -63,7 +63,7 @@ func initNameserversTestData() *Nameservers {
} }
return nil, status.Errorf(status.NotFound, "nameserver group with ID %s not found", nsGroupID) 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{ return &nbdns.NameServerGroup{
ID: existingNSGroupID, ID: existingNSGroupID,
Name: name, Name: name,
@ -75,16 +75,16 @@ func initNameserversTestData() *Nameservers {
Domains: domains, Domains: domains,
}, nil }, nil
}, },
DeleteNameServerGroupFunc: func(accountID, nsGroupID string) error { DeleteNameServerGroupFunc: func(accountID, nsGroupID, _ string) error {
return nil return nil
}, },
SaveNameServerGroupFunc: func(accountID string, nsGroupToSave *nbdns.NameServerGroup) error { SaveNameServerGroupFunc: func(accountID, _ string, nsGroupToSave *nbdns.NameServerGroup) error {
if nsGroupToSave.ID == existingNSGroupID { if nsGroupToSave.ID == existingNSGroupID {
return nil return nil
} }
return status.Errorf(status.NotFound, "nameserver group with ID %s was not found", nsGroupToSave.ID) 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() nsGroupToUpdate := baseExistingNSGroup.Copy()
if nsGroupID != nsGroupToUpdate.ID { if nsGroupID != nsGroupToUpdate.ID {
return nil, status.Errorf(status.NotFound, "nameserver group ID %s no longer exists", nsGroupID) return nil, status.Errorf(status.NotFound, "nameserver group ID %s no longer exists", nsGroupID)
@ -110,7 +110,7 @@ func initNameserversTestData() *Nameservers {
return nsGroupToUpdate, nil return nsGroupToUpdate, nil
}, },
GetAccountFromTokenFunc: func(_ jwtclaims.AuthorizationClaims) (*server.Account, *server.User, error) { GetAccountFromTokenFunc: func(_ jwtclaims.AuthorizationClaims) (*server.Account, *server.User, error) {
return testingNSAccount, nil, nil return testingNSAccount, testingAccount.Users["test_user"], nil
}, },
}, },
authAudience: "", 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{} req := &api.PutApiPeersIdJSONBody{}
err := json.NewDecoder(r.Body).Decode(&req) err := json.NewDecoder(r.Body).Decode(&req)
if err != nil { 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} 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 { if err != nil {
util.WriteError(err, w) util.WriteError(err, w)
return return
@ -81,7 +81,7 @@ func (h *Peers) HandlePeer(w http.ResponseWriter, r *http.Request) {
h.deletePeer(account.Id, user.Id, peer, w, r) h.deletePeer(account.Id, user.Id, peer, w, r)
return return
case http.MethodPut: case http.MethodPut:
h.updatePeer(account, peer, w, r) h.updatePeer(account, user, peer, w, r)
return return
case http.MethodGet: case http.MethodGet:
util.WriteJSONObject(w, toPeerResponse(peer, account, dnsDomain)) 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 // CreateRouteHandler handles route creation request
func (h *Routes) CreateRouteHandler(w http.ResponseWriter, r *http.Request) { func (h *Routes) CreateRouteHandler(w http.ResponseWriter, r *http.Request) {
claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience) claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience)
account, _, err := h.accountManager.GetAccountFromToken(claims) account, user, err := h.accountManager.GetAccountFromToken(claims)
if err != nil { if err != nil {
util.WriteError(err, w) util.WriteError(err, w)
return return
@ -67,16 +67,6 @@ func (h *Routes) CreateRouteHandler(w http.ResponseWriter, r *http.Request) {
return 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) _, newPrefix, err := route.ParseNetwork(req.Network)
if err != nil { if err != nil {
util.WriteError(err, w) util.WriteError(err, w)
@ -89,7 +79,7 @@ func (h *Routes) CreateRouteHandler(w http.ResponseWriter, r *http.Request) {
return 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 { if err != nil {
util.WriteError(err, w) util.WriteError(err, w)
return return
@ -138,9 +128,9 @@ func (h *Routes) UpdateRouteHandler(w http.ResponseWriter, r *http.Request) {
peerKey := req.Peer peerKey := req.Peer
if req.Peer != "" { if req.Peer != "" {
peer, err := h.accountManager.GetPeerByIP(account.Id, req.Peer) peer := account.GetPeerByIP(req.Peer)
if err != nil { if peer == nil {
util.WriteError(err, w) util.WriteError(status.Errorf(status.NotFound, "peer %s not found", req.Peer), w)
return return
} }
peerKey = peer.Key peerKey = peer.Key
@ -165,7 +155,7 @@ func (h *Routes) UpdateRouteHandler(w http.ResponseWriter, r *http.Request) {
Groups: req.Groups, Groups: req.Groups,
} }
err = h.accountManager.SaveRoute(account.Id, newRoute) err = h.accountManager.SaveRoute(account.Id, user.Id, newRoute)
if err != nil { if err != nil {
util.WriteError(err, w) util.WriteError(err, w)
return return
@ -329,7 +319,7 @@ func (h *Routes) PatchRouteHandler(w http.ResponseWriter, r *http.Request) {
// DeleteRouteHandler handles route deletion request // DeleteRouteHandler handles route deletion request
func (h *Routes) DeleteRouteHandler(w http.ResponseWriter, r *http.Request) { func (h *Routes) DeleteRouteHandler(w http.ResponseWriter, r *http.Request) {
claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience) claims := h.jwtExtractor.ExtractClaimsFromRequestContext(r, h.authAudience)
account, _, err := h.accountManager.GetAccountFromToken(claims) account, user, err := h.accountManager.GetAccountFromToken(claims)
if err != nil { if err != nil {
util.WriteError(err, w) util.WriteError(err, w)
return return
@ -341,7 +331,7 @@ func (h *Routes) DeleteRouteHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
err = h.accountManager.DeleteRoute(account.Id, routeID) err = h.accountManager.DeleteRoute(account.Id, routeID, user.Id)
if err != nil { if err != nil {
util.WriteError(err, w) util.WriteError(err, w)
return return

View File

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

View File

@ -44,21 +44,21 @@ type MockAccountManager struct {
GetUsersFromAccountFunc func(accountID, userID string) ([]*server.UserInfo, error) GetUsersFromAccountFunc func(accountID, userID string) ([]*server.UserInfo, error)
UpdatePeerMetaFunc func(peerKey string, meta server.PeerSystemMeta) error UpdatePeerMetaFunc func(peerKey string, meta server.PeerSystemMeta) error
UpdatePeerSSHKeyFunc func(peerKey string, sshKey string) error UpdatePeerSSHKeyFunc func(peerKey string, sshKey string) error
UpdatePeerFunc func(accountID string, peer *server.Peer) (*server.Peer, 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) (*route.Route, 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) 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) 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) ListRoutesFunc func(accountID, userID string) ([]*route.Route, error)
SaveSetupKeyFunc func(accountID string, key *server.SetupKey, userID string) (*server.SetupKey, error) SaveSetupKeyFunc func(accountID string, key *server.SetupKey, userID string) (*server.SetupKey, error)
ListSetupKeysFunc func(accountID, userID string) ([]*server.SetupKey, error) ListSetupKeysFunc func(accountID, userID string) ([]*server.SetupKey, error)
SaveUserFunc func(accountID, userID string, user *server.User) (*server.UserInfo, error) SaveUserFunc func(accountID, userID string, user *server.User) (*server.UserInfo, error)
GetNameServerGroupFunc func(accountID, nsGroupID string) (*nbdns.NameServerGroup, 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) 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 string, nsGroupToSave *nbdns.NameServerGroup) error SaveNameServerGroupFunc func(accountID, userID string, nsGroupToSave *nbdns.NameServerGroup) error
UpdateNameServerGroupFunc func(accountID, nsGroupID string, operations []server.NameServerGroupUpdateOperation) (*nbdns.NameServerGroup, error) UpdateNameServerGroupFunc func(accountID, nsGroupID, userID string, operations []server.NameServerGroupUpdateOperation) (*nbdns.NameServerGroup, error)
DeleteNameServerGroupFunc func(accountID, nsGroupID string) error DeleteNameServerGroupFunc func(accountID, nsGroupID, userID string) error
ListNameServerGroupsFunc func(accountID string) ([]*nbdns.NameServerGroup, error) ListNameServerGroupsFunc func(accountID string) ([]*nbdns.NameServerGroup, error)
CreateUserFunc func(accountID, userID string, key *server.UserInfo) (*server.UserInfo, error) CreateUserFunc func(accountID, userID string, key *server.UserInfo) (*server.UserInfo, error)
GetAccountFromTokenFunc func(claims jwtclaims.AuthorizationClaims) (*server.Account, *server.User, 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 // 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 { 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") return nil, status.Errorf(codes.Unimplemented, "method UpdatePeerFunc is is not implemented")
} }
// CreateRoute mock implementation of CreateRoute from server.AccountManager interface // 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 { 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") 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 // 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 { 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") return status.Errorf(codes.Unimplemented, "method SaveRoute is not implemented")
} }
// UpdateRoute mock implementation of UpdateRoute from server.AccountManager interface // 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 { if am.UpdateRouteFunc != nil {
return am.UpdateRouteFunc(accountID, ruleID, operations) 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 // 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 { 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") 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 // 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 { 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 return nil, nil
} }
// SaveNameServerGroup mocks SaveNameServerGroup of the AccountManager interface // 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 { if am.SaveNameServerGroupFunc != nil {
return am.SaveNameServerGroupFunc(accountID, nsGroupToSave) return am.SaveNameServerGroupFunc(accountID, userID, nsGroupToSave)
} }
return nil return nil
} }
// UpdateNameServerGroup mocks UpdateNameServerGroup of the AccountManager interface // 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 { if am.UpdateNameServerGroupFunc != nil {
return am.UpdateNameServerGroupFunc(accountID, nsGroupID, operations) return am.UpdateNameServerGroupFunc(accountID, nsGroupID, userID, operations)
} }
return nil, nil return nil, nil
} }
// DeleteNameServerGroup mocks DeleteNameServerGroup of the AccountManager interface // 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 { if am.DeleteNameServerGroupFunc != nil {
return am.DeleteNameServerGroupFunc(accountID, nsGroupID) return am.DeleteNameServerGroupFunc(accountID, nsGroupID, userID)
} }
return nil return nil
} }

View File

@ -3,6 +3,7 @@ package server
import ( import (
"github.com/miekg/dns" "github.com/miekg/dns"
nbdns "github.com/netbirdio/netbird/dns" nbdns "github.com/netbirdio/netbird/dns"
"github.com/netbirdio/netbird/management/server/activity"
"github.com/netbirdio/netbird/management/server/status" "github.com/netbirdio/netbird/management/server/status"
"github.com/rs/xid" "github.com/rs/xid"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@ -77,7 +78,7 @@ func (am *DefaultAccountManager) GetNameServerGroup(accountID, nsGroupID string)
} }
// CreateNameServerGroup creates and saves a new nameserver group // 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) unlock := am.Store.AcquireAccountLock(accountID)
defer unlock() 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) 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 return newNSGroup.Copy(), nil
} }
// SaveNameServerGroup saves nameserver group // 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) unlock := am.Store.AcquireAccountLock(accountID)
defer unlock() 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) 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 return nil
} }
// UpdateNameServerGroup updates existing nameserver group with set of operations // 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) unlock := am.Store.AcquireAccountLock(accountID)
defer unlock() defer unlock()
@ -265,7 +270,7 @@ func (am *DefaultAccountManager) UpdateNameServerGroup(accountID, nsGroupID stri
} }
// DeleteNameServerGroup deletes nameserver group with nsGroupID // 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) unlock := am.Store.AcquireAccountLock(accountID)
defer unlock() defer unlock()
@ -275,6 +280,10 @@ func (am *DefaultAccountManager) DeleteNameServerGroup(accountID, nsGroupID stri
return err 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) delete(account.NameServerGroups, nsGroupID)
account.Network.IncSerial() account.Network.IncSerial()
@ -285,10 +294,11 @@ func (am *DefaultAccountManager) DeleteNameServerGroup(accountID, nsGroupID stri
err = am.updateAccountPeers(account) err = am.updateAccountPeers(account)
if err != nil { if err != nil {
log.Error(err)
return status.Errorf(status.Internal, "failed to update peers after deleting nameserver %s", nsGroupID) 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 return nil
} }

View File

@ -380,6 +380,7 @@ func TestCreateNameServerGroup(t *testing.T) {
testCase.inputArgs.primary, testCase.inputArgs.primary,
testCase.inputArgs.domains, testCase.inputArgs.domains,
testCase.inputArgs.enabled, testCase.inputArgs.enabled,
userID,
) )
testCase.errFunc(t, err) 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) testCase.errFunc(t, err)
@ -952,7 +953,7 @@ func TestUpdateNameServerGroup(t *testing.T) {
t.Error("account should be saved") 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) testCase.errFunc(t, err)
if !testCase.shouldCreate { if !testCase.shouldCreate {
@ -1009,7 +1010,7 @@ func TestDeleteNameServerGroup(t *testing.T) {
t.Error("failed to save account") t.Error("failed to save account")
} }
err = am.DeleteNameServerGroup(account.Id, testingNSGroup.ID) err = am.DeleteNameServerGroup(account.Id, testingNSGroup.ID, userID)
if err != nil { if err != nil {
t.Error("deleting nameserver group failed with error: ", err) 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. // 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) unlock := am.Store.AcquireAccountLock(accountID)
defer unlock() defer unlock()
@ -201,7 +201,14 @@ func (am *DefaultAccountManager) UpdatePeer(accountID string, update *Peer) (*Pe
return nil, err return nil, err
} }
if peer.SSHEnabled != update.SSHEnabled {
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 { if peer.Name != update.Name {
peer.Name = update.Name peer.Name = update.Name
@ -214,6 +221,8 @@ func (am *DefaultAccountManager) UpdatePeer(accountID string, update *Peer) (*Pe
} }
peer.DNSLabel = newLabel peer.DNSLabel = newLabel
am.storeEvent(userID, peer.IP.String(), accountID, activity.PeerRenamed, peer.EventMeta(am.GetDNSDomain()))
} }
account.UpdatePeer(peer) account.UpdatePeer(peer)

View File

@ -2,6 +2,7 @@ package server
import ( import (
"github.com/netbirdio/netbird/management/proto" "github.com/netbirdio/netbird/management/proto"
"github.com/netbirdio/netbird/management/server/activity"
"github.com/netbirdio/netbird/management/server/status" "github.com/netbirdio/netbird/management/server/status"
"github.com/netbirdio/netbird/route" "github.com/netbirdio/netbird/route"
"github.com/rs/xid" "github.com/rs/xid"
@ -118,7 +119,7 @@ func (am *DefaultAccountManager) checkPrefixPeerExists(accountID, peer string, p
} }
// CreateRoute creates and saves a new route // 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) unlock := am.Store.AcquireAccountLock(accountID)
defer unlock() defer unlock()
@ -127,23 +128,25 @@ func (am *DefaultAccountManager) CreateRoute(accountID string, network, peer, de
return nil, err 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 var newRoute route.Route
prefixType, newPrefix, err := route.ParseNetwork(network) prefixType, newPrefix, err := route.ParseNetwork(network)
if err != nil { if err != nil {
return nil, status.Errorf(status.InvalidArgument, "failed to parse IP %s", network) 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 { if err != nil {
return nil, err 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 { if metric < route.MinMetric || metric > route.MaxMetric {
return nil, status.Errorf(status.InvalidArgument, "metric should be between %d and %d", route.MinMetric, 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 return nil, err
} }
newRoute.Peer = peer newRoute.Peer = peerKey
newRoute.ID = xid.New().String() newRoute.ID = xid.New().String()
newRoute.Network = newPrefix newRoute.Network = newPrefix
newRoute.NetworkType = prefixType newRoute.NetworkType = prefixType
@ -184,11 +187,14 @@ func (am *DefaultAccountManager) CreateRoute(accountID string, network, peer, de
log.Error(err) log.Error(err)
return &newRoute, status.Errorf(status.Internal, "failed to update peers after create route %s", newPrefix) 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 return &newRoute, nil
} }
// SaveRoute saves route // 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) unlock := am.Store.AcquireAccountLock(accountID)
defer unlock() defer unlock()
@ -232,6 +238,8 @@ func (am *DefaultAccountManager) SaveRoute(accountID string, routeToSave *route.
return err return err
} }
am.storeEvent(userID, routeToSave.ID, accountID, activity.RouteUpdated, routeToSave.EventMeta())
return am.updateAccountPeers(account) return am.updateAccountPeers(account)
} }
@ -339,7 +347,7 @@ func (am *DefaultAccountManager) UpdateRoute(accountID, routeID string, operatio
} }
// DeleteRoute deletes route with routeID // 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) unlock := am.Store.AcquireAccountLock(accountID)
defer unlock() defer unlock()
@ -348,6 +356,10 @@ func (am *DefaultAccountManager) DeleteRoute(accountID, routeID string) error {
return err 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) delete(account.Routes, routeID)
account.Network.IncSerial() account.Network.IncSerial()
@ -355,6 +367,8 @@ func (am *DefaultAccountManager) DeleteRoute(accountID, routeID string) error {
return err return err
} }
am.storeEvent(userID, routy.ID, accountID, activity.RouteRemoved, routy.EventMeta())
return am.updateAccountPeers(account) return am.updateAccountPeers(account)
} }

View File

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

View File

@ -76,6 +76,11 @@ type Route struct {
Groups []string 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 // Copy copies a route object
func (r *Route) Copy() *Route { func (r *Route) Copy() *Route {
return &Route{ return &Route{