mirror of
https://github.com/netbirdio/netbird.git
synced 2026-07-17 12:09:58 +00:00
Add setup key events
This commit is contained in:
@@ -40,8 +40,8 @@ func cacheEntryExpiration() time.Duration {
|
||||
type AccountManager interface {
|
||||
GetOrCreateAccountByUser(userId, domain string) (*Account, error)
|
||||
CreateSetupKey(accountID string, keyName string, keyType SetupKeyType, expiresIn time.Duration,
|
||||
autoGroups []string, usageLimit int) (*SetupKey, error)
|
||||
SaveSetupKey(accountID string, key *SetupKey) (*SetupKey, error)
|
||||
autoGroups []string, usageLimit int, userID string) (*SetupKey, error)
|
||||
SaveSetupKey(accountID string, key *SetupKey, userID string) (*SetupKey, error)
|
||||
CreateUser(accountID, userID string, key *UserInfo) (*UserInfo, error)
|
||||
ListSetupKeys(accountID, userID string) ([]*SetupKey, error)
|
||||
SaveUser(accountID string, key *User) (*UserInfo, error)
|
||||
|
||||
@@ -21,6 +21,14 @@ const (
|
||||
RuleUpdated
|
||||
// RuleRemoved indicates that a user removed a rule
|
||||
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 (
|
||||
@@ -42,6 +50,14 @@ const (
|
||||
RuleRemovedMessage string = "Rule deleted"
|
||||
// RuleUpdatedMessage is a human-readable text message of the RuleRemoved activity
|
||||
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
|
||||
@@ -68,6 +84,14 @@ func (a Activity) Message() string {
|
||||
return RuleRemovedMessage
|
||||
case RuleUpdated:
|
||||
return RuleUpdatedMessage
|
||||
case SetupKeyCreated:
|
||||
return SetupKeyCreatedMessage
|
||||
case SetupKeyUpdated:
|
||||
return SetupKeyUpdatedMessage
|
||||
case SetupKeyRevoked:
|
||||
return SetupKeyRevokedMessage
|
||||
case SetupKeyOverused:
|
||||
return SetupKeyOverusedMessage
|
||||
default:
|
||||
return "UNKNOWN_ACTIVITY"
|
||||
}
|
||||
@@ -94,6 +118,14 @@ func (a Activity) StringCode() string {
|
||||
return "rule.delete"
|
||||
case RuleUpdated:
|
||||
return "rule.update"
|
||||
case SetupKeyCreated:
|
||||
return "setupkey.add"
|
||||
case SetupKeyRevoked:
|
||||
return "setupkey.revoke"
|
||||
case SetupKeyOverused:
|
||||
return "setupkey.overuse"
|
||||
case SetupKeyUpdated:
|
||||
return "setupkey.update"
|
||||
default:
|
||||
return "UNKNOWN_ACTIVITY"
|
||||
}
|
||||
|
||||
@@ -519,7 +519,11 @@ components:
|
||||
activity_code:
|
||||
description: The string code of the activity that occurred during the event
|
||||
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:
|
||||
description: The ID of the initiator of the event. E.g., an ID of a user that triggered the event.
|
||||
type: string
|
||||
|
||||
@@ -17,7 +17,11 @@ const (
|
||||
EventActivityCodeRuleAdd EventActivityCode = "rule.add"
|
||||
EventActivityCodeRuleDelete EventActivityCode = "rule.delete"
|
||||
EventActivityCodeRuleUpdate EventActivityCode = "rule.update"
|
||||
EventActivityCodeSetupkeyAdd EventActivityCode = "setupkey.add"
|
||||
EventActivityCodeSetupkeyOveruse EventActivityCode = "setupkey.overuse"
|
||||
EventActivityCodeSetupkeyPeerAdd EventActivityCode = "setupkey.peer.add"
|
||||
EventActivityCodeSetupkeyRevoke EventActivityCode = "setupkey.revoke"
|
||||
EventActivityCodeSetupkeyUpdate EventActivityCode = "setupkey.update"
|
||||
EventActivityCodeUserInvite EventActivityCode = "user.invite"
|
||||
EventActivityCodeUserJoin EventActivityCode = "user.join"
|
||||
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
|
||||
func (h *SetupKeys) CreateSetupKeyHandler(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
|
||||
@@ -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,
|
||||
req.AutoGroups, req.UsageLimit)
|
||||
req.AutoGroups, req.UsageLimit, user.Id)
|
||||
if err != nil {
|
||||
util.WriteError(err, w)
|
||||
return
|
||||
@@ -98,7 +98,7 @@ func (h *SetupKeys) GetSetupKeyHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// UpdateSetupKeyHandler is a PUT request to update server.SetupKey
|
||||
func (h *SetupKeys) UpdateSetupKeyHandler(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
|
||||
@@ -134,7 +134,7 @@ func (h *SetupKeys) UpdateSetupKeyHandler(w http.ResponseWriter, r *http.Request
|
||||
newKey.Name = req.Name
|
||||
newKey.Id = keyID
|
||||
|
||||
newKey, err = h.accountManager.SaveSetupKey(account.Id, newKey)
|
||||
newKey, err = h.accountManager.SaveSetupKey(account.Id, newKey, user.Id)
|
||||
if err != nil {
|
||||
util.WriteError(err, w)
|
||||
return
|
||||
|
||||
@@ -2,6 +2,7 @@ package server
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/netbirdio/netbird/management/server/activity"
|
||||
"github.com/netbirdio/netbird/management/server/status"
|
||||
"hash/fnv"
|
||||
"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.
|
||||
// E.g., "831F6*******************************"
|
||||
func (key *SetupKey) HiddenCopy() *SetupKey {
|
||||
func (key *SetupKey) HiddenCopy(length int) *SetupKey {
|
||||
k := key.Copy()
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
// 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,
|
||||
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)
|
||||
defer unlock()
|
||||
|
||||
@@ -211,12 +220,23 @@ func (am *DefaultAccountManager) CreateSetupKey(accountID string, keyName string
|
||||
|
||||
setupKey := GenerateSetupKey(keyName, keyType, keyDuration, autoGroups, usageLimit)
|
||||
account.SetupKeys[setupKey.Key] = setupKey
|
||||
|
||||
err = am.Store.SaveAccount(account)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
// (e.g. the key itself, creation date, ID, etc).
|
||||
// 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)
|
||||
defer unlock()
|
||||
|
||||
@@ -261,6 +281,20 @@ func (am *DefaultAccountManager) SaveSetupKey(accountID string, keyToSave *Setup
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -282,7 +316,7 @@ func (am *DefaultAccountManager) ListSetupKeys(accountID, userID string) ([]*Set
|
||||
for _, key := range account.SetupKeys {
|
||||
var k *SetupKey
|
||||
if !user.IsAdmin() {
|
||||
k = key.HiddenCopy()
|
||||
k = key.HiddenCopy(999)
|
||||
} else {
|
||||
k = key.Copy()
|
||||
}
|
||||
@@ -324,7 +358,7 @@ func (am *DefaultAccountManager) GetSetupKey(accountID, userID, keyID string) (*
|
||||
}
|
||||
|
||||
if !user.IsAdmin() {
|
||||
foundKey = foundKey.HiddenCopy()
|
||||
foundKey = foundKey.HiddenCopy(999)
|
||||
}
|
||||
|
||||
return foundKey, nil
|
||||
|
||||
Reference in New Issue
Block a user