Plasma Plasma - 3 months ago 27
Python Question

flask-security roles_required with pluggable views

I'm trying to require a role to access a view that I've defined as a MethodView. However, I can't seem to get the route to be named correctly.

If I simply require logging in with a decorator everything works:

activities = Blueprint("activities", __name__, url_prefix="/activities")

class ActivitiesView(MethodView):
def get():
pass

def post():
pass

view = login_required(ActivitiesView.as_view("activities"))
activities.add_url_rule('/', view_func=view)


I get the desired route name, i.e.
activities.activities
:

>>> current_app.url_map
Map([...
<Rule '/activities/' (HEAD, POST, OPTIONS, GET) -> activities.activities>,
...])


However, when I try to use
roles_required
, the name of the route is mangled and the
POST
method is no longer listed:

view = roles_required("experimenter", ActivitiesView.as_view("activities"))
activities.add_url_rule('/', view_func=view)

>>> current_app.url_map
Map([...
<Rule '/activities/' (HEAD, OPTIONS, GET) -> activities.wrapper>,
...])


Switching the arguments to
add_url_rule
doesn't change anything. How can I use
roles_required
without messing up the route name?

Doing this fixes the route name, but not the missing POST method:

view = roles_required("experimenter", endpoint="activities", ActivitiesView.as_view("activities"))
activities.add_url_rule('/', view_func=view)

Answer

The solution is to call the decorator:

view = roles_required("experimenter")(ActivitiesView.as_view("activities"))
activities.add_url_rule('/', view_func=view)

Alternatively:

decorators = [roles_required("experimenter")]

Thanks to this article:

http://scottlobdell.me/2015/04/decorators-arguments-python/