vimalloc / flask-jwt-extended

An open source Flask extension that provides JWT support (with batteries included)!
http://flask-jwt-extended.readthedocs.io/en/stable/
MIT License
1.56k stars 239 forks source link

Custom admin_required() decorator #476

Closed aristotelous-perivola closed 2 years ago

aristotelous-perivola commented 2 years ago

I followed the example on https://flask-jwt-extended.readthedocs.io/en/stable/custom_decorators. I tried to create a PUT request and decorate it with @admin_required. My custom decorator looks like this:

def admin_required():
    def wrapper(fn):
        @wraps(fn)
        def decorator(*args, **kwargs):
            verify_jwt_in_request()
            email = get_jwt_identity()
            user = UserModel.find_by_email(email)
            if user.role == UserRole.ADMIN.name:
                return fn(*args, **kwargs)
            else:
                return {'error': 'Only admin can access this resource'}, 403
        return decorator
    return wrapper

The resource is this

    @admin_required()
    def put(self):
        user_json = request.get_json()
        email = user_json.get('email')
        user = UserModel.find_by_email(email)
        if user:
            if user.is_verified:
                raise PromilistBaseException(f'User {email} is already verified')
            else:
                user.is_verified = True
                user.update()
                return {'message': f'User {email} has been verified'}, 201
        else:
            return {'message': f'No user {email} exists'},404

After making the PUT request with parameters that will enter the else branch of the decorator, the request is successful, but I see the following errors in my logs: 127.0.0.1 - - [17/Apr/2022 14:14:27] "PUT /api/admin/verify-user HTTP/1.1" 403 - 127.0.0.1 - - [17/Apr/2022 14:14:27] code 400, message Bad request syntax ('{') 127.0.0.1 - - [17/Apr/2022 14:14:27] "None /api/admin/verify-user HTTP/0.9" HTTPStatus.BAD_REQUEST

However, when I am making a GET request with the same decorator, there is no issue. 127.0.0.1 - - [17/Apr/2022 14:38:51] "GET /api/admin/user-list HTTP/1.1" 403 -

The GET resource is this:

    @admin_required()
    def get(self):
        users = UserModel.find_not_verified()
        if users:
            return json.loads(users_view_schema.dumps(users)), 200
        else:
            return {'message': 'No pending verification at the moment'}
vimalloc commented 2 years ago

I think you need to jsonify the results in your else block:

from flask import jsonify

####

  else:
    return jsonify(error='Only admin can access this resource'), 403