mirror of
https://github.com/netbirdio/netbird.git
synced 2026-09-30 18:49:08 +02:00
Merge branch 'feature/user-info-with-role-permissions' into feature/users-roles-endpoint
# Conflicts: # management/server/http/handlers/users/users_handler.go # management/server/permissions/manager.go
This commit is contained in:
@@ -211,17 +211,8 @@ components:
|
||||
- read
|
||||
- write
|
||||
example: {"networks": { "read": true, "write": false}, "peers": { "read": false, "write": false} }
|
||||
default:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: boolean
|
||||
propertyNames:
|
||||
type: string
|
||||
enum:
|
||||
- read
|
||||
- write
|
||||
required:
|
||||
- default
|
||||
- modules
|
||||
- is_restricted
|
||||
UserRequest:
|
||||
type: object
|
||||
|
||||
@@ -1710,11 +1710,9 @@ type UserCreateRequest struct {
|
||||
|
||||
// UserPermissions defines model for UserPermissions.
|
||||
type UserPermissions struct {
|
||||
Default map[string]bool `json:"default"`
|
||||
|
||||
// IsRestricted Indicates whether this User's Peers view is restricted
|
||||
IsRestricted bool `json:"is_restricted"`
|
||||
Modules *map[string]map[string]bool `json:"modules,omitempty"`
|
||||
IsRestricted bool `json:"is_restricted"`
|
||||
Modules map[string]map[string]bool `json:"modules"`
|
||||
}
|
||||
|
||||
// UserRequest defines model for UserRequest.
|
||||
|
||||
@@ -328,45 +328,21 @@ func toRolesResponse(roles map[types.UserRole]roles.RolePermissions) []api.RoleP
|
||||
func toUserWithPermissionsResponse(user *users.UserInfoWithPermissions, userID string) *api.User {
|
||||
response := toUserResponse(user.UserInfo, userID)
|
||||
|
||||
response.Permissions = &api.UserPermissions{
|
||||
IsRestricted: user.Restricted,
|
||||
Default: toOperationsMapResponse(user.Permissions.AutoAllowNew),
|
||||
Modules: toModulesMapResponse(user.Permissions.Permissions),
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
func toOperationsMapResponse[K ~string, V any](input map[K]V) map[string]V {
|
||||
if len(input) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := make(map[string]V, len(input))
|
||||
for k, v := range input {
|
||||
result[string(k)] = v
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func toModulesMapResponse[K, L ~string](input map[K]map[L]bool) *map[string]map[string]bool {
|
||||
if len(input) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// stringify modules and operations keys
|
||||
modules := make(map[string]map[string]bool)
|
||||
for module, operations := range input {
|
||||
if converted := toOperationsMapResponse(operations); len(converted) > 0 {
|
||||
modules[string(module)] = converted
|
||||
for module, operations := range user.Permissions {
|
||||
modules[string(module)] = make(map[string]bool)
|
||||
for op, val := range operations {
|
||||
modules[string(module)][string(op)] = val
|
||||
}
|
||||
}
|
||||
|
||||
if len(modules) == 0 {
|
||||
return nil
|
||||
response.Permissions = &api.UserPermissions{
|
||||
IsRestricted: user.Restricted,
|
||||
Modules: modules,
|
||||
}
|
||||
|
||||
return &modules
|
||||
return response
|
||||
}
|
||||
|
||||
func toUserResponse(user *types.UserInfo, currenUserID string) *api.User {
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
nbcontext "github.com/netbirdio/netbird/management/server/context"
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/mock_server"
|
||||
"github.com/netbirdio/netbird/management/server/permissions/modules"
|
||||
"github.com/netbirdio/netbird/management/server/permissions/roles"
|
||||
"github.com/netbirdio/netbird/management/server/status"
|
||||
"github.com/netbirdio/netbird/management/server/types"
|
||||
@@ -149,7 +150,7 @@ func initUsersTestData() *handler {
|
||||
NonDeletable: false,
|
||||
Issued: "api",
|
||||
},
|
||||
Permissions: roles.Owner,
|
||||
Permissions: mergeRolePermissions(roles.Owner),
|
||||
}, nil
|
||||
case "regular-user":
|
||||
return &users.UserInfoWithPermissions{
|
||||
@@ -163,7 +164,7 @@ func initUsersTestData() *handler {
|
||||
NonDeletable: false,
|
||||
Issued: "api",
|
||||
},
|
||||
Permissions: roles.User,
|
||||
Permissions: mergeRolePermissions(roles.User),
|
||||
}, nil
|
||||
|
||||
case "admin-user":
|
||||
@@ -179,7 +180,7 @@ func initUsersTestData() *handler {
|
||||
LastLogin: time.Time{},
|
||||
Issued: "api",
|
||||
},
|
||||
Permissions: roles.Admin,
|
||||
Permissions: mergeRolePermissions(roles.Admin),
|
||||
}, nil
|
||||
case "restricted-user":
|
||||
return &users.UserInfoWithPermissions{
|
||||
@@ -194,7 +195,7 @@ func initUsersTestData() *handler {
|
||||
LastLogin: time.Time{},
|
||||
Issued: "api",
|
||||
},
|
||||
Permissions: roles.User,
|
||||
Permissions: mergeRolePermissions(roles.User),
|
||||
Restricted: true,
|
||||
}, nil
|
||||
}
|
||||
@@ -606,13 +607,7 @@ func TestCurrentUser(t *testing.T) {
|
||||
Issued: ptr("api"),
|
||||
LastLogin: ptr(time.Time{}),
|
||||
Permissions: &api.UserPermissions{
|
||||
IsRestricted: false,
|
||||
Default: map[string]bool{
|
||||
"read": true,
|
||||
"create": true,
|
||||
"update": true,
|
||||
"delete": true,
|
||||
},
|
||||
Modules: stringifyPermissionsKeys(mergeRolePermissions(roles.Owner)),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -631,12 +626,7 @@ func TestCurrentUser(t *testing.T) {
|
||||
Issued: ptr("api"),
|
||||
LastLogin: ptr(time.Time{}),
|
||||
Permissions: &api.UserPermissions{
|
||||
Default: map[string]bool{
|
||||
"read": false,
|
||||
"create": false,
|
||||
"update": false,
|
||||
"delete": false,
|
||||
},
|
||||
Modules: stringifyPermissionsKeys(mergeRolePermissions(roles.User)),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -655,21 +645,7 @@ func TestCurrentUser(t *testing.T) {
|
||||
Issued: ptr("api"),
|
||||
LastLogin: ptr(time.Time{}),
|
||||
Permissions: &api.UserPermissions{
|
||||
IsRestricted: false,
|
||||
Default: map[string]bool{
|
||||
"read": true,
|
||||
"create": true,
|
||||
"update": true,
|
||||
"delete": true,
|
||||
},
|
||||
Modules: ptr(map[string]map[string]bool{
|
||||
"accounts": {
|
||||
"read": true,
|
||||
"create": false,
|
||||
"update": false,
|
||||
"delete": false,
|
||||
},
|
||||
}),
|
||||
Modules: stringifyPermissionsKeys(mergeRolePermissions(roles.Admin)),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -689,12 +665,7 @@ func TestCurrentUser(t *testing.T) {
|
||||
LastLogin: ptr(time.Time{}),
|
||||
Permissions: &api.UserPermissions{
|
||||
IsRestricted: true,
|
||||
Default: map[string]bool{
|
||||
"read": false,
|
||||
"create": false,
|
||||
"update": false,
|
||||
"delete": false,
|
||||
},
|
||||
Modules: stringifyPermissionsKeys(mergeRolePermissions(roles.User)),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -729,3 +700,28 @@ func TestCurrentUser(t *testing.T) {
|
||||
func ptr[T any, PT *T](x T) PT {
|
||||
return &x
|
||||
}
|
||||
|
||||
func mergeRolePermissions(role roles.RolePermissions) roles.Permissions {
|
||||
permissions := roles.Permissions{}
|
||||
|
||||
for k := range modules.All {
|
||||
if rolePermissions, ok := role.Permissions[k]; ok {
|
||||
permissions[k] = rolePermissions
|
||||
continue
|
||||
}
|
||||
permissions[k] = role.AutoAllowNew
|
||||
}
|
||||
|
||||
return permissions
|
||||
}
|
||||
|
||||
func stringifyPermissionsKeys(permissions roles.Permissions) map[string]map[string]bool {
|
||||
modules := make(map[string]map[string]bool)
|
||||
for module, operations := range permissions {
|
||||
modules[string(module)] = make(map[string]bool)
|
||||
for op, val := range operations {
|
||||
modules[string(module)][string(op)] = val
|
||||
}
|
||||
}
|
||||
return modules
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user