[Fix] Fix Perm for creating entities (#341)

Co-authored-by: Tim Lorsbach <tim@lorsba.ch>
Reviewed-on: enviPath/enviPy#341
This commit is contained in:
2026-02-27 03:56:33 +13:00
parent d2c2e643cb
commit cc9598775c

View File

@ -37,6 +37,13 @@ from .models import (
Package = s.GET_PACKAGE_MODEL() Package = s.GET_PACKAGE_MODEL()
def get_package_for_write(user, package_uuid):
p = PackageManager.get_package_by_id(user, package_uuid)
if not PackageManager.writable(user, p):
raise ValueError("You do not have the rights to write to this Package!")
return p
def _anonymous_or_real(request): def _anonymous_or_real(request):
if request.user.is_authenticated and not request.user.is_anonymous: if request.user.is_authenticated and not request.user.is_anonymous:
return request.user return request.user
@ -455,7 +462,7 @@ class UpdatePackage(Schema):
@router.post("/package/{uuid:package_uuid}", response={200: PackageSchema | Any, 400: Error}) @router.post("/package/{uuid:package_uuid}", response={200: PackageSchema | Any, 400: Error})
def update_package(request, package_uuid, pack: Form[UpdatePackage]): def update_package(request, package_uuid, pack: Form[UpdatePackage]):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
if pack.hiddenMethod: if pack.hiddenMethod:
if pack.hiddenMethod == "DELETE": if pack.hiddenMethod == "DELETE":
@ -717,7 +724,7 @@ def create_package_compound(
c: Form[CreateCompound], c: Form[CreateCompound],
): ):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
# inchi is not used atm # inchi is not used atm
c = Compound.create( c = Compound.create(
p, c.compoundSmiles, c.compoundName, c.compoundDescription, inchi=c.inchi p, c.compoundSmiles, c.compoundName, c.compoundDescription, inchi=c.inchi
@ -730,14 +737,10 @@ def create_package_compound(
@router.delete("/package/{uuid:package_uuid}/compound/{uuid:compound_uuid}") @router.delete("/package/{uuid:package_uuid}/compound/{uuid:compound_uuid}")
def delete_compound(request, package_uuid, compound_uuid): def delete_compound(request, package_uuid, compound_uuid):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
c = Compound.objects.get(package=p, uuid=compound_uuid)
if PackageManager.writable(request.user, p): c.delete()
c = Compound.objects.get(package=p, uuid=compound_uuid) return redirect(f"{p.url}/compound")
c.delete()
return redirect(f"{p.url}/compound")
else:
raise ValueError("You do not have the rights to delete this Compound!")
except ValueError: except ValueError:
return 403, { return 403, {
"message": f"Deleting Compound with id {compound_uuid} failed due to insufficient rights!" "message": f"Deleting Compound with id {compound_uuid} failed due to insufficient rights!"
@ -749,31 +752,29 @@ def delete_compound(request, package_uuid, compound_uuid):
) )
def delete_compound_structure(request, package_uuid, compound_uuid, structure_uuid): def delete_compound_structure(request, package_uuid, compound_uuid, structure_uuid):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
if PackageManager.writable(request.user, p): c = Compound.objects.get(package=p, uuid=compound_uuid)
c = Compound.objects.get(package=p, uuid=compound_uuid) cs = CompoundStructure.objects.get(compound=c, uuid=structure_uuid)
cs = CompoundStructure.objects.get(compound=c, uuid=structure_uuid)
# Check if we have to delete the compound as no structure is left # Check if we have to delete the compound as no structure is left
if len(cs.compound.structures.all()) == 1: if len(cs.compound.structures.all()) == 1:
# This will delete the structure as well # This will delete the structure as well
c.delete()
return redirect(p.url + "/compound")
else:
if cs.normalized_structure:
c.delete() c.delete()
return redirect(p.url + "/compound") return redirect(p.url + "/compound")
else: else:
if cs.normalized_structure: if c.default_structure == cs:
c.delete() cs.delete()
return redirect(p.url + "/compound") c.default_structure = c.structures.all().first()
return redirect(c.url + "/structure")
else: else:
if c.default_structure == cs: cs.delete()
cs.delete() return redirect(c.url + "/structure")
c.default_structure = c.structures.all().first()
return redirect(c.url + "/structure")
else:
cs.delete()
return redirect(c.url + "/structure")
else:
raise ValueError("You do not have the rights to delete this CompoundStructure!")
except ValueError: except ValueError:
return 403, { return 403, {
"message": f"Deleting CompoundStructure with id {compound_uuid} failed due to insufficient rights!" "message": f"Deleting CompoundStructure with id {compound_uuid} failed due to insufficient rights!"
@ -960,7 +961,7 @@ def create_package_simple_rule(
r: Form[CreateSimpleRule], r: Form[CreateSimpleRule],
): ):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
if r.rdkitrule and r.rdkitrule.strip() == "true": if r.rdkitrule and r.rdkitrule.strip() == "true":
raise ValueError("Not yet implemented!") raise ValueError("Not yet implemented!")
@ -996,7 +997,7 @@ def create_package_parallel_rule(
r: Form[CreateParallelRule], r: Form[CreateParallelRule],
): ):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
srs = SimpleRule.objects.filter(package=p, url__in=r.simpleRules) srs = SimpleRule.objects.filter(package=p, url__in=r.simpleRules)
@ -1040,7 +1041,7 @@ def post_package_parallel_rule(request, package_uuid, rule_uuid, compound: Form[
def _post_package_rule(request, package_uuid, rule_uuid, compound: Form[str]): def _post_package_rule(request, package_uuid, rule_uuid, compound: Form[str]):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
r = Rule.objects.get(package=p, uuid=rule_uuid) r = Rule.objects.get(package=p, uuid=rule_uuid)
if compound is not None: if compound is not None:
@ -1085,14 +1086,11 @@ def delete_parallel_rule(request, package_uuid, rule_uuid):
def _delete_rule(request, package_uuid, rule_uuid): def _delete_rule(request, package_uuid, rule_uuid):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
r = Rule.objects.get(package=p, uuid=rule_uuid)
r.delete()
return redirect(f"{p.url}/rule")
if PackageManager.writable(request.user, p):
r = Rule.objects.get(package=p, uuid=rule_uuid)
r.delete()
return redirect(f"{p.url}/rule")
else:
raise ValueError("You do not have the rights to delete this Rule!")
except ValueError: except ValueError:
return 403, { return 403, {
"message": f"Deleting Rule with id {rule_uuid} failed due to insufficient rights!" "message": f"Deleting Rule with id {rule_uuid} failed due to insufficient rights!"
@ -1207,7 +1205,7 @@ def create_package_reaction(
r: Form[CreateReaction], r: Form[CreateReaction],
): ):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
if r.smirks is None and (r.educt is None or r.product is None): if r.smirks is None and (r.educt is None or r.product is None):
raise ValueError("Either SMIRKS or educt/product must be provided") raise ValueError("Either SMIRKS or educt/product must be provided")
@ -1253,14 +1251,11 @@ def create_package_reaction(
@router.delete("/package/{uuid:package_uuid}/reaction/{uuid:reaction_uuid}") @router.delete("/package/{uuid:package_uuid}/reaction/{uuid:reaction_uuid}")
def delete_reaction(request, package_uuid, reaction_uuid): def delete_reaction(request, package_uuid, reaction_uuid):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
if PackageManager.writable(request.user, p): r = Reaction.objects.get(package=p, uuid=reaction_uuid)
r = Reaction.objects.get(package=p, uuid=reaction_uuid) r.delete()
r.delete() return redirect(f"{p.url}/reaction")
return redirect(f"{p.url}/reaction")
else:
raise ValueError("You do not have the rights to delete this Reaction!")
except ValueError: except ValueError:
return 403, { return 403, {
"message": f"Deleting Reaction with id {reaction_uuid} failed due to insufficient rights!" "message": f"Deleting Reaction with id {reaction_uuid} failed due to insufficient rights!"
@ -1340,14 +1335,12 @@ def create_package_scenario(request, package_uuid):
@router.delete("/package/{uuid:package_uuid}/scenario") @router.delete("/package/{uuid:package_uuid}/scenario")
def delete_scenarios(request, package_uuid): def delete_scenarios(request, package_uuid):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
scens = Scenario.objects.filter(package=p)
scens.delete()
return redirect(f"{p.url}/scenario")
if PackageManager.writable(request.user, p):
scens = Scenario.objects.filter(package=p)
scens.delete()
return redirect(f"{p.url}/scenario")
else:
raise ValueError("You do not have the rights to delete Scenarios!")
except ValueError: except ValueError:
return 403, {"message": "Deleting Scenarios failed due to insufficient rights!"} return 403, {"message": "Deleting Scenarios failed due to insufficient rights!"}
@ -1355,14 +1348,12 @@ def delete_scenarios(request, package_uuid):
@router.delete("/package/{uuid:package_uuid}/scenario/{uuid:scenario_uuid}") @router.delete("/package/{uuid:package_uuid}/scenario/{uuid:scenario_uuid}")
def delete_scenario(request, package_uuid, scenario_uuid): def delete_scenario(request, package_uuid, scenario_uuid):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
scen = Scenario.objects.get(package=p, uuid=scenario_uuid)
scen.delete()
return redirect(f"{p.url}/scenario")
if PackageManager.writable(request.user, p):
scen = Scenario.objects.get(package=p, uuid=scenario_uuid)
scen.delete()
return redirect(f"{p.url}/scenario")
else:
raise ValueError("You do not have the rights to delete this Scenario!")
except ValueError: except ValueError:
return 403, { return 403, {
"message": f"Deleting Scenario with id {scenario_uuid} failed due to insufficient rights!" "message": f"Deleting Scenario with id {scenario_uuid} failed due to insufficient rights!"
@ -1523,7 +1514,10 @@ def create_pathway(
pw: Form[CreatePathway], pw: Form[CreatePathway],
): ):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
if not PackageManager.writable(request.user, p):
raise ValueError("You do not have the rights to create a Pathway!")
stand_smiles = FormatConverter.standardize(pw.smilesinput.strip(), remove_stereo=True) stand_smiles = FormatConverter.standardize(pw.smilesinput.strip(), remove_stereo=True)
@ -1558,14 +1552,12 @@ def create_pathway(
@router.delete("/package/{uuid:package_uuid}/pathway/{uuid:pathway_uuid}") @router.delete("/package/{uuid:package_uuid}/pathway/{uuid:pathway_uuid}")
def delete_pathway(request, package_uuid, pathway_uuid): def delete_pathway(request, package_uuid, pathway_uuid):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
pw = Pathway.objects.get(package=p, uuid=pathway_uuid)
pw.delete()
return redirect(f"{p.url}/pathway")
if PackageManager.writable(request.user, p):
pw = Pathway.objects.get(package=p, uuid=pathway_uuid)
pw.delete()
return redirect(f"{p.url}/pathway")
else:
raise ValueError("You do not have the rights to delete this pathway!")
except ValueError: except ValueError:
return 403, { return 403, {
"message": f"Deleting Pathway with id {pathway_uuid} failed due to insufficient rights!" "message": f"Deleting Pathway with id {pathway_uuid} failed due to insufficient rights!"
@ -1673,7 +1665,7 @@ class CreateNode(Schema):
) )
def add_pathway_node(request, package_uuid, pathway_uuid, n: Form[CreateNode]): def add_pathway_node(request, package_uuid, pathway_uuid, n: Form[CreateNode]):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
pw = Pathway.objects.get(package=p, uuid=pathway_uuid) pw = Pathway.objects.get(package=p, uuid=pathway_uuid)
if n.nodeDepth is not None and n.nodeDepth.strip() != "": if n.nodeDepth is not None and n.nodeDepth.strip() != "":
@ -1691,15 +1683,13 @@ def add_pathway_node(request, package_uuid, pathway_uuid, n: Form[CreateNode]):
@router.delete("/package/{uuid:package_uuid}/pathway/{uuid:pathway_uuid}/node/{uuid:node_uuid}") @router.delete("/package/{uuid:package_uuid}/pathway/{uuid:pathway_uuid}/node/{uuid:node_uuid}")
def delete_node(request, package_uuid, pathway_uuid, node_uuid): def delete_node(request, package_uuid, pathway_uuid, node_uuid):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
pw = Pathway.objects.get(package=p, uuid=pathway_uuid)
n = Node.objects.get(pathway=pw, uuid=node_uuid)
n.delete()
return redirect(f"{pw.url}/node")
if PackageManager.writable(request.user, p):
pw = Pathway.objects.get(package=p, uuid=pathway_uuid)
n = Node.objects.get(pathway=pw, uuid=node_uuid)
n.delete()
return redirect(f"{pw.url}/node")
else:
raise ValueError("You do not have the rights to delete this Node!")
except ValueError: except ValueError:
return 403, { return 403, {
"message": f"Deleting Node with id {node_uuid} failed due to insufficient rights!" "message": f"Deleting Node with id {node_uuid} failed due to insufficient rights!"
@ -1783,7 +1773,7 @@ class CreateEdge(Schema):
) )
def add_pathway_edge(request, package_uuid, pathway_uuid, e: Form[CreateEdge]): def add_pathway_edge(request, package_uuid, pathway_uuid, e: Form[CreateEdge]):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
pw = Pathway.objects.get(package=p, uuid=pathway_uuid) pw = Pathway.objects.get(package=p, uuid=pathway_uuid)
if e.edgeAsSmirks is None and (e.educts is None or e.products is None): if e.edgeAsSmirks is None and (e.educts is None or e.products is None):
@ -1841,15 +1831,13 @@ def add_pathway_edge(request, package_uuid, pathway_uuid, e: Form[CreateEdge]):
@router.delete("/package/{uuid:package_uuid}/pathway/{uuid:pathway_uuid}/edge/{uuid:edge_uuid}") @router.delete("/package/{uuid:package_uuid}/pathway/{uuid:pathway_uuid}/edge/{uuid:edge_uuid}")
def delete_edge(request, package_uuid, pathway_uuid, edge_uuid): def delete_edge(request, package_uuid, pathway_uuid, edge_uuid):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
pw = Pathway.objects.get(package=p, uuid=pathway_uuid)
e = Edge.objects.get(pathway=pw, uuid=edge_uuid)
e.delete()
return redirect(f"{pw.url}/edge")
if PackageManager.writable(request.user, p):
pw = Pathway.objects.get(package=p, uuid=pathway_uuid)
e = Edge.objects.get(pathway=pw, uuid=edge_uuid)
e.delete()
return redirect(f"{pw.url}/edge")
else:
raise ValueError("You do not have the rights to delete this Edge!")
except ValueError: except ValueError:
return 403, { return 403, {
"message": f"Deleting Edge with id {edge_uuid} failed due to insufficient rights!" "message": f"Deleting Edge with id {edge_uuid} failed due to insufficient rights!"
@ -1985,14 +1973,11 @@ def get_model(request, package_uuid, model_uuid, c: Query[Classify]):
@router.delete("/package/{uuid:package_uuid}/model/{uuid:model_uuid}") @router.delete("/package/{uuid:package_uuid}/model/{uuid:model_uuid}")
def delete_model(request, package_uuid, model_uuid): def delete_model(request, package_uuid, model_uuid):
try: try:
p = PackageManager.get_package_by_id(request.user, package_uuid) p = get_package_for_write(request.user, package_uuid)
if PackageManager.writable(request.user, p): m = EPModel.objects.get(package=p, uuid=model_uuid)
m = EPModel.objects.get(package=p, uuid=model_uuid) m.delete()
m.delete() return redirect(f"{p.url}/model")
return redirect(f"{p.url}/model")
else:
raise ValueError("You do not have the rights to delete this Model!")
except ValueError: except ValueError:
return 403, { return 403, {
"message": f"Deleting Model with id {model_uuid} failed due to insufficient rights!" "message": f"Deleting Model with id {model_uuid} failed due to insufficient rights!"