254 lines
7.3 KiB
Nix
254 lines
7.3 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
shb,
|
|
...
|
|
}:
|
|
|
|
let
|
|
cfg = config.shb.audiobookshelf;
|
|
|
|
fqdn = "${cfg.subdomain}.${cfg.domain}";
|
|
|
|
roleClaim = "audiobookshelf_groups";
|
|
in
|
|
{
|
|
options.shb.audiobookshelf = {
|
|
enable = lib.mkEnableOption "selfhostblocks.audiobookshelf";
|
|
|
|
subdomain = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Subdomain under which audiobookshelf will be served.";
|
|
example = "abs";
|
|
};
|
|
|
|
domain = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "domain under which audiobookshelf will be served.";
|
|
example = "mydomain.com";
|
|
};
|
|
|
|
webPort = lib.mkOption {
|
|
type = lib.types.int;
|
|
description = "Audiobookshelf web port";
|
|
default = 8113;
|
|
};
|
|
|
|
ssl = lib.mkOption {
|
|
description = "Path to SSL files";
|
|
type = lib.types.nullOr shb.contracts.ssl.certs;
|
|
default = null;
|
|
};
|
|
|
|
extraServiceConfig = lib.mkOption {
|
|
type = lib.types.attrsOf lib.types.str;
|
|
description = "Extra configuration given to the systemd service file.";
|
|
default = { };
|
|
example = lib.literalExpression ''
|
|
{
|
|
MemoryHigh = "512M";
|
|
MemoryMax = "900M";
|
|
}
|
|
'';
|
|
};
|
|
|
|
sso = lib.mkOption {
|
|
description = "SSO configuration.";
|
|
default = { };
|
|
type = lib.types.submodule {
|
|
options = {
|
|
enable = lib.mkEnableOption "SSO";
|
|
|
|
provider = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "OIDC provider name";
|
|
default = "Authelia";
|
|
};
|
|
|
|
endpoint = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "OIDC endpoint for SSO";
|
|
example = "https://authelia.example.com";
|
|
};
|
|
|
|
clientID = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Client ID for the OIDC endpoint";
|
|
default = "audiobookshelf";
|
|
};
|
|
|
|
adminUserGroup = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "OIDC admin group";
|
|
default = "audiobookshelf_admin";
|
|
};
|
|
|
|
userGroup = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "OIDC user group";
|
|
default = "audiobookshelf_user";
|
|
};
|
|
|
|
authorization_policy = lib.mkOption {
|
|
type = lib.types.enum [
|
|
"one_factor"
|
|
"two_factor"
|
|
];
|
|
description = "Require one factor (password) or two factor (device) authentication.";
|
|
default = "one_factor";
|
|
};
|
|
|
|
sharedSecret = lib.mkOption {
|
|
description = "OIDC shared secret for Audiobookshelf.";
|
|
type = lib.types.submodule {
|
|
options = shb.contracts.secret.mkRequester {
|
|
mode = "0440";
|
|
owner = "audiobookshelf";
|
|
group = "audiobookshelf";
|
|
restartUnits = [ "audiobookshelfd.service" ];
|
|
};
|
|
};
|
|
};
|
|
|
|
sharedSecretForAuthelia = lib.mkOption {
|
|
description = "OIDC shared secret for Authelia.";
|
|
type = lib.types.submodule {
|
|
options = shb.contracts.secret.mkRequester {
|
|
mode = "0400";
|
|
ownerText = "config.shb.authelia.autheliaUser";
|
|
owner = config.shb.authelia.autheliaUser;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
backup = lib.mkOption {
|
|
description = ''
|
|
Backup configuration.
|
|
'';
|
|
type = lib.types.submodule {
|
|
options = shb.contracts.backup.mkRequester {
|
|
user = "audiobookshelf";
|
|
sourceDirectories = [
|
|
"/var/lib/audiobookshelf"
|
|
];
|
|
};
|
|
};
|
|
};
|
|
|
|
logLevel = lib.mkOption {
|
|
type = lib.types.nullOr (
|
|
lib.types.enum [
|
|
"critical"
|
|
"error"
|
|
"warning"
|
|
"info"
|
|
"debug"
|
|
]
|
|
);
|
|
description = "Enable logging.";
|
|
default = false;
|
|
example = true;
|
|
};
|
|
|
|
dashboard = lib.mkOption {
|
|
description = ''
|
|
Dashboard contract consumer
|
|
'';
|
|
default = { };
|
|
type = lib.types.submodule {
|
|
options = shb.contracts.dashboard.mkRequester {
|
|
externalUrl = "https://${cfg.subdomain}.${cfg.domain}";
|
|
externalUrlText = "https://\${config.shb.audiobookshelf.subdomain}.\${config.shb.audiobookshelf.domain}";
|
|
internalUrl = "http://127.0.0.1:${toString cfg.webPort}";
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable (
|
|
lib.mkMerge [
|
|
{
|
|
|
|
services.audiobookshelf = {
|
|
enable = true;
|
|
openFirewall = true;
|
|
dataDir = "audiobookshelf";
|
|
host = "127.0.0.1";
|
|
port = cfg.webPort;
|
|
};
|
|
|
|
services.nginx.enable = true;
|
|
services.nginx.virtualHosts."${fqdn}" = {
|
|
http2 = true;
|
|
forceSSL = !(isNull cfg.ssl);
|
|
sslCertificate = lib.mkIf (!(isNull cfg.ssl)) cfg.ssl.paths.cert;
|
|
sslCertificateKey = lib.mkIf (!(isNull cfg.ssl)) cfg.ssl.paths.key;
|
|
|
|
# https://github.com/advplyr/audiobookshelf#nginx-reverse-proxy
|
|
extraConfig = ''
|
|
set $audiobookshelf 127.0.0.1;
|
|
location / {
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
|
|
proxy_http_version 1.1;
|
|
|
|
proxy_pass http://$audiobookshelf:${builtins.toString cfg.webPort};
|
|
proxy_redirect http:// https://;
|
|
}
|
|
'';
|
|
};
|
|
|
|
shb.authelia.extraDefinitions = {
|
|
user_attributes.${roleClaim}.expression =
|
|
''"${cfg.sso.adminUserGroup}" in groups ? ["admin"] : ("${cfg.sso.userGroup}" in groups ? ["user"] : [""])'';
|
|
};
|
|
|
|
shb.authelia.extraOidcClaimsPolicies.${roleClaim} = {
|
|
custom_claims = {
|
|
"${roleClaim}" = { };
|
|
};
|
|
};
|
|
|
|
shb.authelia.extraOidcScopes."${roleClaim}" = {
|
|
claims = [ "${roleClaim}" ];
|
|
};
|
|
|
|
shb.authelia.oidcClients = lib.lists.optionals cfg.sso.enable [
|
|
{
|
|
client_id = cfg.sso.clientID;
|
|
client_name = "Audiobookshelf";
|
|
client_secret.source = cfg.sso.sharedSecretForAuthelia.result.path;
|
|
claims_policy = "${roleClaim}";
|
|
public = false;
|
|
authorization_policy = cfg.sso.authorization_policy;
|
|
redirect_uris = [
|
|
"https://${cfg.subdomain}.${cfg.domain}/auth/openid/callback"
|
|
"https://${cfg.subdomain}.${cfg.domain}/auth/openid/mobile-redirect"
|
|
];
|
|
scopes = [
|
|
"openid"
|
|
"profile"
|
|
"email"
|
|
"groups"
|
|
"${roleClaim}"
|
|
];
|
|
require_pkce = true;
|
|
pkce_challenge_method = "S256";
|
|
userinfo_signed_response_alg = "none";
|
|
token_endpoint_auth_method = "client_secret_basic";
|
|
}
|
|
];
|
|
}
|
|
{
|
|
systemd.services.audiobookshelfd.serviceConfig = cfg.extraServiceConfig;
|
|
}
|
|
]
|
|
);
|
|
}
|