Skip to content

Commit

Permalink
oauth: add patron pid
Browse files Browse the repository at this point in the history
* Adds `patron_info` with patron pid for institutions to scope.
* Closes #3778.

Co-Authored-by: Peter Weber <[email protected]>
  • Loading branch information
rerowep committed Dec 4, 2024
1 parent cea2d9f commit 4f14655
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 57 deletions.
4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -319,9 +319,11 @@ 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"
# deprecated scopes
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"
patron_types = "rero_ils.oauth.scopes:patron_types"
Expand Down
3 changes: 3 additions & 0 deletions rero_ils/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
88 changes: 41 additions & 47 deletions rero_ils/modules/patrons/views.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -19,7 +19,6 @@

from __future__ import absolute_import, print_function

import copy
import datetime
import re

Expand Down Expand Up @@ -321,41 +320,21 @@ 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(),
Expand All @@ -364,35 +343,50 @@ def get_institution_code(institution):
fullname = ", ".join(filter(None, name_parts))
if "fullname" in token_scopes and fullname:
data["fullname"] = fullname
birthdate = current_user.user_profile.get("birth_date")
if "birthdate" in token_scopes and birthdate:
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]
patrons = current_patrons
if len(patrons) > 0:
patron = patrons[0]
# Barcode
if patron.get("patron", {}).get("barcode"):
data["barcode"] = patron["patron"]["barcode"][0]
# Patron types
if "patron_types" in token_scopes:
patron_types = []
patron_infos = {}
for patron in patrons:
info = {}
patron_type_code = patron.get("patron", {}).get("type", {}).get("code")
if patron_type_code:
# old list
info = {"patron_pid": patron.pid}
patron_type = PatronType.get_record_by_pid(
extracted_data_from_ref(patron["patron"]["type"]["$ref"])
)
if patron_type_code := patron_type.get("code"):
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 org := patron.organisation:
info["institution"] = get_institution_code(org)
if expiration_date := patron.get("patron", {}).get("expiration_date"):
info["expiration_date"] = datetime.datetime.strptime(
patron["patron"]["expiration_date"], "%Y-%m-%d"
expiration_date, "%Y-%m-%d"
).isoformat()
if info:
patron_types.append(info)
patron_types.append(info)
# new dict
if org := patron.organisation:
org_code = get_institution_code(org)
patron_info = {"patron_pid": patron.pid, "institution": org_code}
if patron_type_code := patron_type.get("code"):
patron_info["patron_type"] = patron_type_code
if expiration_date := patron.get("patron", {}).get("expiration_date"):
patron_info["expiration_date"] = datetime.datetime.strptime(
expiration_date, "%Y-%m-%d"
).isoformat()
patron_infos[org_code] = patron_info

if patron_types:
data["patron_types"] = patron_types

data["patron_info"] = patron_infos
return jsonify(data)


Expand Down
16 changes: 11 additions & 5 deletions rero_ils/oauth/scopes.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -21,7 +21,13 @@

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")
expiration_date = Scope("expiration_date", help_text="Expiration date", 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_info = Scope("patron_info", help_text="Patrons", group="User")
expiration_date = Scope(
"expiration_date", help_text="Expiration date (deprecated)", group="User"
)
barcode = Scope("barcode", help_text="Barcode (deprecated)", group="User")
institution = Scope("institution", help_text="Institution (deprecated)", group="User")
patron_type = Scope("patron_type", help_text="Patron type (deprecated)", group="User")
patron_types = Scope(
"patron_types", help_text="Patron types (deprecated)", group="User"
)
6 changes: 4 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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=[
Expand Down
14 changes: 12 additions & 2 deletions tests/api/patrons/test_patrons_rest.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down

0 comments on commit 4f14655

Please sign in to comment.