github.com/KiraCore/sekai@v0.3.43/x/gov/keeper/permission_registry.go (about) 1 package keeper 2 3 import ( 4 "strconv" 5 6 "github.com/KiraCore/sekai/x/gov/types" 7 "github.com/cosmos/cosmos-sdk/store/prefix" 8 sdk "github.com/cosmos/cosmos-sdk/types" 9 "github.com/gogo/protobuf/proto" 10 ) 11 12 func (k Keeper) GetNextRoleId(ctx sdk.Context) uint64 { 13 store := ctx.KVStore(k.storeKey) 14 bz := store.Get(NextRolePrefix) 15 if bz == nil { 16 return 1 17 } 18 return sdk.BigEndianToUint64(bz) 19 } 20 21 func (k Keeper) SetNextRoleId(ctx sdk.Context, nextRoleId uint64) { 22 store := ctx.KVStore(k.storeKey) 23 store.Set(NextRolePrefix, sdk.Uint64ToBigEndian(nextRoleId)) 24 } 25 26 func (k Keeper) SetRole(ctx sdk.Context, role types.Role) { 27 bz, err := proto.Marshal(&role) 28 if err != nil { 29 panic(err) 30 } 31 prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), RoleIdToInfo) 32 prefixStore.Set(roleToBytes(uint64(role.Id)), bz) 33 34 prefixStore = prefix.NewStore(ctx.KVStore(k.storeKey), RoleSidToIdRegistry) 35 prefixStore.Set([]byte(role.Sid), sdk.Uint64ToBigEndian(uint64(role.Id))) 36 37 // set empty permissions 38 perms := types.NewPermissions(nil, nil) 39 k.savePermissionsForRole(ctx, uint64(role.Id), perms) 40 } 41 42 func (k Keeper) DeleteRole(ctx sdk.Context, role types.Role) { 43 prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), RoleIdToInfo) 44 prefixStore.Delete(roleToBytes(uint64(role.Id))) 45 46 prefixStore = prefix.NewStore(ctx.KVStore(k.storeKey), RoleSidToIdRegistry) 47 prefixStore.Delete([]byte(role.Sid)) 48 49 k.deletePermissionsForRole(ctx, uint64(role.Id)) 50 } 51 52 func (k Keeper) GetRole(ctx sdk.Context, roleId uint64) (types.Role, error) { 53 prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), RoleIdToInfo) 54 bz := prefixStore.Get(roleToBytes(uint64(roleId))) 55 if bz == nil { 56 return types.Role{}, types.ErrRoleDoesNotExist 57 } 58 role := types.Role{} 59 err := proto.Unmarshal(bz, &role) 60 return role, err 61 } 62 63 func (k Keeper) GetRoleBySid(ctx sdk.Context, sId string) (types.Role, error) { 64 prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), RoleSidToIdRegistry) 65 bz := prefixStore.Get([]byte(sId)) 66 if bz == nil { 67 return types.Role{}, types.ErrRoleDoesNotExist 68 } 69 return k.GetRole(ctx, sdk.BigEndianToUint64(bz)) 70 } 71 72 func (k Keeper) CreateRole(ctx sdk.Context, sid, description string) uint64 { 73 newRoleId := k.GetNextRoleId(ctx) 74 k.SetRole(ctx, types.Role{ 75 Id: uint32(newRoleId), 76 Sid: sid, 77 Description: description, 78 }) 79 k.SetNextRoleId(ctx, newRoleId+1) 80 return newRoleId 81 } 82 83 // savePermissionsForRole adds permissions to role in the permission Registry. 84 func (k Keeper) savePermissionsForRole(ctx sdk.Context, role uint64, permissions *types.Permissions) { 85 prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), RolePermissionRegistry) 86 prefixStore.Set(roleToBytes(role), k.cdc.MustMarshal(permissions)) 87 } 88 89 // deletePermissionsForRole delete permissions on the role in the permission Registry. 90 func (k Keeper) deletePermissionsForRole(ctx sdk.Context, role uint64) { 91 prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), RolePermissionRegistry) 92 prefixStore.Delete(roleToBytes(role)) 93 } 94 95 func (k Keeper) GetAllRoles(ctx sdk.Context) []types.Role { 96 prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), RoleIdToInfo) 97 iterator := sdk.KVStorePrefixIterator(prefixStore, nil) 98 defer iterator.Close() 99 100 roles := []types.Role{} 101 for ; iterator.Valid(); iterator.Next() { 102 role := types.Role{} 103 err := proto.Unmarshal(iterator.Value(), &role) 104 if err != nil { 105 panic(err) 106 } 107 roles = append(roles, role) 108 } 109 return roles 110 } 111 112 // GetPermissionsForRole returns the permissions assigned to the specific role. 113 func (k Keeper) GetPermissionsForRole(ctx sdk.Context, role uint64) (types.Permissions, bool) { 114 prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), RolePermissionRegistry) 115 bz := prefixStore.Get(roleToBytes(role)) 116 if bz == nil { 117 return types.Permissions{}, false 118 } 119 120 var perm types.Permissions 121 k.cdc.MustUnmarshal(bz, &perm) 122 123 return perm, true 124 } 125 126 func (k Keeper) GetRoleIdFromIdentifierString(ctx sdk.Context, identifier string) (uint64, error) { 127 if roleId, err := strconv.Atoi(identifier); err == nil { 128 return uint64(roleId), nil 129 } 130 role, err := k.GetRoleBySid(ctx, identifier) // sid 131 if err != nil { 132 return 0, err 133 } 134 return uint64(role.Id), nil 135 } 136 137 func (k Keeper) SetWhiltelistPermRoleKey(ctx sdk.Context, role uint64, perm types.PermValue) { 138 store := ctx.KVStore(k.storeKey) 139 store.Set(prefixWhitelistRole(perm, role), roleToBytes(role)) 140 } 141 142 func (k Keeper) WhitelistRolePermission(ctx sdk.Context, role uint64, perm types.PermValue) error { 143 store := ctx.KVStore(k.storeKey) 144 145 prefixStore := prefix.NewStore(store, RolePermissionRegistry) 146 bz := prefixStore.Get(roleToBytes(role)) 147 if bz == nil { 148 return types.ErrRoleDoesNotExist 149 } 150 151 var perms types.Permissions 152 k.cdc.MustUnmarshal(bz, &perms) 153 154 err := perms.AddToWhitelist(perm) 155 if err != nil { 156 return err 157 } 158 159 k.savePermissionsForRole(ctx, role, &perms) 160 k.SetWhiltelistPermRoleKey(ctx, role, perm) 161 162 return nil 163 } 164 165 func (k Keeper) BlacklistRolePermission(ctx sdk.Context, role uint64, perm types.PermValue) error { 166 store := ctx.KVStore(k.storeKey) 167 168 prefixStore := prefix.NewStore(store, RolePermissionRegistry) 169 bz := prefixStore.Get(roleToBytes(role)) 170 if bz == nil { 171 return types.ErrRoleDoesNotExist 172 } 173 174 var perms types.Permissions 175 k.cdc.MustUnmarshal(bz, &perms) 176 177 err := perms.AddToBlacklist(perm) 178 if err != nil { 179 return err 180 } 181 182 k.savePermissionsForRole(ctx, role, &perms) 183 184 return nil 185 } 186 187 func (k Keeper) RemoveWhitelistRolePermission(ctx sdk.Context, role uint64, perm types.PermValue) error { 188 store := ctx.KVStore(k.storeKey) 189 190 prefixStore := prefix.NewStore(store, RolePermissionRegistry) 191 bz := prefixStore.Get(roleToBytes(role)) 192 if bz == nil { 193 return types.ErrRoleDoesNotExist 194 } 195 196 var perms types.Permissions 197 k.cdc.MustUnmarshal(bz, &perms) 198 199 err := perms.RemoveFromWhitelist(perm) 200 if err != nil { 201 return err 202 } 203 204 k.savePermissionsForRole(ctx, role, &perms) 205 store.Delete(prefixWhitelistRole(perm, role)) 206 207 return nil 208 } 209 210 func (k Keeper) RemoveBlacklistRolePermission(ctx sdk.Context, role uint64, perm types.PermValue) error { 211 store := ctx.KVStore(k.storeKey) 212 prefixStore := prefix.NewStore(store, RolePermissionRegistry) 213 214 bz := prefixStore.Get(roleToBytes(role)) 215 if bz == nil { 216 return types.ErrRoleDoesNotExist 217 } 218 219 var perms types.Permissions 220 k.cdc.MustUnmarshal(bz, &perms) 221 222 err := perms.RemoveFromBlacklist(perm) 223 if err != nil { 224 return err 225 } 226 227 k.savePermissionsForRole(ctx, role, &perms) 228 229 return nil 230 } 231 232 func (k Keeper) IterateRoles(ctx sdk.Context) sdk.Iterator { 233 return sdk.KVStorePrefixIterator(ctx.KVStore(k.storeKey), RolePermissionRegistry) 234 } 235 236 func (k Keeper) GetPermissionsFromIterator(iterator sdk.Iterator) types.Permissions { 237 bz := iterator.Value() 238 if bz == nil { 239 return types.Permissions{} 240 } 241 242 var perms types.Permissions 243 k.cdc.MustUnmarshal(bz, &perms) 244 return perms 245 } 246 247 func (k Keeper) GetRolesByWhitelistedPerm(ctx sdk.Context, perm types.PermValue) sdk.Iterator { 248 store := ctx.KVStore(k.storeKey) 249 return sdk.KVStorePrefixIterator(store, prefixWhitelist(perm)) 250 } 251 252 func (k Keeper) CheckIfAllowedPermission(ctx sdk.Context, addr sdk.AccAddress, permValue types.PermValue) bool { 253 return CheckIfAllowedPermission(ctx, k, addr, permValue) 254 } 255 256 func prefixWhitelist(perm types.PermValue) []byte { 257 return append(WhitelistRolePrefix, permToBytes(perm)...) 258 } 259 260 func prefixWhitelistRole(perm types.PermValue, role uint64) []byte { 261 return append(prefixWhitelist(perm), roleToBytes(role)...) 262 }