From 56fe5690c182002a9fe541e91b49a24354b8d8c2 Mon Sep 17 00:00:00 2001
From: Alexander Tomokhov <alexoundos@selfprivacy.org>
Date: Wed, 15 Jan 2025 18:03:19 +0400
Subject: [PATCH] fix roundcube: OAuth secret, ExecStartPost ignore failure

---
 sp-modules/roundcube/config-paths-needed.json |  1 +
 sp-modules/roundcube/module.nix               | 28 +++++++++++++++++--
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/sp-modules/roundcube/config-paths-needed.json b/sp-modules/roundcube/config-paths-needed.json
index 31c78d0..dd62508 100644
--- a/sp-modules/roundcube/config-paths-needed.json
+++ b/sp-modules/roundcube/config-paths-needed.json
@@ -2,6 +2,7 @@
   [ "mailserver", "fqdn" ],
   [ "passthru", "selfprivacy", "auth", "auth-fqdn" ],
   [ "passthru", "selfprivacy", "auth", "oauth2-provider-name" ],
+  [ "passthru", "selfprivacy", "auth", "oauth2-systemd-service" ],
   [ "selfprivacy", "domain" ],
   [ "selfprivacy", "modules", "auth" ],
   [ "selfprivacy", "modules", "roundcube" ]
diff --git a/sp-modules/roundcube/module.nix b/sp-modules/roundcube/module.nix
index 78747b9..45b160d 100644
--- a/sp-modules/roundcube/module.nix
+++ b/sp-modules/roundcube/module.nix
@@ -6,6 +6,22 @@ let
   auth-passthru = config.passthru.selfprivacy.auth;
   auth-fqdn = auth-passthru.auth-fqdn;
   oauth-client-id = "roundcube";
+  roundcube-group = "roundcube";
+  kanidmExecStartPreScriptRoot = pkgs.writeShellScript
+    "${oauth-client-id}-kanidm-ExecStartPre-root-script.sh"
+    ''
+      # set-group-ID bit allows for kanidm user to create files,
+      mkdir -p -v --mode=u+rwx,g+rs,g-w,o-rwx /run/keys/${oauth-client-id}
+      chown kanidm:${roundcube-group} /run/keys/${oauth-client-id}
+    '';
+  kanidm-oauth-client-secret-fp =
+    "/run/keys/${oauth-client-id}/kanidm-oauth-client-secret";
+  kanidmExecStartPreScript = pkgs.writeShellScript
+    "${oauth-client-id}-kanidm-ExecStartPre-script.sh" ''
+    set -o xtrace
+    [ -f "${kanidm-oauth-client-secret-fp}" ] || \
+      "${lib.getExe pkgs.openssl}" rand -base64 -out "${kanidm-oauth-client-secret-fp}" 32
+  '';
 in
 {
   options.selfprivacy.modules.roundcube = {
@@ -48,7 +64,7 @@ in
         $config['oauth_provider'] = 'generic';
         $config['oauth_provider_name'] = '${auth-passthru.oauth2-provider-name}';
         $config['oauth_client_id'] = '${oauth-client-id}';
-        $config['oauth_client_secret'] = 'VERYSTRONGSECRETFORROUNDCUBE'; # FIXME
+        $config['oauth_client_secret'] = "$(<${kanidm-oauth-client-secret-fp})";
         $config['oauth_auth_uri'] = 'https://${auth-fqdn}/ui/oauth2';
         $config['oauth_token_uri'] = 'https://${auth-fqdn}/oauth2/token';
         $config['oauth_identity_uri'] = 'https://${auth-fqdn}/oauth2/openid/${oauth-client-id}/userinfo';
@@ -70,6 +86,14 @@ in
 
     systemd.slices.roundcube.description = "Roundcube service slice";
 
+    systemd.services.kanidm = lib.mkIf is-auth-enabled {
+      serviceConfig.ExecStartPre = lib.mkAfter [
+        ("-+" + kanidmExecStartPreScriptRoot)
+        ("-" + kanidmExecStartPreScript)
+      ];
+      requires = [ auth-passthru.oauth2-systemd-service ];
+    };
+
     services.kanidm.provision = lib.mkIf is-auth-enabled {
       groups = {
         "sp.roundcube.admins".members = [ "sp.admins" ];
@@ -79,7 +103,7 @@ in
         displayName = "Roundcube";
         originUrl = "https://${cfg.subdomain}.${domain}/index.php/login/oauth";
         originLanding = "https://${cfg.subdomain}.${domain}/";
-        basicSecretFile = pkgs.writeText "bs-roundcube" "VERYSTRONGSECRETFORROUNDCUBE"; # FIXME
+        basicSecretFile = kanidm-oauth-client-secret-fp;
         # when true, name is passed to a service instead of name@domain
         preferShortUsername = false;
         allowInsecureClientDisablePkce = true; # FIXME is it needed?