mirror of
https://github.com/netbirdio/netbird.git
synced 2024-11-25 01:23:22 +01:00
[management] Limit the setup-key update operation (#2841)
This commit is contained in:
parent
4aee3c9e33
commit
d9b691b8a5
@ -521,19 +521,6 @@ components:
|
|||||||
SetupKeyRequest:
|
SetupKeyRequest:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
name:
|
|
||||||
description: Setup Key name
|
|
||||||
type: string
|
|
||||||
example: Default key
|
|
||||||
type:
|
|
||||||
description: Setup key type, one-off for single time usage and reusable
|
|
||||||
type: string
|
|
||||||
example: reusable
|
|
||||||
expires_in:
|
|
||||||
description: Expiration time in seconds, 0 will mean the key never expires
|
|
||||||
type: integer
|
|
||||||
minimum: 0
|
|
||||||
example: 86400
|
|
||||||
revoked:
|
revoked:
|
||||||
description: Setup key revocation status
|
description: Setup key revocation status
|
||||||
type: boolean
|
type: boolean
|
||||||
@ -544,21 +531,9 @@ components:
|
|||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
example: "ch8i4ug6lnn4g9hqv7m0"
|
example: "ch8i4ug6lnn4g9hqv7m0"
|
||||||
usage_limit:
|
|
||||||
description: A number of times this key can be used. The value of 0 indicates the unlimited usage.
|
|
||||||
type: integer
|
|
||||||
example: 0
|
|
||||||
ephemeral:
|
|
||||||
description: Indicate that the peer will be ephemeral or not
|
|
||||||
type: boolean
|
|
||||||
example: true
|
|
||||||
required:
|
required:
|
||||||
- name
|
|
||||||
- type
|
|
||||||
- expires_in
|
|
||||||
- revoked
|
- revoked
|
||||||
- auto_groups
|
- auto_groups
|
||||||
- usage_limit
|
|
||||||
CreateSetupKeyRequest:
|
CreateSetupKeyRequest:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
@ -1098,23 +1098,8 @@ type SetupKeyRequest struct {
|
|||||||
// AutoGroups List of group IDs to auto-assign to peers registered with this key
|
// AutoGroups List of group IDs to auto-assign to peers registered with this key
|
||||||
AutoGroups []string `json:"auto_groups"`
|
AutoGroups []string `json:"auto_groups"`
|
||||||
|
|
||||||
// Ephemeral Indicate that the peer will be ephemeral or not
|
|
||||||
Ephemeral *bool `json:"ephemeral,omitempty"`
|
|
||||||
|
|
||||||
// ExpiresIn Expiration time in seconds, 0 will mean the key never expires
|
|
||||||
ExpiresIn int `json:"expires_in"`
|
|
||||||
|
|
||||||
// Name Setup Key name
|
|
||||||
Name string `json:"name"`
|
|
||||||
|
|
||||||
// Revoked Setup key revocation status
|
// Revoked Setup key revocation status
|
||||||
Revoked bool `json:"revoked"`
|
Revoked bool `json:"revoked"`
|
||||||
|
|
||||||
// Type Setup key type, one-off for single time usage and reusable
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
// UsageLimit A number of times this key can be used. The value of 0 indicates the unlimited usage.
|
|
||||||
UsageLimit int `json:"usage_limit"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// User defines model for User.
|
// User defines model for User.
|
||||||
|
@ -137,11 +137,6 @@ func (h *SetupKeysHandler) UpdateSetupKey(w http.ResponseWriter, r *http.Request
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if req.Name == "" {
|
|
||||||
util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "setup key name field is invalid: %s", req.Name), w)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.AutoGroups == nil {
|
if req.AutoGroups == nil {
|
||||||
util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "setup key AutoGroups field is invalid"), w)
|
util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "setup key AutoGroups field is invalid"), w)
|
||||||
return
|
return
|
||||||
@ -150,7 +145,6 @@ func (h *SetupKeysHandler) UpdateSetupKey(w http.ResponseWriter, r *http.Request
|
|||||||
newKey := &server.SetupKey{}
|
newKey := &server.SetupKey{}
|
||||||
newKey.AutoGroups = req.AutoGroups
|
newKey.AutoGroups = req.AutoGroups
|
||||||
newKey.Revoked = req.Revoked
|
newKey.Revoked = req.Revoked
|
||||||
newKey.Name = req.Name
|
|
||||||
newKey.Id = keyID
|
newKey.Id = keyID
|
||||||
|
|
||||||
newKey, err = h.accountManager.SaveSetupKey(r.Context(), accountID, newKey, userID)
|
newKey, err = h.accountManager.SaveSetupKey(r.Context(), accountID, newKey, userID)
|
||||||
|
@ -12,9 +12,10 @@ import (
|
|||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/management/server/activity"
|
"github.com/netbirdio/netbird/management/server/activity"
|
||||||
"github.com/netbirdio/netbird/management/server/status"
|
"github.com/netbirdio/netbird/management/server/status"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -276,7 +277,7 @@ func (am *DefaultAccountManager) CreateSetupKey(ctx context.Context, accountID s
|
|||||||
// SaveSetupKey saves the provided SetupKey to the database overriding the existing one.
|
// SaveSetupKey saves the provided SetupKey to the database overriding the existing one.
|
||||||
// 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: AutoGroups, Revoked (only from false to true), and the UpdatedAt. The rest is copied from the existing key.
|
||||||
func (am *DefaultAccountManager) SaveSetupKey(ctx context.Context, accountID string, keyToSave *SetupKey, userID string) (*SetupKey, error) {
|
func (am *DefaultAccountManager) SaveSetupKey(ctx context.Context, accountID string, keyToSave *SetupKey, userID string) (*SetupKey, error) {
|
||||||
if keyToSave == nil {
|
if keyToSave == nil {
|
||||||
return nil, status.Errorf(status.InvalidArgument, "provided setup key to update is nil")
|
return nil, status.Errorf(status.InvalidArgument, "provided setup key to update is nil")
|
||||||
@ -312,9 +313,12 @@ func (am *DefaultAccountManager) SaveSetupKey(ctx context.Context, accountID str
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// only auto groups, revoked status, and name can be updated for now
|
if oldKey.Revoked && !keyToSave.Revoked {
|
||||||
|
return status.Errorf(status.InvalidArgument, "can't un-revoke a revoked setup key")
|
||||||
|
}
|
||||||
|
|
||||||
|
// only auto groups, revoked status (from false to true) can be updated
|
||||||
newKey = oldKey.Copy()
|
newKey = oldKey.Copy()
|
||||||
newKey.Name = keyToSave.Name
|
|
||||||
newKey.AutoGroups = keyToSave.AutoGroups
|
newKey.AutoGroups = keyToSave.AutoGroups
|
||||||
newKey.Revoked = keyToSave.Revoked
|
newKey.Revoked = keyToSave.Revoked
|
||||||
newKey.UpdatedAt = time.Now().UTC()
|
newKey.UpdatedAt = time.Now().UTC()
|
||||||
|
@ -56,11 +56,9 @@ func TestDefaultAccountManager_SaveSetupKey(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
autoGroups := []string{"group_1", "group_2"}
|
autoGroups := []string{"group_1", "group_2"}
|
||||||
newKeyName := "my-new-test-key"
|
|
||||||
revoked := true
|
revoked := true
|
||||||
newKey, err := manager.SaveSetupKey(context.Background(), account.Id, &SetupKey{
|
newKey, err := manager.SaveSetupKey(context.Background(), account.Id, &SetupKey{
|
||||||
Id: key.Id,
|
Id: key.Id,
|
||||||
Name: newKeyName,
|
|
||||||
Revoked: revoked,
|
Revoked: revoked,
|
||||||
AutoGroups: autoGroups,
|
AutoGroups: autoGroups,
|
||||||
}, userID)
|
}, userID)
|
||||||
@ -68,7 +66,7 @@ func TestDefaultAccountManager_SaveSetupKey(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertKey(t, newKey, newKeyName, revoked, "reusable", 0, key.CreatedAt, key.ExpiresAt,
|
assertKey(t, newKey, keyName, revoked, "reusable", 0, key.CreatedAt, key.ExpiresAt,
|
||||||
key.Id, time.Now().UTC(), autoGroups, true)
|
key.Id, time.Now().UTC(), autoGroups, true)
|
||||||
|
|
||||||
// check the corresponding events that should have been generated
|
// check the corresponding events that should have been generated
|
||||||
@ -76,7 +74,7 @@ func TestDefaultAccountManager_SaveSetupKey(t *testing.T) {
|
|||||||
|
|
||||||
assert.NotNil(t, ev)
|
assert.NotNil(t, ev)
|
||||||
assert.Equal(t, account.Id, ev.AccountID)
|
assert.Equal(t, account.Id, ev.AccountID)
|
||||||
assert.Equal(t, newKeyName, ev.Meta["name"])
|
assert.Equal(t, keyName, ev.Meta["name"])
|
||||||
assert.Equal(t, fmt.Sprint(key.Type), fmt.Sprint(ev.Meta["type"]))
|
assert.Equal(t, fmt.Sprint(key.Type), fmt.Sprint(ev.Meta["type"]))
|
||||||
assert.NotEmpty(t, ev.Meta["key"])
|
assert.NotEmpty(t, ev.Meta["key"])
|
||||||
assert.Equal(t, userID, ev.InitiatorID)
|
assert.Equal(t, userID, ev.InitiatorID)
|
||||||
@ -89,7 +87,6 @@ func TestDefaultAccountManager_SaveSetupKey(t *testing.T) {
|
|||||||
autoGroups = append(autoGroups, groupAll.ID)
|
autoGroups = append(autoGroups, groupAll.ID)
|
||||||
_, err = manager.SaveSetupKey(context.Background(), account.Id, &SetupKey{
|
_, err = manager.SaveSetupKey(context.Background(), account.Id, &SetupKey{
|
||||||
Id: key.Id,
|
Id: key.Id,
|
||||||
Name: newKeyName,
|
|
||||||
Revoked: revoked,
|
Revoked: revoked,
|
||||||
AutoGroups: autoGroups,
|
AutoGroups: autoGroups,
|
||||||
}, userID)
|
}, userID)
|
||||||
@ -449,3 +446,31 @@ func TestSetupKeyAccountPeersUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDefaultAccountManager_CreateSetupKey_ShouldNotAllowToUpdateRevokedKey(t *testing.T) {
|
||||||
|
manager, err := createManager(t)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
userID := "testingUser"
|
||||||
|
account, err := manager.GetOrCreateAccountByUser(context.Background(), userID, "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
key, err := manager.CreateSetupKey(context.Background(), account.Id, "testName", SetupKeyReusable, time.Hour, nil, SetupKeyUnlimitedUsage, userID, false)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// revoke the key
|
||||||
|
updateKey := key.Copy()
|
||||||
|
updateKey.Revoked = true
|
||||||
|
_, err = manager.SaveSetupKey(context.Background(), account.Id, updateKey, userID)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// re-activate revoked key
|
||||||
|
updateKey.Revoked = false
|
||||||
|
_, err = manager.SaveSetupKey(context.Background(), account.Id, updateKey, userID)
|
||||||
|
assert.Error(t, err, "should not allow to update revoked key")
|
||||||
|
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user