about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--gn3/case_attributes.py86
1 files changed, 86 insertions, 0 deletions
diff --git a/gn3/case_attributes.py b/gn3/case_attributes.py
index f2beb7d..9f2370d 100644
--- a/gn3/case_attributes.py
+++ b/gn3/case_attributes.py
@@ -6,6 +6,11 @@ from flask import jsonify, Response, Blueprint, current_app
 
 from gn3.db_utils import Connection, database_connection
 
+from gn3.auth.authentication.users import User
+from gn3.auth.authentication.oauth2.resource_server import require_oauth
+
+from gn3.auth.authorisation.errors import AuthorisationError
+
 caseattr = Blueprint("case-attribute", __name__)
 
 @caseattr.route("/<int:inbredset_id>/names", methods=["GET"])
@@ -68,3 +73,84 @@ def inbredset_case_attribute_values(inbredset_id: int) -> Response:
     """Retrieve the group's (InbredSet's) case-attribute values."""
     with database_connection(current_app.config["SQL_URI"]) as conn:
         return jsonify(__case_attributes_by_inbred_set__(conn, inbredset_id))
+
+def __process_edit_data__(form_data) -> tuple[dict, ...]:
+    """Process data from form and return tuple of dicts."""
+    raise NotImplementedError
+
+def __compute_diff__(original_data: tuple[dict, ...], edit_data: tuple[dict, ...]):
+    """Return the diff of the data."""
+    raise NotImplementedError
+
+def __queue_diff__(conn: Connection, user: User, diff) -> str:
+    """
+    Queue diff for future processing.
+
+    Returns: `diff`
+        On success, this will return the filename where the diff was saved.
+        On failure, it will raise a MySQL error.
+    """
+    # TODO: Check user has "edit case attribute privileges"
+    raise NotImplementedError
+
+def __apply_diff__(conn: Connection, user: User, diff_filename) -> None:
+    """
+    Apply the changes in the diff at `diff_filename` to the data in the database
+    if the user has appropriate privileges.
+    """
+    # TODO: Check user has "approve/reject case attribute diff privileges"
+    def __save_diff__(conn: Connection, diff_filename):
+        """Save to the database."""
+        raise NotImplementedError
+    raise NotImplementedError
+
+def __reject_diff__(conn: Connection, user: User, diff_filename) -> None:
+    """
+    Reject the changes in the diff at `diff_filename` to the data in the
+    database if the user has appropriate privileges.
+    """
+    # TODO: Check user has "approve/reject case attribute diff privileges"
+    raise NotImplementedError
+
+@caseattr.route("/<int:inbredset_id>/edit", methods=["POST"])
+def edit_case_attributes(inbredset_id: int) -> Response:
+    """Edit the case attributes for `InbredSetId` based on data received."""
+    with (require_oauth.acquire("profile resource") as the_token,
+          database_connection(current_app.config["SQL_URI"]) as conn):
+        # TODO: Check user has "edit case attribute privileges"
+        user = the_token.user
+        diff_filename = __queue_diff__(conn, user, __compute_diff__(
+            __case_attributes_by_inbred_set__(conn, inbredset_id)
+            __process_edit_data__(request.form)))
+        try:
+            __apply_diff__(conn, user, diff_filename)
+            return jsonify({
+                "diff-status": "applied",
+                "message": ("The changes to the case-attributes have been "
+                            "applied successfully.")
+            })
+        except AuthorisationError as _auth_err:
+            return jsonify({
+                "diff-status": "queued",
+                "message": ("The changes to the case-attributes have been "
+                            "queued for approval.")
+                "diff-filename": diff_filename
+            })
+
+@caseattr.route("/approve/<path:filename>", methods=["POST"])
+def approve_case_attributes_diff(inbredset_id: int) -> Response:
+    """Approve the changes to the case attributes in the diff."""
+    # TODO: Check user has "approve/reject case attribute diff privileges"
+    with (require_oauth.acquire("profile resource") as the_token,
+          database_connection(current_app.config["SQL_URI"]) as conn):
+        __apply_diff__(conn, the_token.user, diff_filename)
+        raise NotImplementedError
+
+@caseattr.route("/reject/<path:filename>", methods=["POST"])
+def reject_case_attributes_diff(inbredset_id: int) -> Response:
+    """Reject the changes to the case attributes in the diff."""
+    # TODO: Check user has "approve/reject case attribute diff privileges"
+    with (require_oauth.acquire("profile resource") as the_token,
+          database_connection(current_app.config["SQL_URI"]) as conn):
+        __reject_diff__(conn, the_token.user, diff_filename)
+        raise NotImplementedError