new perms

This commit is contained in:
Daniel Tsvetkov 2021-05-15 01:04:17 +02:00
parent 2efd1e357f
commit d1191c782d
77 changed files with 803 additions and 73 deletions

View File

@ -25,3 +25,7 @@ MAKEDIRS = [
]
TRANSLATION_LANGUAGES = ['en', 'bg']
APP_BASE_URL = "https://blog.pi2.dev"
SECURITY_ENABLED = True
SSO_BASE_URL = 'https://sso.localhost:5008'
SSO_CLIENT_ID = APP_BASE_URL

View File

@ -1,2 +1,2 @@
email,password,role_names
admin@blog.pi2.dev,__SENSITIVE__.ADMIN_PASSWORD,admin
username,_m_n_roles
daniel,1
1 email username password _m_n_roles role_names
2 admin@blog.pi2.dev daniel __SENSITIVE__.ADMIN_PASSWORD 1 admin

View File

@ -0,0 +1,40 @@
"""002
Revision ID: 40f7b6561b4a
Revises: d091fbf48f6f
Create Date: 2021-05-15 00:35:30.800690
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '40f7b6561b4a'
down_revision = 'd091fbf48f6f'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('permission',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('uuid', sa.Unicode(), nullable=True),
sa.Column('subject', sa.UnicodeText(), nullable=True),
sa.Column('subject_id', sa.Integer(), nullable=True),
sa.Column('action', sa.UnicodeText(), nullable=True),
sa.Column('object', sa.UnicodeText(), nullable=True),
sa.Column('object_id', sa.Integer(), nullable=True),
sa.Column('is_allowed', sa.Boolean(), nullable=True),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_permission_uuid'), 'permission', ['uuid'], unique=False)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_permission_uuid'), table_name='permission')
op.drop_table('permission')
# ### end Alembic commands ###

View File

@ -40,8 +40,7 @@ def upgrade():
op.create_table('user',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('uuid', sa.Unicode(), nullable=True),
sa.Column('email', sa.Unicode(), nullable=True),
sa.Column('password', sa.Unicode(), nullable=True),
sa.Column('username', sa.Unicode(), nullable=True),
sa.Column('active', sa.Boolean(), nullable=True),
sa.Column('confirmed_at', sa.DateTime(), nullable=True),
sa.Column('timezone', sa.String(), nullable=True),

1
run.py
View File

@ -12,6 +12,5 @@ app.template_folder = TEMPLATES_FOLDER
app.static_folder = STATIC_FOLDER
if __name__ == "__main__":
app.run(debug=True)

View File

@ -1,3 +1,4 @@
from oshipka.persistance import db
from webapp.models.tag import Tag
from webapp.models.blog_post import BlogPost
from webapp.models.permission import Permission

View File

@ -9,6 +9,11 @@ blog_post__tag = db.Table('blog_post__tag',
class BlogPost(db.Model, ModelController, Ownable):
__searchable__ = ['body', ]
_file_columns = []
model_acls = {'get': {'authn': False, 'authz': []}, 'list': {'authn': False, 'authz': []}, 'table': {'authn': False, 'authz': []}, 'search': {
'authn': False, 'authz': []}, 'create': {'authn': True, 'authz': ['admin']}, 'update': {'authn': True, 'authz': ['admin']}, 'delete': {'authn': True, 'authz': ['admin']}}
filename = db.Column(db.UnicodeText,)
title = db.Column(db.UnicodeText,)
body = db.Column(db.UnicodeText,)

View File

@ -0,0 +1,19 @@
from oshipka.persistance import db, ModelController, index_service, LiberalBoolean, Ownable
class Permission(db.Model, ModelController):
_file_columns = []
model_acls = {'get': {'authn': True, 'authz': []}, 'list': {'authn': True, 'authz': []}, 'table': {'authn': True, 'authz': []}, 'search': {
'authn': True, 'authz': []}, 'create': {'authn': True, 'authz': []}, 'update': {'authn': True, 'authz': []}, 'delete': {'authn': True, 'authz': []}}
subject = db.Column(db.UnicodeText,)
subject_id = db.Column(db.Integer,)
action = db.Column(db.UnicodeText,)
object = db.Column(db.UnicodeText,)
object_id = db.Column(db.Integer,)
is_allowed = db.Column(LiberalBoolean,)
def __repr__(self):
return "{} ({} - {})".format(self.subject, self.action, self.object)

View File

@ -2,6 +2,12 @@ from oshipka.persistance import db, ModelController, index_service, LiberalBoole
class Tag(db.Model, ModelController, Ownable):
_file_columns = []
model_acls = {'get': {'authn': False, 'authz': []}, 'list': {'authn': False, 'authz': []}, 'table': {'authn': False, 'authz': []}, 'search': {
'authn': False, 'authz': []}, 'create': {'authn': True, 'authz': ['admin']}, 'update': {'authn': True, 'authz': ['admin']}, 'delete': {'authn': True, 'authz': ['admin']}}
name = db.Column(db.UnicodeText,)
def __repr__(self):

View File

@ -0,0 +1 @@
from webapp.models._permission import Permission

View File

@ -1,2 +1,3 @@
from webapp.routes.tag import *
from webapp.routes.blog_post import *
from webapp.routes.permission import *

View File

@ -4,12 +4,18 @@
Edit the hooks in webapp/routes/blog_post_hooks.py instead
"""
from flask import render_template
from flask_security import login_required
from oshipka.webapp import app
from oshipka.webapp.views import ModelView
from webapp.models import BlogPost
from webapp.routes.blog_post_hooks import *
from webapp.models import BlogPost
blog_post = ModelView(app, BlogPost, {'name': 'BlogPost', 'searchable': ['body'], 'inherits': ['Ownable'], 'access': [{'verb': 'all', 'login_required': True, 'roles_required': ['admin']}, {'verb': 'get', 'login_required': False}, {'verb': 'list', 'login_required': False}, {'verb': 'table', 'login_required': False}, {'verb': 'search', 'login_required': False}], 'columns': [{'name': 'filename', '_type': 'db.UnicodeText'}, {'name': 'title', '_type': 'db.UnicodeText'}, {'name': 'body', 'type': 'long_text', '_type': 'db.UnicodeText'}, {'name': 'tag', 'type': 'relationship', 'multiple': True, 'secondary': {'name': 'blog_post__tag', 'columns': [{'name': 'blog_post'}, {'name': 'tag'}]}, '_type': 'relationship'}, {'name': 'created_dt', '_type': 'db.UnicodeText'}, {'name': 'updated_dt', '_type': 'db.UnicodeText'}], 'display': {'primary': 'title', 'secondary': 'created_dt'}, '_secondaries': [{'name': 'blog_post__tag', 'columns': [{'name': 'blog_post'}, {'name': 'tag'}]}], '_verbs': {'get': {'per_item': 'True', 'methods': [
'GET'], 'is_login_required': False, 'the_roles_required': []}, 'list': {'per_item': 'False', 'methods': ['GET'], 'is_login_required': False, 'the_roles_required': []}, 'table': {'per_item': 'False', 'methods': ['GET'], 'is_login_required': False, 'the_roles_required': []}, 'search': {'per_item': 'False', 'methods': ['GET'], 'is_login_required': False, 'the_roles_required': []}, 'create': {'per_item': 'False', 'methods': ['GET', 'POST'], 'is_login_required': True, 'the_roles_required': ['admin']}, 'update': {'per_item': 'True', 'methods': ['GET', 'POST'], 'is_login_required': True, 'the_roles_required': ['admin']}, 'delete': {'per_item': 'True', 'methods': ['GET', 'POST'], 'is_login_required': True, 'the_roles_required': ['admin']}}, 'acls': {'get': {'authn': False, 'authz': []}, 'list': {'authn': False, 'authz': []}, 'table': {'authn': False, 'authz': []}, 'search': {'authn': False, 'authz': []}, 'create': {'authn': True, 'authz': ['admin']}, 'update': {'authn': True, 'authz': ['admin']}, 'delete': {'authn': True, 'authz': ['admin']}}})
blog_post = ModelView(app, BlogPost)
blog_post.register_verb(view_context=get_view_context,
verb="get",

View File

@ -0,0 +1,74 @@
"""
!!!AUTOGENERATED: DO NOT EDIT!!!
Edit the hooks in webapp/routes/permission_hooks.py instead
"""
from flask import render_template
from flask_security import login_required
from oshipka.webapp import app
from oshipka.webapp.views import ModelView
from webapp.routes.permission_hooks import *
from webapp.models import Permission
permission = ModelView(app, Permission, {'name': 'Permission', 'access': [{'verb': 'all', 'login_required': True}], 'columns': [{'name': 'subject', '_type': 'db.UnicodeText'}, {'name': 'subject_id', 'type': 'int', '_type': 'db.Integer'}, {'name': 'action', '_type': 'db.UnicodeText'}, {'name': 'object', '_type': 'db.UnicodeText'}, {'name': 'object_id', 'type': 'int', '_type': 'db.Integer'}, {'name': 'is_allowed', 'type': 'boolean', '_type': 'LiberalBoolean'}], 'display': {'primary': 'subject', 'secondary': 'action', 'tertiary': 'object'}, '_verbs': {'get': {'per_item': 'True', 'methods': ['GET'], 'is_login_required': True, 'the_roles_required': []}, 'list': {'per_item': 'False', 'methods': ['GET'], 'is_login_required': True, 'the_roles_required': []}, 'table': {'per_item': 'False', 'methods': [
'GET'], 'is_login_required': True, 'the_roles_required': []}, 'search': {'per_item': 'False', 'methods': ['GET'], 'is_login_required': True, 'the_roles_required': []}, 'create': {'per_item': 'False', 'methods': ['GET', 'POST'], 'is_login_required': True, 'the_roles_required': []}, 'update': {'per_item': 'True', 'methods': ['GET', 'POST'], 'is_login_required': True, 'the_roles_required': []}, 'delete': {'per_item': 'True', 'methods': ['GET', 'POST'], 'is_login_required': True, 'the_roles_required': []}}, 'acls': {'get': {'authn': True, 'authz': []}, 'list': {'authn': True, 'authz': []}, 'table': {'authn': True, 'authz': []}, 'search': {'authn': True, 'authz': []}, 'create': {'authn': True, 'authz': []}, 'update': {'authn': True, 'authz': []}, 'delete': {'authn': True, 'authz': []}}})
permission.register_verb(view_context=get_view_context,
verb="get",
methods=['GET'],
per_item=True,
is_login_required=True,
the_roles_required=[],
)
permission.register_verb(view_context=list_view_context,
verb="list",
methods=['GET'],
per_item=False,
is_login_required=True,
the_roles_required=[],
)
permission.register_verb(view_context=table_view_context,
verb="table",
methods=['GET'],
per_item=False,
is_login_required=True,
the_roles_required=[],
)
permission.register_verb(view_context=search_view_context,
verb="search",
methods=['GET'],
per_item=False,
is_login_required=True,
the_roles_required=[],
)
permission.register_verb(view_context=create_view_context,
verb="create",
methods=['GET', 'POST'],
per_item=False,
is_login_required=True,
the_roles_required=[],
)
permission.register_verb(view_context=update_view_context,
verb="update",
methods=['GET', 'POST'],
per_item=True,
is_login_required=True,
the_roles_required=[],
)
permission.register_verb(view_context=delete_view_context,
verb="delete",
methods=['GET', 'POST'],
per_item=True,
is_login_required=True,
the_roles_required=[],
)

View File

@ -0,0 +1,71 @@
from oshipka.webapp.views import ViewContext, default_get_args_func, default_get_func, default_list_func, \
default_get_form_func, default_create_func, default_update_func, default_delete_func, default_search_func
def get_template(vc):
vc.template = "{}/get.html".format(vc.model_view.model_name)
def list_template(vc):
vc.template = "{}/list.html".format(vc.model_view.model_name)
def table_template(vc):
vc.template = "{}/table.html".format(vc.model_view.model_name)
def search_template(vc):
vc.template = "{}/search.html".format(vc.model_view.model_name)
def create_template(vc):
vc.template = "{}/create.html".format(vc.model_view.model_name)
def update_template(vc):
vc.template = "{}/update.html".format(vc.model_view.model_name)
def delete_template(vc):
vc.template = "delete_instance.html".format(vc.model_view.model_name)
get_view_context = ViewContext(
filter_func=default_get_func,
template_func=get_template,
)
list_view_context = ViewContext(
filter_func=default_list_func,
template_func=list_template,
)
table_view_context = ViewContext(
filter_func=default_list_func,
template_func=table_template,
)
search_view_context = ViewContext(
filter_func=default_search_func,
template_func=list_template,
)
create_view_context = ViewContext(
args_get_func=default_get_form_func,
template_func=create_template,
execute_func=default_create_func,
)
update_view_context = ViewContext(
args_get_func=default_get_form_func,
filter_func=default_get_func,
template_func=update_template,
execute_func=default_update_func,
)
delete_view_context = ViewContext(
args_get_func=default_get_form_func,
filter_func=default_get_func,
template_func=delete_template,
execute_func=default_delete_func,
)

View File

@ -4,12 +4,18 @@
Edit the hooks in webapp/routes/tag_hooks.py instead
"""
from flask import render_template
from flask_security import login_required
from oshipka.webapp import app
from oshipka.webapp.views import ModelView
from webapp.models import Tag
from webapp.routes.tag_hooks import *
from webapp.models import Tag
tag = ModelView(app, Tag, {'name': 'Tag', 'inherits': ['Ownable'], 'access': [{'verb': 'all', 'login_required': True, 'roles_required': ['admin']}, {'verb': 'get', 'login_required': False}, {'verb': 'list', 'login_required': False}, {'verb': 'table', 'login_required': False}, {'verb': 'search', 'login_required': False}], 'columns': [{'name': 'name', '_type': 'db.UnicodeText'}], 'display': {'primary': 'name'}, '_verbs': {'get': {'per_item': 'True', 'methods': ['GET'], 'is_login_required': False, 'the_roles_required': []}, 'list': {'per_item': 'False', 'methods': ['GET'], 'is_login_required': False, 'the_roles_required': []}, 'table': {'per_item': 'False', 'methods': ['GET'], 'is_login_required': False, 'the_roles_required': []}, 'search': {
'per_item': 'False', 'methods': ['GET'], 'is_login_required': False, 'the_roles_required': []}, 'create': {'per_item': 'False', 'methods': ['GET', 'POST'], 'is_login_required': True, 'the_roles_required': ['admin']}, 'update': {'per_item': 'True', 'methods': ['GET', 'POST'], 'is_login_required': True, 'the_roles_required': ['admin']}, 'delete': {'per_item': 'True', 'methods': ['GET', 'POST'], 'is_login_required': True, 'the_roles_required': ['admin']}}, 'acls': {'get': {'authn': False, 'authz': []}, 'list': {'authn': False, 'authz': []}, 'table': {'authn': False, 'authz': []}, 'search': {'authn': False, 'authz': []}, 'create': {'authn': True, 'authz': ['admin']}, 'update': {'authn': True, 'authz': ['admin']}, 'delete': {'authn': True, 'authz': ['admin']}}})
tag = ModelView(app, Tag)
tag.register_verb(view_context=get_view_context,
verb="get",

View File

@ -0,0 +1,3 @@
{% if has_permission('blog_post', 'create') %}
<a href="{{ url_for('create_blog_post') }}">{{ _("Create") }}</a>
{% endif %}

View File

@ -1 +1,3 @@
{% if has_permission('blog_post', 'delete', instance) %}
<a href="{{ url_for('delete_blog_post', uuid=instance.id, _next=request.path) }}">x</a>
{% endif %}

View File

@ -1 +1,3 @@
{% if has_permission('blog_post', 'update', instance) %}
<a href="{{ url_for('update_blog_post', uuid=instance.id, _next=request.path) }}">e</a>
{% endif %}

View File

@ -0,0 +1,3 @@
{% if has_permission('blog_post', 'list') %}
<a href="{{ url_for('list_blog_post') }}">{{ _("list") }}</a>
{% endif %}

View File

@ -0,0 +1,6 @@
{% if has_permission('blog_post', 'search') %}
<form action="{{ url_for('search_blog_post') }}">
<input type="text" name="q" value="{{ request.args.q }}" placeholder="search BlogPosts">
<input type="submit">
</form>
{% endif %}

View File

@ -0,0 +1,3 @@
{% if has_permission('blog_post', 'table') %}
<a href="{{ url_for('table_blog_post') }}">{{ _("table") }}</a>
{% endif %}

View File

@ -1,4 +1,7 @@
[
{% include "blog_post/_action_edit.html" %} |
{% include "blog_post/_action_delete.html" %}
]
{% if not has_permission('blog_post', 'update', instance) and not has_permission('blog_post', 'delete', instance) %}
{% else %}
[
{% include "blog_post/_action_edit.html" %} |
{% include "blog_post/_action_delete.html" %}
]
{% endif %}

View File

@ -0,0 +1,2 @@
{% include "blog_post/_action_list.html" %} |
{% include "blog_post/_action_table.html" %}

View File

@ -1,4 +1,5 @@
<form action="{{ url_for('create_blog_post') }}" method="post">
<form action="{{ url_for('create_blog_post') }}" method="post" enctype="multipart/form-data">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<input type="hidden" name="_next" value="{{ _next or request.args.get('_next') or url_for('list_blog_post') }}"/>
<table>
{% if "filename" not in disabled_columns %}

View File

@ -1,19 +1,59 @@
{% if has_permission("blog_post", "filename.read", instance) %}
{% if "filename" not in skip_list %}
<li id="display-blog_post-filename"><strong>{{ _("filename") }}</strong>: {{ instance.filename }}</li>
<li id="display-blog_post-filename"><strong>{{ _("filename") }}</strong>:
{% if not instance.filename %}{% else %}
{{ instance.filename }}
</li>
{% endif %}
{% endif %}
{% endif %}
{% if has_permission("blog_post", "title.read", instance) %}
{% if "title" not in skip_list %}
<li id="display-blog_post-title"><strong>{{ _("title") }}</strong>: {{ instance.title }}</li>
<li id="display-blog_post-title"><strong>{{ _("title") }}</strong>:
{% if not instance.title %}{% else %}
{{ instance.title }}
</li>
{% endif %}
{% endif %}
{% endif %}
{% if has_permission("blog_post", "body.read", instance) %}
{% if "body" not in skip_list %}
<li id="display-blog_post-body"><strong>{{ _("body") }}</strong>: {{ instance.body }}</li>
<li id="display-blog_post-body"><strong>{{ _("body") }}</strong>:
{% if not instance.body %}{% else %}
{{ instance.body }}
</li>
{% endif %}
{% endif %}
{% endif %}
{% if has_permission("blog_post", "tag.read", instance) %}
{% if "tag" not in skip_list %}
<li id="display-blog_post-tag"><strong>{{ _("tags") }}</strong>: {{ instance.tags }}</li>
<li id="display-blog_post-tag"><strong>{{ _("tags") }}</strong>:
{% if not instance.tags %}{% else %}
<ul>
{% for instance in instance.tags %}
{% include "tag/_list_item.html" %}
{% endfor %}
</ul>
</li>
{% endif %}
{% endif %}
{% endif %}
{% if has_permission("blog_post", "created_dt.read", instance) %}
{% if "created_dt" not in skip_list %}
<li id="display-blog_post-created_dt"><strong>{{ _("created_dt") }}</strong>: {{ instance.created_dt }}</li>
<li id="display-blog_post-created_dt"><strong>{{ _("created_dt") }}</strong>:
{% if not instance.created_dt %}{% else %}
{{ instance.created_dt }}
</li>
{% endif %}
{% endif %}
{% endif %}
{% if has_permission("blog_post", "updated_dt.read", instance) %}
{% if "updated_dt" not in skip_list %}
<li id="display-blog_post-updated_dt"><strong>{{ _("updated_dt") }}</strong>: {{ instance.updated_dt }}</li>
<li id="display-blog_post-updated_dt"><strong>{{ _("updated_dt") }}</strong>:
{% if not instance.updated_dt %}{% else %}
{{ instance.updated_dt }}
</li>
{% endif %}
{% endif %}
{% endif %}

View File

@ -0,0 +1,8 @@
{% if has_permission('blog_post', 'get') %}
<a href="{{ url_for('get_blog_post', uuid=instance.id) }}">
{% endif %}
{% include "blog_post/_title.html" %}
{% if has_permission('blog_post', 'get') %}
</a>
{% endif %}
{% include "blog_post/_actions.html" %}

View File

@ -1,3 +1,6 @@
{% for instance in instances %}
{% include "blog_post/_list_item.html" %}
{% endfor %}
<br>
{% import "_macros.html" as m %}
{{ m.render_pagination(pagination, 'list_blog_post') }}

View File

@ -1,14 +1,3 @@
<li>
<a href="{{ url_for('get_blog_post', uuid=instance.id) }}">
{% include "blog_post/_title.html" %}</a>
{% include "blog_post/_actions.html" %}
{% if instance.tags %}
<ul>
<li>
<small><i>{{ _("Tags") }}: {% for tag in instance.tags %}
<a href="{{ url_for('get_tag', uuid=tag.id) }}">{{ tag.name }}</a>{% if not loop.last %},
{% endif %} {% endfor %}</i></small><br>
</li>
</ul>
{% endif %}
{% include "blog_post/_item.html" %}
</li>

View File

@ -3,9 +3,6 @@
<a href="{{ url_for('get_blog_post', uuid=instance.id) }}">
{% include "blog_post/_title.html" %}</a>
|
[
<a href="{{ url_for('update_blog_post', uuid=instance.id) }}">e</a> |
<a href="{{ url_for('delete_blog_post', uuid=instance.id) }}">x</a>
]
{% include "blog_post/_actions.html" %}
</li>
{% endfor %}

View File

@ -56,8 +56,7 @@
</td>
{% endif %}
<td>
<a href="{{ url_for('update_blog_post', uuid=instance.id, _next=request.path) }}">e</a> |
<a href="{{ url_for('delete_blog_post', uuid=instance.id, _next=request.path) }}">x</a>
{% include "blog_post/_actions.html" %}
</td>
</tr>
{% endfor %}

View File

@ -1,4 +1,5 @@
<form action="{{ url_for('update_blog_post', uuid=instance.id) }}" method="post">
<form action="{{ url_for('update_blog_post', uuid=instance.id) }}" method="post" enctype="multipart/form-data">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<input type="hidden" name="_next" value="{{ _next or request.args.get('_next') or url_for('get_blog_post', uuid=instance.id) }}"/>
<table>
{% if "filename" not in disabled_columns %}

View File

@ -0,0 +1,10 @@
<a href="{{ url_for('home') }}">{{ _("Home") }}</a> |
<div class="pull-right">
{% if current_user.is_authenticated %}
<a href="{{ config.SSO_BASE_URL }}">{{ current_user.username }}</a> |
<a href="{{ url_for('security.logout') }}">{{ _("Logout") }}</a> |
{% else %}
<a href="{{ url_for('security.login') }}">{{ _("Login SSO") }}</a>
{% endif %}
</div>

View File

@ -1,9 +1,10 @@
<a href="{{ url_for('home') }}">{{ _("PiSquared Blog") }}</a> |
<a href="{{ url_for('index') }}">{{ _("Index") }}</a> |
<a href="{{ url_for('list_tag') }}">{{ _("Tags") }}</a> |
<a href="{{ url_for('rss') }}">{{ _("RSS") }}</a> |
<a href="{{ url_for('aboutme') }}">{{ _("About Me") }}</a>
<a href="{{ url_for('home') }}">{{ _("Home") }}</a> |
{% if current_user.is_authenticated %}
| <a href="{{ url_for('list_blog_post') }}" style="background-color: red;">{{ _("Admin") }}</a>
{% endif %}
<div class="pull-right">
{% if current_user.is_authenticated %}
<a href="{{ config.SSO_BASE_URL }}">{{ current_user.username }}</a> |
<a href="{{ url_for('security.logout') }}">{{ _("Logout") }}</a> |
{% else %}
<a href="{{ url_for('security.login') }}">{{ _("Login SSO") }}</a>
{% endif %}
</div>

View File

@ -0,0 +1,3 @@
{% if has_permission('permission', 'create') %}
<a href="{{ url_for('create_permission') }}">{{ _("Create") }}</a>
{% endif %}

View File

@ -0,0 +1,3 @@
{% if has_permission('permission', 'delete', instance) %}
<a href="{{ url_for('delete_permission', uuid=instance.id, _next=request.path) }}">x</a>
{% endif %}

View File

@ -0,0 +1,3 @@
{% if has_permission('permission', 'update', instance) %}
<a href="{{ url_for('update_permission', uuid=instance.id, _next=request.path) }}">e</a>
{% endif %}

View File

@ -0,0 +1,3 @@
{% if has_permission('permission', 'list') %}
<a href="{{ url_for('list_permission') }}">{{ _("list") }}</a>
{% endif %}

View File

@ -0,0 +1,6 @@
{% if has_permission('permission', 'search') %}
<form action="{{ url_for('search_permission') }}">
<input type="text" name="q" value="{{ request.args.q }}" placeholder="search Permissions">
<input type="submit">
</form>
{% endif %}

View File

@ -0,0 +1,3 @@
{% if has_permission('permission', 'table') %}
<a href="{{ url_for('table_permission') }}">{{ _("table") }}</a>
{% endif %}

View File

@ -0,0 +1,7 @@
{% if not has_permission('permission', 'update', instance) and not has_permission('permission', 'delete', instance) %}
{% else %}
[
{% include "permission/_action_edit.html" %} |
{% include "permission/_action_delete.html" %}
]
{% endif %}

View File

@ -0,0 +1,2 @@
{% include "permission/_action_list.html" %} |
{% include "permission/_action_table.html" %}

View File

@ -0,0 +1,62 @@
<form action="{{ url_for('create_permission') }}" method="post" enctype="multipart/form-data">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<input type="hidden" name="_next" value="{{ _next or request.args.get('_next') or url_for('list_permission') }}"/>
<table>
{% if "subject" not in disabled_columns %}
<tr {% if "subject" in hidden_columns %}style="display: none;"{% endif %}><td>
<label for="input-permission-subject">{{ _("subject") }}</label>:
</td><td>
<input id="input-permission-subject"
type="text" name="subject" autocomplete="off"
/>
</td></tr>
{% endif %}
{% if "subject_id" not in disabled_columns %}
<tr {% if "subject_id" in hidden_columns %}style="display: none;"{% endif %}><td>
<label for="input-permission-subject_id">{{ _("subject_id") }}</label>:
</td><td>
<input id="input-permission-subject_id"
type="number" name="subject_id"
/>
</td></tr>
{% endif %}
{% if "action" not in disabled_columns %}
<tr {% if "action" in hidden_columns %}style="display: none;"{% endif %}><td>
<label for="input-permission-action">{{ _("action") }}</label>:
</td><td>
<input id="input-permission-action"
type="text" name="action" autocomplete="off"
/>
</td></tr>
{% endif %}
{% if "object" not in disabled_columns %}
<tr {% if "object" in hidden_columns %}style="display: none;"{% endif %}><td>
<label for="input-permission-object">{{ _("object") }}</label>:
</td><td>
<input id="input-permission-object"
type="text" name="object" autocomplete="off"
/>
</td></tr>
{% endif %}
{% if "object_id" not in disabled_columns %}
<tr {% if "object_id" in hidden_columns %}style="display: none;"{% endif %}><td>
<label for="input-permission-object_id">{{ _("object_id") }}</label>:
</td><td>
<input id="input-permission-object_id"
type="number" name="object_id"
/>
</td></tr>
{% endif %}
{% if "is_allowed" not in disabled_columns %}
<tr {% if "is_allowed" in hidden_columns %}style="display: none;"{% endif %}><td>
<label for="input-permission-is_allowed">{{ _("is_allowed") }}</label>:
</td><td>
<input type="hidden" name="_is_allowed" value="0" />
<input id="input-permission-is_allowed"
type="checkbox" value="1" name="_is_allowed"
/>
</td></tr>
{% endif %}
</table>
<input type="submit">
</form>

View File

@ -0,0 +1,53 @@
{% if has_permission("permission", "subject.read", instance) %}
{% if "subject" not in skip_list %}
<li id="display-permission-subject"><strong>{{ _("subject") }}</strong>:
{% if not instance.subject %}{% else %}
{{ instance.subject }}
</li>
{% endif %}
{% endif %}
{% endif %}
{% if has_permission("permission", "subject_id.read", instance) %}
{% if "subject_id" not in skip_list %}
<li id="display-permission-subject_id"><strong>{{ _("subject_id") }}</strong>:
{% if not instance.subject_id %}{% else %}
{{ instance.subject_id }}
</li>
{% endif %}
{% endif %}
{% endif %}
{% if has_permission("permission", "action.read", instance) %}
{% if "action" not in skip_list %}
<li id="display-permission-action"><strong>{{ _("action") }}</strong>:
{% if not instance.action %}{% else %}
{{ instance.action }}
</li>
{% endif %}
{% endif %}
{% endif %}
{% if has_permission("permission", "object.read", instance) %}
{% if "object" not in skip_list %}
<li id="display-permission-object"><strong>{{ _("object") }}</strong>:
{% if not instance.object %}{% else %}
{{ instance.object }}
</li>
{% endif %}
{% endif %}
{% endif %}
{% if has_permission("permission", "object_id.read", instance) %}
{% if "object_id" not in skip_list %}
<li id="display-permission-object_id"><strong>{{ _("object_id") }}</strong>:
{% if not instance.object_id %}{% else %}
{{ instance.object_id }}
</li>
{% endif %}
{% endif %}
{% endif %}
{% if has_permission("permission", "is_allowed.read", instance) %}
{% if "is_allowed" not in skip_list %}
<li id="display-permission-is_allowed"><strong>{{ _("is_allowed") }}</strong>:
{{ instance.is_allowed|bool }}
</li>
{% endif %}
{% endif %}

View File

@ -0,0 +1,8 @@
{% if has_permission('permission', 'get') %}
<a href="{{ url_for('get_permission', uuid=instance.id) }}">
{% endif %}
{% include "permission/_title.html" %}
{% if has_permission('permission', 'get') %}
</a>
{% endif %}
{% include "permission/_actions.html" %}

View File

@ -0,0 +1,6 @@
{% for instance in instances %}
{% include "permission/_list_item.html" %}
{% endfor %}
<br>
{% import "_macros.html" as m %}
{{ m.render_pagination(pagination, 'list_permission') }}

View File

@ -0,0 +1,3 @@
<li>
{% include "permission/_item.html" %}
</li>

View File

@ -0,0 +1,8 @@
{% for instance in instances %}
<li>
<a href="{{ url_for('get_permission', uuid=instance.id) }}">
{% include "permission/_title.html" %}</a>
|
{% include "permission/_actions.html" %}
</li>
{% endfor %}

View File

@ -0,0 +1,64 @@
<table class="full-width data-table">
<thead>
<tr>
{% if "subject" not in skip_columns %}
<th>{{ _("subject") }}</th>
{% endif %}
{% if "subject_id" not in skip_columns %}
<th>{{ _("subject_id") }}</th>
{% endif %}
{% if "action" not in skip_columns %}
<th>{{ _("action") }}</th>
{% endif %}
{% if "object" not in skip_columns %}
<th>{{ _("object") }}</th>
{% endif %}
{% if "object_id" not in skip_columns %}
<th>{{ _("object_id") }}</th>
{% endif %}
{% if "is_allowed" not in skip_columns %}
<th>{{ _("is_allowed") }}</th>
{% endif %}
<th>{{ _("Actions") }}</th>
</tr>
</thead>
<tbody>
{% for instance in instances %}
<tr>
{% if "subject" not in skip_columns %}
<td>
{{ instance.subject }}
</td>
{% endif %}
{% if "subject_id" not in skip_columns %}
<td>
{{ instance.subject_id }}
</td>
{% endif %}
{% if "action" not in skip_columns %}
<td>
{{ instance.action }}
</td>
{% endif %}
{% if "object" not in skip_columns %}
<td>
{{ instance.object }}
</td>
{% endif %}
{% if "object_id" not in skip_columns %}
<td>
{{ instance.object_id }}
</td>
{% endif %}
{% if "is_allowed" not in skip_columns %}
<td>
{{ instance.is_allowed }}
</td>
{% endif %}
<td>
{% include "permission/_actions.html" %}
</td>
</tr>
{% endfor %}
</tbody>
</table>

View File

@ -0,0 +1,4 @@
{{ instance.subject }}
- {{ instance.action }}
- {{ instance.object }}

View File

@ -0,0 +1,68 @@
<form action="{{ url_for('update_permission', uuid=instance.id) }}" method="post" enctype="multipart/form-data">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<input type="hidden" name="_next" value="{{ _next or request.args.get('_next') or url_for('get_permission', uuid=instance.id) }}"/>
<table>
{% if "subject" not in disabled_columns %}
<tr {% if "subject" in hidden_columns %}style="display: none;"{% endif %}><td>
<label for="input-permission-subject">{{ _("subject") }}</label>:
</td><td>
<input id="input-permission-subject"
value="{{ instance.subject }}"
type="text" name="subject" autocomplete="off"
/>
</td></tr>
{% endif %}
{% if "subject_id" not in disabled_columns %}
<tr {% if "subject_id" in hidden_columns %}style="display: none;"{% endif %}><td>
<label for="input-permission-subject_id">{{ _("subject_id") }}</label>:
</td><td>
<input id="input-permission-subject_id"
value="{{ instance.subject_id }}"
type="number" name="subject_id"
/>
</td></tr>
{% endif %}
{% if "action" not in disabled_columns %}
<tr {% if "action" in hidden_columns %}style="display: none;"{% endif %}><td>
<label for="input-permission-action">{{ _("action") }}</label>:
</td><td>
<input id="input-permission-action"
value="{{ instance.action }}"
type="text" name="action" autocomplete="off"
/>
</td></tr>
{% endif %}
{% if "object" not in disabled_columns %}
<tr {% if "object" in hidden_columns %}style="display: none;"{% endif %}><td>
<label for="input-permission-object">{{ _("object") }}</label>:
</td><td>
<input id="input-permission-object"
value="{{ instance.object }}"
type="text" name="object" autocomplete="off"
/>
</td></tr>
{% endif %}
{% if "object_id" not in disabled_columns %}
<tr {% if "object_id" in hidden_columns %}style="display: none;"{% endif %}><td>
<label for="input-permission-object_id">{{ _("object_id") }}</label>:
</td><td>
<input id="input-permission-object_id"
value="{{ instance.object_id }}"
type="number" name="object_id"
/>
</td></tr>
{% endif %}
{% if "is_allowed" not in disabled_columns %}
<tr {% if "is_allowed" in hidden_columns %}style="display: none;"{% endif %}><td>
<label for="input-permission-is_allowed">{{ _("is_allowed") }}</label>:
</td><td>
<input type="hidden" name="_is_allowed" value="0" />
<input id="input-permission-is_allowed"
type="checkbox" name="_is_allowed" {% if instance.is_allowed %}checked=checked{% endif %}
value="1"
/>
</td></tr>
{% endif %}
</table>
<input type="submit">
</form>

View File

@ -0,0 +1,6 @@
{% extends "layout.html" %}
{% block content %}
<h2>{{ _("Create") }} {{_("Permission") }}</h2>
{% include "permission/_create.html" %}
{% endblock %}

View File

@ -0,0 +1,8 @@
{% extends "layout.html" %}
{% block content %}
{% include "permission/_actions_multiple.html" %}
<h2>{% include "permission/_title.html" %}</h2>
{% include "permission/_actions.html" %}
{% include "permission/_get.html" %}
{% endblock %}

View File

@ -0,0 +1,10 @@
{% extends "layout.html" %}
{% block content %}
<h2>{{ _("Permissions") }}</h2>
{% include "permission/_action_create.html" %} |
{% include "permission/_action_table.html" %}
{% include "permission/_action_search.html" %}
<br>
{% include "permission/_list.html" %}
{% endblock %}

View File

@ -0,0 +1,10 @@
<a href="{{ url_for('home') }}">{{ _("Home") }}</a> |
<div class="pull-right">
{% if current_user.is_authenticated %}
<a href="{{ config.SSO_BASE_URL }}">{{ current_user.username }}</a> |
<a href="{{ url_for('security.logout') }}">{{ _("Logout") }}</a> |
{% else %}
<a href="{{ url_for('security.login') }}">{{ _("Login SSO") }}</a>
{% endif %}
</div>

View File

@ -0,0 +1,8 @@
{% extends "layout.html" %}
{% block content %}
<h2>{{ _("Search results for") }} {{ _("Permissions") }}</h2>
<a href="{{ url_for('create_permission') }}">{{ _("Create") }}</a>
<br>
{% include "permission/_search.html" %}
{% endblock %}

View File

@ -0,0 +1,8 @@
{% extends "layout.html" %}
{% block content %}
<h2>{{ _("Permissions") }}</h2>
{% include "permission/_action_create.html" %}
<br>
{% include "permission/_table.html" %}
{% endblock %}

View File

@ -0,0 +1,6 @@
{% extends "layout.html" %}
{% block content %}
<h2>{{ _("Edit") }} {% include "permission/_title.html" %}</h2>
{% include "permission/_update.html" %}
{% endblock %}

View File

@ -0,0 +1,3 @@
{% if has_permission('tag', 'create') %}
<a href="{{ url_for('create_tag') }}">{{ _("Create") }}</a>
{% endif %}

View File

@ -1 +1,3 @@
{% if has_permission('tag', 'delete', instance) %}
<a href="{{ url_for('delete_tag', uuid=instance.id, _next=request.path) }}">x</a>
{% endif %}

View File

@ -1 +1,3 @@
{% if has_permission('tag', 'update', instance) %}
<a href="{{ url_for('update_tag', uuid=instance.id, _next=request.path) }}">e</a>
{% endif %}

View File

@ -0,0 +1,3 @@
{% if has_permission('tag', 'list') %}
<a href="{{ url_for('list_tag') }}">{{ _("list") }}</a>
{% endif %}

View File

@ -0,0 +1,6 @@
{% if has_permission('tag', 'search') %}
<form action="{{ url_for('search_tag') }}">
<input type="text" name="q" value="{{ request.args.q }}" placeholder="search Tags">
<input type="submit">
</form>
{% endif %}

View File

@ -0,0 +1,3 @@
{% if has_permission('tag', 'table') %}
<a href="{{ url_for('table_tag') }}">{{ _("table") }}</a>
{% endif %}

View File

@ -1,4 +1,7 @@
[
{% include "tag/_action_edit.html" %} |
{% include "tag/_action_delete.html" %}
]
{% if not has_permission('tag', 'update', instance) and not has_permission('tag', 'delete', instance) %}
{% else %}
[
{% include "tag/_action_edit.html" %} |
{% include "tag/_action_delete.html" %}
]
{% endif %}

View File

@ -0,0 +1,2 @@
{% include "tag/_action_list.html" %} |
{% include "tag/_action_table.html" %}

View File

@ -1,4 +1,5 @@
<form action="{{ url_for('create_tag') }}" method="post">
<form action="{{ url_for('create_tag') }}" method="post" enctype="multipart/form-data">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<input type="hidden" name="_next" value="{{ _next or request.args.get('_next') or url_for('list_tag') }}"/>
<table>
{% if "name" not in disabled_columns %}

View File

@ -1,4 +1,10 @@
{% if has_permission("tag", "name.read", instance) %}
{% if "name" not in skip_list %}
<li id="display-tag-name"><strong>{{ _("name") }}</strong>: {{ instance.name }}</li>
<li id="display-tag-name"><strong>{{ _("name") }}</strong>:
{% if not instance.name %}{% else %}
{{ instance.name }}
</li>
{% endif %}
{% endif %}
{% endif %}

View File

@ -0,0 +1,8 @@
{% if has_permission('tag', 'get') %}
<a href="{{ url_for('get_tag', uuid=instance.id) }}">
{% endif %}
{% include "tag/_title.html" %}
{% if has_permission('tag', 'get') %}
</a>
{% endif %}
{% include "tag/_actions.html" %}

View File

@ -1,3 +1,6 @@
{% for instance in instances %}
{% include "tag/_list_item.html" %}
{% endfor %}
<br>
{% import "_macros.html" as m %}
{{ m.render_pagination(pagination, 'list_tag') }}

View File

@ -1,7 +1,3 @@
<li>
<a href="{{ url_for('get_tag', uuid=instance.id) }}">
{% include "tag/_title.html" %}</a> ({{ instance.blog_posts|count }})
{% if current_user.is_authenticated %}
{% include "tag/_actions.html" %}
{% endif %}
{% include "tag/_item.html" %}
</li>

View File

@ -3,9 +3,6 @@
<a href="{{ url_for('get_tag', uuid=instance.id) }}">
{% include "tag/_title.html" %}</a>
|
[
<a href="{{ url_for('update_tag', uuid=instance.id) }}">e</a> |
<a href="{{ url_for('delete_tag', uuid=instance.id) }}">x</a>
]
{% include "tag/_actions.html" %}
</li>
{% endfor %}

View File

@ -16,8 +16,7 @@
</td>
{% endif %}
<td>
<a href="{{ url_for('update_tag', uuid=instance.id, _next=request.path) }}">e</a> |
<a href="{{ url_for('delete_tag', uuid=instance.id, _next=request.path) }}">x</a>
{% include "tag/_actions.html" %}
</td>
</tr>
{% endfor %}

View File

@ -1,4 +1,5 @@
<form action="{{ url_for('update_tag', uuid=instance.id) }}" method="post">
<form action="{{ url_for('update_tag', uuid=instance.id) }}" method="post" enctype="multipart/form-data">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<input type="hidden" name="_next" value="{{ _next or request.args.get('_next') or url_for('get_tag', uuid=instance.id) }}"/>
<table>
{% if "name" not in disabled_columns %}

View File

@ -0,0 +1,10 @@
<a href="{{ url_for('home') }}">{{ _("Home") }}</a> |
<div class="pull-right">
{% if current_user.is_authenticated %}
<a href="{{ config.SSO_BASE_URL }}">{{ current_user.username }}</a> |
<a href="{{ url_for('security.logout') }}">{{ _("Logout") }}</a> |
{% else %}
<a href="{{ url_for('security.login') }}">{{ _("Login SSO") }}</a>
{% endif %}
</div>

View File

@ -1,7 +1,7 @@
name: BlogPost
searchable:
- body
interits:
inherits:
- Ownable
access:
- verb: all

View File

@ -0,0 +1,18 @@
name: Permission
access:
- verb: all
login_required: true
columns:
- name: subject
- name: subject_id
type: int
- name: action
- name: object
- name: object_id
type: int
- name: is_allowed
type: boolean
display:
primary: subject
secondary: action
tertiary: object

View File

@ -1,5 +1,5 @@
name: Tag
interits:
inherits:
- Ownable
access:
- verb: all