Better unauthorized error page
All checks were successful
docker-image / docker (push) Successful in 1m21s
All checks were successful
docker-image / docker (push) Successful in 1m21s
This commit is contained in:
parent
99d40ad66e
commit
292185bb7d
3 changed files with 39 additions and 4 deletions
|
@ -17,19 +17,51 @@ class BottleHelpers:
|
||||||
|
|
||||||
def require_login(self, func: Callable) -> Callable:
|
def require_login(self, func: Callable) -> Callable:
|
||||||
if self.group is not None:
|
if self.group is not None:
|
||||||
return self.auth.require_login(self.auth.require_attribute('groups', self.group)(func))
|
return self.auth.require_login(self.require_attribute('groups', self.group)(func))
|
||||||
else:
|
else:
|
||||||
return self.auth.require_login(func)
|
return self.auth.require_login(func)
|
||||||
|
|
||||||
|
def require_attribute(self, attr, value):
|
||||||
|
""" Decorator requires specific attribute value. """
|
||||||
|
|
||||||
|
def test_attrs(challenge, standard):
|
||||||
|
"""Compare list or val the standard."""
|
||||||
|
|
||||||
|
stand_list = standard if type(standard) is list else [standard]
|
||||||
|
chal_list = challenge if type(challenge) is list else [challenge]
|
||||||
|
|
||||||
|
for chal in chal_list:
|
||||||
|
if chal in stand_list:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _outer_wrapper(f):
|
||||||
|
|
||||||
|
def _wrapper(*args, **kwargs):
|
||||||
|
|
||||||
|
if attr in self.auth.my_attrs:
|
||||||
|
resource = request.session[self.auth.sess_attr][attr]
|
||||||
|
|
||||||
|
if test_attrs(resource, value):
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
|
||||||
|
abort(401, 'Not Authorized')
|
||||||
|
|
||||||
|
_wrapper.__name__ = f.__name__
|
||||||
|
return _wrapper
|
||||||
|
|
||||||
|
return _outer_wrapper
|
||||||
|
|
||||||
def require_authz(self, func: Callable) -> Callable:
|
def require_authz(self, func: Callable) -> Callable:
|
||||||
if self.group is not None:
|
if self.group is not None:
|
||||||
return self.auth.require_attribute('groups', self.group)(func)
|
return self.require_attribute('groups', self.group)(func)
|
||||||
else:
|
else:
|
||||||
def _outer_wrapper(f):
|
def _outer_wrapper(f):
|
||||||
def _wrapper(*args, **kwargs):
|
def _wrapper(*args, **kwargs):
|
||||||
if self.auth.my_username is not None:
|
if self.auth.my_username is not None:
|
||||||
return f(*args, **kwargs)
|
return f(*args, **kwargs)
|
||||||
abort(401, 'Not Authorized')
|
abort(401, 'Not Authorized')
|
||||||
|
return None
|
||||||
|
|
||||||
_wrapper.__name__ = f.__name__
|
_wrapper.__name__ = f.__name__
|
||||||
return _wrapper
|
return _wrapper
|
||||||
|
@ -47,6 +79,7 @@ class BottleHelpers:
|
||||||
if addr.overlaps(allowed):
|
if addr.overlaps(allowed):
|
||||||
return f(*args, **kwargs)
|
return f(*args, **kwargs)
|
||||||
abort(401, 'Not Authorized')
|
abort(401, 'Not Authorized')
|
||||||
|
return None
|
||||||
|
|
||||||
_wrapper.__name__ = f.__name__
|
_wrapper.__name__ = f.__name__
|
||||||
return _wrapper
|
return _wrapper
|
||||||
|
|
|
@ -84,6 +84,7 @@ def get_api_lock(id):
|
||||||
return update_poller.get_lock(id)
|
return update_poller.get_lock(id)
|
||||||
|
|
||||||
@app.post('/api/lock/<id>')
|
@app.post('/api/lock/<id>')
|
||||||
|
@bottle_helpers.require_sourceip
|
||||||
@bottle_helpers.require_authz
|
@bottle_helpers.require_authz
|
||||||
def post_api_lock(id):
|
def post_api_lock(id):
|
||||||
return ccujack.lock_unlock(id, request.json["locking"])
|
return ccujack.lock_unlock(id, request.json["locking"])
|
||||||
|
@ -92,15 +93,16 @@ def post_api_lock(id):
|
||||||
@jinja2_view("not_authorized.html.j2")
|
@jinja2_view("not_authorized.html.j2")
|
||||||
def not_authorized(error):
|
def not_authorized(error):
|
||||||
code, msg = error.args
|
code, msg = error.args
|
||||||
|
groups = request.session[auth.sess_attr]['groups'] if 'groups' in request.session[auth.sess_attr] else []
|
||||||
return {
|
return {
|
||||||
'user': auth.my_username,
|
'user': auth.my_username,
|
||||||
'ip': request.remote_addr,
|
'ip': request.remote_addr,
|
||||||
'error': error,
|
'error': error,
|
||||||
'code': code,
|
'code': code,
|
||||||
'msg': msg,
|
'msg': msg,
|
||||||
|
'groups': groups,
|
||||||
}
|
}
|
||||||
|
|
||||||
app.error_handler[401] = not_authorized
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(host=config.listen_host, port=config.listen_port, server=GeventWebSocketServer, debug=config.debug, quiet=not config.debug)
|
app.run(host=config.listen_host, port=config.listen_port, server=GeventWebSocketServer, debug=config.debug, quiet=not config.debug)
|
||||||
|
|
|
@ -8,6 +8,6 @@
|
||||||
<body>
|
<body>
|
||||||
<h1>HM Dooris - {{ msg }}</h1>
|
<h1>HM Dooris - {{ msg }}</h1>
|
||||||
<p>You are not authorized to lock or unlock.</p>
|
<p>You are not authorized to lock or unlock.</p>
|
||||||
<p>user: {{ user }}, ip: {{ ip }}, error: {{ error }}, code: {{ code }}, msg: {{ msg }}</p>
|
<p>user: {{ user }}, groups: {{ groups }}, ip: {{ ip }}, error: {{ error }}, code: {{ code }}, msg: {{ msg }}</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue