Fix role selection on user creation.

Security improvements
This commit is contained in:
Andrew 2024-05-28 17:14:05 -04:00
parent 2a6c0ca751
commit d8ad8f5e09
6 changed files with 60 additions and 18 deletions

View File

@ -2,6 +2,7 @@ import typing as t
from jsonschema import ValidationError, validate
import orjson
from playhouse.shortcuts import model_to_dict
from app.classes.models.crafty_permissions import EnumPermissionsCrafty
from app.classes.web.base_api_handler import BaseApiHandler
create_role_schema = {
@ -71,7 +72,7 @@ class ApiRolesIndexHandler(BaseApiHandler):
return
(
_,
_,
exec_user_permissions_crafty,
_,
superuser,
_,
@ -81,7 +82,10 @@ class ApiRolesIndexHandler(BaseApiHandler):
# GET /api/v2/roles?ids=true
get_only_ids = self.get_query_argument("ids", None) == "true"
if not superuser:
if (
not superuser
and not EnumPermissionsCrafty.ROLES_CONFIG in exec_user_permissions_crafty
):
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
self.finish_json(
@ -104,14 +108,17 @@ class ApiRolesIndexHandler(BaseApiHandler):
return
(
_,
_,
exec_user_permissions_crafty,
_,
superuser,
user,
_,
) = auth_data
if not superuser:
if (
not superuser
and not EnumPermissionsCrafty.ROLES_CONFIG in exec_user_permissions_crafty
):
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
try:
@ -138,6 +145,8 @@ class ApiRolesIndexHandler(BaseApiHandler):
role_name = data["name"]
manager = data.get("manager", None)
if not superuser and not manager:
manager = auth_data[4]["user_id"]
if manager == self.controller.users.get_id_by_name("SYSTEM") or manager == 0:
manager = None

View File

@ -1,6 +1,7 @@
from jsonschema import ValidationError, validate
import orjson
from peewee import DoesNotExist
from peewee import DoesNotExist, IntegrityError
from app.classes.models.crafty_permissions import EnumPermissionsCrafty
from app.classes.web.base_api_handler import BaseApiHandler
modify_role_schema = {
@ -70,14 +71,17 @@ class ApiRolesRoleIndexHandler(BaseApiHandler):
return
(
_,
_,
exec_user_permissions_crafty,
_,
superuser,
_,
_,
) = auth_data
if not superuser:
if (
not superuser
and not EnumPermissionsCrafty.ROLES_CONFIG in exec_user_permissions_crafty
):
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
try:
@ -100,8 +104,11 @@ class ApiRolesRoleIndexHandler(BaseApiHandler):
user,
_,
) = auth_data
if not superuser:
role = self.controller.roles.get_role(role_id)
if (
str(role.get("manager", "no manager found")) != str(auth_data[4]["user_id"])
and not superuser
):
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
self.controller.roles.remove_role(role_id)
@ -179,7 +186,10 @@ class ApiRolesRoleIndexHandler(BaseApiHandler):
)
except DoesNotExist:
return self.finish_json(404, {"status": "error", "error": "ROLE_NOT_FOUND"})
except IntegrityError:
return self.finish_json(
404, {"status": "error", "error": "ROLE_NAME_EXISTS"}
)
self.controller.management.add_to_audit_log(
user["user_id"],
f"modified role with ID {role_id}",

View File

@ -153,7 +153,11 @@ class ApiUsersIndexHandler(BaseApiHandler):
for role in roles:
role = self.controller.roles.get_role(role)
if int(role["manager"]) != int(auth_data[4]["user_id"]) and not superuser:
if (
str(role.get("manager", "no manager found"))
!= str(auth_data[4]["user_id"])
and not superuser
):
return self.finish_json(
400, {"status": "error", "error": "INVALID_ROLES_CREATE"}
)

View File

@ -132,7 +132,6 @@ class ApiUsersUserIndexHandler(BaseApiHandler):
return self.finish_json(
400, {"status": "error", "error": "INVALID_JSON", "error_data": str(e)}
)
try:
validate(data, user_patch_schema)
except ValidationError as e:
@ -144,10 +143,8 @@ class ApiUsersUserIndexHandler(BaseApiHandler):
"error_data": str(e),
},
)
if user_id == "@me":
user_id = user["user_id"]
if (
EnumPermissionsCrafty.USER_CONFIG not in exec_user_crafty_permissions
and str(user["user_id"]) != str(user_id)
@ -215,6 +212,25 @@ class ApiUsersUserIndexHandler(BaseApiHandler):
return self.finish_json(
400, {"status": "error", "error": "INVALID_ROLES_MODIFY"}
)
user_modify = self.controller.users.get_user_roles_id(user_id)
for role in data["roles"]:
# Check if user is not a super user and that the exec user is the role
# manager or that the role already exists in the user's list
if not superuser and (
str(
self.controller.roles.get_role(role).get(
"manager", "no manager found"
)
)
!= str(auth_data[4]["user_id"])
and role not in user_modify
):
for item in user_modify:
print(type(role), type(item))
return self.finish_json(
400, {"status": "error", "error": "INVALID_ROLES_MODIFY"}
)
user_obj = HelperUsers.get_user_model(user_id)
if "password" in data and str(user["user_id"]) != str(user_id):

View File

@ -428,10 +428,13 @@
if (responseData.status === "ok") {
window.location.href = "/panel/panel_config";
} else {
let errordata = responseData.error;
if (responseData.error_data){
errordata = responseData.error
}
bootbox.alert({
title: responseData.error,
message: responseData.error_data
message: errordata
});
}
});

View File

@ -393,6 +393,7 @@ data['lang']) }}{% end %}
}
function replacer(key, value) {
if (typeof value == "boolean" || key === "email" || key === "permissions" || key === "roles") {
console.log(key)
return value
} else {
console.log(key, value)
@ -433,6 +434,7 @@ data['lang']) }}{% end %}
let disabled_flag = false;
let roles = null;
if (superuser || userId != edit_id){
console.log("ROLES")
roles = $('.role_check').map(function() {
if ($(this).attr("disabled")){
disabled_flag = true;
@ -457,9 +459,7 @@ data['lang']) }}{% end %}
delete formDataObject.username
}
if (superuser || userId != edit_id){
if (!disabled_flag){
formDataObject.roles = roles;
}
if ($("#permissions").length){
formDataObject.permissions = permissions;
}