From 94b9e9118a8a91ac75b72c5ef43a9e3f63172afa Mon Sep 17 00:00:00 2001 From: Daniel Grams Date: Tue, 31 Aug 2021 14:21:22 +0200 Subject: [PATCH] Manage OrganizationId out of sync #286 --- project/__init__.py | 2 +- project/jinja_filters.py | 7 +++---- project/requests.py | 20 ++++++++++++++++++++ project/views/manage.py | 32 ++++++++++++++++---------------- project/views/utils.py | 20 +++++++++++++++++++- tests/views/test_manage.py | 9 +++++++-- 6 files changed, 66 insertions(+), 24 deletions(-) create mode 100644 project/requests.py diff --git a/project/__init__.py b/project/__init__.py index fb37f39..1efc895 100644 --- a/project/__init__.py +++ b/project/__init__.py @@ -165,7 +165,7 @@ if os.getenv("TESTING", False): # pragma: no cover import project.cli.test import project.cli.user -from project import i10n, init_data, jinja_filters +from project import i10n, init_data, jinja_filters, requests # Routes from project.views import ( diff --git a/project/jinja_filters.py b/project/jinja_filters.py index e6b7a2d..9a5729f 100644 --- a/project/jinja_filters.py +++ b/project/jinja_filters.py @@ -83,14 +83,13 @@ def get_context_processors(): def get_current_admin_unit(): from flask_security import current_user - from project.access import get_admin_unit_for_manage, get_admin_units_for_manage + from project.access import get_admin_units_for_manage + from project.views.utils import get_manage_admin_unit_from_request admin_unit = None if current_user.is_authenticated: - if "manage_admin_unit_id" in request.cookies: - manage_admin_unit_id = int(request.cookies.get("manage_admin_unit_id")) - admin_unit = get_admin_unit_for_manage(manage_admin_unit_id) + admin_unit = get_manage_admin_unit_from_request(request) if not admin_unit: admin_units = get_admin_units_for_manage() diff --git a/project/requests.py b/project/requests.py new file mode 100644 index 0000000..64ae4a5 --- /dev/null +++ b/project/requests.py @@ -0,0 +1,20 @@ +from datetime import datetime, timedelta + +from flask import g +from flask_login.utils import encode_cookie + +from project import app + + +@app.after_request +def set_manage_admin_unit_cookie(response): + manage_admin_unit_id = getattr(g, "manage_admin_unit_id", 0) + if manage_admin_unit_id > 0: + encoded = encode_cookie(str(manage_admin_unit_id)) + response.set_cookie( + "manage_admin_unit_id", + value=encoded, + expires=datetime.utcnow() + timedelta(days=365), + ) + + return response diff --git a/project/views/manage.py b/project/views/manage.py index c7a96ef..eec5be3 100644 --- a/project/views/manage.py +++ b/project/views/manage.py @@ -1,4 +1,4 @@ -from flask import flash, make_response, redirect, render_template, request, url_for +from flask import flash, g, redirect, render_template, request, url_for from flask_babelex import gettext from flask_security import auth_required, current_user from sqlalchemy.exc import SQLAlchemyError @@ -7,7 +7,6 @@ from sqlalchemy.sql import desc, func from project import app, db from project.access import ( admin_unit_suggestions_enabled_or_404, - get_admin_unit_for_manage, get_admin_unit_for_manage_or_404, get_admin_units_for_manage, has_access, @@ -30,6 +29,7 @@ from project.services.event_suggestion import get_event_reviews_query from project.views.event import get_event_category_choices from project.views.utils import ( flash_errors, + get_manage_admin_unit_from_request, get_pagination_urls, handleSqlError, permission_missing, @@ -45,15 +45,10 @@ def manage_after_login(): @app.route("/manage") @auth_required() def manage(): - try: - if "manage_admin_unit_id" in request.cookies: - manage_admin_unit_id = int(request.cookies.get("manage_admin_unit_id")) - admin_unit = get_admin_unit_for_manage(manage_admin_unit_id) + admin_unit = get_manage_admin_unit_from_request(request) - if admin_unit: - return redirect(url_for("manage_admin_unit", id=admin_unit.id)) - except Exception: - pass + if admin_unit: + return redirect(url_for("manage_admin_unit", id=admin_unit.id)) if "from_login" in request.args: admin_units = get_admin_units_for_manage() @@ -90,18 +85,15 @@ def manage_admin_units(): @auth_required() def manage_admin_unit(id): admin_unit = get_admin_unit_for_manage_or_404(id) - - response = make_response( - redirect(url_for("manage_admin_unit_events", id=admin_unit.id)) - ) - response.set_cookie("manage_admin_unit_id", str(admin_unit.id)) - return response + g.manage_admin_unit_id = id + return redirect(url_for("manage_admin_unit_events", id=admin_unit.id)) @app.route("/manage/admin_unit//reviews") @auth_required() def manage_admin_unit_event_reviews(id): admin_unit = get_admin_unit_for_manage_or_404(id) + g.manage_admin_unit_id = id admin_unit_suggestions_enabled_or_404(admin_unit) event_suggestions_paginate = ( @@ -123,6 +115,7 @@ def manage_admin_unit_event_reviews(id): @auth_required() def manage_admin_unit_events(id): admin_unit = get_admin_unit_for_manage_or_404(id) + g.manage_admin_unit_id = id params = EventSearchParams() @@ -157,6 +150,8 @@ def manage_admin_unit_events(id): @auth_required() def manage_admin_unit_organizers(id): admin_unit = get_admin_unit_for_manage_or_404(id) + g.manage_admin_unit_id = id + organizers = ( EventOrganizer.query.filter(EventOrganizer.admin_unit_id == admin_unit.id) .order_by(func.lower(EventOrganizer.name)) @@ -175,6 +170,7 @@ def manage_admin_unit_organizers(id): @auth_required() def manage_admin_unit_event_places(id): admin_unit = get_admin_unit_for_manage_or_404(id) + g.manage_admin_unit_id = id form = FindEventPlaceForm(**request.args) @@ -196,6 +192,7 @@ def manage_admin_unit_event_places(id): @auth_required() def manage_admin_unit_members(id): admin_unit = get_admin_unit_for_manage_or_404(id) + g.manage_admin_unit_id = id if not has_access(admin_unit, "admin_unit.members:read"): return permission_missing(url_for("manage_admin_unit", id=id)) @@ -229,6 +226,7 @@ def manage_admin_unit_members(id): @auth_required() def manage_admin_unit_relations(id, path=None): admin_unit = get_admin_unit_for_manage_or_404(id) + g.manage_admin_unit_id = id return render_template( "manage/relations.html", @@ -240,6 +238,8 @@ def manage_admin_unit_relations(id, path=None): @auth_required() def manage_admin_unit_widgets(id): admin_unit = get_admin_unit_for_manage_or_404(id) + g.manage_admin_unit_id = id + default_background_color = "#ffffff" default_primary_color = "#007bff" diff --git a/project/views/utils.py b/project/views/utils.py index 9999178..a576e67 100644 --- a/project/views/utils.py +++ b/project/views/utils.py @@ -1,18 +1,36 @@ from urllib.parse import quote_plus -from flask import Markup, flash, redirect, render_template, request, url_for +from flask import Markup, flash, g, redirect, render_template, request, url_for from flask_babelex import gettext +from flask_login.utils import decode_cookie from flask_mail import Message from psycopg2.errorcodes import UNIQUE_VIOLATION from sqlalchemy.exc import SQLAlchemyError from wtforms import FormField from project import app, db, mail +from project.access import get_admin_unit_for_manage from project.dateutils import gmt_tz from project.models import Analytics, EventAttendanceMode, EventDate from project.utils import get_place_str +def get_manage_admin_unit_from_request(request): + manage_admin_unit_id = getattr(g, "manage_admin_unit_id", 0) + if manage_admin_unit_id > 0: + return get_admin_unit_for_manage(manage_admin_unit_id) + + try: + if "manage_admin_unit_id" in request.cookies: + encoded = request.cookies.get("manage_admin_unit_id") + manage_admin_unit_id = int(decode_cookie(encoded)) + return get_admin_unit_for_manage(manage_admin_unit_id) + except Exception: + pass + + return None + + def track_analytics(key, value1, value2): result = Analytics(key=key, value1=value1) diff --git a/tests/views/test_manage.py b/tests/views/test_manage.py index 215a073..29ae133 100644 --- a/tests/views/test_manage.py +++ b/tests/views/test_manage.py @@ -8,9 +8,14 @@ def test_index_noCookie(client, seeder, utils): utils.assert_response_redirect(response, "manage_admin_units") -def test_index_withValidCookie(client, seeder, utils): +def test_index_withValidCookie(client, seeder, app, utils): + from flask_login.utils import encode_cookie + user_id, admin_unit_id = seeder.setup_base() - client.set_cookie("localhost", "manage_admin_unit_id", str(admin_unit_id)) + + with app.app_context(): + encoded = encode_cookie(str(admin_unit_id)) + client.set_cookie("localhost", "manage_admin_unit_id", encoded) response = utils.get_endpoint("manage") utils.assert_response_redirect(response, "manage_admin_unit", id=admin_unit_id)