diff --git a/capport-example.yaml b/capport-example.yaml
index 7e124f2..27bba9a 100644
--- a/capport-example.yaml
+++ b/capport-example.yaml
@@ -1,7 +1,11 @@
---
-secret: mysecret
+comm-secret: mysecret
+cookie-secret: mysecret
controllers:
- capport-controller1.example.com
- capport-controller2.example.com
session-timeout: 3600 # in seconds
venue-info-url: 'https://example.com'
+server-names:
+- localhost
+- ...
diff --git a/src/capport/api/__init__.py b/src/capport/api/__init__.py
index ac785e2..8a018e1 100644
--- a/src/capport/api/__init__.py
+++ b/src/capport/api/__init__.py
@@ -131,7 +131,8 @@ async def _run_hub(*, task_status=trio.TASK_STATUS_IGNORED) -> None:
@app.before_serving
async def init():
global config
- config = Config.load()
+ config = Config.load_default_once()
+ app.secret_key = config.cookie_secret
capport.utils.cli.init_logger(config)
await app.nursery.start(_run_hub)
@@ -152,6 +153,7 @@ async def login():
address = get_client_ip()
mac = await get_client_mac(address)
await user_login(address, mac)
+ await quart.flash('Logged in')
return quart.redirect('/', code=303)
@@ -159,6 +161,7 @@ async def login():
async def logout():
mac = await get_client_mac()
await user_logout(mac)
+ await quart.flash('Logged out')
return quart.redirect('/', code=303)
diff --git a/src/capport/api/hypercorn_conf.py b/src/capport/api/hypercorn_conf.py
new file mode 100644
index 0000000..4661c0a
--- /dev/null
+++ b/src/capport/api/hypercorn_conf.py
@@ -0,0 +1,12 @@
+from __future__ import annotations
+
+import capport.config
+
+_config = capport.config.Config.load_default_once()
+
+worker_class = 'trio'
+
+if _config.server_names:
+ server_names = _config.server_names
+elif not _config.debug:
+ raise Exception("production setup requires server-names in config (list of accepted hostnames in http requests)")
diff --git a/src/capport/api/templates/base.html b/src/capport/api/templates/base.html
new file mode 100644
index 0000000..88b314c
--- /dev/null
+++ b/src/capport/api/templates/base.html
@@ -0,0 +1,14 @@
+
+
+
+
+ {% block title %}Captive Portal Universität Stuttgart{% endblock %}
+
+
+
+ {% block content %}{% endblock %}
+ {% for message in get_flashed_messages() %}
+ {{ message }}
+ {% endfor %}
+
+
diff --git a/src/capport/api/templates/index.html b/src/capport/api/templates/index.html
index bc762a7..b5ad377 100644
--- a/src/capport/api/templates/index.html
+++ b/src/capport/api/templates/index.html
@@ -1,22 +1,16 @@
-
-
-
-
- Captive Portal Universität Stuttgart
-
-
-
- {% if not state.mac %}
- It seems you're accessing this site from outside the network this captive portal is running for.
- {% elif state.captive %}
- To get access to the internet please accept our usage guidelines by clicking this button:
-
- {% else %}
- You already accepted out conditions and are currently granted access to the internet:
-
-
-
- Your current session will last for {{ state.allowed_remaining }} seconds.
- {% endif %}
-
-
\ No newline at end of file
+{% extends "base.html" %}
+{% block content %}
+ {% if not state.mac %}
+ It seems you're accessing this site from outside the network this captive portal is running for.
+ Your clients IP address is {{ state.address }}
+ {% elif state.captive %}
+ To get access to the internet please accept our usage guidelines by clicking this button:
+
+ {% else %}
+ You already accepted out conditions and are currently granted access to the internet:
+
+
+
+ Your current session will last for {{ state.allowed_remaining }} seconds.
+ {% endif %}
+{% endblock %}
\ No newline at end of file
diff --git a/src/capport/comm/hub.py b/src/capport/comm/hub.py
index 2401f4e..6f02aa0 100644
--- a/src/capport/comm/hub.py
+++ b/src/capport/comm/hub.py
@@ -339,7 +339,7 @@ class Hub:
await trio.sleep_forever()
def _calc_authentication(self, ssl_binding: bytes, server_side: bool) -> bytes:
- m = hmac.new(self._config.secret.encode('utf8'), digestmod=hashlib.sha256)
+ m = hmac.new(self._config.comm_secret.encode('utf8'), digestmod=hashlib.sha256)
if server_side:
m.update(b'server$')
else:
diff --git a/src/capport/config.py b/src/capport/config.py
index 6ebb52d..eb43a53 100644
--- a/src/capport/config.py
+++ b/src/capport/config.py
@@ -7,16 +7,28 @@ import typing
import yaml
+_cached_config: typing.Optional[Config] = None
+
+
@dataclasses.dataclass
class Config:
controllers: typing.List[str]
- secret: str
+ server_names: typing.List[str]
+ comm_secret: str
+ cookie_secret: str
venue_info_url: typing.Optional[str]
session_timeout: int # in seconds
debug: bool
@staticmethod
- def load(filename: typing.Optional[str]=None) -> 'Config':
+ def load_default_once() -> Config:
+ global _cached_config
+ if not _cached_config:
+ _cached_config = Config.load()
+ return _cached_config
+
+ @staticmethod
+ def load(filename: typing.Optional[str]=None) -> Config:
if filename is None:
for name in ('capport.yaml', '/etc/capport.yaml'):
if os.path.exists(name):
@@ -27,7 +39,9 @@ class Config:
controllers = list(map(str, data['controllers']))
return Config(
controllers=controllers,
- secret=str(data['secret']),
+ server_names=data.get('server-names', []),
+ comm_secret=str(data.get('comm-secret', None) or data['secret']),
+ cookie_secret=str(data['cookie-secret']),
venue_info_url=str(data.get('venue-info-url')),
session_timeout=data.get('session-timeout', 3600),
debug=data.get('debug', False)
diff --git a/src/capport/control/run.py b/src/capport/control/run.py
index 106c5c5..4ce75f2 100644
--- a/src/capport/control/run.py
+++ b/src/capport/control/run.py
@@ -48,7 +48,7 @@ async def amain(config: capport.config.Config) -> None:
def main() -> None:
- config = capport.config.Config.load()
+ config = capport.config.Config.load_default_once()
capport.utils.cli.init_logger(config)
try:
trio.run(amain, config)
diff --git a/start-api.sh b/start-api.sh
index 50c2163..1d9d365 100755
--- a/start-api.sh
+++ b/start-api.sh
@@ -5,4 +5,4 @@ set -e
base=$(dirname "$(readlink -f "$0")")
cd "${base}"
-exec ./venv/bin/hypercorn -k trio capport.api "$@"
+exec ./venv/bin/hypercorn --config python:capport.api.hypercorn_conf capport.api "$@"