Skip to content

Commit 4e3141c

Browse files
committed
feat: rebocar permisos
1 parent c8c0f01 commit 4e3141c

File tree

6 files changed

+104
-12
lines changed

6 files changed

+104
-12
lines changed

Diff for: jsclient/src/controllers/permrow_controller.js

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { Controller } from "stimulus";
2+
3+
export default class extends Controller {
4+
5+
static targets = [ "removelink" ]
6+
static values = {
7+
csrf: String
8+
}
9+
10+
delete(event) {
11+
event.preventDefault();
12+
if (confirm('¿Rebocar este permiso?')) {
13+
// TODO: hacer un post al DICED para permisos
14+
var form = new FormData()
15+
form.append("csrf_token", this.csrfValue)
16+
17+
fetch( this.removelinkTarget, {
18+
method: "POST",
19+
body: form
20+
}).then(res => {
21+
if ( res.ok ) {
22+
res.json().then(data => {
23+
this.element.classList.add('hide')
24+
M.toast({
25+
html: data.message,
26+
classes: 'rounded yellow darken-4'
27+
})
28+
})
29+
} else {
30+
M.toast({
31+
html: 'No se pude rebocar el permiso',
32+
classes: 'rounded red darken-3'
33+
})
34+
}
35+
}).catch(error => {
36+
console.log(error)
37+
M.toast({
38+
html: 'Error en la petición',
39+
classes: 'rounded red darken-3'
40+
})
41+
})
42+
}
43+
}
44+
45+
}

Diff for: newswriter/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from flask_caching import Cache
99
from flask_static_digest import FlaskStaticDigest
1010
from flask_menu import register_menu, Menu
11+
from flask_wtf import CSRFProtect
1112
from apifairy import APIFairy
1213
from flask_marshmallow import Marshmallow
1314
# from celery import Celery
@@ -30,6 +31,7 @@
3031
flask_statics = FlaskStaticDigest()
3132
apifairy = APIFairy()
3233
ma = Marshmallow()
34+
csrf = CSRFProtect()
3335
# celery = Celery(__name__)
3436
# Breadcrumbs is a subclass of flask_menu.Menu
3537
menu = Menu()
@@ -94,6 +96,7 @@ def create_app(config='newswriter.config.Config'):
9496
flask_statics.init_app(app)
9597
ma.init_app(app)
9698
menu.init_app(app)
99+
csrf.init_app(app)
97100
apifairy.init_app(app)
98101

99102
# incluir modulos y rutas

Diff for: newswriter/models/permissions.py

+14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from newswriter.permissions import AdminRolNeed
22
from flask_principal import Permission, ItemNeed, Need
3+
from typing import Any, List
34

45
# Boards
56
LISTAR_CONTENIDO = 'listar::articulo'
@@ -47,3 +48,16 @@ class PonerArticulosPermission(Permission):
4748
def __init__(self, board_name):
4849
need = ItemNeed(PONER_CONTENIDO, board_name, 'board')
4950
super().__init__(need, AdminRolNeed, PonerArticulosNeed)
51+
52+
53+
class BoardPermissionHelpers(object):
54+
55+
@classmethod
56+
def getPermissionLabel(cls, k: str) -> str:
57+
return BOARD_PERMS_DESCRIPTIONS[k]
58+
59+
@classmethod
60+
def getFormChoices(cls) -> List[Any]:
61+
return [
62+
(k, cls.getPermissionLabel(k)) for k in BOARD_PERMS_DESCRIPTIONS
63+
]

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

+11-2
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,23 @@ <h4>Listado de permisos para {{ role.name }}</h4>
2525
<th>Permiso</th>
2626
<th>Modelo</th>
2727
<th>Objeto</th>
28+
<!-- operaciones -->
29+
<th></th>
2830
</tr>
2931
</thead>
3032
<tbody>
3133
{% for p in permission_list %}
32-
<tr>
33-
<td>{{ p.name }}</td>
34+
<tr data-controller="permrow" data-permrow-csrf-value="{{ csrf_token() }}">
35+
<td>{{ get_permission_label(p.name) }}</td>
3436
<td>{{ p.model_name }}</td>
3537
<td>{{ p.record_id }}</td>
38+
<td>
39+
<a data-permrow-target="removelink" href="{{ url_for('admin_perms.delete', pk=p.id) }}"
40+
class="waves-effect waves-light btn-small red" title="Revocar permiso"
41+
data-action="click->permrow#delete">
42+
<i class="material-icons">delete</i>
43+
</a>
44+
</td>
3645
</tr>
3746
{% endfor %}
3847
</tbody>

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

+30-10
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,73 @@
11
'''CRUD en permisos'''
2-
from wtforms import validators
32
from newswriter.models import security
4-
from newswriter.models import permissions as perms
3+
from newswriter.models.permissions import BoardPermissionHelpers
54
from flask_wtf import FlaskForm
6-
from wtforms import SelectField, StringField, HiddenField
5+
from wtforms import SelectField, StringField, HiddenField, SubmitField
76
from wtforms.validators import DataRequired
87
from flask_diced import Diced
98
from flask import url_for, render_template, flash, redirect
109

1110

12-
def _pl(k):
13-
return (k, perms.BOARD_PERMS_DESCRIPTIONS[k])
14-
15-
1611
class PermissionCreateForm(FlaskForm):
1712
name = SelectField(
18-
"Permiso", choices=[_pl(k) for k in perms.BOARD_PERMS_DESCRIPTIONS])
13+
"Permiso", choices=BoardPermissionHelpers.getFormChoices())
1914
model_name = SelectField(
2015
"Modelo", choices=[('board', 'Board')])
2116
record_id = StringField("Objeto")
2217
role_id = HiddenField("Role", validators=[DataRequired()])
2318

2419

20+
class RevokePermissionForm(FlaskForm):
21+
submit = SubmitField('Rebocar permiso')
22+
23+
2524
class PermissionDiced(Diced):
2625
model = security.Permission
27-
exclude_views = ('detail',)
26+
exclude_views = ('detail', 'edit')
2827

2928
# rules
3029
index_rule = '/<role_id>/'
3130
create_rule = '/<role_id>/create/'
31+
delete_rule = '/<pk>/delete/'
3232

3333
# forms
3434
create_form_class = PermissionCreateForm
35+
delete_form_class = RevokePermissionForm
3536

3637
# properties
3738

39+
# views
3840
def index_view(self, role_id):
3941
"""index view function"""
4042
role = security.Role.query.get_or_404(role_id)
4143
context = self.index_view_context({
4244
self.object_list_name: self.query_all(role),
43-
"role": role
45+
"role": role,
46+
"get_permission_label": BoardPermissionHelpers.getPermissionLabel
4447
})
4548
return render_template(self.index_template, **context)
4649

4750
def query_all(self, role: security.Role):
4851
"""returns all objects"""
4952
return role.permissions
5053

54+
def delete_view(self, pk):
55+
"""delete view function
56+
57+
:param pk:
58+
the primary key of the model to be deleted.
59+
"""
60+
obj = self.query_object(pk)
61+
form = self.delete_form_class(obj=obj)
62+
if form.validate_on_submit():
63+
obj.delete()
64+
message = self.delete_flash_message
65+
if message is None:
66+
message = self.object_name + ' deleted'
67+
return {"message": message}
68+
context = self.delete_view_context({self.delete_form_name: form})
69+
return render_template(self.delete_template, **context)
70+
5171
def create_view(self, role_id):
5272
"""create view function"""
5373
role = security.Role.query.get_or_404(role_id)

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

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class RoleCreateForm(FlaskForm):
1616
class RoleDeleteForm(FlaskForm):
1717
submit = SubmitField('Eliminar rol')
1818

19+
1920
class RevokeRoleForm(FlaskForm):
2021
submit = SubmitField('Quitar del grupo')
2122

0 commit comments

Comments
 (0)