Skip to content

Commit ee17b76

Browse files
authored
Merge pull request #1933 from NYPL-Simplified/TGR-35-circulation-manager-dependabot-alerts
TGR-35 Requirements Upgrades
2 parents 6a01164 + b41d937 commit ee17b76

15 files changed

Lines changed: 125 additions & 54 deletions

File tree

Dockerfile

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -221,14 +221,14 @@ CMD ["webapp"]
221221
###############################################################################
222222

223223
FROM cm_webapp_base AS cm_webapp_local
224-
ENV FLASK_ENV development
224+
ENV FLASK_DEBUG 1
225225

226226
###############################################################################
227227
## cm_webapp_active - self-contained version of webapp, for remote deploy
228228
###############################################################################
229229

230230
FROM cm_webapp_base AS cm_webapp_active
231-
ENV FLASK_ENV production
231+
ENV FLASK_DEBUG 0
232232

233233
COPY --chown=simplified:simplified . /home/simplified/circulation/
234234

@@ -263,14 +263,14 @@ CMD ["scripts", "|& tee -a /var/log/cron.log 2>$1"]
263263
###############################################################################
264264

265265
FROM cm_scripts_base AS cm_scripts_local
266-
ENV FLASK_ENV development
266+
ENV FLASK_DEBUG 1
267267

268268
###############################################################################
269269
## cm_scripts_active - self-contained version of scripts, for remote deploy
270270
###############################################################################
271271

272272
FROM cm_scripts_base AS cm_scripts_active
273-
ENV FLASK_ENV production
273+
ENV FLASK_DEBUG 0
274274

275275
COPY --chown=simplified:simplified . /home/simplified/circulation/
276276

@@ -286,13 +286,13 @@ CMD ["exec"]
286286
###############################################################################
287287

288288
FROM cm_exec_base AS cm_exec_local
289-
ENV FLASK_ENV development
289+
ENV FLASK_DEBUG 1
290290

291291
###############################################################################
292292
## cm_exec_active - self-contained version of exec, for remote deploy
293293
###############################################################################
294294

295295
FROM cm_exec_base AS cm_exec_active
296-
ENV FLASK_ENV production
296+
ENV FLASK_DEBUG 0
297297

298298
COPY --chown=simplified:simplified . /home/simplified/circulation/

api/admin/controller/__init__.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -351,16 +351,16 @@ def __call__(self, collection, book, path=None):
351351
redirect_url = flask.request.url
352352

353353
if (collection):
354-
quoted_collection = urllib.parse.quote(collection)
355354
redirect_url = redirect_url.replace(
356-
quoted_collection,
357-
quoted_collection.replace("/", "%2F"))
355+
collection,
356+
urllib.parse.quote_plus(collection)
357+
)
358358

359-
if (book):
360-
quoted_book = urllib.parse.quote(book)
359+
if (book):
361360
redirect_url = redirect_url.replace(
362-
quoted_book,
363-
quoted_book.replace("/", "%2F"))
361+
book,
362+
urllib.parse.quote_plus(book)
363+
)
364364

365365
return redirect(self.url_for('admin_sign_in', redirect=redirect_url))
366366

api/app.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@
1919
Flask,
2020
Response,
2121
redirect,
22+
request
2223
)
2324
from flask_swagger_ui import get_swaggerui_blueprint
24-
from flask_sqlalchemy_session import flask_scoped_session
25+
from .flask_sqlalchemy_session import flask_scoped_session
2526
from .config import Configuration
2627
from core.model import (
2728
ConfigurationSetting,
@@ -37,12 +38,16 @@
3738
from flask_babel import Babel
3839

3940

41+
def get_locale():
42+
languages = Configuration.localization_languages()
43+
return request.accept_languages.best_match(languages, default="en")
44+
4045
app = Flask(__name__)
4146
app._db = None
4247
app.static_resources_dir = Configuration.static_resources_dir()
4348
app.config['BABEL_DEFAULT_LOCALE'] = LanguageCodes.three_to_two[Configuration.localization_languages()[0]]
4449
app.config['BABEL_TRANSLATION_DIRECTORIES'] = "../translations"
45-
babel = Babel(app)
50+
babel = Babel(app, locale_selector=get_locale)
4651

4752
swaggerui_print = get_swaggerui_blueprint(
4853
'/apidocs_admin', '/admin_docs', blueprint_name='apmin_api'

api/authenticator.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from sqlalchemy.ext.hybrid import hybrid_property
1919
from sqlalchemy.orm.exc import NoResultFound
2020
from sqlalchemy.sql.expression import or_
21-
from werkzeug.datastructures import Headers
21+
from werkzeug.datastructures import auth, Headers
2222

2323
from api.util.short_client_token import ShortClientTokenUtility
2424
from api.annotations import AnnotationWriter
@@ -834,7 +834,7 @@ def authenticated_patron(self, _db, header):
834834

835835
if (self.basic_auth_provider
836836
and (
837-
(isinstance(header, dict) and 'username' in header)
837+
(isinstance(header, (dict, auth.Authorization)) and 'username' in header)
838838
or provider_name == BasicAuthenticationProvider.BEARER_TOKEN_PROVIDER_NAME
839839
)
840840
):
@@ -1955,7 +1955,7 @@ def authenticate(self, _db, credentials):
19551955
if isinstance(credentials, str):
19561956
return self._authenticate_from_token(_db, credentials)
19571957

1958-
elif isinstance(credentials, dict):
1958+
elif isinstance(credentials, (dict, auth.Authorization)):
19591959
return self._authenticate_from_credentials(_db, credentials)
19601960

19611961
def _authenticate_from_token(self, _db, credentials):
@@ -2108,7 +2108,7 @@ def get_credential_from_header(self, header):
21082108
21092109
:param header: A dictionary with keys `username` and `password`.
21102110
"""
2111-
if not isinstance(header, dict):
2111+
if not isinstance(header, (dict, auth.Authorization)):
21122112
return None
21132113
return header.get('password', None)
21142114

api/flask_sqlalchemy_session.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
"""
2+
https://github.com/dtheodor/flask-sqlalchemy-session is archived
3+
4+
Implements fixes to make it work with modern Werkzeug
5+
https://github.com/dtheodor/flask-sqlalchemy-session/pull/17
6+
https://github.com/dtheodor/flask-sqlalchemy-session/pull/15
7+
"""
8+
9+
from flask import current_app
10+
from sqlalchemy.orm import scoped_session
11+
from werkzeug.local import LocalProxy
12+
13+
14+
def _get_session():
15+
app = current_app._get_current_object()
16+
if not hasattr(app, "scoped_session"):
17+
raise AttributeError(
18+
"{} has no 'scoped_session' attribute. You need to initialize it "
19+
"with a flask_scoped_session.".format(app)
20+
)
21+
return app.scoped_session
22+
23+
24+
current_session = LocalProxy(_get_session)
25+
"""Provides the current SQL Alchemy session within a request.
26+
27+
Will raise an exception if no :data:`~flask.current_app` is available or it has
28+
not been initialized with a :class:`flask_scoped_session`
29+
"""
30+
31+
32+
class flask_scoped_session(scoped_session):
33+
"""A :class:`~sqlalchemy.orm.scoping.scoped_session` whose scope is set to
34+
the Flask application context.
35+
"""
36+
37+
def __init__(self, session_factory, app=None):
38+
"""
39+
:param session_factory: A callable that returns a
40+
:class:`~sqlalchemy.orm.session.Session`
41+
:param app: a :class:`~flask.Flask` application
42+
"""
43+
try:
44+
from greenlet import getcurrent as scopefunc
45+
except ImportError:
46+
from threading import get_ident as scopefunc
47+
super().__init__(session_factory, scopefunc=scopefunc)
48+
if app is not None:
49+
self.init_app(app)
50+
51+
def init_app(self, app):
52+
"""Setup scoped session creation and teardown for the passed ``app``.
53+
54+
:param app: a :class:`~flask.Flask` application
55+
"""
56+
app.scoped_session = self
57+
58+
@app.teardown_appcontext
59+
def remove_scoped_session(*args, **kwargs):
60+
app.scoped_session.remove()

api/routes.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from flask_cors.core import get_cors_options, set_cors_headers
1414
from werkzeug.exceptions import HTTPException
1515

16-
from .app import app, babel
16+
from .app import app
1717

1818
# We use URIs as identifiers throughout the application, meaning that
1919
# we never want werkzeug's merge_slashes feature.
@@ -57,10 +57,6 @@ def initialize_app_settings():
5757
# Finds or generates a site-wide bearer token signing secret
5858
BearerTokenSigner.bearer_token_signing_secret(app.manager._db)
5959

60-
@babel.localeselector
61-
def get_locale():
62-
languages = Configuration.localization_languages()
63-
return request.accept_languages.best_match(languages)
6460

6561
@app.teardown_request
6662
def shutdown_session(exception):

core/tests/test_app_server.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ def setup_method(self):
248248
self.controller = ComplaintController()
249249
self.edition, self.pool = self._edition(with_license_pool=True)
250250
self.app = Flask(__name__)
251-
Babel(self.app)
251+
Babel(self.app, locale_selector=lambda: "en")
252252

253253
def test_no_license_pool(self):
254254
with self.app.test_request_context("/"):
@@ -294,7 +294,7 @@ class TestLoadMethods(DatabaseTest):
294294
def setup_method(self):
295295
super(TestLoadMethods, self).setup_method()
296296
self.app = Flask(__name__)
297-
Babel(self.app)
297+
Babel(self.app, locale_selector=lambda: "en")
298298

299299
def test_load_facets_from_request(self):
300300
# The library has two EntryPoints enabled.
@@ -437,7 +437,7 @@ class MockManager(object):
437437

438438
self.app = Flask(__name__)
439439
self.app.manager = MockManager()
440-
Babel(self.app)
440+
Babel(self.app, locale_selector=lambda: "en")
441441

442442
def activate_debug_mode(self):
443443
"""Set a site-wide setting that controls whether

core/util/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import string
66
from collections import Counter
77

8-
import flask_sqlalchemy_session
8+
import api.flask_sqlalchemy_session
99
import sqlalchemy
1010
from money import Money
1111
from sqlalchemy import distinct, select
@@ -542,7 +542,7 @@ def is_session(value):
542542
:return: Boolean value indicating whether the value is a valid SQLAlchemy session or not
543543
:rtype: bool
544544
"""
545-
return isinstance(value, (sqlalchemy.orm.session.Session, flask_sqlalchemy_session.flask_scoped_session))
545+
return isinstance(value, (sqlalchemy.orm.session.Session, api.flask_sqlalchemy_session.flask_scoped_session))
546546

547547

548548
def first_or_default(collection, default=None):

docker/Dockerfile-es654.arm64

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ ENV JAVA_HOME="/usr/lib/jvm/java-11-openjdk-java-home"
55

66
EXPOSE 9200 9300
77

8+
RUN sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo
9+
RUN sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo
10+
RUN sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo
11+
812
RUN yum update -y \
913
&& yum install -y \
1014
java-11-openjdk \

requirements-base.txt

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88
#
99
apispec==5.1.1
1010
apispec-webframeworks==0.5.2
11-
Babel==2.8.0
11+
Babel==2.15.0
1212
boto3==1.23.2
1313
botocore==1.26.2
1414
certifi==2021.10.8
1515
cffi==1.15.0
1616
chardet==5.2.0
1717
click==8.1.3
1818
contextlib2==21.6.0
19-
cryptography==37.0.2
19+
cryptography==42.0.8
2020
# defusedxml is required for SAML authentication
2121
defusedxml==0.7.1
2222
# docker is used for the LCP feature.
@@ -27,10 +27,9 @@ elasticsearch-dsl==6.4.0
2727
enum34==1.1.10
2828
expiringdict==1.2.1
2929
feedparser==6.0.2
30-
Flask==2.1.2
31-
Flask-Babel==2.0.0
30+
Flask==2.2.5
31+
Flask-Babel==4.0.0
3232
Flask-Cors==3.0.10
33-
flask-sqlalchemy-session==1.1
3433
flask-swagger-ui==4.11.1
3534
# freezegun is used for unit tests.
3635
freezegun==1.2.1
@@ -44,10 +43,10 @@ ipaddress==1.0.23
4443
isbnlib==3.10.10
4544
isodate==0.6.1
4645
itsdangerous==2.1.2
47-
Jinja2==3.1.2
46+
Jinja2==3.1.4
4847
jsonschema==3.2.0
4948
loggly-python-handler==1.0.1
50-
lxml==4.6.5
49+
lxml==4.9.1
5150
markupsafe==2.1.1
5251
money==1.3.0
5352
multipledispatch==0.6.0
@@ -61,7 +60,7 @@ newrelic==8.5.0
6160
nltk==3.7
6261
oauth2client==4.1.3
6362
packaging==24.1
64-
Pillow==9.1.1
63+
Pillow==9.3.0
6564
pyasn1==0.4.8
6665
pyasn1-modules==0.2.8
6766
py-bcrypt==0.4
@@ -75,16 +74,16 @@ PyLD==1.0.5
7574
pymarc==4.2.2
7675
pyparsing==2.4.7
7776
pypostalcode==0.3.6
78-
pyOpenSSL==19.1.0
77+
pyOpenSSL==24.1.0
7978
pyspellchecker==0.5.5
80-
pytz==2021.3
79+
pytz==2022.7
8180
python-dateutil==2.8.2
8281
# TODO: python-Levenshtein is supposedly required for author name
8382
# matching, but is not a core requirement; perhaps it can be removed.
8483
python-Levenshtein==0.12.2
8584
pyrsistent==0.16.1
8685
# python-saml is required for SAML authentication
87-
python3-saml==1.14.0
86+
python3-saml==1.16.0
8887
requests==2.31.0
8988
requests-futures==1.0.0
9089
# requests-mock is used for unit tests.
@@ -105,13 +104,13 @@ textblob==0.15.3
105104
typing==3.7.4.3
106105
unicodecsv==0.14.1
107106
uritemplate==3.0.1
108-
urllib3==1.26.9
107+
urllib3==1.26.19
109108
uszipcode==1.0.1
110109
# watchtower is for Cloudwatch logging integration
111110
watchtower==0.8.0
112111
wcag-contrast-ratio==0.9
113112
websocket-client==0.57.0
114-
Werkzeug==2.0.3
113+
Werkzeug==2.3.8
115114
# xmlsec is required for SAML authentication
116115
xmlsec==1.3.12
117116

0 commit comments

Comments
 (0)