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):
|
def register_filters(app):
|
||||||
|
# register jinja filters
|
||||||
_paragraph_re = re.compile(r'(?:\r\n|\r|\n){2,}')
|
_paragraph_re = re.compile(r'(?:\r\n|\r|\n){2,}')
|
||||||
|
from oshipka.webapp.views import MODEL_VIEWS
|
||||||
|
|
||||||
@app.template_filter('nl2br')
|
@app.template_filter('nl2br')
|
||||||
def nl2br(text):
|
def nl2br(text):
|
||||||
@ -234,6 +236,26 @@ def register_filters(app):
|
|||||||
def bool_filter(v):
|
def bool_filter(v):
|
||||||
return bool(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):
|
class Proxy(object):
|
||||||
def __init__(self, proxied):
|
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_choice_header_py" %]
|
||||||
[%- include "_model_searchable_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 %]
|
[%- for column in columns %]
|
||||||
[%- if column._type == 'relationship' %]
|
[%- 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 @@
|
|||||||
|
{% 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>
|
<a href="{{ url_for('delete_[[ name|camel_to_snake ]]', uuid=instance.id, _next=request.path) }}">x</a>
|
||||||
|
{% endif %}
|
@ -1 +1,3 @@
|
|||||||
|
{% 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>
|
<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 @@
|
|||||||
|
{% 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_edit.html" %} |
|
||||||
{% include "[[ name|camel_to_snake ]]/_action_delete.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>
|
<li>
|
||||||
|
{% if has_permission('[[ name|camel_to_snake ]]', 'get') %}
|
||||||
<a href="{{ url_for('get_[[ name|camel_to_snake ]]', uuid=instance.id) }}">
|
<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" %}
|
{% include "[[ name|camel_to_snake ]]/_actions.html" %}
|
||||||
</li>
|
</li>
|
@ -3,9 +3,6 @@
|
|||||||
<a href="{{ url_for('get_[[ name|camel_to_snake ]]', uuid=instance.id) }}">
|
<a href="{{ url_for('get_[[ name|camel_to_snake ]]', uuid=instance.id) }}">
|
||||||
{% include "[[ name|camel_to_snake ]]/_title.html" %}</a>
|
{% include "[[ name|camel_to_snake ]]/_title.html" %}</a>
|
||||||
|
|
|
|
||||||
[
|
{% include "[[ name|camel_to_snake ]]/_actions.html" %}
|
||||||
<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>
|
|
||||||
]
|
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
@ -28,8 +28,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
[%- endfor %]
|
[%- endfor %]
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ url_for('update_[[ name|camel_to_snake ]]', uuid=instance.id, _next=request.path) }}">e</a> |
|
{% include "[[ name|camel_to_snake ]]/_action.html" %} |
|
||||||
<a href="{{ url_for('delete_[[ name|camel_to_snake ]]', uuid=instance.id, _next=request.path) }}">x</a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
{% extends "layout.html" %}
|
{% extends "layout.html" %}
|
||||||
|
|
||||||
{% block content %}
|
{% 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>
|
<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> |
|
{% include "[[ name|camel_to_snake ]]/_actions.html" %}
|
||||||
<a href="{{ url_for('delete_[[ name|camel_to_snake ]]', uuid=instance.id) }}">{{ _("delete") }}</a>
|
|
||||||
{% include "[[ name|camel_to_snake ]]/_get.html" %}
|
{% include "[[ name|camel_to_snake ]]/_get.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h2>{{ _("[[ name|pluralize ]]") }}</h2>
|
<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>
|
<br>
|
||||||
{% include "[[ name|camel_to_snake ]]/_list.html" %}
|
{% include "[[ name|camel_to_snake ]]/_list.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -1,7 +1,7 @@
|
|||||||
<a href="{{ url_for('home') }}">{{ _("Home") }}</a> |
|
<a href="{{ url_for('home') }}">{{ _("Home") }}</a> |
|
||||||
[%- for nav in navigation_items %]
|
[%- for nav in navigation_items %]
|
||||||
[%- if nav._verbs.list.is_login_required %]
|
[%- if nav._verbs.list.is_login_required %]
|
||||||
{% if current_user.is_authenticated %}
|
{% if has_permission('[[ nav.name|camel_to_snake ]]', 'list') %}
|
||||||
[%- endif %]
|
[%- endif %]
|
||||||
<a href="{{ url_for('list_[[ nav.name|camel_to_snake ]]') }}">{{ _("[[ nav.name ]]") }}</a>[%- if not loop.last %]|[%- 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 %]
|
[%- if nav._verbs.list.is_login_required %]
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h2>{{ _("[[ name|pluralize ]]") }}</h2>
|
<h2>{{ _("[[ name|pluralize ]]") }}</h2>
|
||||||
<a href="{{ url_for('create_[[ name|camel_to_snake ]]') }}">{{ _("Create") }}</a>
|
{% include "[[ name|camel_to_snake ]]/_action_create.html" %}
|
||||||
<br>
|
<br>
|
||||||
{% include "[[ name|camel_to_snake ]]/_table.html" %}
|
{% include "[[ name|camel_to_snake ]]/_table.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -135,13 +135,13 @@ def enrich_view_model(view_model):
|
|||||||
if verb == 'all':
|
if verb == 'all':
|
||||||
for verb in VERBS:
|
for verb in VERBS:
|
||||||
view_model['_verbs'][verb]['is_login_required'] = acl.get('login_required')
|
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:
|
else:
|
||||||
is_login_required = acl.get('login_required')
|
is_login_required = acl.get('login_required')
|
||||||
if is_login_required is False: # overrides all
|
if is_login_required is False: # overrides all
|
||||||
view_model['_verbs'][verb]['the_roles_required'] = acl.get('login_required')
|
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]['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
|
return view_model
|
||||||
|
|
||||||
|
|
||||||
@ -159,6 +159,9 @@ def process_navigation(view_models):
|
|||||||
|
|
||||||
def process_model(view_model):
|
def process_model(view_model):
|
||||||
template = env.get_template('model_py')
|
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 = autopep8.fix_code(template.render(**view_model), options=pep_options)
|
||||||
_model_name = view_model.get('name')
|
_model_name = view_model.get('name')
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user