Compare commits

...

3 Commits

Author SHA1 Message Date
c3831e9efe
routes/home: handle missing groups 2022-09-03 15:29:54 +10:00
860dbe6032
docs: add readme 2022-09-03 15:29:54 +10:00
aa86f5de48
routes/home: configure brand name 2022-09-03 15:29:51 +10:00
4 changed files with 49 additions and 7 deletions

37
README.md Normal file
View File

@ -0,0 +1,37 @@
# frontpage (name pending)
The front page of your self-hosted server.
This app fits the use case of having multiple applications with access gated by
an OIDC provider, and showing a user what applications they have access to.
## Usage
```sh
frontpage -c CONFIG.TOML
```
where a minimal config file looks like:
```toml
[oidc]
client_id = "some_id"
client_secret = "some_secret"
issuer = "https://auth.example.com/oauth"
scopes = [ "groups" ]
```
Applications are defined using the `apps` keys:
```toml
[apps.login]
name = "Login portal"
url = "https://auth.example.com"
description = "Update your user details"
groups = [ "users" ]
```
In this example, only users whose OIDC groups claim includes `users` will be
allowed to see a link to the login portal. Protection of the link, should a user
gain access to it otherwise, is expected to be done externall (e.g., via an
ingress controller).

View File

@ -15,6 +15,7 @@ class CoreConfig:
debug: bool = False
port: int = 5000
name: str = "Front page"
@dataclass
@ -43,8 +44,8 @@ class AppConfig:
class Config:
"""Top-level configuration."""
core: CoreConfig
oidc: OidcConfig
core: CoreConfig = field(default_factory=CoreConfig)
oidc: OidcConfig = field(default_factory=OidcConfig)
apps: Dict[str, AppConfig] = field(default_factory=dict)

View File

@ -7,7 +7,7 @@ from flask import Blueprint, current_app, render_template
from flask_pyoidc import OIDCAuthentication
from flask_pyoidc.user_session import UserSession
from frontpage.config import AppConfig, current_config
from frontpage.config import AppConfig, Config, current_config
def _allowed(items_from: Iterable[Any], items_in: Iterable[Any]) -> bool:
@ -29,12 +29,16 @@ def register(auth: OIDCAuthentication, auth_provider: str) -> Blueprint:
Renders the home route.
"""
user_session = UserSession(flask.session)
groups: List[str] = user_session.userinfo["groups"]
groups: List[str] = user_session.userinfo.get("groups") or []
apps: AppConfig = current_config().apps
config: Config = current_config()
name = config.core.name
apps = config.apps
allowed_apps = {
ident: a for ident, a in apps.items() if _allowed(a.groups, groups)
}
return render_template("home.html", apps=allowed_apps, groups=groups)
return render_template(
"home.html", brand_name=name, apps=allowed_apps, groups=groups
)
return routes

View File

@ -8,7 +8,7 @@
<body>
<nav class="nav">
<div class="nav-left">
<a class="brand" href="/">Front page</a>
<a class="brand" href="/">{{ brand_name }}</a>
</div>
</nav>
<main class="container">