From 99b0b74ac87c77b5f39e21c65141d8fcc6753ca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isma=C3=ABl=20Bouya?= Date: Wed, 6 Mar 2019 16:43:44 +0100 Subject: Add taskwarrior-web Fixes https://git.immae.eu/mantisbt/view.php?id=67 --- nixops/modules/task/default.nix | 224 ++++++++++++++++++++++++++++++++-------- 1 file changed, 181 insertions(+), 43 deletions(-) (limited to 'nixops/modules/task/default.nix') diff --git a/nixops/modules/task/default.nix b/nixops/modules/task/default.nix index 3dc3299..2fd61aa 100644 --- a/nixops/modules/task/default.nix +++ b/nixops/modules/task/default.nix @@ -6,6 +6,81 @@ let user = config.services.taskserver.user; env = myconfig.env.tools.task; group = config.services.taskserver.group; + taskserver-user-certs = pkgs.runCommand "taskserver-user-certs" {} '' + mkdir -p $out/bin + cat > $out/bin/taskserver-user-certs <<"EOF" + #!/usr/bin/env bash + + user=$1 + + silent_certtool() { + if ! output="$("${pkgs.gnutls.bin}/bin/certtool" "$@" 2>&1)"; then + echo "GNUTLS certtool invocation failed with output:" >&2 + echo "$output" >&2 + fi + } + + silent_certtool -p \ + --bits 4096 \ + --outfile "${vardir}/userkeys/$user.key.pem" + ${pkgs.gnused}/bin/sed -i -n -e '/^-----BEGIN RSA PRIVATE KEY-----$/,$p' "${vardir}/userkeys/$user.key.pem" + + silent_certtool -c \ + --template "${pkgs.writeText "taskserver-ca.template" '' + tls_www_client + encryption_key + signing_key + expiration_days = 3650 + ''}" \ + --load-ca-certificate "${vardir}/keys/ca.cert" \ + --load-ca-privkey "${vardir}/keys/ca.key" \ + --load-privkey "${vardir}/userkeys/$user.key.pem" \ + --outfile "${vardir}/userkeys/$user.cert.pem" + EOF + chmod a+x $out/bin/taskserver-user-certs + patchShebangs $out/bin/taskserver-user-certs + ''; + taskwarrior-web = pkgs.callPackage ./taskwarrior-web.nix { + inherit (mylibs) fetchedGithub; + inherit env; + }; + taskwebPages = let + uidPages = lib.attrsets.zipAttrs ( + lib.lists.flatten + (lib.attrsets.mapAttrsToList (k: c: map (v: { "${v}" = k; }) c.uid) env.taskwarrior-web) + ); + pages = lib.attrsets.mapAttrs (uid: items: + if lib.lists.length items == 1 then + '' + + + + + + + '' + else + '' + + + To-do list disponibles + + + + + + + + '' + ) uidPages; + in + pkgs.runCommand "taskwerver-pages" {} '' + mkdir -p $out/ + ${builtins.concatStringsSep "\n" (lib.attrsets.mapAttrsToList (k: v: "cp ${pkgs.writeText k v} $out/${k}.html") pages)} + echo "Please login" > $out/index.html + ''; in { options.services.myTasks = { enable = lib.mkEnableOption "my tasks service"; @@ -13,7 +88,7 @@ in { config = lib.mkIf cfg.enable { security.acme.certs."eldiron".extraDomains.${fqdn} = null; - services.myWebsites.tools.modules = [ "proxy_fcgi" ]; + services.myWebsites.tools.modules = [ "proxy_fcgi" "sed" ]; services.myWebsites.tools.vhostConfs.task = { certName = "eldiron"; hosts = [ "task.immae.eu" ]; @@ -34,7 +109,48 @@ in { SetEnv TASKD_LDAP_BASE "${env.ldap.base}" SetEnv TASKD_LDAP_FILTER "${env.ldap.search}" - '' ]; + '' + '' + + ProxyPass "unix://${taskwarrior-web.socketsDir}/%{folderName}.sock|http://localhost-%{folderName}/" + ProxyPassReverse "unix://${taskwarrior-web.socketsDir}/%{folderName}.sock|http://localhost-%{folderName}/" + ProxyPassReverse http://${fqdn}/ + + SetOutputFilter Sed + OutputSed "s|/ajax|/taskweb/%{folderName}/ajax|g" + OutputSed "s|\([^x]\)/tasks|\1/taskweb/%{folderName}/tasks|g" + OutputSed "s|\([^x]\)/projects|\1/taskweb/%{folderName}/projects|g" + OutputSed "s|http://${fqdn}/|/taskweb/%{folderName}/|g" + OutputSed "s|/img/relax.jpg|/taskweb/%{folderName}/img/relax.jpg|g" + + '' + '' + Alias /taskweb ${taskwebPages} + + DirectoryIndex index.html + Require all granted + + + RewriteEngine on + RewriteRule ^/taskweb$ /taskweb/ [R=301,L] + RedirectMatch permanent ^/taskweb/([^/]+)$ /taskweb/$1/ + + RewriteCond %{LA-U:REMOTE_USER} !="" + RewriteCond ${taskwebPages}/%{LA-U:REMOTE_USER}.html -f + RewriteRule ^/taskweb/?$ ${taskwebPages}/%{LA-U:REMOTE_USER}.html [L] + + + Use LDAPConnect + Require ldap-group cn=users,cn=taskwarrior,ou=services,dc=immae,dc=eu + + '' + ] ++ (lib.attrsets.mapAttrsToList (k: v: '' + + ${builtins.concatStringsSep "\n" (map (uid: "Require ldap-attribute uid=${uid}") v.uid)} + + Use Taskwarrior ${k} + + '') env.taskwarrior-web); }; services.myPhpfpm.poolConfigs = { tasks = '' @@ -69,47 +185,7 @@ in { ''; }; - users.users.${user}.packages = [ - (pkgs.runCommand "taskserver-user-certs" {} '' - mkdir -p $out/bin - cat > $out/bin/taskserver-user-certs <<"EOF" - #!/usr/bin/env bash - - user=$1 - - silent_certtool() { - if ! output="$("${pkgs.gnutls.bin}/bin/certtool" "$@" 2>&1)"; then - echo "GNUTLS certtool invocation failed with output:" >&2 - echo "$output" >&2 - fi - } - - silent_certtool -p \ - --bits 4096 \ - --outfile "${vardir}/userkeys/$user.key.pem" - ${pkgs.gnused}/bin/sed -i -n -e '/^-----BEGIN RSA PRIVATE KEY-----$/,$p' "${vardir}/userkeys/$user.key.pem" - - silent_certtool -c \ - --template "${pkgs.writeText "taskserver-ca.template" '' - tls_www_client - encryption_key - signing_key - expiration_days = 3650 - ''}" \ - --load-ca-certificate "${vardir}/keys/ca.cert" \ - --load-ca-privkey "${vardir}/keys/ca.key" \ - --load-privkey "${vardir}/userkeys/$user.key.pem" \ - --outfile "${vardir}/userkeys/$user.cert.pem" - EOF - chmod a+x $out/bin/taskserver-user-certs - patchShebangs $out/bin/taskserver-user-certs - '') - ]; - - systemd.services.taskserver-ca.postStart = '' - chown :${group} "${vardir}/keys/ca.key" - chmod g+r "${vardir}/keys/ca.key" - ''; + users.users.${user}.packages = [ taskserver-user-certs ]; system.activationScripts.taskserver = { deps = [ "users" ]; @@ -127,5 +203,67 @@ in { listenHost = "::"; requestLimit = 104857600; }; + + system.activationScripts.taskwarrior-web = { + deps = [ "users" ]; + text = '' + install -m 0755 -o ${user} -g ${group} -d ${taskwarrior-web.socketsDir} + install -m 0750 -o ${user} -g ${group} -d ${taskwarrior-web.varDir} + ${builtins.concatStringsSep "\n" (lib.attrsets.mapAttrsToList + (k: v: "install -m 0750 -o ${user} -g ${group} -d ${taskwarrior-web.varDir}/${k}") + env.taskwarrior-web + )} + if [ ! -f ${vardir}/userkeys/taskwarrior-web.cert.pem ]; then + ${taskserver-user-certs}/bin/taskserver-user-certs taskwarrior-web + chown taskd:taskd ${vardir}/userkeys/taskwarrior-web.cert.pem ${vardir}/userkeys/taskwarrior-web.key.pem + fi + ''; + }; + + systemd.services = (lib.attrsets.mapAttrs' (name: userConfig: + let + credentials = "${userConfig.org}/${name}/${userConfig.key}"; + dateFormat = userConfig.date; + taskrc = pkgs.writeText "taskrc" '' + data.location=${taskwarrior-web.varDir}/${name} + taskd.certificate=${vardir}/userkeys/taskwarrior-web.cert.pem + taskd.key=${vardir}/userkeys/taskwarrior-web.key.pem + taskd.ca=${vardir}/keys/server.cert + taskd.server=${fqdn}:${toString config.services.taskserver.listenPort} + taskd.credentials=${credentials} + dateformat=${dateFormat} + ''; + in lib.attrsets.nameValuePair "taskwarrior-web-${name}" { + description = "Taskwarrior webapp for ${name}"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + path = [ pkgs.taskwarrior ]; + + environment.TASKRC = taskrc; + environment.BUNDLE_PATH = "${taskwarrior-web.gems}/lib/ruby/gems/2.5.0"; + environment.BUNDLE_GEMFILE = "${taskwarrior-web.gems.confFiles}/Gemfile"; + environment.LC_ALL = "fr_FR.UTF-8"; + + script = '' + exec ${taskwarrior-web.gems}/lib/ruby/gems/2.5.0/bin/bundle exec thin start -R config.ru -S ${taskwarrior-web.socketsDir}/${name}.sock + ''; + + serviceConfig = { + User = user; + PrivateTmp = true; + Restart = "always"; + TimeoutSec = 60; + Type = "simple"; + WorkingDirectory = taskwarrior-web.rubyRoot; + }; + + unitConfig.RequiresMountsFor = taskwarrior-web.varDir; + }) env.taskwarrior-web) // { + taskserver-ca.postStart = '' + chown :${group} "${vardir}/keys/ca.key" + chmod g+r "${vardir}/keys/ca.key" + ''; + }; + }; } -- cgit v1.2.3