diff options
Diffstat (limited to 'uploader/species')
-rw-r--r-- | uploader/species/models.py | 8 | ||||
-rw-r--r-- | uploader/species/views.py | 69 |
2 files changed, 68 insertions, 9 deletions
diff --git a/uploader/species/models.py b/uploader/species/models.py index 53e7de0..cea3549 100644 --- a/uploader/species/models.py +++ b/uploader/species/models.py @@ -81,3 +81,11 @@ def save_species(conn: mdb.Connection, **species, "species_id": species_id } + + +def species_families(conn: mdb.Connection) -> tuple: + """Retrieve the families under which species are grouped.""" + with conn.cursor(cursorclass=DictCursor) as cursor: + cursor.execute( + "SELECT DISTINCT(Family) FROM Species WHERE Family IS NOT NULL") + return tuple(fam["Family"] for fam in cursor.fetchall()) diff --git a/uploader/species/views.py b/uploader/species/views.py index 5de5277..d994e41 100644 --- a/uploader/species/views.py +++ b/uploader/species/views.py @@ -1,4 +1,5 @@ """Endpoints handling species.""" +from pymonad.either import Left, Right, Either from flask import (flash, request, url_for, @@ -9,9 +10,10 @@ from flask import (flash, from uploader.population import popbp from uploader.ui import make_template_renderer from uploader.db_utils import database_connection +from uploader.oauth2.client import oauth2_get, oauth2_post from uploader.authorisation import require_login, require_token -from .models import all_species, save_species, species_by_id +from .models import all_species, save_species, species_by_id, species_families speciesbp = Blueprint("species", __name__) @@ -100,11 +102,11 @@ def create_species(): return redirect(url_for("species.view_species", species_id=species["species_id"])) -@speciesbp.route("/<int:species_id>/edit") +@speciesbp.route("/<int:species_id>/edit-extra", methods=["GET", "POST"]) @require_login @require_token #def edit_species(species_id: int): -def edit_species(token: dict, species_id: int): +def edit_species_extra(token: dict, species_id: int):# pylint: disable=[unused-argument] """Edit a species' details. Parameters @@ -112,9 +114,58 @@ def edit_species(token: dict, species_id: int): token: A JWT token used for authorisation. species_id: An identifier for the species being edited. """ - app.logger.debug("======================\n" - "Token: %s\n" - "SpeciesId: %s\n" - "======================", - token, species_id) - return "Would edit the species." + def __failure__(res): + app.logger.debug( + "There was an error in the attempt to edit the species: %s", res) + flash(res, "alert-danger") + return redirect(url_for("species.view_species", species_id=species_id)) + + def __system_resource_uuid__(resources) -> Either: + sys_res = [ + resource for resource in resources + if resource["resource_category"]["resource_category_key"] == "system" + ] + if len(sys_res) != 1: + return Left("Could not find/identify a valid system resource.") + return Right(sys_res[0]["resource_id"]) + + def __check_privileges__(authorisations): + if len(authorisations.items()) != 1: + return Left("Got authorisations for more than a single resource!") + + auths = tuple(authorisations.items())[0][1] + authorised = "system:species:edit-extra-info" in tuple( + privilege["privilege_id"] + for role in auths["roles"] + for privilege in role["privileges"]) + if authorised: + return Right(authorised) + return Left("You are not authorised to edit species extra details.") + + with database_connection(app.config["SQL_URI"]) as conn: + species = species_by_id(conn, species_id) + families = species_families(conn) + if bool(species) and request.method == "GET": + return oauth2_get("auth/user/resources").then( + __system_resource_uuid__ + ).then( + lambda resource_id: oauth2_post( + "auth/resource/authorisation", + json={"resource-ids": [resource_id]}) + ).then(__check_privileges__).then( + lambda authorisations: render_template("species/edit-species.html", + species=species, + families=families, + activelink="edit-species") + ).either(__failure__, lambda res: res) + + if bool(species) and request.method == "POST": + flash("We would have edited the species, but the feature is not " + "currently implemented …", + "alert-danger") + return redirect(url_for("species.edit_species_extra", + species_id=species_id)) + + flash("Species with the given identifier was not found!", + "alert-danger") + return redirect(url_for("species.list_species")) |