import re import secrets from datetime import datetime, timedelta from typing import Callable import BottleOIDC from bottle import static_file, request, redirect, Bottle from hmdooris import CSRF from hmdooris.AppConfig import AppConfig from hmdooris.Template import template_or_error class WebEndpoints: """ Defines endpoints for interaction with the user's browser. """ def __init__(self, app: Bottle, auth: BottleOIDC, basepath: str, config: AppConfig): self.app = app self.auth = auth self.basepath = basepath self.config = config self.valid_username_re = '^[a-zA-Z0-9_-]+$' # set up routing directly, since decorators can only be used in a global scope app.route(path='/static/', callback=self.static) app.get(path='/', callback=template_or_error('home')(self.home)) app.get(path='/foo', callback=self.require_login(template_or_error('home')(self.home))) app.get(path='/api', callback=self.require_login(self.api_get)) # app.get(path='/invite', callback=self.get_invite) # app.post(path='/invite', callback=self.require_login(template_or_error('invite_result')(self.post_invite))) # app.get(path='/claim', callback=template_or_error('claim_form')(self.get_claim)) # app.post(path='/claim', callback=template_or_error('claim_result')(self.post_claim)) def require_login(self, func: Callable) -> Callable: if self.config.requires_group is not None: return self.auth.require_login(self.auth.require_attribute('groups', self.config.requires_group)(func)) else: return self.auth.require_login(func) def static(self, filename): return static_file(filename, root=f'{self.basepath}/static') def home(self): """ Present the home page :param username: :return: """ return { '_csrf': CSRF.get_token(), # 'username': self.auth.my_attrs['username'], } def api_get(self): """ Interact withe HomeMatic CCU through ccu-jack :return: """ return { '_csrf': CSRF.get_token(), 'foo': 'bar' } def api_put(self): """ Interact withe HomeMatic CCU through ccu-jack :return: """ return {}