From 9cd89354c6d17809145d3a163b2c72b096785b4b Mon Sep 17 00:00:00 2001 From: Ingo Date: Wed, 27 Nov 2024 12:43:04 +0100 Subject: [PATCH] fix permissions handling and user delete --- lib/controller/controller.go | 6 ++++ lib/controller/import_types.go | 31 ++++++++++++++++++- lib/controller/users.go | 32 ++++++++++++++----- tests/users_test.go | 56 +++++++++++++++++++++++++--------- 4 files changed, 102 insertions(+), 23 deletions(-) diff --git a/lib/controller/controller.go b/lib/controller/controller.go index 2ed1b1f..757715f 100644 --- a/lib/controller/controller.go +++ b/lib/controller/controller.go @@ -86,6 +86,12 @@ func (this *Controller) Migrate() error { Execute: true, Administrate: true, } + resource.RolePermissions["admin"] = permV2.PermissionsMap{ + Read: true, + Write: true, + Execute: true, + Administrate: true, + } _, err, _ = this.permV2Client.SetPermission(permV2.InternalAdminToken, PermV2Topic, importType.Id, resource.ResourcePermissions) if err != nil { return err diff --git a/lib/controller/import_types.go b/lib/controller/import_types.go index 2a6535d..195ee07 100644 --- a/lib/controller/import_types.go +++ b/lib/controller/import_types.go @@ -18,6 +18,7 @@ package controller import ( "errors" + "github.com/SENERGY-Platform/permissions-v2/pkg/client" "net/http" "github.com/SENERGY-Platform/import-repository/lib/model" @@ -53,7 +54,27 @@ func (this *Controller) CreateImportType(importType model.ImportType, token jwt. if err != nil { return result, err, http.StatusInternalServerError } - + _, err, code = this.permV2Client.SetPermission(client.InternalAdminToken, PermV2Topic, importType.Id, client.ResourcePermissions{ + UserPermissions: map[string]permV2Model.PermissionsMap{ + importType.Owner: { + Read: true, + Write: true, + Execute: true, + Administrate: true, + }, + }, + RolePermissions: map[string]permV2Model.PermissionsMap{ + "admin": { + Read: true, + Write: true, + Execute: true, + Administrate: true, + }, + }, + }) + if err != nil { + return result, err, code + } return importType, nil, http.StatusCreated } @@ -142,6 +163,14 @@ func (this *Controller) DeleteImportType(id string, token jwt.Token) (err error, if err != nil { return err, code } + return this.deleteImportType(id) +} + +func (this *Controller) deleteImportType(id string) (err error, code int) { + err, code = this.permV2Client.RemoveResource(client.InternalAdminToken, PermV2Topic, id) + if err != nil { + return err, code + } ctx, _ := getTimeoutContext() err = this.db.RemoveImportType(ctx, id) if err != nil { diff --git a/lib/controller/users.go b/lib/controller/users.go index de62439..dd695d7 100644 --- a/lib/controller/users.go +++ b/lib/controller/users.go @@ -21,28 +21,44 @@ import ( ) func (this *Controller) DeleteUser(userId string) error { + // if the count of import types becomes to big, we may want to list for all permissions separately, filtered by the deleted user + // eg: + // readIds, err, _ := this.permV2Client.ListAccessibleResourceIds(tokenOfUser, ..., permV2.Read) + // ids = append(ids, readIds...) + // writeIds, err, _ := this.permV2Client.ListAccessibleResourceIds(tokenOfUser, ..., permV2.Write) + // ids = append(ids, readIds...) + // ... + // importTypes, err, _ := this.permV2Client.ListResourcesWithAdminPermission(permV2.InternalAdminToken, PermV2Topic, permV2.ListOptions{Ids: ids}) importTypes, err, _ := this.permV2Client.ListResourcesWithAdminPermission(permV2.InternalAdminToken, PermV2Topic, permV2.ListOptions{}) if err != nil { return err } for _, importType := range importTypes { - perm, ok := importType.UserPermissions[userId] + _, ok := importType.UserPermissions[userId] if !ok { continue // user has no rights to that import type } - if !perm.Administrate { - continue // user has no administrate rights to that import type - } - delete(importType.UserPermissions, userId) // find any user beside this one + + // remove user permissions + delete(importType.UserPermissions, userId) + + //other admin exists? found := false for _, perm := range importType.UserPermissions { if perm.Administrate { found = true + break } } - if !found { - ctx, _ := getTimeoutContext() - err = this.db.RemoveImportType(ctx, importType.Id) + + //no other admin user + if found { + _, err, _ = this.permV2Client.SetPermission(permV2.InternalAdminToken, PermV2Topic, importType.Id, importType.ResourcePermissions) + if err != nil { + return err + } + } else { + err, _ = this.deleteImportType(importType.Id) if err != nil { return err } diff --git a/tests/users_test.go b/tests/users_test.go index 4a71036..de3878d 100644 --- a/tests/users_test.go +++ b/tests/users_test.go @@ -20,6 +20,7 @@ import ( "context" "encoding/json" "reflect" + "slices" "sort" "strconv" "sync" @@ -63,7 +64,8 @@ func TestUserDelete(t *testing.T) { ids := []string{} t.Run("create import-types", initImportTypes(conf, user1, user2, &ids)) - time.Sleep(30 * time.Second) + t.Run("check user1 before permission change", checkUserImportTypes(permv2Client, user1, ids[:10], ids)) + t.Run("check user2 before permission change", checkUserImportTypes(permv2Client, user2, ids[10:], ids)) t.Run("change permissions", func(t *testing.T) { for i := 0; i < 2; i++ { @@ -106,11 +108,17 @@ func TestUserDelete(t *testing.T) { } } - for i := 10; i < 12; i++ { + for i := 8; i < 12; i++ { id := ids[i] err = setPermission(permv2Client, id, permV2.ResourcePermissions{ UserPermissions: map[string]permV2.PermissionsMap{ - user1.Sub: permV2.PermissionsMap{ + user1.Sub: { + Read: true, + Write: true, + Execute: true, + Administrate: true, + }, + user2.Sub: { Read: true, Write: true, Execute: true, @@ -124,7 +132,7 @@ func TestUserDelete(t *testing.T) { } } - for i := 12; i < 14; i++ { + for i := 16; i < 18; i++ { id := ids[i] err = setPermission(permv2Client, id, permV2.ResourcePermissions{ UserPermissions: map[string]permV2.PermissionsMap{ @@ -146,8 +154,7 @@ func TestUserDelete(t *testing.T) { } } - // 10, 11, 12, 13, 14 for user1 rwxa - for i := 13; i < 15; i++ { + for i := 18; i < 20; i++ { id := ids[i] err = setPermission(permv2Client, id, permV2.ResourcePermissions{ UserPermissions: map[string]permV2.PermissionsMap{ @@ -166,10 +173,14 @@ func TestUserDelete(t *testing.T) { } }) - time.Sleep(30 * time.Second) - - t.Run("check user1 before delete", checkUserImportTypes(permv2Client, user1, ids[:15])) - t.Run("check user2 before delete", checkUserImportTypes(permv2Client, user2, append(append([]string{}, ids[:4]...), ids[10:]...))) + users1Expected := []string{} + users1Expected = append(users1Expected, ids[2:12]...) + users1Expected = append(users1Expected, ids[16:]...) + t.Run("check user1 before delete", checkUserImportTypes(permv2Client, user1, users1Expected, ids)) + users2Expected := []string{} + users2Expected = append(users2Expected, ids[:4]...) + users2Expected = append(users2Expected, ids[8:18]...) + t.Run("check user2 before delete", checkUserImportTypes(permv2Client, user2, users2Expected, ids)) t.Run("delete user1", func(t *testing.T) { kafkaConf := sarama.NewConfig() @@ -203,8 +214,11 @@ func TestUserDelete(t *testing.T) { time.Sleep(5 * time.Second) - t.Run("check user1 after delete", checkUserImportTypes(permv2Client, user1, []string{})) - t.Run("check user2 after delete", checkUserImportTypes(permv2Client, user2, append(append(append([]string{}, ids[:4]...), ids[10:12]...), ids[14:]...))) + users2Expected = []string{} + users2Expected = append(users2Expected, ids[:4]...) + users2Expected = append(users2Expected, ids[8:16]...) + t.Run("check user1 after delete", checkUserImportTypes(permv2Client, user1, []string{}, ids)) + t.Run("check user2 after delete", checkUserImportTypes(permv2Client, user2, users2Expected, ids)) } @@ -270,7 +284,7 @@ func setPermission(permv2Client permV2.Client, id string, permissions permV2.Res return err } -func checkUserImportTypes(permV2Client permV2.Client, token jwt.Token, expectedIdsOrig []string) func(t *testing.T) { +func checkUserImportTypes(permV2Client permV2.Client, token jwt.Token, expectedIdsOrig []string, allIds []string) func(t *testing.T) { return func(t *testing.T) { expectedIds := []string{} temp, err := json.Marshal(expectedIdsOrig) @@ -289,11 +303,25 @@ func checkUserImportTypes(permV2Client permV2.Client, token jwt.Token, expectedI t.Error(err) return } + if actualIds == nil { + actualIds = []string{} + } sort.Strings(actualIds) sort.Strings(expectedIds) if !reflect.DeepEqual(actualIds, expectedIds) { - t.Error("\n", actualIds, "\n", expectedIds) + aIndexes := listToIndexList(actualIds, allIds) + eIndexes := listToIndexList(expectedIds, allIds) + sort.Ints(aIndexes) + sort.Ints(eIndexes) + t.Error("\na=", aIndexes, "\ne=", eIndexes) return } } } + +func listToIndexList(list []string, allIds []string) (indexes []int) { + for _, id := range list { + indexes = append(indexes, slices.Index(allIds, id)) + } + return indexes +}