From 5cb94a782032289d51b08960fc37d9c0adda48d6 Mon Sep 17 00:00:00 2001 From: lemonScaletech Date: Thu, 7 Dec 2023 19:33:59 +0530 Subject: [PATCH] fix: * added logic if role is deleted then also be deleted from user side if role is assigned to that user. * default role should be subset of roles --- server/resolvers/update_env.go | 61 ++++++++++++++++++++++++++++++---- server/utils/common.go | 40 ++++++++++++++++++++++ 2 files changed, 94 insertions(+), 7 deletions(-) diff --git a/server/resolvers/update_env.go b/server/resolvers/update_env.go index e7ceb70..4bda560 100644 --- a/server/resolvers/update_env.go +++ b/server/resolvers/update_env.go @@ -7,6 +7,7 @@ import ( "fmt" "reflect" "strings" + "time" log "github.com/sirupsen/logrus" @@ -93,6 +94,42 @@ func clearSessionIfRequired(currentData, updatedData map[string]interface{}) { } } +func updateRoles(ctx context.Context, deletedRoles []string) error { + data, err := db.Provider.ListUsers(ctx, &model.Pagination{ + Limit: 1, + Offset: 1, + }) + if err != nil { + return err + } + + allData, err := db.Provider.ListUsers(ctx, &model.Pagination{ + Limit: data.Pagination.Total, + }) + if err != nil { + return err + } + + for i := range allData.Users { + now := time.Now().Unix() + allData.Users[i].Roles = utils.DeleteFromArray(allData.Users[i].Roles, deletedRoles) + allData.Users[i].UpdatedAt = &now + } + + for i := range allData.Users { + updatedValues := map[string]interface{}{ + "roles": strings.Join(allData.Users[i].Roles, ","), + "updated_at": time.Now().Unix(), + } + id := []string{allData.Users[i].ID} + err = db.Provider.UpdateUsers(ctx, updatedValues, id) + if err != nil { + return err + } + } + return nil +} + // UpdateEnvResolver is a resolver for update config mutation // This is admin only mutation func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model.Response, error) { @@ -291,12 +328,17 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model }, nil) } + previousRoles := strings.Split(currentData[constants.EnvKeyRoles].(string), ",") + updatedRoles := strings.Split(updatedData[constants.EnvKeyRoles].(string), ",") + updatedDefaultRoles := strings.Split(updatedData[constants.EnvKeyDefaultRoles].(string), ",") + updatedProtectedRoles := strings.Split(updatedData[constants.EnvKeyProtectedRoles].(string), ",") + // check the roles change - if len(params.Roles) > 0 { - if len(params.DefaultRoles) > 0 { + if len(updatedRoles) > 0 { + if len(updatedDefaultRoles) > 0 { // should be subset of roles - for _, role := range params.DefaultRoles { - if !utils.StringSliceContains(params.Roles, role) { + for _, role := range updatedDefaultRoles { + if !utils.StringSliceContains(updatedRoles, role) { log.Debug("Default roles should be subset of roles") return res, fmt.Errorf("default role %s is not in roles", role) } @@ -304,15 +346,20 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model } } - if len(params.ProtectedRoles) > 0 { - for _, role := range params.ProtectedRoles { - if utils.StringSliceContains(params.Roles, role) || utils.StringSliceContains(params.DefaultRoles, role) { + if len(updatedProtectedRoles) > 0 { + for _, role := range updatedProtectedRoles { + if utils.StringSliceContains(updatedRoles, role) || utils.StringSliceContains(updatedDefaultRoles, role) { log.Debug("Protected roles should not be in roles or default roles") return res, fmt.Errorf("protected role %s found roles or default roles", role) } } } + deletedRoles := utils.FindDeletedValues(previousRoles, updatedRoles) + if len(deletedRoles) > 0 { + go updateRoles(ctx, deletedRoles) + } + // Update local store memorystore.Provider.UpdateEnvStore(updatedData) jwk, err := crypto.GenerateJWKBasedOnEnv() diff --git a/server/utils/common.go b/server/utils/common.go index 642d859..b5f81b6 100644 --- a/server/utils/common.go +++ b/server/utils/common.go @@ -95,3 +95,43 @@ func GetInviteVerificationURL(verificationURL, token, redirectURI string) string func GetEmailVerificationURL(token, hostname, redirectURI string) string { return hostname + "/verify_email?token=" + token + "&redirect_uri=" + redirectURI } + +// FindDeletedValues find deleted values between original and updated one +func FindDeletedValues(original, updated []string) []string { + deletedValues := make([]string, 0) + + // Create a map to store elements of the updated array for faster lookups + updatedMap := make(map[string]bool) + for _, value := range updated { + updatedMap[value] = true + } + + // Check for deleted values in the original array + for _, value := range original { + if _, found := updatedMap[value]; !found { + deletedValues = append(deletedValues, value) + } + } + + return deletedValues +} + +// DeleteFromArray will delete array from an array +func DeleteFromArray(original, valuesToDelete []string) []string { + result := make([]string, 0) + + // Create a map to store values to delete for faster lookups + valuesToDeleteMap := make(map[string]bool) + for _, value := range valuesToDelete { + valuesToDeleteMap[value] = true + } + + // Check if each element in the original array should be deleted + for _, value := range original { + if _, found := valuesToDeleteMap[value]; !found { + result = append(result, value) + } + } + + return result +}