diff --git a/pyproject.toml b/pyproject.toml index 442976224e..7cf699bc29 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -319,11 +319,13 @@ vendors = "rero_ils.modules.vendors.jsonschemas" files = "rero_ils.modules.files.jsonschemas" [tool.poetry.plugins."invenio_oauth2server.scopes"] +fullname = "rero_ils.oauth.scopes:fullname" birthdate = "rero_ils.oauth.scopes:birthdate" +patron_info = "rero_ils.oauth.scopes:patron_info" expiration_date = "rero_ils.oauth.scopes:expiration_date" -fullname = "rero_ils.oauth.scopes:fullname" institution = "rero_ils.oauth.scopes:institution" patron_type = "rero_ils.oauth.scopes:patron_type" +# deprecated scopes patron_types = "rero_ils.oauth.scopes:patron_types" [tool.poetry.plugins."invenio_pidstore.fetchers"] diff --git a/rero_ils/config.py b/rero_ils/config.py index 7ce7b5ec4d..1f5c0c35c2 100644 --- a/rero_ils/config.py +++ b/rero_ils/config.py @@ -3613,6 +3613,9 @@ def _(x): "bf:Place": "places", } +# Change institution code for /info +RERO_ILS_APP_INSTITUTION_CODE_TRANSFORMATION = {"nj": "rbnj"} + # The absolute path to put the agent synchronization logs, default is the # instance path # RERO_ILS_MEF_SYNC_LOG_DIR = "/var/logs/reroils" diff --git a/rero_ils/modules/patrons/views.py b/rero_ils/modules/patrons/views.py index 54967e5dad..c6e5cdb159 100644 --- a/rero_ils/modules/patrons/views.py +++ b/rero_ils/modules/patrons/views.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # # RERO ILS -# Copyright (C) 2019-2023 RERO +# Copyright (C) 2024 RERO # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by @@ -19,7 +19,6 @@ from __future__ import absolute_import, print_function -import copy import datetime import re @@ -321,78 +320,80 @@ def info(): """Get patron info.""" token_scopes = flask_request.oauth.access_token.scopes - def get_main_patron(patrons): - """Return the main patron. - - :param patrons: List of patrons. - :returns: The main patron. - """ - # TODO: Find a way to determine which is the main patron. - return patrons[0] - def get_institution_code(institution): """Get the institution code for a given institution. - Special transformation for `nj`. - :param institution: Institution object. :returns: Code for the institution. """ - # TODO: make this non rero specific using a configuration - return institution["code"] if institution["code"] != "nj" else "rbnj" - - user = User.get_record(current_user.id).dumps_metadata() - - # Process for all patrons - patrons = copy.deepcopy(current_patrons) - for patron in patrons: - patron["institution"] = patron.organisation - patron["patron"]["type"] = PatronType.get_record_by_pid( - extracted_data_from_ref(patron["patron"]["type"]["$ref"]) - ) + code = institution["code"] + if changed_code := current_app.config.get( + "RERO_ILS_APP_INSTITUTION_CODE_TRANSFORMATION", {} + ).get(code): + return changed_code + return code # Birthdate data = {} - birthdate = current_user.user_profile.get("birth_date") - if "birthdate" in token_scopes and birthdate: - data["birthdate"] = birthdate # Full name name_parts = [ current_user.user_profile.get("last_name", "").strip(), current_user.user_profile.get("first_name", "").strip(), ] fullname = ", ".join(filter(None, name_parts)) - if "fullname" in token_scopes and fullname: + if fullname and "fullname" in token_scopes: data["fullname"] = fullname + birthdate = current_user.user_profile.get("birth_date") + if birthdate and "birthdate" in token_scopes: + data["birthdate"] = birthdate - # No patrons found for user - if not patrons: - return jsonify(data) - - # Get the main patron - patron = get_main_patron(patrons) - # Barcode - if patron.get("patron", {}).get("barcode"): - data["barcode"] = patron["patron"]["barcode"][0] - # Patron types - if "patron_types" in token_scopes: - patron_types = [] - for patron in patrons: - info = {} - patron_type_code = patron.get("patron", {}).get("type", {}).get("code") - if patron_type_code: + patrons = current_patrons + if len(patrons) > 0: + patron = patrons[0] + # Barcode + if patron.get("patron", {}).get("barcode"): + data["barcode"] = patron["patron"]["barcode"][0] + # Patron + patron_types = [] + patron_infos = {} + for patron in patrons: + patron_type = PatronType.get_record_by_pid( + extracted_data_from_ref(patron["patron"]["type"]["$ref"]) + ) + patron_type_code = patron_type.get("code") + institution = get_institution_code(patron.organisation) + expiration_date = patron.get("patron", {}).get("expiration_date") + + # old list (patron_types) + if "patron_types" in token_scopes: + info = {"patron_pid": patron.pid} + if patron_type_code and "patron_type" in token_scopes: info["patron_type"] = patron_type_code - if patron.get("institution"): - info["institution"] = get_institution_code(patron["institution"]) - if patron.get("patron", {}).get("expiration_date"): + if institution and "institution" in token_scopes: + info["institution"] = get_institution_code(institution) + if expiration_date and "expiration_date" in token_scopes: info["expiration_date"] = datetime.datetime.strptime( - patron["patron"]["expiration_date"], "%Y-%m-%d" + expiration_date, "%Y-%m-%d" + ).isoformat() + patron_types.append(info) + + # new dict (patron_info) + if "patron_info" in token_scopes: + patron_info = {"patron_pid": patron.pid} + if institution and "institution" in token_scopes: + patron_info["institution"] = institution + if patron_type_code and "patron_type" in token_scopes: + patron_info["patron_type"] = patron_type_code + if expiration_date and "expiration_date" in token_scopes: + patron_info["expiration_date"] = datetime.datetime.strptime( + expiration_date, "%Y-%m-%d" ).isoformat() - if info: - patron_types.append(info) + patron_infos[institution] = patron_info + if patron_types: data["patron_types"] = patron_types - + if patron_infos: + data["patron_info"] = patron_infos return jsonify(data) diff --git a/rero_ils/oauth/scopes.py b/rero_ils/oauth/scopes.py index 93922c449c..0862557457 100644 --- a/rero_ils/oauth/scopes.py +++ b/rero_ils/oauth/scopes.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # # RERO ILS -# Copyright (C) 2021 RERO +# Copyright (C) 2024 RERO # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by @@ -21,7 +21,11 @@ fullname = Scope("fullname", help_text="Full name", group="User") birthdate = Scope("birthdate", help_text="Birthdate", group="User") -institution = Scope("institution", help_text="Institution", group="User") +patron_info = Scope("patron_info", help_text="Patrons", group="User") expiration_date = Scope("expiration_date", help_text="Expiration date", group="User") +barcode = Scope("barcode", help_text="Barcode", group="User") +institution = Scope("institution", help_text="Institution", group="User") patron_type = Scope("patron_type", help_text="Patron type", group="User") -patron_types = Scope("patron_types", help_text="Patron types", group="User") +patron_types = Scope( + "patron_types", help_text="Patron types (deprecated)", group="User" +) diff --git a/setup.py b/setup.py index 0137a76b43..097d9be1b0 100644 --- a/setup.py +++ b/setup.py @@ -370,10 +370,12 @@ def run(self): 'invenio_oauth2server.scopes': [ 'fullname = rero_ils.oauth.scopes:fullname', 'birthdate = rero_ils.oauth.scopes:birthdate', - 'institution = rero_ils.oauth.scopes:institution', + 'patron_info = rero_ils.oauth.scopes:patron_info', + # deprecated scopes 'expiration_date = rero_ils.oauth.scopes:expiration_date', + 'institution = rero_ils.oauth.scopes:institution', 'patron_type = rero_ils.oauth.scopes:patron_type', - 'patron_types = rero_ils.oauth.scopes:patron_types' + 'patron_types = rero_ils.oauth.scopes:patron_types', ] }, classifiers=[ diff --git a/tests/api/patrons/test_patrons_rest.py b/tests/api/patrons/test_patrons_rest.py index 855e9de4f5..48cd94300f 100644 --- a/tests/api/patrons/test_patrons_rest.py +++ b/tests/api/patrons/test_patrons_rest.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # # RERO ILS -# Copyright (C) 2019 RERO +# Copyright (C) 2024 RERO # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by @@ -558,10 +558,20 @@ def test_patron_info(app, client, patron_martigny, librarian_martigny): { "expiration_date": patron_martigny["patron"]["expiration_date"] + "T00:00:00", - "institution": "org1", + "institution": "ORG1", + "patron_pid": patron_martigny.pid, "patron_type": "patron-code", } ], + "patron_info": { + "ORG1": { + "expiration_date": patron_martigny["patron"]["expiration_date"] + + "T00:00:00", + "institution": "ORG1", + "patron_pid": patron_martigny.pid, + "patron_type": "patron-code", + } + }, } # librarian information with all scopes diff --git a/tests/conftest.py b/tests/conftest.py index ccda2b4a70..630b487c82 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -217,6 +217,7 @@ def app_config(app_config): }, } app_config["INDEXER_DEFAULT_INDEX"] = "records-record-v1.0.0" + app_config["RERO_ILS_APP_INSTITUTION_CODE_TRANSFORMATION"] = {"org1": "ORG1"} return app_config