keycloak service: add themes support

Custom themes can be packaged and then added using `themes` config
attribute.
This commit is contained in:
Nikolay Amiantov 2022-01-09 20:58:25 +03:00
parent a42abe27c0
commit 84f70eefd1
2 changed files with 56 additions and 2 deletions

View file

@ -229,6 +229,20 @@ in
''; '';
}; };
themes = lib.mkOption {
type = lib.types.attrsOf lib.types.package;
default = {};
description = ''
Additional theme packages for Keycloak. Each theme is linked into
subdirectory with a corresponding attribute name.
Theme packages consist of several subdirectories which provide
different theme types: for example, <literal>account</literal>,
<literal>login</literal> etc. After adding a theme to this option you
can select it by its name in Keycloak administration console.
'';
};
extraConfig = lib.mkOption { extraConfig = lib.mkOption {
type = lib.types.attrsOf lib.types.anything; type = lib.types.attrsOf lib.types.anything;
default = { }; default = { };
@ -289,16 +303,45 @@ in
${pkgs.jre}/bin/keytool -importcert -trustcacerts -alias MySQLCACert -file ${cfg.database.caCert} -keystore $out -storepass notsosecretpassword -noprompt ${pkgs.jre}/bin/keytool -importcert -trustcacerts -alias MySQLCACert -file ${cfg.database.caCert} -keystore $out -storepass notsosecretpassword -noprompt
''; '';
# Both theme and theme type directories need to be actual directories in one hierarchy to pass Keycloak checks.
themesBundle = pkgs.runCommand "keycloak-themes" {} ''
linkTheme() {
theme="$1"
name="$2"
mkdir "$out/$name"
for typeDir in "$theme"/*; do
if [ -d "$typeDir" ]; then
type="$(basename "$typeDir")"
mkdir "$out/$name/$type"
for file in "$typeDir"/*; do
ln -sn "$file" "$out/$name/$type/$(basename "$file")"
done
fi
done
}
mkdir -p "$out"
for theme in ${cfg.package}/themes/*; do
if [ -d "$theme" ]; then
linkTheme "$theme" "$(basename "$theme")"
fi
done
${lib.concatStringsSep "\n" (lib.mapAttrsToList (name: theme: "linkTheme ${theme} ${lib.escapeShellArg name}") cfg.themes)}
'';
keycloakConfig' = builtins.foldl' lib.recursiveUpdate { keycloakConfig' = builtins.foldl' lib.recursiveUpdate {
"interface=public".inet-address = cfg.bindAddress; "interface=public".inet-address = cfg.bindAddress;
"socket-binding-group=standard-sockets"."socket-binding=http".port = cfg.httpPort; "socket-binding-group=standard-sockets"."socket-binding=http".port = cfg.httpPort;
"subsystem=keycloak-server"."spi=hostname" = { "subsystem=keycloak-server" = {
"provider=default" = { "spi=hostname"."provider=default" = {
enabled = true; enabled = true;
properties = { properties = {
inherit (cfg) frontendUrl forceBackendUrlToFrontendUrl; inherit (cfg) frontendUrl forceBackendUrlToFrontendUrl;
}; };
}; };
"theme=defaults".dir = toString themesBundle;
}; };
"subsystem=datasources"."data-source=KeycloakDS" = { "subsystem=datasources"."data-source=KeycloakDS" = {
max-pool-size = "20"; max-pool-size = "20";

View file

@ -131,6 +131,17 @@
</warning> </warning>
</section> </section>
<section xml:id="module-services-keycloak-themes">
<title>Themes</title>
<para>
You can package custom themes and make them visible to Keycloak via
<xref linkend="opt-services.keycloak.themes" />
option. See the <link xlink:href="https://www.keycloak.org/docs/latest/server_development/#_themes">
Themes section of the Keycloak Server Development Guide</link>
and respective NixOS option description for more information.
</para>
</section>
<section xml:id="module-services-keycloak-extra-config"> <section xml:id="module-services-keycloak-extra-config">
<title>Additional configuration</title> <title>Additional configuration</title>
<para> <para>