permissions improvement
This commit is contained in:
parent
699c8910a2
commit
9d85c95584
@ -184,7 +184,9 @@ user_datastore = SQLAlchemyUserDatastore(db, User, Role)
|
||||
|
||||
|
||||
def register_filters(app):
|
||||
# register jinja filters
|
||||
_paragraph_re = re.compile(r'(?:\r\n|\r|\n){2,}')
|
||||
from oshipka.webapp.views import MODEL_VIEWS
|
||||
|
||||
@app.template_filter('nl2br')
|
||||
def nl2br(text):
|
||||
@ -234,6 +236,26 @@ def register_filters(app):
|
||||
def bool_filter(v):
|
||||
return bool(v)
|
||||
|
||||
def has_permission(model, verb, instance=None):
|
||||
acl = MODEL_VIEWS.get(model, {}).model.acls.get(verb)
|
||||
# Anonymous user -> do we require AuthN?
|
||||
if current_user.is_anonymous:
|
||||
return not acl.get('authn')
|
||||
# Not Anonymous user -> Check roles
|
||||
roles = acl.get('authz')
|
||||
# No roles required -> has permission
|
||||
if not roles:
|
||||
return True
|
||||
# One role is enough to grant permission
|
||||
for role in roles:
|
||||
if role in ['owner']:
|
||||
return instance.user == current_user
|
||||
if current_user.has_role(role):
|
||||
return True
|
||||
return False
|
||||
|
||||
app.jinja_env.globals.update(has_permission=has_permission)
|
||||
|
||||
|
||||
class Proxy(object):
|
||||
def __init__(self, proxied):
|
||||
|
@ -6,7 +6,8 @@ class [[ name ]](db.Model, ModelController[% for inherit in interits %], [[ inhe
|
||||
[%- include "_model_choice_header_py" %]
|
||||
[%- include "_model_searchable_header_py" %]
|
||||
|
||||
_file_columns = [ [%- for column in columns %][%- if column.is_file %]"[[ column.name ]]"[%- endif %] [%- endfor %] ]
|
||||
_file_columns = [ [%- for column in columns %][%- if column.is_file %]"[[ column.name ]]", [%- endif %] [%- endfor %] ]
|
||||
acls = [[ acls ]]
|
||||
|
||||
[%- for column in columns %]
|
||||
[%- if column._type == 'relationship' %]
|
||||
|
3
vm_gen/templates/html/_action_create.html
Normal file
3
vm_gen/templates/html/_action_create.html
Normal file
@ -0,0 +1,3 @@
|
||||
{% if has_permission('[[ name|camel_to_snake ]]', 'create', instance) %}
|
||||
<a href="{{ url_for('create_[[ name|camel_to_snake ]]') }}">{{ _("Create") }}</a>
|
||||
{% endif %}
|
@ -1 +1,3 @@
|
||||
<a href="{{ url_for('delete_[[ name|camel_to_snake ]]', uuid=instance.id, _next=request.path) }}">x</a>
|
||||
{% if has_permission('[[ name|camel_to_snake ]]', 'delete', instance) %}
|
||||
<a href="{{ url_for('delete_[[ name|camel_to_snake ]]', uuid=instance.id, _next=request.path) }}">x</a>
|
||||
{% endif %}
|
@ -1 +1,3 @@
|
||||
<a href="{{ url_for('update_[[ name|camel_to_snake ]]', uuid=instance.id, _next=request.path) }}">e</a>
|
||||
{% if has_permission('[[ name|camel_to_snake ]]', 'update', instance) %}
|
||||
<a href="{{ url_for('update_[[ name|camel_to_snake ]]', uuid=instance.id, _next=request.path) }}">e</a>
|
||||
{% endif %}
|
3
vm_gen/templates/html/_action_list.html
Normal file
3
vm_gen/templates/html/_action_list.html
Normal file
@ -0,0 +1,3 @@
|
||||
{% if has_permission('[[ name|camel_to_snake ]]', 'list') %}
|
||||
<a href="{{ url_for('list_[[ name|camel_to_snake ]]') }}">{{ _("list") }}</a>
|
||||
{% endif %}
|
6
vm_gen/templates/html/_action_search.html
Normal file
6
vm_gen/templates/html/_action_search.html
Normal file
@ -0,0 +1,6 @@
|
||||
{% if has_permission('[[ name|camel_to_snake ]]', 'search') %}
|
||||
<form action="{{ url_for('search_[[ name|camel_to_snake ]]') }}">
|
||||
<input type="text" name="q" value="{{ request.args.q }}" placeholder="search [[ name|pluralize ]]">
|
||||
<input type="submit">
|
||||
</form>
|
||||
{% endif %}
|
3
vm_gen/templates/html/_action_table.html
Normal file
3
vm_gen/templates/html/_action_table.html
Normal file
@ -0,0 +1,3 @@
|
||||
{% if has_permission('[[ name|camel_to_snake ]]', 'table') %}
|
||||
<a href="{{ url_for('table_[[ name|camel_to_snake ]]') }}">{{ _("table") }}</a>
|
||||
{% endif %}
|
@ -1,4 +1,7 @@
|
||||
[
|
||||
{% include "[[ name|camel_to_snake ]]/_action_edit.html" %} |
|
||||
{% include "[[ name|camel_to_snake ]]/_action_delete.html" %}
|
||||
]
|
||||
{% if not has_permission('[[ name|camel_to_snake ]]', 'update', instance) and not has_permission('[[ name|camel_to_snake ]]', 'delete', instance) %}
|
||||
{% else %}
|
||||
[
|
||||
{% include "[[ name|camel_to_snake ]]/_action_edit.html" %} |
|
||||
{% include "[[ name|camel_to_snake ]]/_action_delete.html" %}
|
||||
]
|
||||
{% endif %}
|
2
vm_gen/templates/html/_actions_multiple.html
Normal file
2
vm_gen/templates/html/_actions_multiple.html
Normal file
@ -0,0 +1,2 @@
|
||||
{% include "[[ name|camel_to_snake ]]/_action_list.html" %} |
|
||||
{% include "[[ name|camel_to_snake ]]/_action_table.html" %}
|
@ -1,5 +1,10 @@
|
||||
<li>
|
||||
{% if has_permission('[[ name|camel_to_snake ]]', 'get') %}
|
||||
<a href="{{ url_for('get_[[ name|camel_to_snake ]]', uuid=instance.id) }}">
|
||||
{% include "[[ name|camel_to_snake ]]/_title.html" %}</a>
|
||||
{% endif %}
|
||||
{% include "[[ name|camel_to_snake ]]/_title.html" %}
|
||||
{% if has_permission('[[ name|camel_to_snake ]]', 'get') %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% include "[[ name|camel_to_snake ]]/_actions.html" %}
|
||||
</li>
|
@ -3,9 +3,6 @@
|
||||
<a href="{{ url_for('get_[[ name|camel_to_snake ]]', uuid=instance.id) }}">
|
||||
{% include "[[ name|camel_to_snake ]]/_title.html" %}</a>
|
||||
|
|
||||
[
|
||||
<a href="{{ url_for('update_[[ name|camel_to_snake ]]', uuid=instance.id) }}">e</a> |
|
||||
<a href="{{ url_for('delete_[[ name|camel_to_snake ]]', uuid=instance.id) }}">x</a>
|
||||
]
|
||||
{% include "[[ name|camel_to_snake ]]/_actions.html" %}
|
||||
</li>
|
||||
{% endfor %}
|
@ -28,8 +28,7 @@
|
||||
{% endif %}
|
||||
[%- endfor %]
|
||||
<td>
|
||||
<a href="{{ url_for('update_[[ name|camel_to_snake ]]', uuid=instance.id, _next=request.path) }}">e</a> |
|
||||
<a href="{{ url_for('delete_[[ name|camel_to_snake ]]', uuid=instance.id, _next=request.path) }}">x</a>
|
||||
{% include "[[ name|camel_to_snake ]]/_action.html" %} |
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
@ -1,9 +1,8 @@
|
||||
{% extends "layout.html" %}
|
||||
|
||||
{% block content %}
|
||||
<a href="{{ url_for('list_[[ name|camel_to_snake ]]', uuid=instance.id) }}">{{ _("list") }}</a> |
|
||||
{% include "[[ name|camel_to_snake ]]/_actions_multiple.html" %}
|
||||
<h2>{% include "[[ name|camel_to_snake ]]/_title.html" %}</h2>
|
||||
<a href="{{ url_for('update_[[ name|camel_to_snake ]]', uuid=instance.id, _next=request.path) }}">{{ _("edit") }}</a> |
|
||||
<a href="{{ url_for('delete_[[ name|camel_to_snake ]]', uuid=instance.id) }}">{{ _("delete") }}</a>
|
||||
{% include "[[ name|camel_to_snake ]]/_actions.html" %}
|
||||
{% include "[[ name|camel_to_snake ]]/_get.html" %}
|
||||
{% endblock %}
|
@ -2,7 +2,8 @@
|
||||
|
||||
{% block content %}
|
||||
<h2>{{ _("[[ name|pluralize ]]") }}</h2>
|
||||
<a href="{{ url_for('create_[[ name|camel_to_snake ]]') }}">{{ _("Create") }}</a>
|
||||
{% include "[[ name|camel_to_snake ]]/_action_search.html" %}
|
||||
{% include "[[ name|camel_to_snake ]]/_action_create.html" %}
|
||||
<br>
|
||||
{% include "[[ name|camel_to_snake ]]/_list.html" %}
|
||||
{% endblock %}
|
@ -1,7 +1,7 @@
|
||||
<a href="{{ url_for('home') }}">{{ _("Home") }}</a> |
|
||||
[%- for nav in navigation_items %]
|
||||
[%- if nav._verbs.list.is_login_required %]
|
||||
{% if current_user.is_authenticated %}
|
||||
{% if has_permission('[[ nav.name|camel_to_snake ]]', 'list') %}
|
||||
[%- endif %]
|
||||
<a href="{{ url_for('list_[[ nav.name|camel_to_snake ]]') }}">{{ _("[[ nav.name ]]") }}</a>[%- if not loop.last %]|[%- endif %]
|
||||
[%- if nav._verbs.list.is_login_required %]
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
{% block content %}
|
||||
<h2>{{ _("[[ name|pluralize ]]") }}</h2>
|
||||
<a href="{{ url_for('create_[[ name|camel_to_snake ]]') }}">{{ _("Create") }}</a>
|
||||
{% include "[[ name|camel_to_snake ]]/_action_create.html" %}
|
||||
<br>
|
||||
{% include "[[ name|camel_to_snake ]]/_table.html" %}
|
||||
{% endblock %}
|
@ -135,13 +135,13 @@ def enrich_view_model(view_model):
|
||||
if verb == 'all':
|
||||
for verb in VERBS:
|
||||
view_model['_verbs'][verb]['is_login_required'] = acl.get('login_required')
|
||||
view_model['_verbs'][verb]['the_roles_required'] = acl.get('roles_required')
|
||||
view_model['_verbs'][verb]['the_roles_required'] = acl.get('roles_required', [])
|
||||
else:
|
||||
is_login_required = acl.get('login_required')
|
||||
if is_login_required is False: # overrides all
|
||||
view_model['_verbs'][verb]['the_roles_required'] = acl.get('login_required')
|
||||
view_model['_verbs'][verb]['is_login_required'] = is_login_required
|
||||
view_model['_verbs'][verb]['the_roles_required'] = acl.get('roles_required')
|
||||
view_model['_verbs'][verb]['the_roles_required'] = acl.get('roles_required', [])
|
||||
return view_model
|
||||
|
||||
|
||||
@ -159,6 +159,9 @@ def process_navigation(view_models):
|
||||
|
||||
def process_model(view_model):
|
||||
template = env.get_template('model_py')
|
||||
view_model['acls'] = {}
|
||||
for verb, acl in view_model['_verbs'].items():
|
||||
view_model['acls'][verb] = {'authn': acl['is_login_required'], 'authz': acl['the_roles_required']}
|
||||
model = autopep8.fix_code(template.render(**view_model), options=pep_options)
|
||||
_model_name = view_model.get('name')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user