diff --git a/delivery2/README.md b/delivery2/README.md index 310b141..e364a87 100644 --- a/delivery2/README.md +++ b/delivery2/README.md @@ -149,6 +149,14 @@ Mainly, it's divided into 3 categories: - `POST /file/delete/`: Deletes a file. - Required headers: - `Authorization: token +- `POST /file/acl`: Updates the ACL for a file. + - Required headers: + - `Authorization: token` + - Required payload fields: + - `document_handle`: Document handle. + - `role`: Role name. + - `perm`: Permission name. + - `operation`: `add` | `remove`. (One of the following: add, remove) - `POST /role/create`: Creates a new role. - Required headers: - `Authorization: token` diff --git a/delivery2/server/routes/file.py b/delivery2/server/routes/file.py index 8e9393f..cdd7467 100644 --- a/delivery2/server/routes/file.py +++ b/delivery2/server/routes/file.py @@ -2,8 +2,8 @@ import json from flask import Blueprint, request, jsonify, send_file, Response -from utils import Perm, get_hex_from_temp_file, get_hash, check_valid_time -from services import FileService, OrganizationService, UserService, SessionService +from utils import Perm, get_hex_from_temp_file, get_hash, check_valid_time, PermOperation +from services import FileService, OrganizationService, UserService, SessionService, RoleService file_bp = Blueprint("file", __name__) upload_service = FileService() @@ -164,6 +164,46 @@ def file_delete(document_handle: str): return jsonify(file.to_dict()) +@file_bp.route("/acl", methods=["POST"]) +def file_acl(): + session_token = request.headers.get("Authorization") + if not session_token: + return jsonify({"error": "No session token"}), 400 + + data = request.json + if type(data) is str: + data = json.loads(data) + if "document_handle" not in data or "role" not in data or "perm" not in data or "operation" not in data: + return jsonify({"error": "Missing required fields"}), 400 + + doc_handle = data["document_handle"] + role = data["role"] + perm = Perm.from_str(data["perm"]) + operation = PermOperation.ADD if data["operation"] == "add" else PermOperation.REMOVE + + session = SessionService.validate_session(session_token, required_perms=[Perm.DOC_ACL], doc_handle=doc_handle) + if isinstance(session, tuple): + return session + + org = OrganizationService.get_organization(session.org_id) + if not org: + return jsonify({"error": "Organization not found"}), 404 + + file = FileService.get_file_by_document_handle(doc_handle) + if not file: + return jsonify({"error": "File not found"}), 404 + + if role not in org.roles: + return jsonify({"error": "Role not found"}), 404 + + try: + RoleService.change_perm_on_role_in_file(file, role, perm, operation) + except ValueError as e: + return jsonify({"error": str(e)}), 400 + + return jsonify(file.to_dict()), 200 + + ################################################ diff --git a/delivery2/server/routes/role.py b/delivery2/server/routes/role.py index 5abe0c5..2322777 100644 --- a/delivery2/server/routes/role.py +++ b/delivery2/server/routes/role.py @@ -35,7 +35,7 @@ def role_create(): return jsonify(role), 201 -@role_bp.route("//list/users", methods=["GET"]) +@role_bp.route("//list/users", methods=["GET"]) def role_list_users(role): session_token = request.headers.get("Authorization") if not session_token: @@ -56,7 +56,7 @@ def role_list_users(role): return jsonify(users), 200 -@role_bp.route("//list/perms", methods=["GET"]) +@role_bp.route("//list/perms", methods=["GET"]) def role_list_perms(role): session_token = request.headers.get("Authorization") if not session_token: @@ -77,7 +77,7 @@ def role_list_perms(role): return jsonify(perms), 200 -@role_bp.route("//suspend", methods=["POST"]) +@role_bp.route("//suspend", methods=["POST"]) def role_suspend(role): data = request.json if type(data) is str: @@ -106,7 +106,7 @@ def role_suspend(role): return jsonify({"message": "Role suspended"}), 200 -@role_bp.route("//activate", methods=["POST"]) +@role_bp.route("//activate", methods=["POST"]) def role_activate(role): data = request.json if type(data) is str: @@ -135,7 +135,7 @@ def role_activate(role): return jsonify({"message": "Role activated"}), 200 -@role_bp.route("//user/add/", methods=["POST"]) +@role_bp.route("//user/add/", methods=["POST"]) def role_user_add(role, username): data = request.json if type(data) is str: @@ -168,7 +168,7 @@ def role_user_add(role, username): return jsonify({"message": "User added to role"}), 200 -@role_bp.route("//user/remove/", methods=["POST"]) +@role_bp.route("//user/remove/", methods=["POST"]) def role_user_remove(role, username): data = request.json if type(data) is str: @@ -201,7 +201,7 @@ def role_user_remove(role, username): return jsonify({"message": "User removed from role"}), 200 -@role_bp.route("//perm/add/", methods=["POST"]) +@role_bp.route("//perm/add/", methods=["POST"]) def role_perm_add(role, perm): data = request.json if type(data) is str: @@ -230,7 +230,7 @@ def role_perm_add(role, perm): return jsonify({"message": "Permission added to role"}), 200 -@role_bp.route("//perm/remove/", methods=["POST"]) +@role_bp.route("//perm/remove/", methods=["POST"]) def role_perm_remove(role, perm): data = request.json if type(data) is str: @@ -259,7 +259,7 @@ def role_perm_remove(role, perm): return jsonify({"message": "Permission removed from role"}), 200 -@role_bp.route("/session/assume/", methods=["POST"]) +@role_bp.route("/session/assume/", methods=["POST"]) def role_session_assume(role): session_token = request.headers.get("Authorization") if not session_token: @@ -280,7 +280,7 @@ def role_session_assume(role): return jsonify(session.to_dict()), 200 -@role_bp.route("/session/drop/", methods=["POST"]) +@role_bp.route("/session/drop/", methods=["POST"]) def role_session_drop(role): session_token = request.headers.get("Authorization") if not session_token: @@ -314,7 +314,7 @@ def role_session_list(): roles = SessionService.list_roles(session) return jsonify(roles), 200 -@role_bp.route("/perm//roles", methods=["GET"]) +@role_bp.route("/perm//roles", methods=["GET"]) def perm_list_roles(perm): session_token = request.headers.get("Authorization") if not session_token: