feat: enable OIDC in paperless

This commit is contained in:
oddlama 2024-03-12 23:01:43 +01:00
parent 605aee0a67
commit 6c9042b4d2
No known key found for this signature in database
GPG key ID: 14EFE510775FE39A
6 changed files with 77 additions and 39 deletions

View file

@ -2,6 +2,7 @@
config,
lib,
nodes,
pkgs,
...
}: let
sentinelCfg = nodes.sentinel.config;
@ -47,6 +48,13 @@ in {
group = "paperless";
};
# Mirror the original oauth2 secret
age.secrets.paperless-oauth2-client-secret = {
inherit (nodes.ward-kanidm.config.age.secrets.kanidm-oauth2-paperless) rekeyFile;
mode = "440";
group = "paperless";
};
environment.persistence."/persist".directories = [
{
directory = "/var/lib/paperless";
@ -56,11 +64,6 @@ in {
}
];
# TODO: workaround for https://github.com/paperless-ngx/paperless-ngx/discussions/5606
systemd.services.paperless-web.script = lib.mkBefore ''
mkdir -p /tmp/paperless
'';
services.paperless = {
enable = true;
address = "0.0.0.0";
@ -73,6 +76,24 @@ in {
PAPERLESS_CORS_ALLOWED_HOSTS = "https://${paperlessDomain}";
PAPERLESS_TRUSTED_PROXIES = sentinelCfg.meta.wireguard.proxy-sentinel.ipv4;
# Authentication via kanidm
PAPERLESS_APPS = "allauth.socialaccount.providers.openid_connect";
PAPERLESS_SOCIALACCOUNT_PROVIDERS = builtins.toJSON {
openid_connect = {
OAUTH_PKCE_ENABLED = "True";
APPS = [
rec {
provider_id = "kanidm";
name = "Kanidm";
client_id = "paperless";
# secret will be added dynamically
#secret = "";
settings.server_url = "https://${sentinelCfg.networking.providedDomains.kanidm}/oauth2/openid/${client_id}/.well-known/openid-configuration";
}
];
};
};
# Ghostscript is entirely bug-free.
PAPERLESS_OCR_USER_ARGS = builtins.toJSON {
continue_on_soft_render_error = true;
@ -109,6 +130,16 @@ in {
mode = "0700";
};
# Add secret to PAPERLESS_SOCIALACCOUNT_PROVIDERS
systemd.services.paperless-web.script = lib.mkBefore ''
oidcSecret=$(< ${config.age.secrets.paperless-oauth2-client-secret.path})
export PAPERLESS_SOCIALACCOUNT_PROVIDERS=$(
${pkgs.jq}/bin/jq <<< "$PAPERLESS_SOCIALACCOUNT_PROVIDERS" \
--compact-output \
--arg oidcSecret "$oidcSecret" '.openid_connect.APPS.[0].secret = $oidcSecret'
)
'';
systemd.services.paperless-backup = let
cfg = config.systemd.services.paperless-consumer;
in {

View file

@ -7,6 +7,12 @@
sentinelCfg = nodes.sentinel.config;
kanidmDomain = "auth.${domains.me}";
kanidmPort = 8300;
mkRandomSecret = {
generator.script = "alnum";
mode = "440";
group = "kanidm";
};
in {
meta.wireguard-proxy.sentinel.allowedTCPPorts = [kanidmPort];
@ -22,41 +28,14 @@ in {
group = "kanidm";
};
age.secrets.kanidm-admin-password = {
generator.script = "alnum";
mode = "440";
group = "kanidm";
};
age.secrets.kanidm-admin-password = mkRandomSecret;
age.secrets.kanidm-idm-admin-password = mkRandomSecret;
age.secrets.kanidm-idm-admin-password = {
generator.script = "alnum";
mode = "440";
group = "kanidm";
};
age.secrets.kanidm-oauth2-immich = {
generator.script = "alnum";
mode = "440";
group = "kanidm";
};
age.secrets.kanidm-oauth2-grafana = {
generator.script = "alnum";
mode = "440";
group = "kanidm";
};
age.secrets.kanidm-oauth2-forgejo = {
generator.script = "alnum";
mode = "440";
group = "kanidm";
};
age.secrets.kanidm-oauth2-web-sentinel = {
generator.script = "alnum";
mode = "440";
group = "kanidm";
};
age.secrets.kanidm-oauth2-forgejo = mkRandomSecret;
age.secrets.kanidm-oauth2-grafana = mkRandomSecret;
age.secrets.kanidm-oauth2-immich = mkRandomSecret;
age.secrets.kanidm-oauth2-paperless = mkRandomSecret;
age.secrets.kanidm-oauth2-web-sentinel = mkRandomSecret;
nodes.sentinel = {
networking.providedDomains.kanidm = kanidmDomain;
@ -130,6 +109,16 @@ in {
scopeMaps."immich.access" = ["openid" "email" "profile"];
};
# Paperless
groups."paperless.access" = {};
systems.oauth2.paperless = {
displayName = "Paperless";
originUrl = "https://${sentinelCfg.networking.providedDomains.paperless}/";
basicSecretFile = config.age.secrets.kanidm-oauth2-paperless.path;
preferShortUsername = true;
scopeMaps."paperless.access" = ["openid" "email" "profile"];
};
# Grafana
groups."grafana.access" = {};
groups."grafana.editors" = {};

View file

@ -0,0 +1,11 @@
age-encryption.org/v1
-> X25519 hzkY1fcGtdk9GFrYskb/0fFAAgD4hAwtyd23quaPCD8
akEojVvE36WwAGv9aZFWZLbBvhIeZjOaSncWtVfwAn4
-> piv-p256 xqSe8Q A2icKgRBVKO9BjUUSNDLds1Eq+DL1+wfLy0r4U1Q8YNP
630Lq8Y4XgZcDFGa4deEHGXTE3qkxPHgev7i4mKtM+o
-> dI-grease _8iXML(
22JTt6b8FjyMsaFuddGHWGgurfZBbpMTUhIHzTn7RC9/RxQblyAWinMlZjcDyGAP
+wQYeeqG0aIyFgasJLMuu1IRBQaEmRKVTiGRgh7Sm5FHnF0u6aAu0pj/iOX2xbw
--- 04iwf902sMdNHLYmynps8wNLhwrYNoK0w99KdPz7SO0
º¼Ãyež€=$¿qÄuÕ°M·/ùú\�àâƒûû}Žu4ÔÈšj¿YŸ…Tõo,_µ lOí fS24�•Ãþù¬SÁ
T;7—pÍ{6²š

Binary file not shown.

View file

@ -0,0 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 vqFVQw q5QZqkI20/kI0xMQ3sRewA122Cm13qfE0LhuFr9K6g8
0qWz+XFjeyiNnGlAfffoL/iZdwS9NzXOYyl7FmUY2hI
-> 2FQ(N@-grease
--- AVDxWkWApQ6FCrAwGvzg9u3RklcWZeQFg2iqqqeNQ2E
Ê^Ç|´^ „²1»D¼ä©"®Zм/Ç`JàÛ¯ãã€òu'ñPv‘ÎU,)Ew¤\§ä¾ä¼gó‹‚ÈdAþ / Má€X@2›