From 9d9a7cecda029fcf40e0ae9fb1b4ead7326512fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexa=20Valentov=C3=A1?= <git@imaniti.org> Date: Wed, 18 Sep 2024 15:27:39 +0200 Subject: [PATCH] update API --- Makefile | 2 +- contracts/admin.py | 1 + contracts/views.py | 108 ++++++++++++++++++++++++++------------ manage.py | 2 +- oidc/auth.py | 10 ++-- registry/settings/base.py | 4 +- registry/wsgi.py | 2 +- 7 files changed, 89 insertions(+), 40 deletions(-) diff --git a/Makefile b/Makefile index 6cfddd0..3dd614c 100644 --- a/Makefile +++ b/Makefile @@ -46,7 +46,7 @@ run: venv ${VENV}/bin/python manage.py runserver ${PORT} --settings=${SETTINGS} shell: venv - ${VENV}/bin/python manage.py shell_plus --settings=${SETTINGS} + ${VENV}/bin/python manage.py shell --settings=${SETTINGS} sync: ${VENV}/bin/python manage.py import_old_contracts https://github.com/pirati-web/smlouvy.pirati.cz.git gh-pages --settings=${SETTINGS} --delete -v 3 diff --git a/contracts/admin.py b/contracts/admin.py index 5bd4f21..25550d3 100644 --- a/contracts/admin.py +++ b/contracts/admin.py @@ -649,6 +649,7 @@ class ContractAdmin( "Naše smluvnà strana", "contractee_signatures__contractee" ), AutocompleteFilterFactory("Jiná smluvnà strana", "signee_signatures__signee"), + AutocompleteFilterFactory("Primárnà smlouva", "primary_contract"), "status", "is_valid", "is_public", diff --git a/contracts/views.py b/contracts/views.py index 6e0d4f8..79e725f 100644 --- a/contracts/views.py +++ b/contracts/views.py @@ -436,7 +436,9 @@ def view_signees(request): # Basic contract view API -def view_contract_json(request, id: int): + + +def get_contract_dict(request, id: int, error_if_missing_perm: bool = True): filter = models.Q(status=Contract.StatusTypes.APPROVED) if not request.user.has_perm("contracts.view_confidential"): @@ -449,40 +451,80 @@ def view_contract_json(request, id: int): ) ) - contract = get_object_or_404( - (get_objects_for_user(request.user, "contracts.view_contract").filter(filter)), - id=id, - ) + try: + contract = get_object_or_404( + ( + get_objects_for_user(request.user, "contracts.view_contract").filter( + filter + ) + ), + id=id, + ) + except Exception as e: + if error_if_missing_perm: + # Re-raise + raise e + else: + return None - return JsonResponse( - { - "id": contract.id, - "created_by": { - "id": contract.created_by_id, - "username": contract.created_by.username, + subcontracts = [] + + for subcontract in contract.subcontracts.order_by("-valid_start_date").all(): + subcontract_dict = get_contract_dict(request, subcontract.id, False) + + if subcontract_dict is None: + continue + + subcontracts.append(subcontract_dict) + + return { + "id": contract.id, + "created_by": { + "id": contract.created_by_id, + "username": contract.created_by.preferred_username, + }, + "created_on": contract.created_on, + "updated_on": contract.updated_on, + "status": contract.status, + "name": contract.name, + "id_number": contract.id_number, + "types": [{"id": type.id, "name": type.name} for type in contract.types.all()], + "summary": contract.summary, + "validity": { + "start_date": contract.valid_start_date, + "end_date": contract.valid_end_date, + }, + "is_valid": contract.is_valid, + "is_public": contract.is_public, + "publishing_rejection_comment": contract.publishing_rejection_comment, + "cost": { + "amount": contract.cost_amount, + "unit": { + "enum": contract.cost_unit, + "display": contract.get_cost_unit_display(), + "other": contract.cost_unit_other, }, - "created_on": contract.created_on, - "updated_on": contract.updated_on, - "status": contract.status, - "name": contract.name, - "id_number": contract.id_number, - "types": [ - {"id": type.id, "name": type.name} for type in contract.types.all() - ], - "summary": contract.summary, - "valid_start_date": contract.valid_start_date, - "valid_end_date": contract.valid_end_date, - "is_valid": contract.is_valid, - "is_public": contract.is_public, - "publishing_rejection_comment": contract.publishing_rejection_comment, - "paper_form_state": contract.paper_form_state, - "paper_form_person_responsible": contract.paper_form_person_responsible, - "tender_url": contract.tender_url, - "issues": [ - {"id": issue.id, "name": issue.name} for issue in contract.issues.all() - ], - } - ) + }, + "paper_form": { + "state": contract.paper_form_state, + "person_responsible": contract.paper_form_person_responsible, + }, + "tender_url": contract.tender_url, + "issues": [ + {"id": issue.id, "name": issue.name} for issue in contract.issues.all() + ], + "intents": [ + {"id": intent.id, "name": intent.name, "url": intent.url} + for intent in contract.intents.all() + ], + "subcontracts": subcontracts, + } + + +def view_contract_json(request, id: int): + contract_dict = get_contract_dict(request, id) + + return JsonResponse(contract_dict) # ARES CORS proxy diff --git a/manage.py b/manage.py index 45b9a48..d8d5a96 100755 --- a/manage.py +++ b/manage.py @@ -6,7 +6,7 @@ import sys def main(): """Run administrative tasks.""" - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "registry.settings") + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "registry.settings.dev") try: from django.core.management import execute_from_command_line except ImportError as exc: diff --git a/oidc/auth.py b/oidc/auth.py index 3bda318..ec7743f 100644 --- a/oidc/auth.py +++ b/oidc/auth.py @@ -75,9 +75,13 @@ class RegistryOIDCAuthenticationBackend(PiratesOIDCAuthenticationBackend): try: result = client.execute(query) - except TransportQueryError: - # rv_gid was not found - raise HTTPExceptions.BAD_REQUEST + except (TransportQueryError, ConnectionError, Exception) as e: + print(e) + + # Return no groups if the Chobotnice connection fails, + # so users can still at least log in. + + return [] groups = [] diff --git a/registry/settings/base.py b/registry/settings/base.py index 9f97f39..d5ab694 100644 --- a/registry/settings/base.py +++ b/registry/settings/base.py @@ -162,7 +162,9 @@ OIDC_OP_TOKEN_ENDPOINT = OIDC_RP_REALM_URL + "protocol/openid-connect/token" OIDC_OP_USER_ENDPOINT = OIDC_RP_REALM_URL + "protocol/openid-connect/userinfo" # Chobotnice - group source -CHOBOTNICE_API_URL = env.str("CHOBOTNICE_API_URL") +CHOBOTNICE_API_URL = env.str( + "CHOBOTNICE_API_URL", "https://chobotnice.pirati.cz/graphql/" +) ## Internationalization diff --git a/registry/wsgi.py b/registry/wsgi.py index bf93aed..f4221c6 100644 --- a/registry/wsgi.py +++ b/registry/wsgi.py @@ -11,6 +11,6 @@ import os from django.core.wsgi import get_wsgi_application -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "registry.settings") +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "registry.settings.dev") application = get_wsgi_application() -- GitLab