Skip to content

Commit

Permalink
make custom action access control easier
Browse files Browse the repository at this point in the history
- init_object takes action kwarg, which drives action-specific init
- e.g. action "delete" would drive view method call "init_object_delete" if the object loads successfully
fixes #66
  • Loading branch information
guruofgentoo committed Jun 7, 2019
1 parent 794f320 commit 63921ee
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
16 changes: 16 additions & 0 deletions keg_auth/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,22 @@ def test_delete(self):

assert not self.user_ent.query.get(user_delete_id)

def test_delete_disallowed_by_action_init(self):
user_delete_id = ents.User.testing_create().id

def init_object_delete(self):
flask.abort(403)

from keg_auth import views
views.User.init_object_delete = init_object_delete

try:
self.client.get('/users/{}/delete'.format(user_delete_id), status=403)
finally:
del views.User.init_object_delete

self.client.get('/users/{}/delete'.format(user_delete_id), status=302)

def test_delete_with_session_key(self):
user_delete = ents.User.testing_create()

Expand Down
14 changes: 11 additions & 3 deletions keg_auth/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,24 +130,32 @@ def add_edit(self, meth, obj=None):
form=form
)

def init_object(self, obj_id):
def init_object(self, obj_id, action=None):
if obj_id is None:
flask.abort(400)
self.objinst = self.orm_cls.query.get(obj_id)
if not self.objinst:
flask.abort(404)
if action:
# Sometimes an action has particular requirements that are different from other actions.
# For instance, a delete may be disallowed based on some property of the object itself,
# which can't be trapped in permissions checks. Now that the object is loaded, see if
# the view has an action init method.
action_method = 'init_object_{}'.format(action)
if hasattr(self, action_method):
getattr(self, action_method)()
return self.objinst

def add(self):
return requires_permissions(self.permissions['add'])(self.add_edit)(flask.request.method)

def edit(self, objid):
obj = self.init_object(objid)
obj = self.init_object(objid, 'edit')
return requires_permissions(self.permissions['edit'])(self.add_edit)(
flask.request.method, obj)

def delete(self, objid):
self.init_object(objid)
self.init_object(objid, 'delete')

def action():
try:
Expand Down

0 comments on commit 63921ee

Please sign in to comment.