Skip to content

Commit e5cc50f

Browse files
committed
Vistas administrativas para Role y Permission
Prepara las vistas necesarias para la administración de permisos. Refs #3
1 parent e1849e4 commit e5cc50f

16 files changed

+352
-20
lines changed

Diff for: newswriter/__init__.py

+5-16
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,9 @@ def create_app(config='newswriter.config.Config'):
3939
"""Inicializar la aplicación"""
4040
if getattr(sys, 'frozen', False):
4141
# para pyinstaller
42-
# template_folder = os.path.join(sys._MEIPASS, 'templates')
43-
# static_folder = os.path.join(sys._MEIPASS, 'static')
4442
instance_path = os.path.join(os.path.expanduser("~"), "newswriter")
4543
app = Flask(
4644
__name__,
47-
# template_folder=template_folder,
48-
# static_folder=static_folder,
4945
instance_path=instance_path)
5046
app.config['PYINSTALLER'] = True
5147
else:
@@ -99,19 +95,22 @@ def create_app(config='newswriter.config.Config'):
9995
ma.init_app(app)
10096
menu.init_app(app)
10197
apifairy.init_app(app)
102-
# if app.config.get('CELERY_ENABLED'):
103-
# init_celery(celery, app)
10498

10599
# incluir modulos y rutas
106100
from newswriter.views.default import default
107101
from newswriter.views.users import users_bp
102+
from newswriter.views.admin import admin_role, admin_permissions
108103
from newswriter.searchcommands import cmd as search_cmd
109104
from newswriter.admin_commands import users_cmds
110105
from adelacommon.deploy import deploy_cmd
111106

112107
# registrar los blueprints
113108
app.register_blueprint(default)
114109
app.register_blueprint(users_bp)
110+
# admin crud
111+
app.register_blueprint(admin_role)
112+
app.register_blueprint(admin_permissions)
113+
# --
115114
app.register_blueprint(search_cmd)
116115
app.register_blueprint(users_cmds)
117116
app.register_blueprint(deploy_cmd)
@@ -145,13 +144,3 @@ def setupMenus():
145144

146145
return app
147146

148-
149-
# def init_celery(instance, app):
150-
# instance.conf.update(app.config)
151-
152-
# class ContextTask(instance.Task):
153-
# def __call__(self, *args, **kwargs):
154-
# with app.app_context():
155-
# return self.run(*args, **kwargs)
156-
157-
# instance.Task = ContextTask

Diff for: newswriter/models/security.py

+13
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
)
2020

2121

22+
@persistence_methods(db)
2223
class Role(db.Model):
2324
id = db.Column(db.String(32), primary_key=True, default=_gen_uuid)
2425
name = db.Column(db.String(80), unique=True)
@@ -45,6 +46,18 @@ def addPermission(self, name, record_id, model_name):
4546

4647
return p
4748

49+
def isPersonal(self) -> bool:
50+
return '_role' in self.name
51+
52+
def getUsername(self) -> str:
53+
"""Returns username for especial user roles"""
54+
if self.isPersonal() is False:
55+
raise ValueError
56+
57+
return User.query.filter_by(
58+
username=self.name.split("_role")[0]
59+
).first().username
60+
4861
@classmethod
4962
def getUserEspecialRole(cls, user: 'User') -> 'Role':
5063
return cls.query.filter_by(

Diff for: newswriter/templates/base_to_copy.html

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{% extends 'layout.html' %}
2+
3+
{% block page_title %}
4+
{% endblock %}
5+
6+
{% block content %}
7+
{% endblock %}

Diff for: newswriter/templates/default/index.html

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
{% extends 'layout.html' %}
22

3-
{% block page_title %}Mis trabajos{% endblock %}
3+
{% block page_title %}
4+
{% if is_personal %}Mis trabajos{% else %}Newswriter - {{ board.name }}{% endif %}
5+
{% endblock %}
46

57
{% block content %}
8+
9+
{% if not is_personal %}<h4><i class="material-icons">dashboard</i> {{ board.name }}</h4>{% endif %}
10+
611
<div class="works-list">
712

813
{% if results.total > 0 %}
@@ -41,9 +46,11 @@
4146
<span class="card-title center-align">
4247
No se encontró ningún artículo
4348
</span>
49+
{% if is_personal %}
4450
<div class="card-action">
4551
<a href="{{ url_for('default.write') }}">Escribir uno</a>
4652
</div>
53+
{% endif %}
4754
</div>
4855
</div>
4956
{% endif %}

Diff for: newswriter/templates/layout.html

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<head>
55
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
66
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0" />
7-
<title>{% block page_title %}Title{% endblock %} - Redacción</title>
7+
<title>{% block page_title %}Title{% endblock %} - NewsWriter</title>
88

99
<!-- CSS -->
1010
<link href="{{ static_url_for('static', filename='css/style.css') }}" type="text/css" rel="stylesheet"
@@ -29,10 +29,12 @@
2929
</a>
3030
</li>
3131
</ul>
32-
<a href="{{ url_for('default.index') }}" class="brand-logo center">Redacción</a>
32+
<a href="{{ url_for('default.index') }}" class="brand-logo center">NewsWriter</a>
3333
</div>
3434
</nav>
3535
</div>
36+
37+
{% block page_header %}{% endblock page_header %}
3638
</header>
3739

3840
<main>

Diff for: newswriter/templates/layout_breadcrumbs.html

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{% extends 'layout.html' %}
2+
3+
{% block page_header %}
4+
<nav>
5+
<div class="nav-wrapper">
6+
<div class="col s12 mx-2">
7+
{% block breadcrumbs %}
8+
<a href="{{ url_for('default.index') }}" class="breadcrumb">Inicio</a>
9+
{% endblock breadcrumbs%}
10+
</div>
11+
</div>
12+
</nav>
13+
{% endblock page_header %}

Diff for: newswriter/templates/permission/index.html

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{% extends 'layout.html' %}
2+
3+
{% block page_title %}Adminstración de permisos{% endblock %}
4+
5+
{% block content %}
6+
<h4>Listado de permisos</h4>
7+
8+
<table class="striped">
9+
<thead>
10+
<tr>
11+
<th>Permiso</th>
12+
<th>Rol / Ususario</th>
13+
<th>Modelo</th>
14+
<th>Objeto</th>
15+
</tr>
16+
</thead>
17+
<tbody>
18+
{% for p in permission_list %}
19+
<tr>
20+
<td>{{ p.name }}</td>
21+
{% if getRole(p.role_id).isPersonal() %}
22+
<td>{{ getRole(p.role_id).getUsername() }}</td>
23+
{% else %}
24+
<td>{{ getRole(p.role_id).name }}</td>
25+
{% endif %}
26+
<td>{{ p.model_name }}</td>
27+
<td>{{ p.record_id }}</td>
28+
</tr>
29+
{% endfor %}
30+
</tbody>
31+
</table>
32+
{% endblock %}

Diff for: newswriter/templates/role/create.html

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{% extends 'role/layout.html' %}
2+
{% from "_formhelpers.html" import render_field %}
3+
4+
{% block page_title %}
5+
Administración - Roles - Crear
6+
{% endblock %}
7+
8+
{% block content %}
9+
<div class="container">
10+
<div class="row">
11+
<h4 class="mb-5">Administración de Roles</h4>
12+
<p>Crear nuevo rol</p>
13+
14+
<form action="" method="post">
15+
{{ form.hidden_tag() }}
16+
<div class="row"> {{ render_field(form.name, 's12') }} </div>
17+
<div class="row"> {{ render_field(form.description, 's12') }} </div>
18+
<div class="row">
19+
<div class="input-field col s12">
20+
<button class="btn waves-effect waves-light" type="submit" name="action">
21+
Crear
22+
<i class="material-icons left">send</i>
23+
</button>
24+
</div>
25+
</div>
26+
</form>
27+
28+
</div>
29+
</div>
30+
31+
{% endblock %}

Diff for: newswriter/templates/role/delete.html

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{% extends 'role/layout.html' %}
2+
3+
{% block page_title %}
4+
Administración - Roles - Eliminar
5+
{% endblock %}
6+
7+
{% block breadcrumbs %}
8+
{{ super() }}
9+
<a href="{{ url_for('admin_role.delete', pk=role.id) }}" class="breadcrumb">Eliminar</a>
10+
{% endblock breadcrumbs %}
11+
12+
{% block content %}
13+
{{ super() }}
14+
<div class="container">
15+
<div class="row">
16+
<h4 class="mb-5">Administración de Roles</h4>
17+
<p>¿Esta seguro que quiere <strong>ELIMINAR</strong> el rol "{{ role.name }}"?</p>
18+
19+
<form action="" method="post">
20+
{{ form.hidden_tag() }}
21+
<div class="row">
22+
<div class="input-field col s12">
23+
<button class="btn red waves-effect waves-light" type="submit" name="action">
24+
Eliminar
25+
<i class="material-icons left">delete</i>
26+
</button>
27+
</div>
28+
</div>
29+
</form>
30+
31+
</div>
32+
</div>
33+
34+
{% endblock %}

Diff for: newswriter/templates/role/edit.html

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{% extends 'role/layout.html' %}
2+
3+
{% block page_title %}
4+
Administración - Roles - Editar
5+
{% endblock %}
6+
7+
{% block breadcrumbs %}
8+
{{ super() }}
9+
<a href="{{ url_for('admin_role.edit', pk=role.id) }}" class="breadcrumb">Editar</a>
10+
{% endblock breadcrumbs %}
11+
12+
{% block content %}
13+
{{ super() }}
14+
<div class="container">
15+
<div class="row">
16+
<h4 class="mb-5">Administración de Roles</h4>
17+
<p>Editar rol "{{ role.name }}"</p>
18+
19+
<form action="" method="post">
20+
{{ form.hidden_tag() }}
21+
<div class="row"> {{ render_field(form.name, 's12') }} </div>
22+
<div class="row"> {{ render_field(form.description, 's12') }} </div>
23+
<div class="row">
24+
<div class="input-field col s12">
25+
<button class="btn waves-effect waves-light" type="submit" name="action">
26+
Guardar
27+
<i class="material-icons left">save</i>
28+
</button>
29+
</div>
30+
</div>
31+
</form>
32+
33+
</div>
34+
</div>
35+
36+
{% endblock %}

Diff for: newswriter/templates/role/index.html

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{% extends 'role/layout.html' %}
2+
3+
{% block page_title %}
4+
Administración - Roles
5+
{% endblock %}
6+
7+
{% block content %}
8+
<h4>Administración de Roles</h4>
9+
10+
<a class="waves-effect waves-light btn" href="{{ url_for('admin_role.create') }}">
11+
<i class="material-icons left">add</i>
12+
Crear rol
13+
</a>
14+
15+
<table class="striped">
16+
<thead>
17+
<tr>
18+
<th>Rol</th>
19+
<th>Descripción</th>
20+
<th></th>
21+
<th></th>
22+
</tr>
23+
</thead>
24+
25+
<tbody>
26+
{% for role in role_list %}
27+
<tr>
28+
{% if role.isPersonal() %}
29+
<td>{{ role.getUsername() }}</td>
30+
{% else %}
31+
<td>{{ role.name }}</td>
32+
{% endif %}
33+
<td>{{ role.description }}</td>
34+
<td>
35+
{% if role.isPersonal() is false %}
36+
<a href="{{ url_for('admin_role.edit', pk=role.id) }}" class="waves-effect waves-light btn-small" title="Editar">
37+
<i class="material-icons">edit</i>
38+
</a>
39+
<a href="{{ url_for('admin_role.delete', pk=role.id) }}" class="waves-effect waves-light btn-small red" title="Eliminar">
40+
<i class="material-icons">delete</i>
41+
</a>
42+
{% endif %}
43+
</td>
44+
<td>
45+
<a class="waves-effect waves-light btn-small" title="Permisos">
46+
<i class="material-icons">security</i>
47+
</a>
48+
{% if role.isPersonal() is false %}
49+
<a class="waves-effect waves-light btn-small" title="Miembros">
50+
<i class="material-icons">people</i>
51+
</a>
52+
{% endif %}
53+
</td>
54+
</tr>
55+
{% endfor %}
56+
</ul>
57+
</tbody>
58+
</table>
59+
60+
61+
{% endblock %}

Diff for: newswriter/templates/role/layout.html

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{% extends 'layout_breadcrumbs.html' %}
2+
{% from "_formhelpers.html" import render_field %}
3+
4+
5+
{% block breadcrumbs %}
6+
{{ super() }}
7+
<a href="{{ url_for('admin_role.index') }}" class="breadcrumb">Roles</a>
8+
{% endblock breadcrumbs %}

Diff for: newswriter/views/admin/__init__.py

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
'''Vistas administrativas'''
2+
from newswriter.views.admin.roles import RoleDiced
3+
from newswriter.views.admin.permissions import PermissionDiced
4+
from flask import Blueprint
5+
6+
7+
admin_role = Blueprint('admin_role', __name__, url_prefix='/admin/role')
8+
admin_permissions = Blueprint('admin_perms', __name__, url_prefix='/admin/permission')
9+
RoleDiced().register(admin_role)
10+
PermissionDiced().register(admin_permissions)

Diff for: newswriter/views/admin/permissions.py

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
'''CRUD en permisos'''
2+
from newswriter.models import security
3+
from flask_diced import Diced
4+
5+
6+
class PermissionDiced(Diced):
7+
model = security.Permission
8+
9+
def index_view_context(self, context):
10+
def getRole(role_id: str) -> security.Role:
11+
return security.Role.query.get(role_id)
12+
13+
context['getRole'] = getRole
14+
return context

0 commit comments

Comments
 (0)