permissions users/roles

This commit is contained in:
Daniel Tsvetkov 2021-05-15 01:04:00 +02:00
parent a56bdf135a
commit 8230dd4950
6 changed files with 31 additions and 21 deletions

View File

@ -8,7 +8,7 @@ columns:
type: int type: int
- name: action - name: action
- name: object - name: object
- name: subject_id - name: object_id
type: int type: int
- name: is_allowed - name: is_allowed
type: boolean type: boolean

View File

@ -208,6 +208,12 @@ def register_filters(app):
result = u'<p>'.join(u'%s' % p.replace('\n', '<br>\n') for p in _paragraph_re.split(text)) result = u'<p>'.join(u'%s' % p.replace('\n', '<br>\n') for p in _paragraph_re.split(text))
return Markup(result) return Markup(result)
@app.template_filter('sp2nbsp')
def sp2nbsp(text):
text = escape(text)
result = u'<p>'.join(u'%s' % p.replace(' ', '&nbsp;') for p in _paragraph_re.split(text))
return Markup(result)
@app.template_filter('format_dt') @app.template_filter('format_dt')
def format_datetime(dt, formatting="%a, %d %b %Y"): def format_datetime(dt, formatting="%a, %d %b %Y"):
""" """

View File

@ -45,7 +45,8 @@ if SECURITY_ENABLED:
@oshipka_bp.route('/sso') @oshipka_bp.route('/sso')
def sso(): def sso():
callback_url = APP_BASE_URL + url_for('oshipka_bp.oidc_callback') 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 session['oidc_state'] = state
params = urllib.parse.urlencode({ params = urllib.parse.urlencode({
'redirect_uri': callback_url, 'redirect_uri': callback_url,
@ -64,7 +65,7 @@ if SECURITY_ENABLED:
if error: if error:
return jsonify({"error": "from auth server: {}".format(error)}), 400 return jsonify({"error": "from auth server: {}".format(error)}), 400
state = request.args.get('state') state = request.args.get('state')
session_state = session['oidc_state'] session_state = session.get('oidc_state')
if state != session_state: if state != session_state:
return jsonify({"error": "state is different from session state"}), 400 return jsonify({"error": "state is different from session state"}), 400
code = request.args.get('code') code = request.args.get('code')
@ -170,6 +171,10 @@ if SECURITY_ENABLED:
for k, v in data.items(): for k, v in data.items():
if k in ['csrf_token']: if k in ['csrf_token']:
continue continue
if k.startswith('users-'):
continue
if k.startswith('roles-'):
continue
_, subject, action = k.split('-') _, subject, action = k.split('-')
sub_split, subject_id = subject.split('_'), None sub_split, subject_id = subject.split('_'), None
if len(sub_split) == 2: if len(sub_split) == 2:

View File

@ -1,5 +1,5 @@
<label>Users: <label>Users:
<select multiple> <select multiple name="users-{{ model_name }}">
{% for user in users %} {% for user in users %}
<option value="{{ user.id }}" <option value="{{ user.id }}"
{% if user.id in selected_users %}selected="selected"{% endif %} {% if user.id in selected_users %}selected="selected"{% endif %}
@ -9,7 +9,7 @@
</select> </select>
</label> </label>
<label>Roles: <label>Roles:
<select multiple> <select multiple name="roles-{{ model_name }}">
{% for role in roles %} {% for role in roles %}
<option value="{{ role.id }}" <option value="{{ role.id }}"
{% if role.id in selected_roles %}selected="selected"{% endif %} {% if role.id in selected_roles %}selected="selected"{% endif %}

View File

@ -4,6 +4,7 @@
<h1>Admin permissions</h1> <h1>Admin permissions</h1>
{{ admin_permissions }} {{ admin_permissions }}
<p>{{ _("Who can access the admin permissions page (this one!):") }}</p> <p>{{ _("Who can access the admin permissions page (this one!):") }}</p>
{% set model_name = "admin" %}
{% set selected_users = admin_permissions_table['selected_users'] %} {% set selected_users = admin_permissions_table['selected_users'] %}
{% set selected_roles = admin_permissions_table['selected_roles'] %} {% set selected_roles = admin_permissions_table['selected_roles'] %}
{% include "_users_roles_multiselect.html" %} {% include "_users_roles_multiselect.html" %}
@ -12,6 +13,7 @@
{% for mv in model_views %} {% for mv in model_views %}
<h2><a href="{{ url_for('model_permissions', model_name=mv) }}">{{ mv }}</a></h2> <h2><a href="{{ url_for('model_permissions', model_name=mv) }}">{{ mv }}</a></h2>
<p>{{ _("Who can access the permissions page for") }} {{ mv }}</p> <p>{{ _("Who can access the permissions page for") }} {{ mv }}</p>
{% set model_name = mv %}
{% set selected_users = model_tables[mv]['selected_users'] %} {% set selected_users = model_tables[mv]['selected_users'] %}
{% set selected_roles = model_tables[mv]['selected_roles'] %} {% set selected_roles = model_tables[mv]['selected_roles'] %}
{% include "_users_roles_multiselect.html" %} {% include "_users_roles_multiselect.html" %}

View File

@ -24,17 +24,14 @@ if SECURITY_ENABLED:
MODEL_VIEWS = dict() MODEL_VIEWS = dict()
def check_instance_perm(model_view, verb, instance): def has_permission(obj, action, instance=None, object_prefix="models", action_prefix="model"):
return True if object_prefix in ['models']:
model_view = MODEL_VIEWS.get(obj, {})
def has_permission(model, verb, instance=None):
model_view = MODEL_VIEWS.get(model, {})
if not model_view: if not model_view:
return False return False
if current_user.is_anonymous: if current_user.is_anonymous:
permission = Permission.query.filter(Permission.object == "models.{}".format(model), permission = Permission.query.filter(Permission.object == "{}.{}".format(object_prefix, obj),
Permission.action == "model.{}".format(verb), Permission.action == "{}.{}".format(action_prefix, action),
Permission.subject == "public").first() Permission.subject == "public").first()
if permission and permission.is_allowed: if permission and permission.is_allowed:
return True return True
@ -43,24 +40,24 @@ def has_permission(model, verb, instance=None):
if instance is not None: if instance is not None:
inherits = model_view.definitions.get('inherits', []) inherits = model_view.definitions.get('inherits', [])
if "Ownable" in 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.object_id == instance.id,
Permission.action == "model.{}".format(verb), Permission.action == "{}.{}".format(action_prefix, action),
Permission.subject == "owner").first() Permission.subject == "owner").first()
if permission and permission.is_allowed: if permission and permission.is_allowed:
return True return True
# LOGGED IN USER # LOGGED IN USER
permission = Permission.query.filter(Permission.object == "models.{}".format(model), permission = Permission.query.filter(Permission.object == "{}.{}".format(object_prefix, obj),
Permission.action == "model.{}".format(verb), Permission.action == "{}.{}".format(action_prefix, action),
Permission.subject == "logged").first() Permission.subject == "logged").first()
if permission and permission.is_allowed: if permission and permission.is_allowed:
return True return True
# ROLE PERMISSIONS # ROLE PERMISSIONS
roles_ids = [r.id for r in current_user.roles] roles_ids = [r.id for r in current_user.roles]
role_permissions = Permission.query.filter(Permission.object == "models.{}".format(model), role_permissions = Permission.query.filter(Permission.object == "{}.{}".format(object_prefix, obj),
Permission.action == "model.{}".format(verb), Permission.action == "{}.{}".format(action_prefix, action),
Permission.subject == "user", Permission.subject == "user",
Permission.subject_id.in_(roles_ids)).all() Permission.subject_id.in_(roles_ids)).all()
for role_permission in role_permissions: for role_permission in role_permissions:
@ -69,8 +66,8 @@ def has_permission(model, verb, instance=None):
# USER PERMISSIONS # USER PERMISSIONS
user_id = current_user.id user_id = current_user.id
user_permission = Permission.query.filter(Permission.object == "models.{}".format(model), user_permission = Permission.query.filter(Permission.object == "{}.{}".format(object_prefix, obj),
Permission.action == "model.{}".format(verb), Permission.action == "{}.{}".format(action_prefix, action),
Permission.subject == "user", Permission.subject == "user",
Permission.subject_id == user_id).first() Permission.subject_id == user_id).first()
if user_permission: if user_permission: