From 42d4b7fafbb3eb3bbc921406b7a4f3a86a178271 Mon Sep 17 00:00:00 2001 From: Ethan Dalool Date: Sat, 12 Sep 2020 11:43:25 -0700 Subject: [PATCH] Add give_token, catch_etiquette_exception to all endpoints at once. --- frontends/etiquette_flask/backend/common.py | 22 +++++++++++++++++++ .../backend/endpoints/album_endpoints.py | 19 ---------------- .../backend/endpoints/basic_endpoints.py | 2 -- .../backend/endpoints/bookmark_endpoints.py | 7 ------ .../backend/endpoints/photo_endpoints.py | 13 ----------- .../backend/endpoints/tag_endpoints.py | 15 ------------- .../backend/endpoints/user_endpoints.py | 7 ------ 7 files changed, 22 insertions(+), 63 deletions(-) diff --git a/frontends/etiquette_flask/backend/common.py b/frontends/etiquette_flask/backend/common.py index df1c107..f4e3313 100644 --- a/frontends/etiquette_flask/backend/common.py +++ b/frontends/etiquette_flask/backend/common.py @@ -10,6 +10,7 @@ from voussoirkit import pathclass import etiquette from . import caching +from . import decorators from . import jinja_filters from . import jsonify from . import sessions @@ -45,6 +46,27 @@ file_cache_manager = caching.FileCacheManager( max_age=BROWSER_CACHE_DURATION, ) +# Flask provides decorators for before_request and after_request, but not for +# wrapping the whole request. The decorators I am using need to wrap the whole +# request, either to catch exceptions (which don't get passed through +# after_request) or to maintain some state before running the function and +# adding it to the response after. +# Instead of copy-pasting my decorators onto every single function and +# forgetting to keep up with them in the future, let's just hijack the +# decorator I know every endpoint will have: site.route. +_original_route = site.route +def decorate_and_route(*route_args, **route_kwargs): + def wrapper(endpoint): + if not hasattr(endpoint, '_fully_decorated'): + endpoint = decorators.catch_etiquette_exception(endpoint) + endpoint = session_manager.give_token(endpoint) + + endpoint = _original_route(*route_args, **route_kwargs)(endpoint) + endpoint._fully_decorated = True + return endpoint + return wrapper +site.route = decorate_and_route + gzip_minimum_size = 500 gzip_level = 3 @site.after_request diff --git a/frontends/etiquette_flask/backend/endpoints/album_endpoints.py b/frontends/etiquette_flask/backend/endpoints/album_endpoints.py index c964eb8..1c7ffff 100644 --- a/frontends/etiquette_flask/backend/endpoints/album_endpoints.py +++ b/frontends/etiquette_flask/backend/endpoints/album_endpoints.py @@ -14,7 +14,6 @@ session_manager = common.session_manager # Individual albums ################################################################################ @site.route('/album/') -@session_manager.give_token def get_album_html(album_id): album = common.P_album(album_id, response_type='html') response = common.render_template( @@ -26,7 +25,6 @@ def get_album_html(album_id): return response @site.route('/album/.json') -@session_manager.give_token def get_album_json(album_id): album = common.P_album(album_id, response_type='json') album = etiquette.jsonify.album(album) @@ -56,7 +54,6 @@ def get_album_zip(album_id): return flask.Response(streamed_zip, headers=outgoing_headers) @site.route('/album//add_child', methods=['POST']) -@decorators.catch_etiquette_exception @decorators.required_fields(['child_id'], forbid_whitespace=True) def post_album_add_child(album_id): album = common.P_album(album_id, response_type='json') @@ -66,7 +63,6 @@ def post_album_add_child(album_id): return jsonify.make_json_response(response) @site.route('/album//remove_child', methods=['POST']) -@decorators.catch_etiquette_exception @decorators.required_fields(['child_id'], forbid_whitespace=True) def post_album_remove_child(album_id): album = common.P_album(album_id, response_type='json') @@ -76,7 +72,6 @@ def post_album_remove_child(album_id): return jsonify.make_json_response(response) @site.route('/album//refresh_directories', methods=['POST']) -@decorators.catch_etiquette_exception def post_album_refresh_directories(album_id): album = common.P_album(album_id, response_type='json') for directory in album.get_associated_directories(): @@ -87,8 +82,6 @@ def post_album_refresh_directories(album_id): # Album photo operations ########################################################################### @site.route('/album//add_photo', methods=['POST']) -@session_manager.give_token -@decorators.catch_etiquette_exception @decorators.required_fields(['photo_id'], forbid_whitespace=True) def post_album_add_photo(album_id): ''' @@ -103,8 +96,6 @@ def post_album_add_photo(album_id): return jsonify.make_json_response(response) @site.route('/album//remove_photo', methods=['POST']) -@session_manager.give_token -@decorators.catch_etiquette_exception @decorators.required_fields(['photo_id'], forbid_whitespace=True) def post_album_remove_photo(album_id): ''' @@ -121,8 +112,6 @@ def post_album_remove_photo(album_id): # Album tag operations ############################################################################# @site.route('/album//add_tag', methods=['POST']) -@decorators.catch_etiquette_exception -@session_manager.give_token def post_album_add_tag(album_id): ''' Apply a tag to every photo in the album. @@ -146,8 +135,6 @@ def post_album_add_tag(album_id): # Album metadata operations ######################################################################## @site.route('/album//edit', methods=['POST']) -@session_manager.give_token -@decorators.catch_etiquette_exception def post_album_edit(album_id): ''' Edit the title / description. @@ -168,7 +155,6 @@ def get_albums_core(): return albums @site.route('/albums') -@session_manager.give_token def get_albums_html(): albums = get_albums_core() response = common.render_template( @@ -180,7 +166,6 @@ def get_albums_html(): return response @site.route('/albums.json') -@session_manager.give_token def get_albums_json(): albums = get_albums_core() albums = [etiquette.jsonify.album(album, minimal=True) for album in albums] @@ -189,8 +174,6 @@ def get_albums_json(): # Album create and delete ########################################################################## @site.route('/albums/create_album', methods=['POST']) -@session_manager.give_token -@decorators.catch_etiquette_exception def post_albums_create(): title = request.form.get('title', None) description = request.form.get('description', None) @@ -209,8 +192,6 @@ def post_albums_create(): return jsonify.make_json_response(response) @site.route('/album//delete', methods=['POST']) -@session_manager.give_token -@decorators.catch_etiquette_exception def post_album_delete(album_id): album = common.P_album(album_id, response_type='json') album.delete(commit=True) diff --git a/frontends/etiquette_flask/backend/endpoints/basic_endpoints.py b/frontends/etiquette_flask/backend/endpoints/basic_endpoints.py index 5eff51c..01ab291 100644 --- a/frontends/etiquette_flask/backend/endpoints/basic_endpoints.py +++ b/frontends/etiquette_flask/backend/endpoints/basic_endpoints.py @@ -10,7 +10,6 @@ session_manager = common.session_manager #################################################################################################### @site.route('/') -@session_manager.give_token def root(): motd = random.choice(common.P.config['motd_strings']) return common.render_template(request, 'root.html', motd=motd) @@ -21,7 +20,6 @@ def favicon(): return flask.send_file(common.FAVICON_PATH.absolute_path) @site.route('/apitest') -@session_manager.give_token def apitest(): response = flask.Response('testing') return response diff --git a/frontends/etiquette_flask/backend/endpoints/bookmark_endpoints.py b/frontends/etiquette_flask/backend/endpoints/bookmark_endpoints.py index 2c725ed..afcc3e3 100644 --- a/frontends/etiquette_flask/backend/endpoints/bookmark_endpoints.py +++ b/frontends/etiquette_flask/backend/endpoints/bookmark_endpoints.py @@ -13,15 +13,12 @@ session_manager = common.session_manager # Individual bookmarks ############################################################################# @site.route('/bookmark/.json') -@session_manager.give_token def get_bookmark_json(bookmark_id): bookmark = common.P_bookmark(bookmark_id, response_type='json') response = etiquette.jsonify.bookmark(bookmark) return jsonify.make_json_response(response) @site.route('/bookmark//edit', methods=['POST']) -@session_manager.give_token -@decorators.catch_etiquette_exception def post_bookmark_edit(bookmark_id): bookmark = common.P_bookmark(bookmark_id, response_type='json') # Emptystring is okay for titles, but not for URL. @@ -36,13 +33,11 @@ def post_bookmark_edit(bookmark_id): # Bookmark listings ################################################################################ @site.route('/bookmarks') -@session_manager.give_token def get_bookmarks_html(): bookmarks = list(common.P.get_bookmarks()) return common.render_template(request, 'bookmarks.html', bookmarks=bookmarks) @site.route('/bookmarks.json') -@session_manager.give_token def get_bookmarks_json(): bookmarks = [etiquette.jsonify.bookmark(b) for b in common.P.get_bookmarks()] return jsonify.make_json_response(bookmarks) @@ -50,7 +45,6 @@ def get_bookmarks_json(): # Bookmark create and delete ####################################################################### @site.route('/bookmarks/create_bookmark', methods=['POST']) -@decorators.catch_etiquette_exception @decorators.required_fields(['url'], forbid_whitespace=True) def post_bookmark_create(): url = request.form['url'] @@ -62,7 +56,6 @@ def post_bookmark_create(): return response @site.route('/bookmark//delete', methods=['POST']) -@decorators.catch_etiquette_exception def post_bookmark_delete(bookmark_id): bookmark = common.P_bookmark(bookmark_id, response_type='json') bookmark.delete(commit=True) diff --git a/frontends/etiquette_flask/backend/endpoints/photo_endpoints.py b/frontends/etiquette_flask/backend/endpoints/photo_endpoints.py index 2fe50f9..02de30c 100644 --- a/frontends/etiquette_flask/backend/endpoints/photo_endpoints.py +++ b/frontends/etiquette_flask/backend/endpoints/photo_endpoints.py @@ -19,13 +19,11 @@ photo_download_zip_tokens = cacheclass.Cache(maxlen=100) # Individual photos ################################################################################ @site.route('/photo/') -@session_manager.give_token def get_photo_html(photo_id): photo = common.P_photo(photo_id, response_type='html') return common.render_template(request, 'photo.html', photo=photo) @site.route('/photo/.json') -@session_manager.give_token def get_photo_json(photo_id): photo = common.P_photo(photo_id, response_type='json') photo = etiquette.jsonify.photo(photo) @@ -71,8 +69,6 @@ def get_thumbnail(photo_id): # Photo create and delete ########################################################################## @site.route('/photo//delete', methods=['POST']) -@decorators.catch_etiquette_exception -@session_manager.give_token def post_photo_delete(photo_id): print(photo_id) photo = common.P_photo(photo_id, response_type='json') @@ -83,7 +79,6 @@ def post_photo_delete(photo_id): # Photo tag operations ############################################################################# -@decorators.catch_etiquette_exception def post_photo_add_remove_tag_core(photo_ids, tagname, add_or_remove): if isinstance(photo_ids, str): photo_ids = etiquette.helpers.comma_space_split(photo_ids) @@ -149,7 +144,6 @@ def post_batch_photos_remove_tag(): # Photo metadata operations ######################################################################## -@decorators.catch_etiquette_exception @site.route('/photo//generate_thumbnail', methods=['POST']) def post_photo_generate_thumbnail(photo_id): special = request.form.to_dict() @@ -161,7 +155,6 @@ def post_photo_generate_thumbnail(photo_id): response = jsonify.make_json_response({}) return response -@decorators.catch_etiquette_exception def post_photo_refresh_metadata_core(photo_ids): if isinstance(photo_ids, str): photo_ids = etiquette.helpers.comma_space_split(photo_ids) @@ -193,21 +186,18 @@ def post_batch_photos_refresh_metadata(): response = post_photo_refresh_metadata_core(photo_ids=request.form['photo_ids']) return response -@decorators.catch_etiquette_exception @site.route('/photo//set_searchhidden', methods=['POST']) def post_photo_set_searchhidden(photo_id): photo = common.P_photo(photo_id, response_type='json') photo.set_searchhidden(True) return jsonify.make_json_response({}) -@decorators.catch_etiquette_exception @site.route('/photo//unset_searchhidden', methods=['POST']) def post_photo_unset_searchhidden(photo_id): photo = common.P_photo(photo_id, response_type='json') photo.set_searchhidden(False) return jsonify.make_json_response({}) -@decorators.catch_etiquette_exception def post_batch_photos_searchhidden_core(photo_ids, searchhidden): if isinstance(photo_ids, str): photo_ids = etiquette.helpers.comma_space_split(photo_ids) @@ -236,7 +226,6 @@ def post_batch_photos_unset_searchhidden(): # Clipboard ######################################################################################## @site.route('/clipboard') -@session_manager.give_token def get_clipboard_page(): return common.render_template(request, 'clipboard.html') @@ -452,7 +441,6 @@ def get_search_core(): return final_results @site.route('/search') -@session_manager.give_token def get_search_html(): search_results = get_search_core() response = common.render_template( @@ -468,7 +456,6 @@ def get_search_html(): return response @site.route('/search.json') -@session_manager.give_token def get_search_json(): search_results = get_search_core() search_kwargs = search_results['search_kwargs'] diff --git a/frontends/etiquette_flask/backend/endpoints/tag_endpoints.py b/frontends/etiquette_flask/backend/endpoints/tag_endpoints.py index 7261864..7bd9e18 100644 --- a/frontends/etiquette_flask/backend/endpoints/tag_endpoints.py +++ b/frontends/etiquette_flask/backend/endpoints/tag_endpoints.py @@ -31,7 +31,6 @@ def get_tag_id_redirect(tag_id): return flask.redirect(url) @site.route('/tag//edit', methods=['POST']) -@decorators.catch_etiquette_exception def post_tag_edit(specific_tag): tag = common.P_tag(specific_tag, response_type='json') name = request.form.get('name', '').strip() @@ -46,8 +45,6 @@ def post_tag_edit(specific_tag): return response @site.route('/tag//add_child', methods=['POST']) -@decorators.catch_etiquette_exception -@session_manager.give_token @decorators.required_fields(['child_name'], forbid_whitespace=True) def post_tag_add_child(tagname): parent = common.P_tag(tagname, response_type='json') @@ -57,8 +54,6 @@ def post_tag_add_child(tagname): return jsonify.make_json_response(response) @site.route('/tag//remove_child', methods=['POST']) -@decorators.catch_etiquette_exception -@session_manager.give_token @decorators.required_fields(['child_name'], forbid_whitespace=True) def post_tag_remove_child(tagname): parent = common.P_tag(tagname, response_type='json') @@ -79,7 +74,6 @@ def get_all_tag_names(): @site.route('/tag/') @site.route('/tags') -@session_manager.give_token def get_tags_html(specific_tag_name=None): if specific_tag_name is None: specific_tag = None @@ -114,7 +108,6 @@ def get_tags_html(specific_tag_name=None): @site.route('/tag/.json') @site.route('/tags.json') -@session_manager.give_token def get_tags_json(specific_tag_name=None): if specific_tag_name is None: specific_tag = None @@ -137,8 +130,6 @@ def get_tags_json(specific_tag_name=None): # Tag create and delete ############################################################################ @site.route('/tags/create_tag', methods=['POST']) -@decorators.catch_etiquette_exception -@session_manager.give_token @decorators.required_fields(['name'], forbid_whitespace=True) def post_tag_create(): name = request.form['name'] @@ -149,8 +140,6 @@ def post_tag_create(): return jsonify.make_json_response(response) @site.route('/tags/easybake', methods=['POST']) -@decorators.catch_etiquette_exception -@session_manager.give_token @decorators.required_fields(['easybake_string'], forbid_whitespace=True) def post_tag_easybake(): easybake_string = request.form['easybake_string'] @@ -160,8 +149,6 @@ def post_tag_easybake(): return jsonify.make_json_response(notes) @site.route('/tag//delete', methods=['POST']) -@decorators.catch_etiquette_exception -@session_manager.give_token def post_tag_delete(tagname): tag = common.P_tag(tagname, response_type='json') tag.delete(commit=True) @@ -169,8 +156,6 @@ def post_tag_delete(tagname): return jsonify.make_json_response(response) @site.route('/tag//remove_synonym', methods=['POST']) -@decorators.catch_etiquette_exception -@session_manager.give_token @decorators.required_fields(['syn_name'], forbid_whitespace=True) def post_tag_remove_synonym(tagname): syn_name = request.form['syn_name'] diff --git a/frontends/etiquette_flask/backend/endpoints/user_endpoints.py b/frontends/etiquette_flask/backend/endpoints/user_endpoints.py index 5283d80..fe42ecd 100644 --- a/frontends/etiquette_flask/backend/endpoints/user_endpoints.py +++ b/frontends/etiquette_flask/backend/endpoints/user_endpoints.py @@ -14,13 +14,11 @@ session_manager = common.session_manager # Individual users ################################################################################# @site.route('/user/') -@session_manager.give_token def get_user_html(username): user = common.P_user(username, response_type='html') return common.render_template(request, 'user.html', user=user) @site.route('/user/.json') -@session_manager.give_token def get_user_json(username): user = common.P_user(username, response_type='json') user = etiquette.jsonify.user(user) @@ -41,7 +39,6 @@ def get_user_id_redirect(user_id): # Login and logout ################################################################################# @site.route('/login', methods=['GET']) -@session_manager.give_token def get_login(): response = common.render_template( request, @@ -52,7 +49,6 @@ def get_login(): return response @site.route('/login', methods=['POST']) -@session_manager.give_token @decorators.required_fields(['username', 'password']) def post_login(): session = session_manager.get(request) @@ -82,7 +78,6 @@ def post_login(): return jsonify.make_json_response({}) @site.route('/logout', methods=['POST']) -@session_manager.give_token def logout(): session_manager.remove(request) response = jsonify.make_json_response({}) @@ -95,8 +90,6 @@ def get_register(): return flask.redirect('/login') @site.route('/register', methods=['POST']) -@session_manager.give_token -@decorators.catch_etiquette_exception @decorators.required_fields(['username', 'password_1', 'password_2']) def post_register(): session = session_manager.get(request)