mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-23 05:49:07 +02:00
Add setup key events
This commit is contained in:
@@ -40,8 +40,8 @@ func cacheEntryExpiration() time.Duration {
|
|||||||
type AccountManager interface {
|
type AccountManager interface {
|
||||||
GetOrCreateAccountByUser(userId, domain string) (*Account, error)
|
GetOrCreateAccountByUser(userId, domain string) (*Account, error)
|
||||||
CreateSetupKey(accountID string, keyName string, keyType SetupKeyType, expiresIn time.Duration,
|
CreateSetupKey(accountID string, keyName string, keyType SetupKeyType, expiresIn time.Duration,
|
||||||
autoGroups []string, usageLimit int) (*SetupKey, error)
|
autoGroups []string, usageLimit int, userID string) (*SetupKey, error)
|
||||||
SaveSetupKey(accountID string, key *SetupKey) (*SetupKey, error)
|
SaveSetupKey(accountID string, key *SetupKey, userID string) (*SetupKey, error)
|
||||||
CreateUser(accountID, userID string, key *UserInfo) (*UserInfo, error)
|
CreateUser(accountID, userID string, key *UserInfo) (*UserInfo, error)
|
||||||
ListSetupKeys(accountID, userID string) ([]*SetupKey, error)
|
ListSetupKeys(accountID, userID string) ([]*SetupKey, error)
|
||||||
SaveUser(accountID string, key *User) (*UserInfo, error)
|
SaveUser(accountID string, key *User) (*UserInfo, error)
|
||||||
|
|||||||
@@ -21,6 +21,14 @@ const (
|
|||||||
RuleUpdated
|
RuleUpdated
|
||||||
// RuleRemoved indicates that a user removed a rule
|
// RuleRemoved indicates that a user removed a rule
|
||||||
RuleRemoved
|
RuleRemoved
|
||||||
|
// SetupKeyCreated indicates that a user created a new setup key
|
||||||
|
SetupKeyCreated
|
||||||
|
// SetupKeyUpdated indicates that a user updated a setup key
|
||||||
|
SetupKeyUpdated
|
||||||
|
// SetupKeyRevoked indicates that a user revoked a setup key
|
||||||
|
SetupKeyRevoked
|
||||||
|
// SetupKeyOverused indicates that setup key usage exhausted
|
||||||
|
SetupKeyOverused
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -42,6 +50,14 @@ const (
|
|||||||
RuleRemovedMessage string = "Rule deleted"
|
RuleRemovedMessage string = "Rule deleted"
|
||||||
// RuleUpdatedMessage is a human-readable text message of the RuleRemoved activity
|
// RuleUpdatedMessage is a human-readable text message of the RuleRemoved activity
|
||||||
RuleUpdatedMessage string = "Rule updated"
|
RuleUpdatedMessage string = "Rule updated"
|
||||||
|
// SetupKeyCreatedMessage is a human-readable text message of the SetupKeyCreated activity
|
||||||
|
SetupKeyCreatedMessage string = "Setup key created"
|
||||||
|
// SetupKeyUpdatedMessage is a human-readable text message of the SetupKeyUpdated activity
|
||||||
|
SetupKeyUpdatedMessage string = "Setup key updated"
|
||||||
|
// SetupKeyRevokedMessage is a human-readable text message of the SetupKeyRevoked activity
|
||||||
|
SetupKeyRevokedMessage string = "Setup key revoked"
|
||||||
|
// SetupKeyOverusedMessage is a human-readable text message of the SetupKeyOverused activity
|
||||||
|
SetupKeyOverusedMessage string = "Setup key overused"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Activity that triggered an Event
|
// Activity that triggered an Event
|
||||||
@@ -68,6 +84,14 @@ func (a Activity) Message() string {
|
|||||||
return RuleRemovedMessage
|
return RuleRemovedMessage
|
||||||
case RuleUpdated:
|
case RuleUpdated:
|
||||||
return RuleUpdatedMessage
|
return RuleUpdatedMessage
|
||||||
|
case SetupKeyCreated:
|
||||||
|
return SetupKeyCreatedMessage
|
||||||
|
case SetupKeyUpdated:
|
||||||
|
return SetupKeyUpdatedMessage
|
||||||
|
case SetupKeyRevoked:
|
||||||
|
return SetupKeyRevokedMessage
|
||||||
|
case SetupKeyOverused:
|
||||||
|
return SetupKeyOverusedMessage
|
||||||
default:
|
default:
|
||||||
return "UNKNOWN_ACTIVITY"
|
return "UNKNOWN_ACTIVITY"
|
||||||
}
|
}
|
||||||
@@ -94,6 +118,14 @@ func (a Activity) StringCode() string {
|
|||||||
return "rule.delete"
|
return "rule.delete"
|
||||||
case RuleUpdated:
|
case RuleUpdated:
|
||||||
return "rule.update"
|
return "rule.update"
|
||||||
|
case SetupKeyCreated:
|
||||||
|
return "setupkey.add"
|
||||||
|
case SetupKeyRevoked:
|
||||||
|
return "setupkey.revoke"
|
||||||
|
case SetupKeyOverused:
|
||||||
|
return "setupkey.overuse"
|
||||||
|
case SetupKeyUpdated:
|
||||||
|
return "setupkey.update"
|
||||||
default:
|
default:
|
||||||
return "UNKNOWN_ACTIVITY"
|
return "UNKNOWN_ACTIVITY"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -519,7 +519,11 @@ components:
|
|||||||
activity_code:
|
activity_code:
|
||||||
description: The string code of the activity that occurred during the event
|
description: The string code of the activity that occurred during the event
|
||||||
type: string
|
type: string
|
||||||
enum: [ "account.create", "user.join", "user.invite", "user.peer.add", "setupkey.peer.add", "user.peer.delete", "rule.add", "rule.delete", "rule.update"]
|
enum: [ "user.peer.delete", "user.join", "user.invite", "user.peer.add",
|
||||||
|
"setupkey.peer.add", "setupkey.add", "setupkey.update", "setupkey.revoke", "setupkey.overuse",
|
||||||
|
"rule.add", "rule.delete", "rule.update",
|
||||||
|
"account.create",
|
||||||
|
]
|
||||||
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.
|
||||||
type: string
|
type: string
|
||||||
|
|||||||
@@ -17,7 +17,11 @@ const (
|
|||||||
EventActivityCodeRuleAdd EventActivityCode = "rule.add"
|
EventActivityCodeRuleAdd EventActivityCode = "rule.add"
|
||||||
EventActivityCodeRuleDelete EventActivityCode = "rule.delete"
|
EventActivityCodeRuleDelete EventActivityCode = "rule.delete"
|
||||||
EventActivityCodeRuleUpdate EventActivityCode = "rule.update"
|
EventActivityCodeRuleUpdate EventActivityCode = "rule.update"
|
||||||
|
EventActivityCodeSetupkeyAdd EventActivityCode = "setupkey.add"
|
||||||
|
EventActivityCodeSetupkeyOveruse EventActivityCode = "setupkey.overuse"
|
||||||
EventActivityCodeSetupkeyPeerAdd EventActivityCode = "setupkey.peer.add"
|
EventActivityCodeSetupkeyPeerAdd EventActivityCode = "setupkey.peer.add"
|
||||||
|
EventActivityCodeSetupkeyRevoke EventActivityCode = "setupkey.revoke"
|
||||||
|
EventActivityCodeSetupkeyUpdate EventActivityCode = "setupkey.update"
|
||||||
EventActivityCodeUserInvite EventActivityCode = "user.invite"
|
EventActivityCodeUserInvite EventActivityCode = "user.invite"
|
||||||
EventActivityCodeUserJoin EventActivityCode = "user.join"
|
EventActivityCodeUserJoin EventActivityCode = "user.join"
|
||||||
EventActivityCodeUserPeerAdd EventActivityCode = "user.peer.add"
|
EventActivityCodeUserPeerAdd EventActivityCode = "user.peer.add"
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ func NewSetupKeysHandler(accountManager server.AccountManager, authAudience stri
|
|||||||
// CreateSetupKeyHandler is a POST requests that creates a new SetupKey
|
// CreateSetupKeyHandler is a POST requests that creates a new SetupKey
|
||||||
func (h *SetupKeys) CreateSetupKeyHandler(w http.ResponseWriter, r *http.Request) {
|
func (h *SetupKeys) CreateSetupKeyHandler(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
|
||||||
@@ -61,7 +61,7 @@ func (h *SetupKeys) CreateSetupKeyHandler(w http.ResponseWriter, r *http.Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
setupKey, err := h.accountManager.CreateSetupKey(account.Id, req.Name, server.SetupKeyType(req.Type), expiresIn,
|
setupKey, err := h.accountManager.CreateSetupKey(account.Id, req.Name, server.SetupKeyType(req.Type), expiresIn,
|
||||||
req.AutoGroups, req.UsageLimit)
|
req.AutoGroups, req.UsageLimit, user.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.WriteError(err, w)
|
util.WriteError(err, w)
|
||||||
return
|
return
|
||||||
@@ -98,7 +98,7 @@ func (h *SetupKeys) GetSetupKeyHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
// UpdateSetupKeyHandler is a PUT request to update server.SetupKey
|
// UpdateSetupKeyHandler is a PUT request to update server.SetupKey
|
||||||
func (h *SetupKeys) UpdateSetupKeyHandler(w http.ResponseWriter, r *http.Request) {
|
func (h *SetupKeys) UpdateSetupKeyHandler(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
|
||||||
@@ -134,7 +134,7 @@ func (h *SetupKeys) UpdateSetupKeyHandler(w http.ResponseWriter, r *http.Request
|
|||||||
newKey.Name = req.Name
|
newKey.Name = req.Name
|
||||||
newKey.Id = keyID
|
newKey.Id = keyID
|
||||||
|
|
||||||
newKey, err = h.accountManager.SaveSetupKey(account.Id, newKey)
|
newKey, err = h.accountManager.SaveSetupKey(account.Id, newKey, user.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.WriteError(err, w)
|
util.WriteError(err, w)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/netbirdio/netbird/management/server/activity"
|
||||||
"github.com/netbirdio/netbird/management/server/status"
|
"github.com/netbirdio/netbird/management/server/status"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -107,12 +108,20 @@ func (key *SetupKey) Copy() *SetupKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EventMeta returns activity event meta related to the peer
|
||||||
|
func (key *SetupKey) EventMeta() map[string]any {
|
||||||
|
return map[string]any{"name": key.Name, "type": key.Type, "key": key.HiddenCopy(1).Key}
|
||||||
|
}
|
||||||
|
|
||||||
// HiddenCopy returns a copy of the key with a Key value hidden with "*" and a 5 character prefix.
|
// HiddenCopy returns a copy of the key with a Key value hidden with "*" and a 5 character prefix.
|
||||||
// E.g., "831F6*******************************"
|
// E.g., "831F6*******************************"
|
||||||
func (key *SetupKey) HiddenCopy() *SetupKey {
|
func (key *SetupKey) HiddenCopy(length int) *SetupKey {
|
||||||
k := key.Copy()
|
k := key.Copy()
|
||||||
prefix := k.Key[0:5]
|
prefix := k.Key[0:5]
|
||||||
k.Key = prefix + strings.Repeat("*", utf8.RuneCountInString(key.Key)-len(prefix))
|
if length > utf8.RuneCountInString(key.Key) {
|
||||||
|
length = utf8.RuneCountInString(key.Key) - len(prefix)
|
||||||
|
}
|
||||||
|
k.Key = prefix + strings.Repeat("*", length)
|
||||||
return k
|
return k
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,7 +198,7 @@ func Hash(s string) uint32 {
|
|||||||
// CreateSetupKey generates a new setup key with a given name, type, list of groups IDs to auto-assign to peers registered with this key,
|
// CreateSetupKey generates a new setup key with a given name, type, list of groups IDs to auto-assign to peers registered with this key,
|
||||||
// and adds it to the specified account. A list of autoGroups IDs can be empty.
|
// and adds it to the specified account. A list of autoGroups IDs can be empty.
|
||||||
func (am *DefaultAccountManager) CreateSetupKey(accountID string, keyName string, keyType SetupKeyType,
|
func (am *DefaultAccountManager) CreateSetupKey(accountID string, keyName string, keyType SetupKeyType,
|
||||||
expiresIn time.Duration, autoGroups []string, usageLimit int) (*SetupKey, error) {
|
expiresIn time.Duration, autoGroups []string, usageLimit int, userID string) (*SetupKey, error) {
|
||||||
unlock := am.Store.AcquireAccountLock(accountID)
|
unlock := am.Store.AcquireAccountLock(accountID)
|
||||||
defer unlock()
|
defer unlock()
|
||||||
|
|
||||||
@@ -211,12 +220,23 @@ func (am *DefaultAccountManager) CreateSetupKey(accountID string, keyName string
|
|||||||
|
|
||||||
setupKey := GenerateSetupKey(keyName, keyType, keyDuration, autoGroups, usageLimit)
|
setupKey := GenerateSetupKey(keyName, keyType, keyDuration, autoGroups, usageLimit)
|
||||||
account.SetupKeys[setupKey.Key] = setupKey
|
account.SetupKeys[setupKey.Key] = setupKey
|
||||||
|
|
||||||
err = am.Store.SaveAccount(account)
|
err = am.Store.SaveAccount(account)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(status.Internal, "failed adding account key")
|
return nil, status.Errorf(status.Internal, "failed adding account key")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, err = am.eventStore.Save(&activity.Event{
|
||||||
|
Timestamp: time.Now(),
|
||||||
|
Activity: activity.SetupKeyCreated,
|
||||||
|
InitiatorID: userID,
|
||||||
|
TargetID: setupKey.Id,
|
||||||
|
AccountID: accountID,
|
||||||
|
Meta: setupKey.EventMeta(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return setupKey, nil
|
return setupKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +244,7 @@ func (am *DefaultAccountManager) CreateSetupKey(accountID string, keyName string
|
|||||||
// Due to the unique nature of a SetupKey certain properties must not be overwritten
|
// Due to the unique nature of a SetupKey certain properties must not be overwritten
|
||||||
// (e.g. the key itself, creation date, ID, etc).
|
// (e.g. the key itself, creation date, ID, etc).
|
||||||
// These properties are overwritten: Name, AutoGroups, Revoked. The rest is copied from the existing key.
|
// These properties are overwritten: Name, AutoGroups, Revoked. The rest is copied from the existing key.
|
||||||
func (am *DefaultAccountManager) SaveSetupKey(accountID string, keyToSave *SetupKey) (*SetupKey, error) {
|
func (am *DefaultAccountManager) SaveSetupKey(accountID string, keyToSave *SetupKey, userID string) (*SetupKey, error) {
|
||||||
unlock := am.Store.AcquireAccountLock(accountID)
|
unlock := am.Store.AcquireAccountLock(accountID)
|
||||||
defer unlock()
|
defer unlock()
|
||||||
|
|
||||||
@@ -261,6 +281,20 @@ func (am *DefaultAccountManager) SaveSetupKey(accountID string, keyToSave *Setup
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !oldKey.Revoked && newKey.Revoked {
|
||||||
|
_, err = am.eventStore.Save(&activity.Event{
|
||||||
|
Timestamp: time.Now(),
|
||||||
|
Activity: activity.SetupKeyRevoked,
|
||||||
|
InitiatorID: userID,
|
||||||
|
TargetID: newKey.Id,
|
||||||
|
AccountID: accountID,
|
||||||
|
Meta: newKey.EventMeta(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return newKey, am.updateAccountPeers(account)
|
return newKey, am.updateAccountPeers(account)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +316,7 @@ func (am *DefaultAccountManager) ListSetupKeys(accountID, userID string) ([]*Set
|
|||||||
for _, key := range account.SetupKeys {
|
for _, key := range account.SetupKeys {
|
||||||
var k *SetupKey
|
var k *SetupKey
|
||||||
if !user.IsAdmin() {
|
if !user.IsAdmin() {
|
||||||
k = key.HiddenCopy()
|
k = key.HiddenCopy(999)
|
||||||
} else {
|
} else {
|
||||||
k = key.Copy()
|
k = key.Copy()
|
||||||
}
|
}
|
||||||
@@ -324,7 +358,7 @@ func (am *DefaultAccountManager) GetSetupKey(accountID, userID, keyID string) (*
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !user.IsAdmin() {
|
if !user.IsAdmin() {
|
||||||
foundKey = foundKey.HiddenCopy()
|
foundKey = foundKey.HiddenCopy(999)
|
||||||
}
|
}
|
||||||
|
|
||||||
return foundKey, nil
|
return foundKey, nil
|
||||||
|
|||||||
Reference in New Issue
Block a user