From 8230dd49501a8f04e8e476d6dbb264e3268b96e4 Mon Sep 17 00:00:00 2001 From: Daniel Tsvetkov Date: Sat, 15 May 2021 01:04:00 +0200 Subject: [PATCH] permissions users/roles --- bootstrap/webapp/view_models/Permission.yaml | 2 +- oshipka/persistance/__init__.py | 6 ++++ oshipka/webapp/default_routes.py | 9 ++++-- .../templates/_users_roles_multiselect.html | 4 +-- .../webapp/templates/permissions_admin.html | 2 ++ oshipka/webapp/views.py | 29 +++++++++---------- 6 files changed, 31 insertions(+), 21 deletions(-) diff --git a/bootstrap/webapp/view_models/Permission.yaml b/bootstrap/webapp/view_models/Permission.yaml index 34ebc50..a297e76 100644 --- a/bootstrap/webapp/view_models/Permission.yaml +++ b/bootstrap/webapp/view_models/Permission.yaml @@ -8,7 +8,7 @@ columns: type: int - name: action - name: object - - name: subject_id + - name: object_id type: int - name: is_allowed type: boolean diff --git a/oshipka/persistance/__init__.py b/oshipka/persistance/__init__.py index b88b0f4..a7b0c07 100644 --- a/oshipka/persistance/__init__.py +++ b/oshipka/persistance/__init__.py @@ -208,6 +208,12 @@ def register_filters(app): result = u'

'.join(u'%s' % p.replace('\n', '
\n') for p in _paragraph_re.split(text)) return Markup(result) + @app.template_filter('sp2nbsp') + def sp2nbsp(text): + text = escape(text) + result = u'

'.join(u'%s' % p.replace(' ', ' ') for p in _paragraph_re.split(text)) + return Markup(result) + @app.template_filter('format_dt') def format_datetime(dt, formatting="%a, %d %b %Y"): """ diff --git a/oshipka/webapp/default_routes.py b/oshipka/webapp/default_routes.py index 2b17dc3..694ad77 100644 --- a/oshipka/webapp/default_routes.py +++ b/oshipka/webapp/default_routes.py @@ -45,7 +45,8 @@ if SECURITY_ENABLED: @oshipka_bp.route('/sso') def sso(): callback_url = APP_BASE_URL + url_for('oshipka_bp.oidc_callback') - state = request.referrer or url_for('home') + "|" + random_string_generator() + url_to_redicrect_back = request.referrer or url_for('home') + state = url_to_redicrect_back + "|" + random_string_generator() session['oidc_state'] = state params = urllib.parse.urlencode({ 'redirect_uri': callback_url, @@ -64,7 +65,7 @@ if SECURITY_ENABLED: if error: return jsonify({"error": "from auth server: {}".format(error)}), 400 state = request.args.get('state') - session_state = session['oidc_state'] + session_state = session.get('oidc_state') if state != session_state: return jsonify({"error": "state is different from session state"}), 400 code = request.args.get('code') @@ -170,6 +171,10 @@ if SECURITY_ENABLED: for k, v in data.items(): if k in ['csrf_token']: continue + if k.startswith('users-'): + continue + if k.startswith('roles-'): + continue _, subject, action = k.split('-') sub_split, subject_id = subject.split('_'), None if len(sub_split) == 2: diff --git a/oshipka/webapp/templates/_users_roles_multiselect.html b/oshipka/webapp/templates/_users_roles_multiselect.html index 1bd950e..fd55525 100644 --- a/oshipka/webapp/templates/_users_roles_multiselect.html +++ b/oshipka/webapp/templates/_users_roles_multiselect.html @@ -1,5 +1,5 @@

{{ _("Who can access the admin permissions page (this one!):") }}

+ {% set model_name = "admin" %} {% set selected_users = admin_permissions_table['selected_users'] %} {% set selected_roles = admin_permissions_table['selected_roles'] %} {% include "_users_roles_multiselect.html" %} @@ -12,6 +13,7 @@ {% for mv in model_views %}

{{ mv }}

{{ _("Who can access the permissions page for") }} {{ mv }}

+ {% set model_name = mv %} {% set selected_users = model_tables[mv]['selected_users'] %} {% set selected_roles = model_tables[mv]['selected_roles'] %} {% include "_users_roles_multiselect.html" %} diff --git a/oshipka/webapp/views.py b/oshipka/webapp/views.py index 1fd90f4..edd2e15 100644 --- a/oshipka/webapp/views.py +++ b/oshipka/webapp/views.py @@ -24,17 +24,14 @@ if SECURITY_ENABLED: MODEL_VIEWS = dict() -def check_instance_perm(model_view, verb, instance): - return True - - -def has_permission(model, verb, instance=None): - model_view = MODEL_VIEWS.get(model, {}) +def has_permission(obj, action, instance=None, object_prefix="models", action_prefix="model"): + if object_prefix in ['models']: + model_view = MODEL_VIEWS.get(obj, {}) if not model_view: return False if current_user.is_anonymous: - permission = Permission.query.filter(Permission.object == "models.{}".format(model), - Permission.action == "model.{}".format(verb), + permission = Permission.query.filter(Permission.object == "{}.{}".format(object_prefix, obj), + Permission.action == "{}.{}".format(action_prefix, action), Permission.subject == "public").first() if permission and permission.is_allowed: return True @@ -43,24 +40,24 @@ def has_permission(model, verb, instance=None): if instance is not None: inherits = model_view.definitions.get('inherits', []) if "Ownable" in inherits: - permission = Permission.query.filter(Permission.object == "models.{}".format(model), + permission = Permission.query.filter(Permission.object == "{}.{}".format(object_prefix, obj), Permission.object_id == instance.id, - Permission.action == "model.{}".format(verb), + Permission.action == "{}.{}".format(action_prefix, action), Permission.subject == "owner").first() if permission and permission.is_allowed: return True # LOGGED IN USER - permission = Permission.query.filter(Permission.object == "models.{}".format(model), - Permission.action == "model.{}".format(verb), + permission = Permission.query.filter(Permission.object == "{}.{}".format(object_prefix, obj), + Permission.action == "{}.{}".format(action_prefix, action), Permission.subject == "logged").first() if permission and permission.is_allowed: return True # ROLE PERMISSIONS roles_ids = [r.id for r in current_user.roles] - role_permissions = Permission.query.filter(Permission.object == "models.{}".format(model), - Permission.action == "model.{}".format(verb), + role_permissions = Permission.query.filter(Permission.object == "{}.{}".format(object_prefix, obj), + Permission.action == "{}.{}".format(action_prefix, action), Permission.subject == "user", Permission.subject_id.in_(roles_ids)).all() for role_permission in role_permissions: @@ -69,8 +66,8 @@ def has_permission(model, verb, instance=None): # USER PERMISSIONS user_id = current_user.id - user_permission = Permission.query.filter(Permission.object == "models.{}".format(model), - Permission.action == "model.{}".format(verb), + user_permission = Permission.query.filter(Permission.object == "{}.{}".format(object_prefix, obj), + Permission.action == "{}.{}".format(action_prefix, action), Permission.subject == "user", Permission.subject_id == user_id).first() if user_permission: