style: format tree
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
latestPkgs: {
|
||||
latestPkgs:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
sp = config.selfprivacy;
|
||||
cfg = sp.modules.vikunja;
|
||||
oauthClientID = "vikunja";
|
||||
@@ -13,18 +15,16 @@ latestPkgs: {
|
||||
# SelfPrivacy uses SP Module ID to identify the group!
|
||||
usersGroup = "sp.vikunja.users";
|
||||
|
||||
oauthClientSecretFP =
|
||||
auth-passthru.mkOAuth2ClientSecretFP oauthClientID;
|
||||
oauthClientSecretFP = auth-passthru.mkOAuth2ClientSecretFP oauthClientID;
|
||||
|
||||
vikunjaPackage = latestPkgs.vikunja.overrideAttrs (old: {
|
||||
doCheck = false; # Tests are slow.
|
||||
patches =
|
||||
(old.patches or [])
|
||||
++ [
|
||||
./load-client-secret-from-env.patch
|
||||
];
|
||||
patches = (old.patches or [ ]) ++ [
|
||||
./load-client-secret-from-env.patch
|
||||
];
|
||||
});
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.selfprivacy.modules.vikunja = {
|
||||
enable =
|
||||
(lib.mkOption {
|
||||
@@ -63,157 +63,168 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
config =
|
||||
lib.mkIf cfg.enable
|
||||
{
|
||||
assertions = [
|
||||
{
|
||||
assertion = sp.sso.enable;
|
||||
message = "Vikunja cannot be enabled when SSO is disabled.";
|
||||
}
|
||||
];
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = sp.sso.enable;
|
||||
message = "Vikunja cannot be enabled when SSO is disabled.";
|
||||
}
|
||||
];
|
||||
|
||||
fileSystems = lib.mkIf sp.useBinds {
|
||||
"/var/lib/vikunja" = {
|
||||
device = "/volumes/${cfg.location}/vikunja";
|
||||
options = ["bind"];
|
||||
};
|
||||
};
|
||||
|
||||
users = {
|
||||
users.vikunja = {
|
||||
isSystemUser = true;
|
||||
group = "vikunja";
|
||||
};
|
||||
groups.vikunja = {};
|
||||
};
|
||||
|
||||
services.postgresql = {
|
||||
ensureDatabases = ["vikunja"];
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "vikunja";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
services.vikunja = {
|
||||
enable = true;
|
||||
package = vikunjaPackage;
|
||||
frontendScheme = "https";
|
||||
frontendHostname = "${cfg.subdomain}.${sp.domain}";
|
||||
port = 4835;
|
||||
|
||||
database = {
|
||||
type = "postgres";
|
||||
host = "/run/postgresql";
|
||||
};
|
||||
|
||||
settings = {
|
||||
service = {
|
||||
enableregistration = false;
|
||||
enabletotp = false;
|
||||
enableuserdeletion = true;
|
||||
};
|
||||
|
||||
auth = {
|
||||
local.enabled = false;
|
||||
openid = {
|
||||
enabled = true;
|
||||
providers = [
|
||||
{
|
||||
name = oauth2-provider-name;
|
||||
authurl = lib.strings.removeSuffix "/.well-known/openid-configuration" oauthDiscoveryURL;
|
||||
clientid = oauthClientID;
|
||||
clientsecret = ""; # There's patch for our Vikunja to make it load client secret from environment variable.
|
||||
scope = "openid profile email";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."${cfg.subdomain}.${sp.domain}" = {
|
||||
useACMEHost = sp.domain;
|
||||
forceSSL = true;
|
||||
extraConfig = ''
|
||||
add_header Strict-Transport-Security $hsts_header;
|
||||
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
|
||||
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
'';
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://127.0.0.1:4835";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd = {
|
||||
services.vikunja = {
|
||||
unitConfig.RequiresMountsFor = lib.mkIf sp.useBinds "/volumes/${cfg.location}/vikunja";
|
||||
serviceConfig = {
|
||||
Slice = "vikunja.slice";
|
||||
LoadCredential = "oauth2-secret:${oauthClientSecretFP}";
|
||||
DynamicUser = lib.mkForce false;
|
||||
User = "vikunja";
|
||||
Group = "vikunja";
|
||||
|
||||
AmbientCapabilities = [""];
|
||||
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateTmp = true;
|
||||
|
||||
PrivateUsers = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
|
||||
ProtectProc = "invisible";
|
||||
|
||||
ProtectSystem = "strict";
|
||||
|
||||
RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"];
|
||||
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
|
||||
RemoveIPC = true;
|
||||
|
||||
SystemCallFilter = ["@system-service" "~@cpu-emulation" "~@debug" "~@keyring" "~@memlock" "~@obsolete" "~@privileged" "~@setuid"];
|
||||
};
|
||||
environment.SP_VIKUNJA_CLIENT_SECRET_PATH = "%d/oauth2-secret";
|
||||
};
|
||||
slices.vikunja = {
|
||||
description = "Vikunja service slice";
|
||||
};
|
||||
};
|
||||
|
||||
selfprivacy.auth.clients.${oauthClientID} = {
|
||||
inherit usersGroup;
|
||||
subdomain = cfg.subdomain;
|
||||
isTokenNeeded = false;
|
||||
originLanding = "https://${cfg.subdomain}.${sp.domain}/";
|
||||
originUrl = "https://${cfg.subdomain}.${sp.domain}/auth/openid/${lib.strings.toLower oauth2-provider-name}";
|
||||
clientSystemdUnits = ["vikunja.service"];
|
||||
enablePkce = false;
|
||||
linuxUserOfClient = "vikunja";
|
||||
linuxGroupOfClient = "vikunja";
|
||||
fileSystems = lib.mkIf sp.useBinds {
|
||||
"/var/lib/vikunja" = {
|
||||
device = "/volumes/${cfg.location}/vikunja";
|
||||
options = [ "bind" ];
|
||||
};
|
||||
};
|
||||
|
||||
users = {
|
||||
users.vikunja = {
|
||||
isSystemUser = true;
|
||||
group = "vikunja";
|
||||
};
|
||||
groups.vikunja = { };
|
||||
};
|
||||
|
||||
services.postgresql = {
|
||||
ensureDatabases = [ "vikunja" ];
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "vikunja";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
services.vikunja = {
|
||||
enable = true;
|
||||
package = vikunjaPackage;
|
||||
frontendScheme = "https";
|
||||
frontendHostname = "${cfg.subdomain}.${sp.domain}";
|
||||
port = 4835;
|
||||
|
||||
database = {
|
||||
type = "postgres";
|
||||
host = "/run/postgresql";
|
||||
};
|
||||
|
||||
settings = {
|
||||
service = {
|
||||
enableregistration = false;
|
||||
enabletotp = false;
|
||||
enableuserdeletion = true;
|
||||
};
|
||||
|
||||
auth = {
|
||||
local.enabled = false;
|
||||
openid = {
|
||||
enabled = true;
|
||||
providers = [
|
||||
{
|
||||
name = oauth2-provider-name;
|
||||
authurl = lib.strings.removeSuffix "/.well-known/openid-configuration" oauthDiscoveryURL;
|
||||
clientid = oauthClientID;
|
||||
clientsecret = ""; # There's patch for our Vikunja to make it load client secret from environment variable.
|
||||
scope = "openid profile email";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."${cfg.subdomain}.${sp.domain}" = {
|
||||
useACMEHost = sp.domain;
|
||||
forceSSL = true;
|
||||
extraConfig = ''
|
||||
add_header Strict-Transport-Security $hsts_header;
|
||||
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
|
||||
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
'';
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://127.0.0.1:4835";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd = {
|
||||
services.vikunja = {
|
||||
unitConfig.RequiresMountsFor = lib.mkIf sp.useBinds "/volumes/${cfg.location}/vikunja";
|
||||
serviceConfig = {
|
||||
Slice = "vikunja.slice";
|
||||
LoadCredential = "oauth2-secret:${oauthClientSecretFP}";
|
||||
DynamicUser = lib.mkForce false;
|
||||
User = "vikunja";
|
||||
Group = "vikunja";
|
||||
|
||||
AmbientCapabilities = [ "" ];
|
||||
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateTmp = true;
|
||||
|
||||
PrivateUsers = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
|
||||
ProtectProc = "invisible";
|
||||
|
||||
ProtectSystem = "strict";
|
||||
|
||||
RestrictAddressFamilies = [
|
||||
"AF_UNIX"
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
];
|
||||
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
|
||||
RemoveIPC = true;
|
||||
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
"~@cpu-emulation"
|
||||
"~@debug"
|
||||
"~@keyring"
|
||||
"~@memlock"
|
||||
"~@obsolete"
|
||||
"~@privileged"
|
||||
"~@setuid"
|
||||
];
|
||||
};
|
||||
environment.SP_VIKUNJA_CLIENT_SECRET_PATH = "%d/oauth2-secret";
|
||||
};
|
||||
slices.vikunja = {
|
||||
description = "Vikunja service slice";
|
||||
};
|
||||
};
|
||||
|
||||
selfprivacy.auth.clients.${oauthClientID} = {
|
||||
inherit usersGroup;
|
||||
subdomain = cfg.subdomain;
|
||||
isTokenNeeded = false;
|
||||
originLanding = "https://${cfg.subdomain}.${sp.domain}/";
|
||||
originUrl = "https://${cfg.subdomain}.${sp.domain}/auth/openid/${lib.strings.toLower oauth2-provider-name}";
|
||||
clientSystemdUnits = [ "vikunja.service" ];
|
||||
enablePkce = false;
|
||||
linuxUserOfClient = "vikunja";
|
||||
linuxGroupOfClient = "vikunja";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user