Clean up of IP checking
All checks were successful
docker-image / docker (push) Successful in 1m28s

This commit is contained in:
Stefan Bethke 2025-05-30 10:31:30 +02:00
commit 6245c11a07
3 changed files with 16 additions and 21 deletions

View file

@ -1,8 +1,7 @@
from ipaddress import ip_address, IPv4Address, ip_network
from typing import Callable, List
from ipaddress import ip_network
from typing import Callable
from BottleOIDC import BottleOIDC
from BottleOIDC.bottle_utils import UnauthorizedError
from bottle import request, abort
@ -15,11 +14,6 @@ class BottleHelpers:
self.auth = auth
self.group = group
def remote_addr(self):
if request.remote_route is not None:
return request.remote_route[-1]
return request.remote_addr
def require_login(self, func: Callable) -> Callable:
if self.group is not None:
return self.auth.require_login(self.require_attribute('groups', self.group)(func))
@ -41,16 +35,12 @@ class BottleHelpers:
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')
abort(401, 'Not Authorized: Not In Group')
_wrapper.__name__ = f.__name__
return _wrapper
@ -65,7 +55,7 @@ class BottleHelpers:
def _wrapper(*args, **kwargs):
if self.auth.my_username is not None:
return f(*args, **kwargs)
abort(401, 'Not Authorized')
abort(401, 'Not Authorized: Not logged in')
return None
_wrapper.__name__ = f.__name__
@ -83,7 +73,7 @@ class BottleHelpers:
for allowed in self.allowed:
if addr.overlaps(allowed):
return f(*args, **kwargs)
abort(401, 'Not Authorized')
abort(401, 'Not Authorized: Wrong IP')
return None
_wrapper.__name__ = f.__name__

View file

@ -3,12 +3,10 @@ FastAPI main entry point
"""
import json
import logging
from typing import Callable
from BottleOIDC import BottleOIDC
from BottleOIDC.bottle_utils import UnauthorizedError
from BottleSessions import BottleSessions
from bottle import route, run, Bottle, static_file, TEMPLATE_PATH, jinja2_view, post, get, request, error
from bottle import Bottle, static_file, TEMPLATE_PATH, jinja2_view, request
from bottle_log import LoggingPlugin
from bottle_websocket import websocket, GeventWebSocketServer
from geventwebsocket.websocket import WebSocket
@ -54,6 +52,7 @@ def server_static(filepath):
def root():
return {}
@app.get("/operate")
@bottle_helpers.require_sourceip
@bottle_helpers.require_login
@ -75,20 +74,24 @@ def websocket_endpoint(ws: WebSocket):
finally:
websocket_clients.remove(ws)
@app.get('/api/lock')
def get_api_lock():
return update_poller.get_locks(True)
@app.get('/api/lock/<id>')
def get_api_lock(id):
return update_poller.get_lock(id)
@app.post('/api/lock/<id>')
@bottle_helpers.require_sourceip
@bottle_helpers.require_authz
def post_api_lock(id):
return ccujack.lock_unlock(id, request.json["locking"])
@app.error(401)
@jinja2_view("not_authorized.html.j2")
def not_authorized(error):
@ -98,7 +101,7 @@ def not_authorized(error):
groups = request.session[auth.sess_attr]['groups']
return {
'user': auth.my_username,
'ip': request.get_header('x-forwarded-for', request.remote_addr),
'ip': request.remote_addr,
'error': error,
'code': code,
'msg': msg,
@ -107,4 +110,5 @@ def not_authorized(error):
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)

View file

@ -8,6 +8,7 @@
<body>
<h1>HM Dooris - {{ msg }}</h1>
<p>You are not authorized to lock or unlock.</p>
<p>user: {{ user }}, groups: {{ groups }}, ip: {{ ip }}, error: {{ error }}, code: {{ code }}, msg: {{ msg }}</p>
<p>user: {{ user }}, groups: {{ groups }}, ip: {{ ip }}, code: {{ code }}, msg: {{ msg }}</p>
<p>{{ headers }}</p>
</body>
</html>