diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/pybind/mgr/restful/decorators.py | |
parent | Initial commit. (diff) | |
download | ceph-upstream/16.2.11+ds.tar.xz ceph-upstream/16.2.11+ds.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | src/pybind/mgr/restful/decorators.py | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/pybind/mgr/restful/decorators.py b/src/pybind/mgr/restful/decorators.py new file mode 100644 index 000000000..d1d3fbcd5 --- /dev/null +++ b/src/pybind/mgr/restful/decorators.py @@ -0,0 +1,82 @@ +from __future__ import absolute_import + +from pecan import request, response +from base64 import b64decode +from functools import wraps + +import traceback + +from . import context + + +# Handle authorization +def auth(f): + @wraps(f) + def decorated(*args, **kwargs): + if not context.instance.enable_auth: + return f(*args, **kwargs) + + if not request.authorization: + response.status = 401 + response.headers['WWW-Authenticate'] = 'Basic realm="Login Required"' + return {'message': 'auth: No HTTP username/password'} + + username, password = b64decode(request.authorization[1]).decode('utf-8').split(':') + + # Check that the username exists + if username not in context.instance.keys: + response.status = 401 + response.headers['WWW-Authenticate'] = 'Basic realm="Login Required"' + return {'message': 'auth: No such user'} + + # Check the password + if context.instance.keys[username] != password: + response.status = 401 + response.headers['WWW-Authenticate'] = 'Basic realm="Login Required"' + return {'message': 'auth: Incorrect password'} + + return f(*args, **kwargs) + return decorated + + +# Helper function to lock the function +def lock(f): + @wraps(f) + def decorated(*args, **kwargs): + with context.instance.requests_lock: + return f(*args, **kwargs) + return decorated + + +# Support ?page=N argument +def paginate(f): + @wraps(f) + def decorated(*args, **kwargs): + _out = f(*args, **kwargs) + + # Do not modify anything without a specific request + if not 'page' in kwargs: + return _out + + # A pass-through for errors, etc + if not isinstance(_out, list): + return _out + + # Parse the page argument + _page = kwargs['page'] + try: + _page = int(_page) + except ValueError: + response.status = 500 + return {'message': 'The requested page is not an integer'} + + # Raise _page so that 0 is the first page and -1 is the last + _page += 1 + + if _page > 0: + _page *= 100 + else: + _page = len(_out) - (_page*100) + + return _out[_page - 100: _page] + return decorated |