#587 Implement SHB module for paperless service
This commit is contained in:
parent
879254bcfd
commit
fd676bdef7
3 changed files with 630 additions and 0 deletions
|
|
@ -302,6 +302,7 @@
|
||||||
// (vm_test "karakeep" ./test/services/karakeep.nix)
|
// (vm_test "karakeep" ./test/services/karakeep.nix)
|
||||||
// (vm_test "nextcloud" ./test/services/nextcloud.nix)
|
// (vm_test "nextcloud" ./test/services/nextcloud.nix)
|
||||||
// (vm_test "open-webui" ./test/services/open-webui.nix)
|
// (vm_test "open-webui" ./test/services/open-webui.nix)
|
||||||
|
// (vm_test "paperless" ./test/services/paperless.nix)
|
||||||
// (vm_test "pinchflat" ./test/services/pinchflat.nix)
|
// (vm_test "pinchflat" ./test/services/pinchflat.nix)
|
||||||
// (vm_test "vaultwarden" ./test/services/vaultwarden.nix)
|
// (vm_test "vaultwarden" ./test/services/vaultwarden.nix)
|
||||||
|
|
||||||
|
|
@ -410,6 +411,7 @@
|
||||||
self.nixosModules.nextcloud-server
|
self.nixosModules.nextcloud-server
|
||||||
self.nixosModules.open-webui
|
self.nixosModules.open-webui
|
||||||
self.nixosModules.pinchflat
|
self.nixosModules.pinchflat
|
||||||
|
self.nixosModules.paperless
|
||||||
self.nixosModules.vaultwarden
|
self.nixosModules.vaultwarden
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
@ -442,6 +444,7 @@
|
||||||
nixosModules.karakeep = modules/services/karakeep.nix;
|
nixosModules.karakeep = modules/services/karakeep.nix;
|
||||||
nixosModules.nextcloud-server = modules/services/nextcloud-server.nix;
|
nixosModules.nextcloud-server = modules/services/nextcloud-server.nix;
|
||||||
nixosModules.open-webui = modules/services/open-webui.nix;
|
nixosModules.open-webui = modules/services/open-webui.nix;
|
||||||
|
nixosModules.paperless = modules/services/paperless.nix;
|
||||||
nixosModules.pinchflat = modules/services/pinchflat.nix;
|
nixosModules.pinchflat = modules/services/pinchflat.nix;
|
||||||
nixosModules.vaultwarden = modules/services/vaultwarden.nix;
|
nixosModules.vaultwarden = modules/services/vaultwarden.nix;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
447
modules/services/paperless.nix
Normal file
447
modules/services/paperless.nix
Normal file
|
|
@ -0,0 +1,447 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.shb.paperless;
|
||||||
|
contracts = pkgs.callPackage ../contracts { };
|
||||||
|
dataFolder = cfg.dataDir;
|
||||||
|
fqdn = "${cfg.subdomain}.${cfg.domain}";
|
||||||
|
protocol = if !(isNull cfg.ssl) then "https" else "http";
|
||||||
|
ssoFqdnWithPort =
|
||||||
|
if isNull cfg.sso.port then cfg.sso.endpoint else "${cfg.sso.endpoint}:${toString cfg.sso.port}";
|
||||||
|
|
||||||
|
ssoClientSettings = {
|
||||||
|
openid_connect = {
|
||||||
|
SCOPE = [
|
||||||
|
"openid"
|
||||||
|
"profile"
|
||||||
|
"email"
|
||||||
|
"groups"
|
||||||
|
];
|
||||||
|
OAUTH_PKCE_ENABLED = true;
|
||||||
|
APPS = [
|
||||||
|
{
|
||||||
|
provider_id = "${cfg.sso.provider}";
|
||||||
|
name = "${cfg.sso.provider}";
|
||||||
|
client_id = "${cfg.sso.clientID}";
|
||||||
|
secret = "%SECRET_CLIENT_SECRET_PLACEHOLDER%";
|
||||||
|
settings = {
|
||||||
|
server_url = ssoFqdnWithPort;
|
||||||
|
token_auth_method = "client_secret_basic";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
ssoClientSettingsFile = pkgs.writeText "paperless-sso-client.env" ''
|
||||||
|
PAPERLESS_SOCIALACCOUNT_PROVIDERS=${builtins.toJSON ssoClientSettings}
|
||||||
|
'';
|
||||||
|
replacements = [
|
||||||
|
{
|
||||||
|
# Note: replaceSecretsScript prepends '%SECRET_' and appends '%'
|
||||||
|
# when doing the replacement
|
||||||
|
name = [ "CLIENT_SECRET_PLACEHOLDER" ];
|
||||||
|
source = cfg.sso.sharedSecret.result.path;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
replaceSecretsScript = lib.shb.replaceSecretsScript {
|
||||||
|
file = ssoClientSettingsFile;
|
||||||
|
resultPath = "/run/paperless/paperless-sso-client.env";
|
||||||
|
inherit replacements;
|
||||||
|
user = "paperless";
|
||||||
|
};
|
||||||
|
inherit (lib)
|
||||||
|
mkEnableOption
|
||||||
|
mkIf
|
||||||
|
lists
|
||||||
|
mkOption
|
||||||
|
optionals
|
||||||
|
;
|
||||||
|
inherit (lib.types)
|
||||||
|
attrs
|
||||||
|
attrsOf
|
||||||
|
bool
|
||||||
|
enum
|
||||||
|
listOf
|
||||||
|
nullOr
|
||||||
|
port
|
||||||
|
submodule
|
||||||
|
str
|
||||||
|
path
|
||||||
|
;
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
../blocks/nginx.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
options.shb.paperless = {
|
||||||
|
enable = mkEnableOption "selfhostblocks.paperless";
|
||||||
|
|
||||||
|
subdomain = mkOption {
|
||||||
|
type = str;
|
||||||
|
description = ''
|
||||||
|
Subdomain under which paperless will be served.
|
||||||
|
|
||||||
|
```
|
||||||
|
<subdomain>.<domain>
|
||||||
|
```
|
||||||
|
'';
|
||||||
|
example = "photos";
|
||||||
|
};
|
||||||
|
|
||||||
|
domain = mkOption {
|
||||||
|
description = ''
|
||||||
|
Domain under which paperless is served.
|
||||||
|
|
||||||
|
```
|
||||||
|
<subdomain>.<domain>
|
||||||
|
```
|
||||||
|
'';
|
||||||
|
type = str;
|
||||||
|
example = "example.com";
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
description = ''
|
||||||
|
Port under which paperless will listen.
|
||||||
|
'';
|
||||||
|
type = port;
|
||||||
|
default = 28981;
|
||||||
|
};
|
||||||
|
|
||||||
|
ssl = mkOption {
|
||||||
|
description = "Path to SSL files";
|
||||||
|
type = nullOr contracts.ssl.certs;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
dataDir = mkOption {
|
||||||
|
description = "Directory where paperless will store data files.";
|
||||||
|
type = str;
|
||||||
|
default = "/var/lib/paperless";
|
||||||
|
};
|
||||||
|
|
||||||
|
mediaDir = mkOption {
|
||||||
|
description = "Directory where paperless will store documents.";
|
||||||
|
type = str;
|
||||||
|
defaultText = lib.literalExpression ''"''${dataDir}/media"'';
|
||||||
|
default = "${cfg.dataDir}/media";
|
||||||
|
};
|
||||||
|
|
||||||
|
consumptionDir = mkOption {
|
||||||
|
description = "Directory from which new documents are imported.";
|
||||||
|
type = str;
|
||||||
|
defaultText = lib.literalExpression ''"''${dataDir}/consume"'';
|
||||||
|
default = "${cfg.dataDir}/consume";
|
||||||
|
};
|
||||||
|
|
||||||
|
configureTika = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to configure Tika and Gotenberg to process Office and e-mail files with OCR.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
adminPassword = mkOption {
|
||||||
|
description = "Secret containing the superuser (admin) password.";
|
||||||
|
type = submodule {
|
||||||
|
options = contracts.secret.mkRequester {
|
||||||
|
mode = "0400";
|
||||||
|
owner = "paperless";
|
||||||
|
group = "paperless";
|
||||||
|
restartUnits = [ "paperless-server.service" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = lib.mkOption {
|
||||||
|
type = lib.types.submodule {
|
||||||
|
freeformType =
|
||||||
|
with lib.types;
|
||||||
|
attrsOf (
|
||||||
|
let
|
||||||
|
typeList = [
|
||||||
|
bool
|
||||||
|
float
|
||||||
|
int
|
||||||
|
str
|
||||||
|
path
|
||||||
|
package
|
||||||
|
];
|
||||||
|
in
|
||||||
|
oneOf (
|
||||||
|
typeList
|
||||||
|
++ [
|
||||||
|
(listOf (oneOf typeList))
|
||||||
|
(attrsOf (oneOf typeList))
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
default = { };
|
||||||
|
description = ''
|
||||||
|
Extra paperless config options.
|
||||||
|
|
||||||
|
See [the documentation](https://docs.paperless-ngx.com/configuration/) for available options.
|
||||||
|
|
||||||
|
Note that some settings such as `PAPERLESS_CONSUMER_IGNORE_PATTERN` expect JSON values.
|
||||||
|
Settings declared as lists or attrsets will automatically be serialised into JSON strings for your convenience.
|
||||||
|
'';
|
||||||
|
example = {
|
||||||
|
PAPERLESS_OCR_LANGUAGE = "deu+eng";
|
||||||
|
PAPERLESS_CONSUMER_IGNORE_PATTERN = [
|
||||||
|
".DS_STORE/*"
|
||||||
|
"desktop.ini"
|
||||||
|
];
|
||||||
|
PAPERLESS_OCR_USER_ARGS = {
|
||||||
|
optimize = 1;
|
||||||
|
pdfa_image_compression = "lossless";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mount = mkOption {
|
||||||
|
type = contracts.mount;
|
||||||
|
description = ''
|
||||||
|
Mount configuration. This is an output option.
|
||||||
|
|
||||||
|
Use it to initialize a block implementing the "mount" contract.
|
||||||
|
For example, with a zfs dataset:
|
||||||
|
|
||||||
|
```
|
||||||
|
shb.zfs.datasets."paperless" = {
|
||||||
|
poolName = "root";
|
||||||
|
} // config.shb.paperless.mount;
|
||||||
|
```
|
||||||
|
'';
|
||||||
|
readOnly = true;
|
||||||
|
default = {
|
||||||
|
path = dataFolder;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
backup = mkOption {
|
||||||
|
description = ''
|
||||||
|
Backup configuration for paperless media files and database.
|
||||||
|
'';
|
||||||
|
default = { };
|
||||||
|
type = submodule {
|
||||||
|
options = contracts.backup.mkRequester {
|
||||||
|
user = "paperless";
|
||||||
|
sourceDirectories = [
|
||||||
|
dataFolder
|
||||||
|
];
|
||||||
|
excludePatterns = [
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
sso = mkOption {
|
||||||
|
description = ''
|
||||||
|
Setup SSO integration.
|
||||||
|
'';
|
||||||
|
default = { };
|
||||||
|
type = submodule {
|
||||||
|
options = {
|
||||||
|
enable = mkEnableOption "SSO integration.";
|
||||||
|
|
||||||
|
provider = mkOption {
|
||||||
|
type = enum [
|
||||||
|
"Authelia"
|
||||||
|
"Keycloak"
|
||||||
|
"Generic"
|
||||||
|
];
|
||||||
|
description = "OIDC provider name, used for display.";
|
||||||
|
default = "Authelia";
|
||||||
|
};
|
||||||
|
|
||||||
|
endpoint = mkOption {
|
||||||
|
type = str;
|
||||||
|
description = "OIDC endpoint for SSO.";
|
||||||
|
example = "https://authelia.example.com";
|
||||||
|
};
|
||||||
|
|
||||||
|
clientID = mkOption {
|
||||||
|
type = str;
|
||||||
|
description = "Client ID for the OIDC endpoint.";
|
||||||
|
default = "paperless";
|
||||||
|
};
|
||||||
|
|
||||||
|
adminUserGroup = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "OIDC admin group";
|
||||||
|
default = "paperless_admin";
|
||||||
|
};
|
||||||
|
|
||||||
|
userGroup = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "OIDC user group";
|
||||||
|
default = "paperless_user";
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
description = "If given, adds a port to the endpoint.";
|
||||||
|
type = nullOr port;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
autoRegister = mkOption {
|
||||||
|
type = bool;
|
||||||
|
description = "Automatically register new users from SSO provider.";
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
autoLaunch = mkOption {
|
||||||
|
type = bool;
|
||||||
|
description = "Automatically redirect to SSO provider.";
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
passwordLogin = mkOption {
|
||||||
|
type = bool;
|
||||||
|
description = "Enable password login.";
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
sharedSecret = mkOption {
|
||||||
|
description = "OIDC shared secret for paperless.";
|
||||||
|
type = submodule {
|
||||||
|
options = contracts.secret.mkRequester {
|
||||||
|
mode = "0400";
|
||||||
|
owner = "paperless";
|
||||||
|
group = "paperless";
|
||||||
|
restartUnits = [ "paperless-server.service" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
sharedSecretForAuthelia = mkOption {
|
||||||
|
description = "OIDC shared secret for Authelia. Content must be the same as `sharedSecret` option.";
|
||||||
|
type = submodule {
|
||||||
|
options = contracts.secret.mkRequester {
|
||||||
|
mode = "0400";
|
||||||
|
owner = "authelia";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
authorization_policy = mkOption {
|
||||||
|
type = enum [
|
||||||
|
"one_factor"
|
||||||
|
"two_factor"
|
||||||
|
];
|
||||||
|
description = "Require one factor (password) or two factor (device) authentication.";
|
||||||
|
default = "one_factor";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = !(isNull cfg.ssl) -> !(isNull cfg.ssl.paths.cert) && !(isNull cfg.ssl.paths.key);
|
||||||
|
message = "SSL is enabled for paperless but no cert or key is provided.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = cfg.sso.enable -> cfg.ssl != null;
|
||||||
|
message = "To integrate SSO, SSL must be enabled, set the shb.paperless.ssl option.";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
# Configure paperless service
|
||||||
|
services.paperless = {
|
||||||
|
enable = true;
|
||||||
|
address = "127.0.0.1";
|
||||||
|
port = cfg.port;
|
||||||
|
consumptionDirIsPublic = true;
|
||||||
|
dataDir = cfg.dataDir;
|
||||||
|
mediaDir = cfg.mediaDir;
|
||||||
|
consumptionDir = cfg.consumptionDir;
|
||||||
|
configureTika = cfg.configureTika;
|
||||||
|
settings = {
|
||||||
|
PAPERLESS_URL = "${protocol}://${fqdn}";
|
||||||
|
}
|
||||||
|
// cfg.settings
|
||||||
|
// lib.optionalAttrs (cfg.sso.enable) {
|
||||||
|
PAPERLESS_APPS = "allauth.socialaccount.providers.openid_connect";
|
||||||
|
PAPERLESS_SOCIAL_AUTO_SIGNUP = cfg.sso.autoRegister;
|
||||||
|
PAPERLESS_SOCIAL_ACCOUNT_SYNC_GROUPS = true;
|
||||||
|
PAPERLESS_DISABLE_REGULAR_LOGIN = !cfg.sso.passwordLogin;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs (cfg.sso.enable) {
|
||||||
|
environmentFile = "/run/paperless/paperless-sso-client.env";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Database defaults to local sqlite
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d ${cfg.dataDir} 0700 paperless paperless"
|
||||||
|
"d ${cfg.consumptionDir} 0700 paperless paperless"
|
||||||
|
"d ${cfg.mediaDir} 0700 paperless paperless"
|
||||||
|
]
|
||||||
|
++ lib.optionals cfg.sso.enable [ "d '/run/paperless' 0750 root root - -" ];
|
||||||
|
|
||||||
|
systemd.services.paperless-pre = lib.mkIf cfg.sso.enable {
|
||||||
|
script = replaceSecretsScript;
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
before = [ "paperless-scheduler.service" ];
|
||||||
|
requiredBy = [ "paperless-scheduler.service" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
shb.nginx.vhosts = [
|
||||||
|
{
|
||||||
|
inherit (cfg) subdomain domain ssl;
|
||||||
|
upstream = "http://127.0.0.1:${toString cfg.port}";
|
||||||
|
autheliaRules = lib.mkIf (cfg.sso.enable) [
|
||||||
|
{
|
||||||
|
domain = fqdn;
|
||||||
|
policy = cfg.sso.authorization_policy;
|
||||||
|
subject = [
|
||||||
|
"group:paperless_user"
|
||||||
|
"group:paperless_admin"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
authEndpoint = lib.mkIf (cfg.sso.enable) cfg.sso.endpoint;
|
||||||
|
extraConfig = ''
|
||||||
|
# See https://github.com/paperless-ngx/paperless-ngx/wiki/Using-a-Reverse-Proxy-with-Paperless-ngx#nginx
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
add_header Referrer-Policy "strict-origin-when-cross-origin";
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
# Allow large uploads
|
||||||
|
services.nginx.virtualHosts."${fqdn}".extraConfig = ''
|
||||||
|
client_max_body_size 500M;
|
||||||
|
'';
|
||||||
|
|
||||||
|
shb.authelia.oidcClients = lists.optionals (cfg.sso.enable && cfg.sso.provider == "Authelia") [
|
||||||
|
{
|
||||||
|
client_id = cfg.sso.clientID;
|
||||||
|
client_name = "paperless";
|
||||||
|
client_secret.source = cfg.sso.sharedSecretForAuthelia.result.path;
|
||||||
|
public = false;
|
||||||
|
authorization_policy = cfg.sso.authorization_policy;
|
||||||
|
token_endpoint_auth_method = "client_secret_basic";
|
||||||
|
redirect_uris = [
|
||||||
|
"${protocol}://${fqdn}/accounts/oidc/${cfg.sso.provider}/login/callback/"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
180
test/services/paperless.nix
Normal file
180
test/services/paperless.nix
Normal file
|
|
@ -0,0 +1,180 @@
|
||||||
|
{ pkgs, lib }:
|
||||||
|
let
|
||||||
|
subdomain = "p";
|
||||||
|
domain = "example.com";
|
||||||
|
|
||||||
|
commonTestScript = lib.shb.accessScript {
|
||||||
|
hasSSL = { node, ... }: !(isNull node.config.shb.paperless.ssl);
|
||||||
|
waitForServices =
|
||||||
|
{ ... }:
|
||||||
|
[
|
||||||
|
"paperless-web.service"
|
||||||
|
"nginx.service"
|
||||||
|
];
|
||||||
|
waitForPorts =
|
||||||
|
{ ... }:
|
||||||
|
[
|
||||||
|
28981
|
||||||
|
80
|
||||||
|
];
|
||||||
|
waitForUrls = { proto_fqdn, ... }: [ "${proto_fqdn}" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
base =
|
||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
lib.shb.baseModule
|
||||||
|
../../modules/services/paperless.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
virtualisation.memorySize = 4096;
|
||||||
|
virtualisation.cores = 2;
|
||||||
|
|
||||||
|
test = {
|
||||||
|
inherit subdomain domain;
|
||||||
|
};
|
||||||
|
|
||||||
|
shb.paperless = {
|
||||||
|
enable = true;
|
||||||
|
inherit subdomain domain;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Required for tests
|
||||||
|
environment.systemPackages = [ pkgs.curl ];
|
||||||
|
};
|
||||||
|
|
||||||
|
basic =
|
||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
imports = [ base ];
|
||||||
|
|
||||||
|
test.hasSSL = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
https =
|
||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
base
|
||||||
|
lib.shb.certs
|
||||||
|
];
|
||||||
|
|
||||||
|
test.hasSSL = true;
|
||||||
|
shb.paperless.ssl = config.shb.certs.certs.selfsigned.n;
|
||||||
|
};
|
||||||
|
|
||||||
|
backup =
|
||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
https
|
||||||
|
(lib.shb.backup config.shb.paperless.backup)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
sso =
|
||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
https
|
||||||
|
lib.shb.ldap
|
||||||
|
(lib.shb.sso config.shb.certs.certs.selfsigned.n)
|
||||||
|
];
|
||||||
|
|
||||||
|
shb.paperless.sso = {
|
||||||
|
enable = true;
|
||||||
|
provider = "Authelia";
|
||||||
|
endpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}";
|
||||||
|
clientID = "paperless";
|
||||||
|
autoLaunch = true;
|
||||||
|
sharedSecret.result = config.shb.hardcodedsecret.paperlessSSOSecret.result;
|
||||||
|
sharedSecretForAuthelia.result = config.shb.hardcodedsecret.paperlessSSOSecretAuthelia.result;
|
||||||
|
};
|
||||||
|
|
||||||
|
shb.hardcodedsecret.paperlessSSOSecret = {
|
||||||
|
request = config.shb.paperless.sso.sharedSecret.request;
|
||||||
|
settings.content = "paperlessSSOSecret";
|
||||||
|
};
|
||||||
|
|
||||||
|
shb.hardcodedsecret.paperlessSSOSecretAuthelia = {
|
||||||
|
request = config.shb.paperless.sso.sharedSecretForAuthelia.request;
|
||||||
|
settings.content = "paperlessSSOSecret";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configure LDAP groups for group-based access control
|
||||||
|
shb.lldap.ensureGroups.paperless_user = { };
|
||||||
|
|
||||||
|
shb.lldap.ensureUsers.paperless_test_user = {
|
||||||
|
email = "paperless_user@example.com";
|
||||||
|
groups = [ "paperless_user" ];
|
||||||
|
password.result = config.shb.hardcodedsecret.ldappaperlessUserPassword.result;
|
||||||
|
};
|
||||||
|
|
||||||
|
shb.lldap.ensureUsers.regular_test_user = {
|
||||||
|
email = "regular_user@example.com";
|
||||||
|
groups = [ ];
|
||||||
|
password.result = config.shb.hardcodedsecret.ldapRegularUserPassword.result;
|
||||||
|
};
|
||||||
|
|
||||||
|
shb.hardcodedsecret.ldappaperlessUserPassword = {
|
||||||
|
request = config.shb.lldap.ensureUsers.paperless_test_user.password.request;
|
||||||
|
settings.content = "paperless_user_password";
|
||||||
|
};
|
||||||
|
|
||||||
|
shb.hardcodedsecret.ldapRegularUserPassword = {
|
||||||
|
request = config.shb.lldap.ensureUsers.regular_test_user.password.request;
|
||||||
|
settings.content = "regular_user_password";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
basic = pkgs.nixosTest {
|
||||||
|
name = "paperless-basic";
|
||||||
|
|
||||||
|
nodes.server = basic;
|
||||||
|
nodes.client = { };
|
||||||
|
|
||||||
|
testScript = commonTestScript;
|
||||||
|
};
|
||||||
|
|
||||||
|
https = pkgs.nixosTest {
|
||||||
|
name = "paperless-https";
|
||||||
|
|
||||||
|
nodes.server = https;
|
||||||
|
nodes.client = { };
|
||||||
|
|
||||||
|
testScript = commonTestScript;
|
||||||
|
};
|
||||||
|
|
||||||
|
sso = pkgs.nixosTest {
|
||||||
|
name = "paperless-https";
|
||||||
|
|
||||||
|
nodes.server = sso;
|
||||||
|
nodes.client = { };
|
||||||
|
|
||||||
|
testScript = commonTestScript;
|
||||||
|
};
|
||||||
|
|
||||||
|
backup = pkgs.nixosTest {
|
||||||
|
name = "paperless-backup";
|
||||||
|
|
||||||
|
nodes.server = backup;
|
||||||
|
nodes.client = { };
|
||||||
|
|
||||||
|
testScript =
|
||||||
|
(lib.shb.mkScripts {
|
||||||
|
hasSSL = args: !(isNull args.node.config.shb.paperless.ssl);
|
||||||
|
waitForServices = args: [
|
||||||
|
"paperless-web.service"
|
||||||
|
"nginx.service"
|
||||||
|
];
|
||||||
|
waitForPorts = args: [
|
||||||
|
28981
|
||||||
|
80
|
||||||
|
];
|
||||||
|
waitForUrls = args: [ "${args.proto_fqdn}" ];
|
||||||
|
}).backup;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue