invenio-app-ils 5.0.2__py2.py3-none-any.whl → 6.0.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- invenio_app_ils/__init__.py +1 -1
- invenio_app_ils/acquisition/config.py +7 -3
- invenio_app_ils/circulation/config.py +2 -2
- invenio_app_ils/cli.py +11 -0
- invenio_app_ils/closures/views.py +2 -2
- invenio_app_ils/config.py +13 -9
- invenio_app_ils/eitems/api.py +32 -0
- invenio_app_ils/ill/config.py +2 -2
- invenio_app_ils/notifications/views.py +2 -2
- invenio_app_ils/patrons/anonymization.py +3 -1
- invenio_app_ils/permissions.py +24 -2
- invenio_app_ils/providers/config.py +6 -3
- invenio_app_ils/records/permissions.py +8 -2
- invenio_app_ils/records/views.py +2 -2
- invenio_app_ils/search_permissions.py +3 -3
- {invenio_app_ils-5.0.2.dist-info → invenio_app_ils-6.0.0.dist-info}/METADATA +10 -1
- {invenio_app_ils-5.0.2.dist-info → invenio_app_ils-6.0.0.dist-info}/RECORD +22 -22
- {invenio_app_ils-5.0.2.dist-info → invenio_app_ils-6.0.0.dist-info}/entry_points.txt +1 -0
- {invenio_app_ils-5.0.2.dist-info → invenio_app_ils-6.0.0.dist-info}/WHEEL +0 -0
- {invenio_app_ils-5.0.2.dist-info → invenio_app_ils-6.0.0.dist-info}/licenses/AUTHORS.rst +0 -0
- {invenio_app_ils-5.0.2.dist-info → invenio_app_ils-6.0.0.dist-info}/licenses/LICENSE +0 -0
- {invenio_app_ils-5.0.2.dist-info → invenio_app_ils-6.0.0.dist-info}/top_level.txt +0 -0
invenio_app_ils/__init__.py
CHANGED
|
@@ -10,7 +10,11 @@ from invenio_indexer.api import RecordIndexer
|
|
|
10
10
|
from invenio_records_rest.facets import terms_filter
|
|
11
11
|
|
|
12
12
|
from invenio_app_ils.config import RECORDS_REST_MAX_RESULT_WINDOW
|
|
13
|
-
from invenio_app_ils.permissions import
|
|
13
|
+
from invenio_app_ils.permissions import (
|
|
14
|
+
backoffice_permission,
|
|
15
|
+
backoffice_read_permission,
|
|
16
|
+
superuser_permission,
|
|
17
|
+
)
|
|
14
18
|
|
|
15
19
|
from .api import ORDER_PID_FETCHER, ORDER_PID_MINTER, ORDER_PID_TYPE, Order
|
|
16
20
|
from .search import OrderSearch
|
|
@@ -44,8 +48,8 @@ RECORDS_REST_ENDPOINTS = dict(
|
|
|
44
48
|
default_media_type="application/json",
|
|
45
49
|
max_result_window=RECORDS_REST_MAX_RESULT_WINDOW,
|
|
46
50
|
error_handlers=dict(),
|
|
47
|
-
read_permission_factory_imp=
|
|
48
|
-
list_permission_factory_imp=
|
|
51
|
+
read_permission_factory_imp=backoffice_read_permission,
|
|
52
|
+
list_permission_factory_imp=backoffice_read_permission,
|
|
49
53
|
create_permission_factory_imp=backoffice_permission,
|
|
50
54
|
update_permission_factory_imp=backoffice_permission,
|
|
51
55
|
delete_permission_factory_imp=superuser_permission,
|
|
@@ -41,7 +41,7 @@ from invenio_app_ils.items.api import (
|
|
|
41
41
|
)
|
|
42
42
|
from invenio_app_ils.patrons.api import patron_exists
|
|
43
43
|
from invenio_app_ils.permissions import (
|
|
44
|
-
|
|
44
|
+
PatronOwnerReadPermission,
|
|
45
45
|
authenticated_user_permission,
|
|
46
46
|
backoffice_permission,
|
|
47
47
|
loan_extend_circulation_permission,
|
|
@@ -254,7 +254,7 @@ ILS_CIRCULATION_RECORDS_REST_ENDPOINTS = dict(
|
|
|
254
254
|
links_factory_imp="invenio_circulation.links:loan_links_factory",
|
|
255
255
|
max_result_window=RECORDS_REST_MAX_RESULT_WINDOW,
|
|
256
256
|
error_handlers=dict(),
|
|
257
|
-
read_permission_factory_imp=
|
|
257
|
+
read_permission_factory_imp=PatronOwnerReadPermission,
|
|
258
258
|
# auth via search_factory
|
|
259
259
|
list_permission_factory_imp=authenticated_user_permission,
|
|
260
260
|
create_permission_factory_imp=superuser_permission,
|
invenio_app_ils/cli.py
CHANGED
|
@@ -1308,6 +1308,7 @@ def data(
|
|
|
1308
1308
|
# Create roles to restrict access
|
|
1309
1309
|
_run_command("roles create admin", verbose)
|
|
1310
1310
|
_run_command("roles create librarian", verbose)
|
|
1311
|
+
_run_command("roles create librarian-readonly", verbose)
|
|
1311
1312
|
|
|
1312
1313
|
# Create users
|
|
1313
1314
|
patron1_profile = {"full_name": "Yannic Vilma"}
|
|
@@ -1328,6 +1329,12 @@ def data(
|
|
|
1328
1329
|
verbose,
|
|
1329
1330
|
)
|
|
1330
1331
|
|
|
1332
|
+
readonly_profile = {"full_name": "Ro Only"}
|
|
1333
|
+
_run_command(
|
|
1334
|
+
f"users create readonly@test.ch -a --password=123456 --profile '{json.dumps(readonly_profile)}'",
|
|
1335
|
+
verbose,
|
|
1336
|
+
)
|
|
1337
|
+
|
|
1331
1338
|
patron3_profile = {"full_name": "Medrod Tara"}
|
|
1332
1339
|
_run_command(
|
|
1333
1340
|
f"users create patron3@test.ch -a --password=123456 --profile '{json.dumps(patron3_profile)}'",
|
|
@@ -1350,6 +1357,7 @@ def data(
|
|
|
1350
1357
|
|
|
1351
1358
|
# assign roles
|
|
1352
1359
|
_run_command("roles add librarian@test.ch librarian", verbose)
|
|
1360
|
+
_run_command("roles add readonly@test.ch librarian-readonly", verbose)
|
|
1353
1361
|
|
|
1354
1362
|
# Index vocabularies
|
|
1355
1363
|
vocabularies_dir = os.path.join(CURRENT_DIR, "vocabularies", "data")
|
|
@@ -1368,6 +1376,9 @@ def data(
|
|
|
1368
1376
|
# Assign actions
|
|
1369
1377
|
_run_command("access allow superuser-access role admin", verbose)
|
|
1370
1378
|
_run_command("access allow ils-backoffice-access role librarian", verbose)
|
|
1379
|
+
_run_command(
|
|
1380
|
+
"access allow ils-backoffice-readonly-access role librarian-readonly", verbose
|
|
1381
|
+
)
|
|
1371
1382
|
|
|
1372
1383
|
# Create demo locations
|
|
1373
1384
|
click.echo("Creating locations and internal locations...")
|
|
@@ -16,7 +16,7 @@ from invenio_rest import ContentNegotiatedMethodView
|
|
|
16
16
|
from invenio_app_ils.locations.api import LOCATION_PID_TYPE
|
|
17
17
|
from invenio_app_ils.closures.serializers import closure_periods_response
|
|
18
18
|
from invenio_app_ils.closures.api import get_closure_periods
|
|
19
|
-
from invenio_app_ils.permissions import
|
|
19
|
+
from invenio_app_ils.permissions import backoffice_read_permission
|
|
20
20
|
from invenio_app_ils.records.permissions import RecordPermission
|
|
21
21
|
|
|
22
22
|
|
|
@@ -53,7 +53,7 @@ class LocationClosurePeriodsResource(ContentNegotiatedMethodView):
|
|
|
53
53
|
"""Get the date ranges for which a location is closure based in the specified year"""
|
|
54
54
|
|
|
55
55
|
factory = RecordPermission(record, "read")
|
|
56
|
-
if not factory.is_public() and not
|
|
56
|
+
if not factory.is_public() and not backoffice_read_permission().can():
|
|
57
57
|
if not current_user.is_authenticated:
|
|
58
58
|
abort(401)
|
|
59
59
|
abort(403)
|
invenio_app_ils/config.py
CHANGED
|
@@ -91,9 +91,10 @@ from .patrons.api import (
|
|
|
91
91
|
)
|
|
92
92
|
from .patrons.search import PatronsSearch
|
|
93
93
|
from .permissions import (
|
|
94
|
-
|
|
94
|
+
PatronOwnerReadPermission,
|
|
95
95
|
authenticated_user_permission,
|
|
96
96
|
backoffice_permission,
|
|
97
|
+
backoffice_read_permission,
|
|
97
98
|
views_permissions_factory,
|
|
98
99
|
)
|
|
99
100
|
from .records.permissions import record_read_permission_factory
|
|
@@ -395,8 +396,8 @@ RECORDS_REST_ENDPOINTS = dict(
|
|
|
395
396
|
default_media_type="application/json",
|
|
396
397
|
max_result_window=RECORDS_REST_MAX_RESULT_WINDOW,
|
|
397
398
|
error_handlers=dict(),
|
|
398
|
-
read_permission_factory_imp=
|
|
399
|
-
list_permission_factory_imp=
|
|
399
|
+
read_permission_factory_imp=backoffice_read_permission,
|
|
400
|
+
list_permission_factory_imp=backoffice_read_permission,
|
|
400
401
|
create_permission_factory_imp=backoffice_permission,
|
|
401
402
|
update_permission_factory_imp=backoffice_permission,
|
|
402
403
|
delete_permission_factory_imp=backoffice_permission,
|
|
@@ -427,8 +428,8 @@ RECORDS_REST_ENDPOINTS = dict(
|
|
|
427
428
|
default_media_type="application/json",
|
|
428
429
|
max_result_window=RECORDS_REST_MAX_RESULT_WINDOW,
|
|
429
430
|
error_handlers=dict(),
|
|
430
|
-
read_permission_factory_imp=
|
|
431
|
-
list_permission_factory_imp=
|
|
431
|
+
read_permission_factory_imp=backoffice_read_permission,
|
|
432
|
+
list_permission_factory_imp=backoffice_read_permission,
|
|
432
433
|
create_permission_factory_imp=backoffice_permission,
|
|
433
434
|
update_permission_factory_imp=backoffice_permission,
|
|
434
435
|
delete_permission_factory_imp=backoffice_permission,
|
|
@@ -522,8 +523,8 @@ RECORDS_REST_ENDPOINTS = dict(
|
|
|
522
523
|
default_media_type="application/json",
|
|
523
524
|
max_result_window=RECORDS_REST_MAX_RESULT_WINDOW,
|
|
524
525
|
error_handlers=dict(),
|
|
525
|
-
read_permission_factory_imp=
|
|
526
|
-
list_permission_factory_imp=
|
|
526
|
+
read_permission_factory_imp=backoffice_read_permission,
|
|
527
|
+
list_permission_factory_imp=backoffice_read_permission,
|
|
527
528
|
create_permission_factory_imp=backoffice_permission,
|
|
528
529
|
update_permission_factory_imp=backoffice_permission,
|
|
529
530
|
delete_permission_factory_imp=backoffice_permission,
|
|
@@ -552,7 +553,7 @@ RECORDS_REST_ENDPOINTS = dict(
|
|
|
552
553
|
max_result_window=RECORDS_REST_MAX_RESULT_WINDOW,
|
|
553
554
|
error_handlers=dict(),
|
|
554
555
|
read_permission_factory_imp=deny_all,
|
|
555
|
-
list_permission_factory_imp=
|
|
556
|
+
list_permission_factory_imp=backoffice_read_permission,
|
|
556
557
|
create_permission_factory_imp=deny_all,
|
|
557
558
|
update_permission_factory_imp=deny_all,
|
|
558
559
|
delete_permission_factory_imp=deny_all,
|
|
@@ -584,7 +585,7 @@ RECORDS_REST_ENDPOINTS = dict(
|
|
|
584
585
|
default_media_type="application/json",
|
|
585
586
|
max_result_window=RECORDS_REST_MAX_RESULT_WINDOW,
|
|
586
587
|
error_handlers=dict(),
|
|
587
|
-
read_permission_factory_imp=
|
|
588
|
+
read_permission_factory_imp=PatronOwnerReadPermission,
|
|
588
589
|
# auth via search_factory
|
|
589
590
|
list_permission_factory_imp=authenticated_user_permission,
|
|
590
591
|
create_permission_factory_imp=authenticated_user_permission,
|
|
@@ -1083,3 +1084,6 @@ THEME_FRONTPAGE = False
|
|
|
1083
1084
|
PAGES_DEFAULT_TEMPLATE = "invenio_pages/default.html"
|
|
1084
1085
|
# default app theme
|
|
1085
1086
|
APP_THEME = ["semantic-ui"]
|
|
1087
|
+
|
|
1088
|
+
# Site name.
|
|
1089
|
+
THEME_SITENAME = _("InvenioILS")
|
invenio_app_ils/eitems/api.py
CHANGED
|
@@ -119,3 +119,35 @@ def eitem_event_builder(event, sender_app, obj=None, **kwargs):
|
|
|
119
119
|
record = kwargs["record"]
|
|
120
120
|
event.update(dict(eitem_pid=record["pid"], document_pid=record.get("document_pid")))
|
|
121
121
|
return event
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def get_eitems_for_document_by_creator(document_pid, creator, case_insensitive=False):
|
|
125
|
+
"""Find eitems by document pid and creator.
|
|
126
|
+
|
|
127
|
+
:param document_pid: The PID of the document of the eitems to search for.
|
|
128
|
+
:param creator: The creator to filter eitems by.
|
|
129
|
+
:param case_insensitive: Whether the creator match should be case insensitive.
|
|
130
|
+
"""
|
|
131
|
+
eitem_search = current_app_ils.eitem_search_cls()
|
|
132
|
+
creator_match = eitem_search.search_by_document_pid(
|
|
133
|
+
document_pid=document_pid
|
|
134
|
+
).filter(
|
|
135
|
+
"term",
|
|
136
|
+
created_by__value={"term": creator, "case_insensitive": case_insensitive},
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
return creator_match
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def get_eitems_for_document_by_source(document_pid, source, case_insensitive=False):
|
|
143
|
+
"""Find eitems by document pid and source.
|
|
144
|
+
|
|
145
|
+
:param document_pid: The PID of the document of the eitems to search for.
|
|
146
|
+
:param source: The source to filter eitems by.
|
|
147
|
+
:param case_insensitive: Whether the source match should be case insensitive.
|
|
148
|
+
"""
|
|
149
|
+
eitem_search = current_app_ils.eitem_search_cls()
|
|
150
|
+
source_match = eitem_search.search_by_document_pid(
|
|
151
|
+
document_pid=document_pid
|
|
152
|
+
).filter("term", source={"value": source, "case_insensitive": case_insensitive})
|
|
153
|
+
return source_match
|
invenio_app_ils/ill/config.py
CHANGED
|
@@ -11,7 +11,7 @@ from invenio_records_rest.facets import terms_filter
|
|
|
11
11
|
|
|
12
12
|
from invenio_app_ils.config import RECORDS_REST_MAX_RESULT_WINDOW
|
|
13
13
|
from invenio_app_ils.permissions import (
|
|
14
|
-
|
|
14
|
+
PatronOwnerReadPermission,
|
|
15
15
|
authenticated_user_permission,
|
|
16
16
|
backoffice_permission,
|
|
17
17
|
superuser_permission,
|
|
@@ -76,7 +76,7 @@ RECORDS_REST_ENDPOINTS = dict(
|
|
|
76
76
|
default_media_type="application/json",
|
|
77
77
|
max_result_window=RECORDS_REST_MAX_RESULT_WINDOW,
|
|
78
78
|
error_handlers=dict(),
|
|
79
|
-
read_permission_factory_imp=
|
|
79
|
+
read_permission_factory_imp=PatronOwnerReadPermission,
|
|
80
80
|
# auth via search_factory
|
|
81
81
|
list_permission_factory_imp=authenticated_user_permission,
|
|
82
82
|
create_permission_factory_imp=backoffice_permission,
|
|
@@ -38,7 +38,7 @@ def get_notifications_blueprint(_):
|
|
|
38
38
|
"size": fields.Int(validate=[validate.Range(min=1, max=100)]),
|
|
39
39
|
}
|
|
40
40
|
)
|
|
41
|
-
@need_permissions("
|
|
41
|
+
@need_permissions("get-notifications-sent-to-patron")
|
|
42
42
|
def get_notifications(
|
|
43
43
|
recipient_user_id=None,
|
|
44
44
|
pid_type=None,
|
|
@@ -69,7 +69,7 @@ def get_notifications_blueprint(_):
|
|
|
69
69
|
return {"hits": notifications, "total": len(notifications)}
|
|
70
70
|
|
|
71
71
|
@blueprint.route("/notifications/<int:id>")
|
|
72
|
-
@need_permissions("
|
|
72
|
+
@need_permissions("get-notifications-sent-to-patron")
|
|
73
73
|
def get_notification(id):
|
|
74
74
|
try:
|
|
75
75
|
notification = NotificationsLogs.query.filter_by(id=id).one()
|
|
@@ -170,7 +170,9 @@ def anonymize_patron_data(patron_pid, force=False):
|
|
|
170
170
|
borrowing_request["patron"] = anonymous_patron_fields
|
|
171
171
|
borrowing_request["patron_pid"] = anonymous_patron_fields["pid"]
|
|
172
172
|
borrowing_request.commit()
|
|
173
|
-
anonymized_records[BORROWING_REQUEST_PID_TYPE]["records"].append(
|
|
173
|
+
anonymized_records[BORROWING_REQUEST_PID_TYPE]["records"].append(
|
|
174
|
+
borrowing_request
|
|
175
|
+
)
|
|
174
176
|
indices += 1
|
|
175
177
|
|
|
176
178
|
DocumentRequestSearch = current_app_ils.document_request_search_cls
|
invenio_app_ils/permissions.py
CHANGED
|
@@ -20,6 +20,7 @@ from invenio_app_ils.errors import InvalidLoanExtendError, LoanCheckoutByPatronF
|
|
|
20
20
|
from invenio_app_ils.proxies import current_app_ils
|
|
21
21
|
|
|
22
22
|
backoffice_access_action = action_factory("ils-backoffice-access")
|
|
23
|
+
backoffice_readonly_access_action = action_factory("ils-backoffice-readonly-access")
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
def need_permissions(action):
|
|
@@ -62,6 +63,11 @@ def backoffice_permission(*args, **kwargs):
|
|
|
62
63
|
return Permission(backoffice_access_action)
|
|
63
64
|
|
|
64
65
|
|
|
66
|
+
def backoffice_read_permission(*args, **kwargs):
|
|
67
|
+
"""Return permission for backoffice (full or read-only) read access."""
|
|
68
|
+
return Permission(backoffice_access_action, backoffice_readonly_access_action)
|
|
69
|
+
|
|
70
|
+
|
|
65
71
|
def superuser_permission(*args, **kwargs):
|
|
66
72
|
"""Return permission to allow only admins."""
|
|
67
73
|
return Permission(superuser_access)
|
|
@@ -160,6 +166,18 @@ def loan_checkout_permission(*args, **kwargs):
|
|
|
160
166
|
raise LoanCheckoutByPatronForbidden(int(loan["patron_pid"]), current_user.id)
|
|
161
167
|
|
|
162
168
|
|
|
169
|
+
class PatronOwnerReadPermission(Permission):
|
|
170
|
+
"""Return Permission to evaluate if the current user owns the record or has backoffice read access."""
|
|
171
|
+
|
|
172
|
+
def __init__(self, record):
|
|
173
|
+
"""Constructor."""
|
|
174
|
+
super().__init__(
|
|
175
|
+
UserNeed(int(record["patron_pid"])),
|
|
176
|
+
backoffice_access_action,
|
|
177
|
+
backoffice_readonly_access_action,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
|
|
163
181
|
class PatronOwnerPermission(Permission):
|
|
164
182
|
"""Return Permission to evaluate if the current user owns the record."""
|
|
165
183
|
|
|
@@ -179,13 +197,15 @@ _is_backoffice_permission = [
|
|
|
179
197
|
"circulation-loan-update-dates",
|
|
180
198
|
"relations-create",
|
|
181
199
|
"relations-delete",
|
|
182
|
-
"stats-most-loaned",
|
|
183
200
|
"document-request-actions",
|
|
184
201
|
"bucket-create",
|
|
185
202
|
"ill-brwreq-patron-loan-create",
|
|
186
203
|
"ill-brwreq-patron-loan-extension-accept",
|
|
187
204
|
"ill-brwreq-patron-loan-extension-decline",
|
|
188
|
-
|
|
205
|
+
]
|
|
206
|
+
_is_backoffice_read_permission = [
|
|
207
|
+
"stats-most-loaned",
|
|
208
|
+
"get-notifications-sent-to-patron",
|
|
189
209
|
]
|
|
190
210
|
_is_patron_owner_permission = [
|
|
191
211
|
"document-request-decline",
|
|
@@ -199,6 +219,8 @@ def views_permissions_factory(action):
|
|
|
199
219
|
return authenticated_user_permission()
|
|
200
220
|
elif action in _is_backoffice_permission:
|
|
201
221
|
return backoffice_permission()
|
|
222
|
+
elif action in _is_backoffice_read_permission:
|
|
223
|
+
return backoffice_read_permission()
|
|
202
224
|
elif action in _is_patron_owner_permission:
|
|
203
225
|
return PatronOwnerPermission
|
|
204
226
|
elif action == "circulation-loan-checkout":
|
|
@@ -10,7 +10,10 @@
|
|
|
10
10
|
from invenio_records_rest.facets import terms_filter
|
|
11
11
|
|
|
12
12
|
from invenio_app_ils.config import RECORDS_REST_MAX_RESULT_WINDOW
|
|
13
|
-
from invenio_app_ils.permissions import
|
|
13
|
+
from invenio_app_ils.permissions import (
|
|
14
|
+
backoffice_permission,
|
|
15
|
+
backoffice_read_permission,
|
|
16
|
+
)
|
|
14
17
|
|
|
15
18
|
from .api import PROVIDER_PID_FETCHER, PROVIDER_PID_MINTER, PROVIDER_PID_TYPE, Provider
|
|
16
19
|
from .indexer import ProviderIndexer
|
|
@@ -47,8 +50,8 @@ RECORDS_REST_ENDPOINTS = dict(
|
|
|
47
50
|
default_media_type="application/json",
|
|
48
51
|
max_result_window=RECORDS_REST_MAX_RESULT_WINDOW,
|
|
49
52
|
error_handlers=dict(),
|
|
50
|
-
read_permission_factory_imp=
|
|
51
|
-
list_permission_factory_imp=
|
|
53
|
+
read_permission_factory_imp=backoffice_read_permission,
|
|
54
|
+
list_permission_factory_imp=backoffice_read_permission,
|
|
52
55
|
create_permission_factory_imp=backoffice_permission,
|
|
53
56
|
update_permission_factory_imp=backoffice_permission,
|
|
54
57
|
delete_permission_factory_imp=backoffice_permission,
|
|
@@ -12,7 +12,10 @@ from flask_principal import ActionNeed, RoleNeed, UserNeed
|
|
|
12
12
|
from invenio_access import Permission, any_user
|
|
13
13
|
from six import string_types
|
|
14
14
|
|
|
15
|
-
from invenio_app_ils.permissions import
|
|
15
|
+
from invenio_app_ils.permissions import (
|
|
16
|
+
backoffice_access_action,
|
|
17
|
+
backoffice_readonly_access_action,
|
|
18
|
+
)
|
|
16
19
|
|
|
17
20
|
create_records_action = ActionNeed("create-records")
|
|
18
21
|
|
|
@@ -68,7 +71,10 @@ class RecordPermission(Permission):
|
|
|
68
71
|
if self.is_public():
|
|
69
72
|
return [any_user]
|
|
70
73
|
else:
|
|
71
|
-
return self.record_needs() + [
|
|
74
|
+
return self.record_needs() + [
|
|
75
|
+
backoffice_readonly_access_action,
|
|
76
|
+
backoffice_access_action,
|
|
77
|
+
]
|
|
72
78
|
|
|
73
79
|
def record_explicit_restrictions(self):
|
|
74
80
|
"""Return the list of user ids/roles allowed for the given action."""
|
invenio_app_ils/records/views.py
CHANGED
|
@@ -17,7 +17,7 @@ from invenio_rest import ContentNegotiatedMethodView
|
|
|
17
17
|
from invenio_app_ils.documents.api import DOCUMENT_PID_TYPE
|
|
18
18
|
from invenio_app_ils.eitems.api import EITEM_PID_TYPE
|
|
19
19
|
from invenio_app_ils.errors import StatsError
|
|
20
|
-
from invenio_app_ils.permissions import
|
|
20
|
+
from invenio_app_ils.permissions import backoffice_read_permission
|
|
21
21
|
from invenio_app_ils.records.permissions import RecordPermission
|
|
22
22
|
from invenio_app_ils.series.api import SERIES_PID_TYPE
|
|
23
23
|
from invenio_app_ils.signals import file_downloaded, record_viewed
|
|
@@ -62,7 +62,7 @@ class DocumentStatsResource(ContentNegotiatedMethodView):
|
|
|
62
62
|
def post(self, pid, record, **kwargs):
|
|
63
63
|
"""Send a signal to count record view for the record stats."""
|
|
64
64
|
factory = RecordPermission(record, "read")
|
|
65
|
-
if not factory.is_public() and not
|
|
65
|
+
if not factory.is_public() and not backoffice_read_permission().can():
|
|
66
66
|
if not current_user.is_authenticated:
|
|
67
67
|
abort(401)
|
|
68
68
|
abort(403)
|
|
@@ -13,7 +13,7 @@ from flask import current_app, g, has_request_context, request
|
|
|
13
13
|
from invenio_search.engine import dsl
|
|
14
14
|
|
|
15
15
|
from invenio_app_ils.errors import SearchQueryError, UnauthorizedSearchError
|
|
16
|
-
from invenio_app_ils.permissions import
|
|
16
|
+
from invenio_app_ils.permissions import backoffice_read_permission
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def _get_user_provides():
|
|
@@ -30,7 +30,7 @@ def _get_user_provides():
|
|
|
30
30
|
|
|
31
31
|
def search_filter_record_permissions():
|
|
32
32
|
"""Filter list of results by `_access` and `restricted` fields."""
|
|
33
|
-
if not has_request_context() or
|
|
33
|
+
if not has_request_context() or backoffice_read_permission().allows(g.identity):
|
|
34
34
|
return dsl.Q()
|
|
35
35
|
|
|
36
36
|
# A record is public if `restricted` field False or missing
|
|
@@ -120,7 +120,7 @@ def _filter_by_patron(patron_id, search, query_string=None):
|
|
|
120
120
|
def _filter_by_current_patron(search, query_string=None):
|
|
121
121
|
"""Filter search results by patron_pid."""
|
|
122
122
|
# if the logged in user is not librarian or admin, validate the query
|
|
123
|
-
if has_request_context() and not
|
|
123
|
+
if has_request_context() and not backoffice_read_permission().allows(g.identity):
|
|
124
124
|
return _filter_by_patron(g.identity.id, search, query_string)
|
|
125
125
|
return search, query_string
|
|
126
126
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: invenio-app-ils
|
|
3
|
-
Version:
|
|
3
|
+
Version: 6.0.0
|
|
4
4
|
Summary: Invenio Integrated Library System.
|
|
5
5
|
Home-page: https://github.com/inveniosoftware/invenio-app-ils
|
|
6
6
|
Author: CERN
|
|
@@ -103,6 +103,15 @@ https://invenioils.docs.cern.ch
|
|
|
103
103
|
Changes
|
|
104
104
|
=======
|
|
105
105
|
|
|
106
|
+
Version 6.0.0 (released 2025-10-03)
|
|
107
|
+
|
|
108
|
+
- breaking change: permissions: turn permission that checks if user can see notifications into read permission
|
|
109
|
+
- permissions: add backoffice readonly action
|
|
110
|
+
|
|
111
|
+
Version 5.1.0 (released 2025-09-24)
|
|
112
|
+
|
|
113
|
+
- eitem: add api methods to get eitems by `created_by` and `source` fields
|
|
114
|
+
|
|
106
115
|
Version 5.0.2 (released 2025-08-20)
|
|
107
116
|
|
|
108
117
|
- fix: ensure the invenio_app_ils configuration is loaded before cds_ils
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
invenio_app_ils/__init__.py,sha256=
|
|
2
|
-
invenio_app_ils/cli.py,sha256=
|
|
3
|
-
invenio_app_ils/config.py,sha256=
|
|
1
|
+
invenio_app_ils/__init__.py,sha256=HLj6S3LblIhvMyNOmHGWKGb9SiQyMpqyt6BLfa8K3UU,285
|
|
2
|
+
invenio_app_ils/cli.py,sha256=GGXMuXUlO9i8S9fpBXwj5wfPcK8aYe0leSDB3V--7Bs,58609
|
|
3
|
+
invenio_app_ils/config.py,sha256=Gi6h7eTlF8CwyOzE8dHxex1e3pAq4muvYNNkFYXtyE4,41157
|
|
4
4
|
invenio_app_ils/errors.py,sha256=HB_iWj-aYxzTzzO6hWb66mUPZdqpWYHgmr2H2t3j3wU,13293
|
|
5
5
|
invenio_app_ils/ext.py,sha256=SULPfx1FxBLaOaKcyNKAAIyvZAuvTH3AcH_a8aXTSYo,11522
|
|
6
6
|
invenio_app_ils/facets.py,sha256=x-ID7vL34zqbxJi7VC3EJSee13l_Jk0CfPZN3RHZrM8,4207
|
|
7
7
|
invenio_app_ils/fetchers.py,sha256=GY5A6BXaqMB9HKvJuTcio3JYoF15t6eqMo3yzQKTqac,520
|
|
8
8
|
invenio_app_ils/indexer.py,sha256=ngXRx2liufDzgsSIoCeusk6q0Y1uskQ3QiVLeAi3KRg,2212
|
|
9
9
|
invenio_app_ils/minters.py,sha256=8JW-45fL9Oy_13eZjlk8kL_12jJGZK59qbKlCeseQgA,537
|
|
10
|
-
invenio_app_ils/permissions.py,sha256=
|
|
10
|
+
invenio_app_ils/permissions.py,sha256=lYdUQosqdSfPaGKLUZuqrwD0KWOP8_915qJiK4qXYho,7744
|
|
11
11
|
invenio_app_ils/proxies.py,sha256=IGBwXQSOxpXHjD8PWFG1nqUm70xGAgzWT8Y0AKdCGiI,453
|
|
12
|
-
invenio_app_ils/search_permissions.py,sha256=
|
|
12
|
+
invenio_app_ils/search_permissions.py,sha256=cJWDgShgzXwxAtCtb7qXCIUfNSrQy_oe0zMuT0TzXgA,5073
|
|
13
13
|
invenio_app_ils/signals.py,sha256=KaN8yQUVq-2O2IKQQvPLtMjqp1S3AU1LYPlRyw9U8Pg,395
|
|
14
14
|
invenio_app_ils/views.py,sha256=qIvinO6O7ZX_vlLMQ_QPnMKvOe7UmYKusNgII022xkc,1734
|
|
15
15
|
invenio_app_ils/webpack.py,sha256=429ksU_x4Wizz_Ut9rP-M5gBnohK8r9XsbJwiHiI2G8,809
|
|
16
16
|
invenio_app_ils/acquisition/__init__.py,sha256=V8eD6gCowj-Wn2WIqWU3NJn4fsnyMuTrUG7N_M4Rytc,232
|
|
17
17
|
invenio_app_ils/acquisition/api.py,sha256=4WYKSw5aKg9KgMYIBuxlT9C7THybl6CfUnlTFzX6lJA,5122
|
|
18
|
-
invenio_app_ils/acquisition/config.py,sha256=
|
|
18
|
+
invenio_app_ils/acquisition/config.py,sha256=GxroZ9_A9c0j5yfGqdQar2mMhlqQiM679E_R4-rpoBA,3602
|
|
19
19
|
invenio_app_ils/acquisition/errors.py,sha256=cUmGj3jYPhnBZFgeORTeKa554R93qDnrNUY9VEfBgFg,507
|
|
20
20
|
invenio_app_ils/acquisition/ext.py,sha256=AcMXLvowZkNSRdx-qw6JVqoO--XUI4Vcq609-heoGsI,3095
|
|
21
21
|
invenio_app_ils/acquisition/proxies.py,sha256=VUTcGAcyVPWQGuaGrdXA7Uz0GLyyWlzsgAtry14iuCA,461
|
|
@@ -39,7 +39,7 @@ invenio_app_ils/assets/semantic-ui/less/theme.config,sha256=j2GQ2ulbymT0K-AEzHNO
|
|
|
39
39
|
invenio_app_ils/assets/semantic-ui/templates/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
40
40
|
invenio_app_ils/circulation/__init__.py,sha256=Gd0KAsGdhPdz0ACEQ9k8xSeOIxZr3xRK_FiE8U3RQWs,248
|
|
41
41
|
invenio_app_ils/circulation/api.py,sha256=jKty3IqTOK0XJdeXLlDqnZH2uhdVzd4xWuVphQe4YKw,14643
|
|
42
|
-
invenio_app_ils/circulation/config.py,sha256=
|
|
42
|
+
invenio_app_ils/circulation/config.py,sha256=pcB5JEjxXrieRRO-8RBUbxgf5dkhRGXXI2BvWfQUUCs,11433
|
|
43
43
|
invenio_app_ils/circulation/indexer.py,sha256=T24J5QqcB38LRJgirkAXL2tmFOucYToDRegxgFW96ag,3887
|
|
44
44
|
invenio_app_ils/circulation/receivers.py,sha256=Ux6KTNbII3DHBvCUS0gxqbi6tNbm76_kbcaHtK0BsB4,2488
|
|
45
45
|
invenio_app_ils/circulation/search.py,sha256=l9DAr9uoaF_JbfiiXVpAFKW3NLv9bgs7D-uDwtU-fv0,6105
|
|
@@ -85,7 +85,7 @@ invenio_app_ils/circulation/transitions/transitions.py,sha256=9W5h4RHm72wMQuY3hK
|
|
|
85
85
|
invenio_app_ils/closures/__init__.py,sha256=zJ2fI8Y34Vm-1uL9qLNeOQoqGKlhgfmiH8YcvvgnQP4,242
|
|
86
86
|
invenio_app_ils/closures/api.py,sha256=5i9C1_gDR0-HLeCtU4-aGcvosc9cSR3YVK6gpXJObdo,4441
|
|
87
87
|
invenio_app_ils/closures/tasks.py,sha256=Uy8W1OPyuByLW4OFdSHVtH9sXmT2tP_uB57FxkV_Vag,4343
|
|
88
|
-
invenio_app_ils/closures/views.py,sha256=
|
|
88
|
+
invenio_app_ils/closures/views.py,sha256=7XzILj73VKGJKz2ml1Um7TRJJ9Vf_ht1nnqKBzIQHGs,2413
|
|
89
89
|
invenio_app_ils/closures/serializers/__init__.py,sha256=PT1NBZEFk3X7u-7JUQ0U6Pbv12wpD7gPCVIpsZAPdp4,494
|
|
90
90
|
invenio_app_ils/closures/serializers/response.py,sha256=kMSpqllro-UgUOquIRUWywqm77GNdJeeaaaYzpKVMnU,937
|
|
91
91
|
invenio_app_ils/closures/serializers/schema.py,sha256=yFQYCPgd-m3tZAk019FR8TDV0BXovYcKW39o7MLGeAc,816
|
|
@@ -150,7 +150,7 @@ invenio_app_ils/documents/schemas/__init__.py,sha256=ngcwrP0RQpnFmW2WG5ZANoPw3A1
|
|
|
150
150
|
invenio_app_ils/documents/schemas/documents/document-v1.0.0.json,sha256=uhtuj4PxrM4AkZUv-2_8CsXUYd8MMY_Cizbov1QZCp4,18138
|
|
151
151
|
invenio_app_ils/documents/schemas/documents/document-v2.0.0.json,sha256=uhtuj4PxrM4AkZUv-2_8CsXUYd8MMY_Cizbov1QZCp4,18138
|
|
152
152
|
invenio_app_ils/eitems/__init__.py,sha256=QAjmRFG-mc0z4BRiBKF_oQtmoc5Lma00n32HU5rw3Xo,227
|
|
153
|
-
invenio_app_ils/eitems/api.py,sha256=
|
|
153
|
+
invenio_app_ils/eitems/api.py,sha256=VThP-l4who7n95KiorXX6-Kvm3iuXXq4m2szYDjWxo8,5156
|
|
154
154
|
invenio_app_ils/eitems/indexer.py,sha256=T9TjHHIEKWOQKJf3MIKHRJhLVjnJhUxwCwJKvzET63U,1800
|
|
155
155
|
invenio_app_ils/eitems/search.py,sha256=7OAC-HBVkubEsONFdlPgy7FfWxkI-_Wa586PKuHOH1A,1796
|
|
156
156
|
invenio_app_ils/eitems/jsonresolvers/__init__.py,sha256=eJEOVjrdQ2npcBT30Sf_xEq01jds8N8lnexskEGZR8o,245
|
|
@@ -181,7 +181,7 @@ invenio_app_ils/files/receivers.py,sha256=8bupcTrNO_amtDApSNezCCtOmiHk5n6qjqQyUS
|
|
|
181
181
|
invenio_app_ils/files/views.py,sha256=dmvZeOo8NinMwdIjquKtmBaULxuAeNnW8jODsyoa7D4,2196
|
|
182
182
|
invenio_app_ils/ill/__init__.py,sha256=kKHP8RvJfcQf8Ht8jbXHRKvTujLWva5c_x3c0FUgbuI,224
|
|
183
183
|
invenio_app_ils/ill/api.py,sha256=qav0RGtp3Gh47VdoKdS-mS3G0BXlN0iyZpE2obE2k4E,13301
|
|
184
|
-
invenio_app_ils/ill/config.py,sha256
|
|
184
|
+
invenio_app_ils/ill/config.py,sha256=PsK4Txrhgyb_v-_glgo6OxhO8GaGKgEJGopZUXFw_Pg,4861
|
|
185
185
|
invenio_app_ils/ill/errors.py,sha256=seRAUrwTbul5nA5W_2hCday2aAF56KzwHvj7xfCqAcw,512
|
|
186
186
|
invenio_app_ils/ill/ext.py,sha256=uPjVsUbRuwGuRZluhCxTgV7KGTh2qAFzIx2Q8CAzMOY,3004
|
|
187
187
|
invenio_app_ils/ill/proxies.py,sha256=wzVr7UDJVZhlU6aDYFNCjnapaFmcWLtKS9aM9c0Isww,453
|
|
@@ -289,11 +289,11 @@ invenio_app_ils/notifications/api.py,sha256=OT6P8hN04SDMZmfUWYonTZyf32jCLNXXrd96
|
|
|
289
289
|
invenio_app_ils/notifications/messages.py,sha256=4pNPuR7YKiwpMFdW6CvmDFFzVVd5p62wSfsfyQLpHTQ,3103
|
|
290
290
|
invenio_app_ils/notifications/models.py,sha256=79yoXBUVv246cGIK_xKl9WZ56f1Z2IGdyhZgnYTMkOw,1516
|
|
291
291
|
invenio_app_ils/notifications/tasks.py,sha256=yLASULAQfGBbo7UuEqH-o0FZbSUpuomI9efdcdwXiHI,1670
|
|
292
|
-
invenio_app_ils/notifications/views.py,sha256=
|
|
292
|
+
invenio_app_ils/notifications/views.py,sha256=umwy7Jowj8zCltOSkaEK9GvsXafaI6m5AzySyv3Hk1I,2566
|
|
293
293
|
invenio_app_ils/notifications/backends/__init__.py,sha256=51F9qVm1JIAOfLfzqn2O80YZlKJ4kVD5cuyoUP2Z748,421
|
|
294
294
|
invenio_app_ils/notifications/backends/mail.py,sha256=NNKgUsdWG2moqkGfEnwj2tPBOPzkOCuSW2F_WzWnc8A,1341
|
|
295
295
|
invenio_app_ils/patrons/__init__.py,sha256=zGad-MTgKFzc_92lH9NNKVIZyxSK9zwZX4BBmHK4tbw,228
|
|
296
|
-
invenio_app_ils/patrons/anonymization.py,sha256=
|
|
296
|
+
invenio_app_ils/patrons/anonymization.py,sha256=YsI8cCTGLFUDJ_EHpgPF_-ghK38XMQPAszhogE3ENko,10102
|
|
297
297
|
invenio_app_ils/patrons/api.py,sha256=ofVURg73zmacmiNbPJ4edCkDgxngdA90IePxoLM7lRc,5396
|
|
298
298
|
invenio_app_ils/patrons/cli.py,sha256=k-aZlygrJwwQGu1yAcI5livU6leERXf3jdV2oqyFegI,2018
|
|
299
299
|
invenio_app_ils/patrons/indexer.py,sha256=3SArGVZicfazVALg5gFS7UdQxewsxre9mrX9tu5nKTI,5956
|
|
@@ -308,7 +308,7 @@ invenio_app_ils/patrons/mappings/v7/__init__.py,sha256=Y6ZR1_PW0J5sX-YQheVddKpns
|
|
|
308
308
|
invenio_app_ils/patrons/mappings/v7/patrons/patron-v1.0.0.json,sha256=jjBiVPliis3RQep-Nct2xzgPLL8dUG6ggOOe7Zsig48,713
|
|
309
309
|
invenio_app_ils/providers/__init__.py,sha256=cHj2TtKKWWlZOnVeKc3kSgd0r7kYC__rBz3_ioqhrRI,229
|
|
310
310
|
invenio_app_ils/providers/api.py,sha256=PNvhnOiqnd3jfWxAUoulzIf6Ds-Wi5aBWyrrFAjFj-w,2122
|
|
311
|
-
invenio_app_ils/providers/config.py,sha256=
|
|
311
|
+
invenio_app_ils/providers/config.py,sha256=2eONs8L5yhi00BdBfjKKx8-tl8D1tMKsg9IrcfTXe1Q,2852
|
|
312
312
|
invenio_app_ils/providers/errors.py,sha256=ozKE-wh91_XL3fb9ib2lL6XZPcDwrR2Y-UwZ7m8E-Cc,639
|
|
313
313
|
invenio_app_ils/providers/ext.py,sha256=OuATVmSP9GTnOZ5xT_p8YdcT92Ift4CgESfyQL4LGAE,3120
|
|
314
314
|
invenio_app_ils/providers/indexer.py,sha256=TkRQkdwwMuyV0bdLybs7C4O46Bl9fcOyTh3zTUzpaWs,2197
|
|
@@ -330,9 +330,9 @@ invenio_app_ils/records/__init__.py,sha256=udEauUMbZmy_rf-YUHkgGbwxghb1JmIRv8xGg
|
|
|
330
330
|
invenio_app_ils/records/api.py,sha256=a5jgfy5Ovxbjo9aVjCT3t4SrYWaCkWWywVaJ-xrt8r8,3070
|
|
331
331
|
invenio_app_ils/records/listeners.py,sha256=6_yZRDh17ujY5zz3gSCArJeId9r8vyo-yadWh-LeAg4,998
|
|
332
332
|
invenio_app_ils/records/metadata_extensions.py,sha256=Y7knwqFTZ6UQU6-Viuhv22cplGd9VsebXasoDB-o39o,3599
|
|
333
|
-
invenio_app_ils/records/permissions.py,sha256=
|
|
333
|
+
invenio_app_ils/records/permissions.py,sha256=jPbeGyoOTYekssHnhwMQW5Z1naEWLxZvyjnD4J6OCis,3903
|
|
334
334
|
invenio_app_ils/records/receivers.py,sha256=z9iEd9EMqVw5wS3_pPZTZzeKRyzOguTHqb8FgsKCoD0,493
|
|
335
|
-
invenio_app_ils/records/views.py,sha256=
|
|
335
|
+
invenio_app_ils/records/views.py,sha256=lp7p2m3SsqL1W-7vD19kG89LoC-dhsElgXZ_AEAuiTs,3420
|
|
336
336
|
invenio_app_ils/records/jsonresolvers/__init__.py,sha256=mhHgwyehRSGfoWcfTT9O7F5pCFoS7-yKwJkbFaYRF8Y,249
|
|
337
337
|
invenio_app_ils/records/jsonresolvers/api.py,sha256=RAM7bqEjqgTn3wx6PlDRY_UEjZknrXiMSB-dMOJwvW0,1183
|
|
338
338
|
invenio_app_ils/records/loaders/__init__.py,sha256=saCzmtbFLKrgmueTclBSikDwO56XVpHA07PZ_dKu4Bo,817
|
|
@@ -445,10 +445,10 @@ invenio_app_ils/vocabularies/sources/__init__.py,sha256=EMLoLQGiq9_qoZ4lKqO_J0u2
|
|
|
445
445
|
invenio_app_ils/vocabularies/sources/base.py,sha256=kmNg85cjrxqc8VErFP2SUtlyo1PnmzOBQgfoSpfTPh4,1418
|
|
446
446
|
invenio_app_ils/vocabularies/sources/json.py,sha256=KGLTJ4AX8zEDdkpi3v92oHGs-h2dUzHbNPSg99-j8o0,1021
|
|
447
447
|
invenio_app_ils/vocabularies/sources/opendefinition.py,sha256=9zbRXuTr0i5lVLt596oUhsLQPiJVf9jiM9-C7T6zbXA,2151
|
|
448
|
-
invenio_app_ils-
|
|
449
|
-
invenio_app_ils-
|
|
450
|
-
invenio_app_ils-
|
|
451
|
-
invenio_app_ils-
|
|
452
|
-
invenio_app_ils-
|
|
453
|
-
invenio_app_ils-
|
|
454
|
-
invenio_app_ils-
|
|
448
|
+
invenio_app_ils-6.0.0.dist-info/licenses/AUTHORS.rst,sha256=BaXCGzdHCmiMOl4qtVlh1qrfy2ROMVOQp6ylzy1m0ww,212
|
|
449
|
+
invenio_app_ils-6.0.0.dist-info/licenses/LICENSE,sha256=9OdaPOAO1ZOJcRQ8BrGj7QAdaJc8SRSUgBtdom49MrI,1062
|
|
450
|
+
invenio_app_ils-6.0.0.dist-info/METADATA,sha256=o6S0b7IdQElHgPL8gZaBzU9wTii19V7m4-mTmygFJ3I,17723
|
|
451
|
+
invenio_app_ils-6.0.0.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
|
|
452
|
+
invenio_app_ils-6.0.0.dist-info/entry_points.txt,sha256=L36OnFZlrAnCaQpXnWoLmYYJ1U6Y1K_TDUZB0nnWeO0,7748
|
|
453
|
+
invenio_app_ils-6.0.0.dist-info/top_level.txt,sha256=p-lnzfSHaDER0BHbQvDV6dvUW7_Q0prMDFaqPhBSK50,16
|
|
454
|
+
invenio_app_ils-6.0.0.dist-info/RECORD,,
|
|
@@ -11,6 +11,7 @@ vocabulary = invenio_app_ils.vocabularies.cli:vocabulary
|
|
|
11
11
|
|
|
12
12
|
[invenio_access.actions]
|
|
13
13
|
backoffice_access_action = invenio_app_ils.permissions:backoffice_access_action
|
|
14
|
+
backoffice_readonly_access_action = invenio_app_ils.permissions:backoffice_readonly_access_action
|
|
14
15
|
|
|
15
16
|
[invenio_assets.webpack]
|
|
16
17
|
invenio_app_ils_theme = invenio_app_ils.webpack:theme
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|