diff options
Diffstat (limited to 'gn_auth/auth/authorisation/resources/views.py')
-rw-r--r-- | gn_auth/auth/authorisation/resources/views.py | 83 |
1 files changed, 72 insertions, 11 deletions
diff --git a/gn_auth/auth/authorisation/resources/views.py b/gn_auth/auth/authorisation/resources/views.py index 31421f4..a960ca3 100644 --- a/gn_auth/auth/authorisation/resources/views.py +++ b/gn_auth/auth/authorisation/resources/views.py @@ -39,21 +39,23 @@ from gn_auth.auth.authorisation.roles.models import ( from gn_auth.auth.authentication.oauth2.resource_server import require_oauth from gn_auth.auth.authentication.users import User, user_by_id, user_by_email -from .checks import authorised_for from .inbredset.views import popbp from .genotypes.views import genobp +from .phenotypes.views import phenobp from .errors import MissingGroupError from .groups.models import Group, user_group +from .checks import authorised_for, authorised_for_spec from .models import ( Resource, resource_data, resource_by_id, public_resources, resource_categories, assign_resource_user, link_data_to_resource, unassign_resource_user, resource_category_by_id, user_roles_on_resources, unlink_data_from_resource, create_resource as _create_resource, - get_resource_id) + get_resource_id, delete_resource as _delete_resource) resources = Blueprint("resources", __name__) resources.register_blueprint(popbp, url_prefix="/") resources.register_blueprint(genobp, url_prefix="/") +resources.register_blueprint(phenobp, url_prefix="/") @resources.route("/categories", methods=["GET"]) @require_oauth("profile group resource") @@ -73,8 +75,7 @@ def create_resource() -> Response: resource_name = form.get("resource_name") resource_category_id = UUID(form.get("resource_category")) db_uri = app.config["AUTH_DB"] - with (db.connection(db_uri) as conn, - db.cursor(conn) as cursor): + with db.connection(db_uri) as conn: try: group = user_group(conn, the_token.user).maybe( False, lambda grp: grp)# type: ignore[misc, arg-type] @@ -82,7 +83,7 @@ def create_resource() -> Response: raise MissingGroupError(# Not all resources require an owner group "User with no group cannot create a resource.") resource = _create_resource( - cursor, + conn, resource_name, resource_category_by_id(conn, resource_category_id), the_token.user, @@ -98,7 +99,9 @@ def create_resource() -> Response: f"{type(sql3ie)=}: {sql3ie=}") raise + @resources.route("/view/<uuid:resource_id>") +@resources.route("/<uuid:resource_id>/view") @require_oauth("profile group resource") def view_resource(resource_id: UUID) -> Response: """View a particular resource's details.""" @@ -135,7 +138,7 @@ def view_resource_data(resource_id: UUID) -> Response: with require_oauth.acquire("profile group resource") as the_token: db_uri = app.config["AUTH_DB"] count_per_page = __safe_get_requests_count__("count_per_page") - offset = (__safe_get_requests_page__("page") - 1) + offset = __safe_get_requests_page__("page") - 1 with db.connection(db_uri) as conn: resource = resource_by_id(conn, the_token.user, resource_id) return jsonify(resource_data( @@ -151,7 +154,7 @@ def link_data(): try: form = request_json() assert "resource_id" in form, "Resource ID not provided." - assert "data_link_id" in form, "Data Link ID not provided." + assert "data_link_ids" in form, "Data Link IDs not provided." assert "dataset_type" in form, "Dataset type not specified" assert form["dataset_type"].lower() in ( "mrna", "genotype", "phenotype"), "Invalid dataset type provided." @@ -159,8 +162,11 @@ def link_data(): with require_oauth.acquire("profile group resource") as the_token: def __link__(conn: db.DbConnection): return link_data_to_resource( - conn, the_token.user, UUID(form["resource_id"]), - form["dataset_type"], UUID(form["data_link_id"])) + conn, + the_token.user, + UUID(form["resource_id"]), + form["dataset_type"], + tuple(UUID(dlinkid) for dlinkid in form["data_link_ids"])) return jsonify(with_db_connection(__link__)) except AssertionError as aserr: @@ -409,9 +415,18 @@ def resource_roles(resource_id: UUID) -> Response: "ON rp.privilege_id=p.privilege_id " "WHERE rr.resource_id=? AND rr.role_created_by=?", (str(resource_id), str(_token.user.user_id))) - results = cursor.fetchall() + user_created = db_rows_to_roles(cursor.fetchall()) + + cursor.execute( + "SELECT ur.user_id, ur.resource_id, r.*, p.* FROM user_roles AS ur " + "INNER JOIN roles AS r ON ur.role_id=r.role_id " + "INNER JOIN role_privileges AS rp ON r.role_id=rp.role_id " + "INNER JOIN privileges AS p ON rp.privilege_id=p.privilege_id " + "WHERE resource_id=? AND user_id=?", + (str(resource_id), str(_token.user.user_id))) + assigned_to_user = db_rows_to_roles(cursor.fetchall()) - return db_rows_to_roles(results) + return assigned_to_user + user_created return jsonify(with_db_connection(__roles__)) @@ -659,3 +674,49 @@ def user_resource_roles(resource_id: UUID, user_id: UUID): return jsonify([asdict(role) for role in _user_resource_roles(conn, _token.user, _resource)]) + + +@resources.route("/delete", methods=["POST"]) +@require_oauth("profile group resource") +def delete_resource(): + """Delete the specified resource, if possible.""" + with (require_oauth.acquire("profile group resource") as the_token, + db.connection(app.config["AUTH_DB"]) as conn): + form = request_json() + try: + resource_id = UUID(form.get("resource_id")) + if not authorised_for_spec( + conn, + the_token.user.user_id, + resource_id, + "(OR group:resource:delete-resource system:resource:delete)"): + raise AuthorisationError("You do not have the appropriate " + "privileges to delete this resource.") + + data = resource_data( + conn, + resource_by_id(conn, the_token.user, resource_id), + 0, + 10) + if bool(data): + return jsonify({ + "error": "NonEmptyResouce", + "error-description": "Cannot delete a resource with linked data" + }), 400 + + _delete_resource(conn, resource_id) + return jsonify({ + "description": f"Successfully deleted resource with ID '{resource_id}'." + }) + except ValueError as _verr: + app.logger.debug("Error!", exc_info=True) + return jsonify({ + "error": "ValueError", + "error-description": "An invalid identifier was provided" + }), 400 + except TypeError as _terr: + app.logger.debug("Error!", exc_info=True) + return jsonify({ + "error": "TypeError", + "error-description": "An invalid identifier was provided" + }), 400 |