mirror of
https://github.com/ilyakooo0/nixpkgs.git
synced 2024-12-29 06:45:54 +03:00
nixos/codimd: add module
This commit is contained in:
parent
a31a917eb9
commit
db846a88a8
@ -683,6 +683,7 @@
|
||||
./services/web-apps/atlassian/confluence.nix
|
||||
./services/web-apps/atlassian/crowd.nix
|
||||
./services/web-apps/atlassian/jira.nix
|
||||
./services/web-apps/codimd.nix
|
||||
./services/web-apps/frab.nix
|
||||
./services/web-apps/mattermost.nix
|
||||
./services/web-apps/nexus.nix
|
||||
|
958
nixos/modules/services/web-apps/codimd.nix
Normal file
958
nixos/modules/services/web-apps/codimd.nix
Normal file
@ -0,0 +1,958 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.codimd;
|
||||
|
||||
prettyJSON = conf:
|
||||
pkgs.runCommand "codimd-config.json" { } ''
|
||||
echo '${builtins.toJSON conf}' | ${pkgs.jq}/bin/jq \
|
||||
'{production:del(.[]|nulls)|del(.[][]?|nulls)}' > $out
|
||||
'';
|
||||
in
|
||||
{
|
||||
options.services.codimd = {
|
||||
enable = mkEnableOption "the CodiMD Markdown Editor";
|
||||
|
||||
groups = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
Groups to which the codimd user should be added.
|
||||
'';
|
||||
};
|
||||
|
||||
workDir = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/codimd";
|
||||
description = ''
|
||||
Working directory for the CodiMD service.
|
||||
'';
|
||||
};
|
||||
|
||||
configuration = {
|
||||
debug = mkEnableOption "debug mode";
|
||||
domain = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "codimd.org";
|
||||
description = ''
|
||||
Domain name for the CodiMD instance.
|
||||
'';
|
||||
};
|
||||
urlPath = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "/url/path/to/codimd";
|
||||
description = ''
|
||||
Path under which CodiMD is accessible.
|
||||
'';
|
||||
};
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
description = ''
|
||||
Address to listen on.
|
||||
'';
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.int;
|
||||
default = 3000;
|
||||
example = "80";
|
||||
description = ''
|
||||
Port to listen on.
|
||||
'';
|
||||
};
|
||||
path = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "/var/run/codimd.sock";
|
||||
description = ''
|
||||
Specify where a UNIX domain socket should be placed.
|
||||
'';
|
||||
};
|
||||
allowOrigin = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "localhost" "codimd.org" ];
|
||||
description = ''
|
||||
List of domains to whitelist.
|
||||
'';
|
||||
};
|
||||
useSSL = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable to use SSL server. This will also enable
|
||||
<option>protocolUseSSL</option>.
|
||||
'';
|
||||
};
|
||||
hsts = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Wheter to enable HSTS if HTTPS is also enabled.
|
||||
'';
|
||||
};
|
||||
maxAgeSeconds = mkOption {
|
||||
type = types.int;
|
||||
default = 31536000;
|
||||
description = ''
|
||||
Max duration for clients to keep the HSTS status.
|
||||
'';
|
||||
};
|
||||
includeSubdomains = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to include subdomains in HSTS.
|
||||
'';
|
||||
};
|
||||
preload = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to allow preloading of the site's HSTS status.
|
||||
'';
|
||||
};
|
||||
};
|
||||
csp = mkOption {
|
||||
type = types.nullOr types.attrs;
|
||||
default = null;
|
||||
example = literalExample ''
|
||||
{
|
||||
enable = true;
|
||||
directives = {
|
||||
scriptSrc = "trustworthy.scripts.example.com";
|
||||
};
|
||||
upgradeInsecureRequest = "auto";
|
||||
addDefaults = true;
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Specify the Content Security Policy which is passed to Helmet.
|
||||
For configuration details see <link xlink:href="https://helmetjs.github.io/docs/csp/"
|
||||
>https://helmetjs.github.io/docs/csp/</link>.
|
||||
'';
|
||||
};
|
||||
protocolUseSSL = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable to use TLS for resource paths.
|
||||
This only applies when <option>domain</option> is set.
|
||||
'';
|
||||
};
|
||||
urlAddPort = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable to add the port to callback URLs.
|
||||
This only applies when <option>domain</option> is set
|
||||
and only for ports other than 80 and 443.
|
||||
'';
|
||||
};
|
||||
useCDN = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to use CDN resources or not.
|
||||
'';
|
||||
};
|
||||
allowAnonymous = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to allow anonymous usage.
|
||||
'';
|
||||
};
|
||||
allowAnonymousEdits = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to allow guests to edit existing notes with the `freely' permission,
|
||||
when <option>allowAnonymous</option> is enabled.
|
||||
'';
|
||||
};
|
||||
allowFreeURL = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to allow note creation by accessing a nonexistent note URL.
|
||||
'';
|
||||
};
|
||||
defaultPermission = mkOption {
|
||||
type = types.enum [ "freely" "editable" "limited" "locked" "private" ];
|
||||
default = "editable";
|
||||
description = ''
|
||||
Default permissions for notes.
|
||||
This only applies for signed-in users.
|
||||
'';
|
||||
};
|
||||
dbURL = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = ''
|
||||
postgres://user:pass@host:5432/dbname
|
||||
'';
|
||||
description = ''
|
||||
Specify which database to use.
|
||||
CodiMD supports mysql, postgres, sqlite and mssql.
|
||||
See <link xlink:href="https://sequelize.readthedocs.io/en/v3/">
|
||||
https://sequelize.readthedocs.io/en/v3/</link> for more information.
|
||||
Note: This option overrides <option>db</option>.
|
||||
'';
|
||||
};
|
||||
db = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
example = literalExample ''
|
||||
{
|
||||
dialect = "sqlite";
|
||||
storage = "/var/lib/codimd/db.codimd.sqlite";
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Specify the configuration for sequelize.
|
||||
CodiMD supports mysql, postgres, sqlite and mssql.
|
||||
See <link xlink:href="https://sequelize.readthedocs.io/en/v3/">
|
||||
https://sequelize.readthedocs.io/en/v3/</link> for more information.
|
||||
Note: This option overrides <option>db</option>.
|
||||
'';
|
||||
};
|
||||
sslKeyPath= mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "/var/lib/codimd/codimd.key";
|
||||
description = ''
|
||||
Path to the SSL key. Needed when <option>useSSL</option> is enabled.
|
||||
'';
|
||||
};
|
||||
sslCertPath = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "/var/lib/codimd/codimd.crt";
|
||||
description = ''
|
||||
Path to the SSL cert. Needed when <option>useSSL</option> is enabled.
|
||||
'';
|
||||
};
|
||||
sslCAPath = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "/var/lib/codimd/ca.crt" ];
|
||||
description = ''
|
||||
SSL ca chain. Needed when <option>useSSL</option> is enabled.
|
||||
'';
|
||||
};
|
||||
dhParamPath = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "/var/lib/codimd/dhparam.pem";
|
||||
description = ''
|
||||
Path to the SSL dh params. Needed when <option>useSSL</option> is enabled.
|
||||
'';
|
||||
};
|
||||
tmpPath = mkOption {
|
||||
type = types.str;
|
||||
default = "/tmp";
|
||||
description = ''
|
||||
Path to the temp directory CodiMD should use.
|
||||
Note that <option>serviceConfig.PrivateTmp</option> is enabled for
|
||||
the CodiMD systemd service by default.
|
||||
(Non-canonical paths are relative to CodiMD's base directory)
|
||||
'';
|
||||
};
|
||||
defaultNotePath = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "./public/default.md";
|
||||
description = ''
|
||||
Path to the default Note file.
|
||||
(Non-canonical paths are relative to CodiMD's base directory)
|
||||
'';
|
||||
};
|
||||
docsPath = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "./public/docs";
|
||||
description = ''
|
||||
Path to the docs directory.
|
||||
(Non-canonical paths are relative to CodiMD's base directory)
|
||||
'';
|
||||
};
|
||||
indexPath = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "./public/views/index.ejs";
|
||||
description = ''
|
||||
Path to the index template file.
|
||||
(Non-canonical paths are relative to CodiMD's base directory)
|
||||
'';
|
||||
};
|
||||
hackmdPath = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "./public/views/hackmd.ejs";
|
||||
description = ''
|
||||
Path to the hackmd template file.
|
||||
(Non-canonical paths are relative to CodiMD's base directory)
|
||||
'';
|
||||
};
|
||||
errorPath = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
defaultText = "./public/views/error.ejs";
|
||||
description = ''
|
||||
Path to the error template file.
|
||||
(Non-canonical paths are relative to CodiMD's base directory)
|
||||
'';
|
||||
};
|
||||
prettyPath = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
defaultText = "./public/views/pretty.ejs";
|
||||
description = ''
|
||||
Path to the pretty template file.
|
||||
(Non-canonical paths are relative to CodiMD's base directory)
|
||||
'';
|
||||
};
|
||||
slidePath = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
defaultText = "./public/views/slide.hbs";
|
||||
description = ''
|
||||
Path to the slide template file.
|
||||
(Non-canonical paths are relative to CodiMD's base directory)
|
||||
'';
|
||||
};
|
||||
uploadsPath = mkOption {
|
||||
type = types.str;
|
||||
default = "${cfg.workDir}/uploads";
|
||||
defaultText = "/var/lib/codimd/uploads";
|
||||
description = ''
|
||||
Path under which uploaded files are saved.
|
||||
'';
|
||||
};
|
||||
sessionName = mkOption {
|
||||
type = types.str;
|
||||
default = "connect.sid";
|
||||
description = ''
|
||||
Specify the name of the session cookie.
|
||||
'';
|
||||
};
|
||||
sessionSecret = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Specify the secret used to sign the session cookie.
|
||||
If unset, one will be generated on startup.
|
||||
'';
|
||||
};
|
||||
sessionLife = mkOption {
|
||||
type = types.int;
|
||||
default = 1209600000;
|
||||
description = ''
|
||||
Session life time in milliseconds.
|
||||
'';
|
||||
};
|
||||
heartbeatInterval = mkOption {
|
||||
type = types.int;
|
||||
default = 5000;
|
||||
description = ''
|
||||
Specify the socket.io heartbeat interval.
|
||||
'';
|
||||
};
|
||||
heartbeatTimeout = mkOption {
|
||||
type = types.int;
|
||||
default = 10000;
|
||||
description = ''
|
||||
Specify the socket.io heartbeat timeout.
|
||||
'';
|
||||
};
|
||||
documentMaxLength = mkOption {
|
||||
type = types.int;
|
||||
default = 100000;
|
||||
description = ''
|
||||
Specify the maximum document length.
|
||||
'';
|
||||
};
|
||||
email = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to enable email sign-in.
|
||||
'';
|
||||
};
|
||||
allowEmailRegister = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Wether to enable email registration.
|
||||
'';
|
||||
};
|
||||
allowGravatar = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to use gravatar as profile picture source.
|
||||
'';
|
||||
};
|
||||
imageUploadType = mkOption {
|
||||
type = types.enum [ "imgur" "s3" "minio" "filesystem" ];
|
||||
default = "filesystem";
|
||||
description = ''
|
||||
Specify where to upload images.
|
||||
'';
|
||||
};
|
||||
minio = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
accessKey = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Minio access key.
|
||||
'';
|
||||
};
|
||||
secretKey = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Minio secret key.
|
||||
'';
|
||||
};
|
||||
endpoint = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Minio endpoint.
|
||||
'';
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.int;
|
||||
default = 9000;
|
||||
description = ''
|
||||
Minio listen port.
|
||||
'';
|
||||
};
|
||||
secure = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to use HTTPS for Minio.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = "Configure the minio third-party integration.";
|
||||
};
|
||||
s3 = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
accessKeyId = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
AWS access key id.
|
||||
'';
|
||||
};
|
||||
secretAccessKey = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
AWS access key.
|
||||
'';
|
||||
};
|
||||
region = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
AWS S3 region.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = "Configure the s3 third-party integration.";
|
||||
};
|
||||
s3bucket = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Specify the bucket name for upload types <literal>s3</literal> and <literal>minio</literal>.
|
||||
'';
|
||||
};
|
||||
allowPDFExport = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to enable PDF exports.
|
||||
'';
|
||||
};
|
||||
imgur.clientId = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Imgur API client ID.
|
||||
'';
|
||||
};
|
||||
azure = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
connectionString = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Azure Blob Storage connection string.
|
||||
'';
|
||||
};
|
||||
container = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Azure Blob Storage container name.
|
||||
It will be created if non-existent.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = "Configure the azure third-party integration.";
|
||||
};
|
||||
oauth2 = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
authorizationURL = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Specify the OAuth authorization URL.
|
||||
'';
|
||||
};
|
||||
tokenURL = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Specify the OAuth token URL.
|
||||
'';
|
||||
};
|
||||
clientID = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Specify the OAuth client ID.
|
||||
'';
|
||||
};
|
||||
clientSecret = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Specify the OAuth client secret.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = "Configure the OAuth integration.";
|
||||
};
|
||||
facebook = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
clientID = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Facebook API client ID.
|
||||
'';
|
||||
};
|
||||
clientSecret = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Facebook API client secret.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = "Configure the facebook third-party integration";
|
||||
};
|
||||
twitter = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
consumerKey = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Twitter API consumer key.
|
||||
'';
|
||||
};
|
||||
consumerSecret = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Twitter API consumer secret.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = "Configure the Twitter third-party integration.";
|
||||
};
|
||||
github = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
clientID = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
GitHub API client ID.
|
||||
'';
|
||||
};
|
||||
clientSecret = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Github API client secret.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = "Configure the GitHub third-party integration.";
|
||||
};
|
||||
gitlab = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
baseURL = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
GitLab API authentication endpoint.
|
||||
Only needed for other endpoints than gitlab.com.
|
||||
'';
|
||||
};
|
||||
clientID = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
GitLab API client ID.
|
||||
'';
|
||||
};
|
||||
clientSecret = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
GitLab API client secret.
|
||||
'';
|
||||
};
|
||||
scope = mkOption {
|
||||
type = types.enum [ "api" "read_user" ];
|
||||
default = "api";
|
||||
description = ''
|
||||
GitLab API requested scope.
|
||||
GitLab snippet import/export requires api scope.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = "Configure the GitLab third-party integration.";
|
||||
};
|
||||
mattermost = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
baseURL = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Mattermost authentication endpoint.
|
||||
'';
|
||||
};
|
||||
clientID = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Mattermost API client ID.
|
||||
'';
|
||||
};
|
||||
clientSecret = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Mattermost API client secret.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = "Configure the Mattermost third-party integration.";
|
||||
};
|
||||
dropbox = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
clientID = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Dropbox API client ID.
|
||||
'';
|
||||
};
|
||||
clientSecret = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Dropbox API client secret.
|
||||
'';
|
||||
};
|
||||
appKey = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Dropbox app key.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = "Configure the Dropbox third-party integration.";
|
||||
};
|
||||
google = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
clientID = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Google API client ID.
|
||||
'';
|
||||
};
|
||||
clientSecret = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Google API client secret.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = "Configure the Google third-party integration.";
|
||||
};
|
||||
ldap = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
providerName = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Optional name to be displayed at login form, indicating the LDAP provider.
|
||||
'';
|
||||
};
|
||||
url = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "ldap://localhost";
|
||||
description = ''
|
||||
URL of LDAP server.
|
||||
'';
|
||||
};
|
||||
bindDn = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Bind DN for LDAP access.
|
||||
'';
|
||||
};
|
||||
bindCredentials = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Bind credentials for LDAP access.
|
||||
'';
|
||||
};
|
||||
searchBase = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "o=users,dc=example,dc=com";
|
||||
description = ''
|
||||
LDAP directory to begin search from.
|
||||
'';
|
||||
};
|
||||
searchFilter = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "(uid={{username}})";
|
||||
description = ''
|
||||
LDAP filter to search with.
|
||||
'';
|
||||
};
|
||||
searchAttributes = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "displayName" "mail" ];
|
||||
description = ''
|
||||
LDAP attributes to search with.
|
||||
'';
|
||||
};
|
||||
userNameField = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
LDAP field which is used as the username on CodiMD.
|
||||
By default <option>useridField</option> is used.
|
||||
'';
|
||||
};
|
||||
useridField = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "uid";
|
||||
description = ''
|
||||
LDAP field which is a unique identifier for users on CodiMD.
|
||||
'';
|
||||
};
|
||||
tlsca = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "server-cert.pem,root.pem";
|
||||
description = ''
|
||||
Root CA for LDAP TLS in PEM format.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = "Configure the LDAP integration.";
|
||||
};
|
||||
saml = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
idpSsoUrl = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "https://idp.example.com/sso";
|
||||
description = ''
|
||||
IdP authentication endpoint.
|
||||
'';
|
||||
};
|
||||
idPCert = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "/path/to/cert.pem";
|
||||
description = ''
|
||||
Path to IdP certificate file in PEM format.
|
||||
'';
|
||||
};
|
||||
issuer = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Optional identity of the service provider.
|
||||
This defaults to the server URL.
|
||||
'';
|
||||
};
|
||||
identifierFormat = mkOption {
|
||||
type = types.str;
|
||||
default = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress";
|
||||
description = ''
|
||||
Optional name identifier format.
|
||||
'';
|
||||
};
|
||||
groupAttribute = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
example = "memberOf";
|
||||
description = ''
|
||||
Optional attribute name for group list.
|
||||
'';
|
||||
};
|
||||
externalGroups = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "Temporary-staff" "External-users" ];
|
||||
description = ''
|
||||
Excluded group names.
|
||||
'';
|
||||
};
|
||||
requiredGroups = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "Hackmd-users" "Codimd-users" ];
|
||||
description = ''
|
||||
Required group names.
|
||||
'';
|
||||
};
|
||||
attribute = {
|
||||
id = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Attribute map for `id'.
|
||||
Defaults to `NameID' of SAML response.
|
||||
'';
|
||||
};
|
||||
username = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Attribute map for `username'.
|
||||
Defaults to `NameID' of SAML response.
|
||||
'';
|
||||
};
|
||||
email = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Attribute map for `email'.
|
||||
Defaults to `NameID' of SAML response if
|
||||
<option>identifierFormat</option> has
|
||||
the default value.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
description = "Configure the SAML integration.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{ assertion = cfg.configuration.db == {} -> (
|
||||
cfg.configuration.dbURL != "" && cfg.configuration.dbURL != null
|
||||
);
|
||||
message = "Database configuration for CodiMD missing."; }
|
||||
];
|
||||
users.groups.codimd = {};
|
||||
users.users.codimd = {
|
||||
description = "CodiMD service user";
|
||||
group = "codimd";
|
||||
extraGroups = cfg.groups;
|
||||
home = cfg.workDir;
|
||||
createHome = true;
|
||||
};
|
||||
|
||||
systemd.services.codimd = {
|
||||
description = "CodiMD Service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "networking.target" ];
|
||||
preStart = ''
|
||||
mkdir -p ${cfg.workDir}
|
||||
chown -R codimd: ${cfg.workDir}
|
||||
'';
|
||||
serviceConfig = {
|
||||
WorkingDirectory = cfg.workDir;
|
||||
ExecStart = "${pkgs.codimd}/bin/codimd";
|
||||
Environment = [
|
||||
"CMD_CONFIG_FILE=${prettyJSON cfg.configuration}"
|
||||
"NODE_ENV=production"
|
||||
];
|
||||
Restart = "always";
|
||||
User = "codimd";
|
||||
PermissionsStartOnly = true;
|
||||
PrivateTmp = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user