Merge branch 'main' into feature/users-roles-endpoint

This commit is contained in:
Pedro Costa
2025-05-07 10:41:51 +01:00
44 changed files with 1754 additions and 623 deletions
+9 -5
View File
@@ -603,11 +603,15 @@ func (am *DefaultAccountManager) DeleteAccount(ctx context.Context, accountID, u
}
for _, otherUser := range account.Users {
if otherUser.IsServiceUser {
if otherUser.Id == userID {
continue
}
if otherUser.Id == userID {
if otherUser.IsServiceUser {
err = am.deleteServiceUser(ctx, accountID, userID, otherUser)
if err != nil {
return err
}
continue
}
@@ -712,7 +716,7 @@ func (am *DefaultAccountManager) loadAccount(ctx context.Context, accountID any)
log.WithContext(ctx).Debugf("account %s not found in cache, reloading", accountID)
accountIDString := fmt.Sprintf("%v", accountID)
account, err := am.Store.GetAccount(ctx, accountIDString)
accountUsers, err := am.Store.GetAccountUsers(ctx, store.LockingStrengthShare, accountIDString)
if err != nil {
return nil, nil, err
}
@@ -721,7 +725,7 @@ func (am *DefaultAccountManager) loadAccount(ctx context.Context, accountID any)
if err != nil {
return nil, nil, err
}
log.WithContext(ctx).Debugf("%d entries received from IdP management", len(userData))
log.WithContext(ctx).Debugf("%d entries received from IdP management for account %s", len(userData), accountIDString)
dataMap := make(map[string]*idp.UserData, len(userData))
for _, datum := range userData {
@@ -729,7 +733,7 @@ func (am *DefaultAccountManager) loadAccount(ctx context.Context, accountID any)
}
matchedUserData := make([]*idp.UserData, 0)
for _, user := range account.Users {
for _, user := range accountUsers {
if user.IsServiceUser {
continue
}
+44
View File
@@ -853,6 +853,42 @@ func TestAccountManager_DeleteAccount(t *testing.T) {
t.Fatal(err)
}
account.Users["service-user-1"] = &types.User{
Id: "service-user-1",
Role: types.UserRoleAdmin,
IsServiceUser: true,
Issued: types.UserIssuedAPI,
PATs: map[string]*types.PersonalAccessToken{
"pat-1": {
ID: "pat-1",
UserID: "service-user-1",
Name: "service-user-1",
HashedToken: "hashedToken",
CreatedAt: time.Now(),
},
},
}
account.Users[userId] = &types.User{
Id: "service-user-2",
Role: types.UserRoleUser,
IsServiceUser: true,
Issued: types.UserIssuedAPI,
PATs: map[string]*types.PersonalAccessToken{
"pat-2": {
ID: "pat-2",
UserID: userId,
Name: userId,
HashedToken: "hashedToken",
CreatedAt: time.Now(),
},
},
}
err = manager.Store.SaveAccount(context.Background(), account)
if err != nil {
t.Fatal(err)
}
err = manager.DeleteAccount(context.Background(), account.Id, userId)
if err != nil {
t.Fatal(err)
@@ -862,6 +898,14 @@ func TestAccountManager_DeleteAccount(t *testing.T) {
if err == nil {
t.Fatal(fmt.Errorf("expected to get an error when trying to get deleted account, got %v", getAccount))
}
pats, err := manager.Store.GetUserPATs(context.Background(), store.LockingStrengthShare, "service-user-1")
require.NoError(t, err)
assert.Len(t, pats, 0)
pats, err = manager.Store.GetUserPATs(context.Background(), store.LockingStrengthShare, userId)
require.NoError(t, err)
assert.Len(t, pats, 0)
}
func BenchmarkTest_GetAccountWithclaims(b *testing.B) {
+21
View File
@@ -352,3 +352,24 @@ func MigrateNewField[T any](ctx context.Context, db *gorm.DB, columnName string,
log.WithContext(ctx).Infof("Migration of empty %s to default value in table %s completed", columnName, tableName)
return nil
}
func DropIndex[T any](ctx context.Context, db *gorm.DB, indexName string) error {
var model T
if !db.Migrator().HasTable(&model) {
log.WithContext(ctx).Debugf("table for %T does not exist, no migration needed", model)
return nil
}
if !db.Migrator().HasIndex(&model, indexName) {
log.WithContext(ctx).Debugf("index %s does not exist in table %T, no migration needed", indexName, model)
return nil
}
if err := db.Migrator().DropIndex(&model, indexName); err != nil {
return fmt.Errorf("failed to drop index %s: %w", indexName, err)
}
log.WithContext(ctx).Infof("dropped index %s from table %T", indexName, model)
return nil
}
@@ -227,3 +227,25 @@ func TestMigrateSetupKeyToHashedSetupKey_ForAlreadyMigratedKey_Case2(t *testing.
assert.Equal(t, "9+FQcmNd2GCxIK+SvHmtp6PPGV4MKEicDS+xuSQmvlE=", key.Key, "Key should be hashed")
}
func TestDropIndex(t *testing.T) {
db := setupDatabase(t)
err := db.AutoMigrate(&types.SetupKey{})
require.NoError(t, err, "Failed to auto-migrate tables")
err = db.Save(&types.SetupKey{
Id: "1",
Key: "9+FQcmNd2GCxIK+SvHmtp6PPGV4MKEicDS+xuSQmvlE=",
}).Error
require.NoError(t, err, "Failed to insert setup key")
exist := db.Migrator().HasIndex(&types.SetupKey{}, "idx_setup_keys_account_id")
assert.True(t, exist, "Should have the index")
err = migration.DropIndex[types.SetupKey](context.Background(), db, "idx_setup_keys_account_id")
require.NoError(t, err, "Migration should not fail to remove index")
exist = db.Migrator().HasIndex(&types.SetupKey{}, "idx_setup_keys_account_id")
assert.False(t, exist, "Should not have the index")
}
@@ -30,7 +30,7 @@ func (p NetworkResourceType) String() string {
}
type NetworkResource struct {
ID string `gorm:"index"`
ID string `gorm:"primaryKey"`
NetworkID string `gorm:"index"`
AccountID string `gorm:"index"`
Name string
@@ -10,7 +10,7 @@ import (
)
type NetworkRouter struct {
ID string `gorm:"index"`
ID string `gorm:"primaryKey"`
NetworkID string `gorm:"index"`
AccountID string `gorm:"index"`
Peer string
+1 -1
View File
@@ -7,7 +7,7 @@ import (
)
type Network struct {
ID string `gorm:"index"`
ID string `gorm:"primaryKey"`
AccountID string `gorm:"index"`
Name string
Description string
+19 -11
View File
@@ -802,7 +802,7 @@ func (s *SqlStore) GetAccountByPeerPubKey(ctx context.Context, peerKey string) (
func (s *SqlStore) GetAnyAccountID(ctx context.Context) (string, error) {
var account types.Account
result := s.db.WithContext(ctx).Select("id").Limit(1).Find(&account)
result := s.db.WithContext(ctx).Select("id").Order("created_at desc").Limit(1).Find(&account)
if result.Error != nil {
return "", status.NewGetAccountFromStoreError(result.Error)
}
@@ -1683,18 +1683,26 @@ func (s *SqlStore) SavePolicy(ctx context.Context, lockStrength LockingStrength,
}
func (s *SqlStore) DeletePolicy(ctx context.Context, lockStrength LockingStrength, accountID, policyID string) error {
result := s.db.Clauses(clause.Locking{Strength: string(lockStrength)}).
Delete(&types.Policy{}, accountAndIDQueryCondition, accountID, policyID)
if err := result.Error; err != nil {
log.WithContext(ctx).Errorf("failed to delete policy from store: %s", err)
return status.Errorf(status.Internal, "failed to delete policy from store")
}
return s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
if err := tx.Where("policy_id = ?", policyID).Delete(&types.PolicyRule{}).Error; err != nil {
return fmt.Errorf("delete policy rules: %w", err)
}
if result.RowsAffected == 0 {
return status.NewPolicyNotFoundError(policyID)
}
result := tx.Clauses(clause.Locking{Strength: string(lockStrength)}).
Where(accountAndIDQueryCondition, accountID, policyID).
Delete(&types.Policy{})
return nil
if err := result.Error; err != nil {
log.WithContext(ctx).Errorf("failed to delete policy from store: %s", err)
return status.Errorf(status.Internal, "failed to delete policy from store")
}
if result.RowsAffected == 0 {
return status.NewPolicyNotFoundError(policyID)
}
return nil
})
}
// GetAccountPostureChecks retrieves posture checks for an account.
+3 -3
View File
@@ -60,10 +60,10 @@ func Test_NewStore(t *testing.T) {
runTestForAllEngines(t, "", func(t *testing.T, store Store) {
if store == nil {
t.Errorf("expected to create a new Store")
t.Fatalf("expected to create a new Store")
}
if len(store.GetAllAccounts(context.Background())) != 0 {
t.Errorf("expected to create a new empty Accounts map when creating a new FileStore")
t.Fatalf("expected to create a new empty Accounts map when creating a new FileStore")
}
})
}
@@ -1115,7 +1115,7 @@ func TestSqlite_CreateAndGetObjectInTransaction(t *testing.T) {
group := &types.Group{
ID: "group-id",
AccountID: "account-id",
AccountID: "bf1c8084-ba50-4ce7-9439-34653001fc3b",
Name: "group-name",
Issued: "api",
Peers: nil,
+9
View File
@@ -315,6 +315,15 @@ func getMigrations(ctx context.Context) []migrationFunc {
func(db *gorm.DB) error {
return migration.MigrateNewField[routerTypes.NetworkRouter](ctx, db, "enabled", true)
},
func(db *gorm.DB) error {
return migration.DropIndex[networkTypes.Network](ctx, db, "idx_networks_id")
},
func(db *gorm.DB) error {
return migration.DropIndex[resourceTypes.NetworkResource](ctx, db, "idx_network_resources_id")
},
func(db *gorm.DB) error {
return migration.DropIndex[routerTypes.NetworkRouter](ctx, db, "idx_network_routers_id")
},
}
}
+1 -1
View File
@@ -14,7 +14,7 @@ const (
// Group of the peers for ACL
type Group struct {
// ID of the group
ID string
ID string `gorm:"primaryKey"`
// AccountID is a reference to Account that this object belongs
AccountID string `json:"-" gorm:"index"`