I'm currently building a REST API using Flask-RESTful and using Flask-HTTPAuth to protect some of the put and get methods. I want to allow access to these methods based on pre-defined user permissions I have stored in a database.
My question is, how can I modify or intercept the results of the function below, so that I can vary access depending on the endpoint/method? After basic authentication clears, I want to be able to check whether the user has the relevant permissions in my database. With Flask-Session this was easy, but here the API is stateless.
@auth.verify_password
def verify_password(user, password):
query_set = models.User.objects(username=user)
if query_set:
return helpers.verify(password, query_set[0].password)
else:
return False
Thank you very much.
To use role based authentication you need to add a second check after the password step is passed.
You have two options. The more straightforward is to add the role check in each of your endpoint functions. If you want something more sophisticated that avoids code duplication, then you can define a custom decorator, such as the one I have used here: https://github.com/miguelgrinberg/flasky/blob/master/app/decorators.py.
You will need to adapt it to use your own user object instead of current_user
, but other than that this is a good example:
def permission_required(permission):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not current_user.can(permission):
abort(403)
return f(*args, **kwargs)
return decorated_function
return decorator
So then in your route, you do this:
@app.route('/api/something')
@auth.login_required
@permission_required('admin')
def something():
pass