aboutsummaryrefslogblamecommitdiff
path: root/nixops/modules/websites/tools/ether.nix
blob: 1c952af5e43a3a3691ff0ee93ae4b9fd6fca0b10 (plain) (tree)
















































































































































































































                                                                                                                                                                                                                                                                            
{ lib, pkgs, config, myconfig, mylibs, ... }:
let
  etherpad = pkgs.webapps.etherpad-lite.withModules
    (builtins.attrValues pkgs.webapps.etherpad-lite-modules);
  env = myconfig.env.tools.etherpad-lite;
  varDir = etherpad.varDir;
  cfg = config.services.myWebsites.tools.etherpad-lite;
  # Make sure we’re not rebuilding whole libreoffice just because of a
  # dependency
  libreoffice = (import <nixpkgs> { overlays = []; }).libreoffice-fresh;
in {
  options.services.myWebsites.tools.etherpad-lite = {
    enable = lib.mkEnableOption "enable etherpad's website";
  };

  config = lib.mkIf cfg.enable {
    mySecrets.keys = [
      {
        dest = "webapps/tools-etherpad-apikey";
        permissions = "0400";
        text = env.api_key;
      }
      {
        dest = "webapps/tools-etherpad-sessionkey";
        permissions = "0400";
        text = env.session_key;
      }
      {
        dest = "webapps/tools-etherpad";
        permissions = "0400";
        text = ''
          {
            "title": "Etherpad",
            "favicon": "favicon.ico",

            "ip": "127.0.0.1",
            "port" : ${env.listenPort},
            "showSettingsInAdminPage" : false,
            "dbType" : "postgres",
            "dbSettings" : {
              "user"    : "${env.postgresql.user}",
              "host"    : "${env.postgresql.socket}",
              "password": "${env.postgresql.password}",
              "database": "${env.postgresql.database}",
              "charset" : "utf8mb4"
            },

            "defaultPadText" : "Welcome to Etherpad!\n\nThis pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!\n\nGet involved with Etherpad at http:\/\/etherpad.org\n",
            "padOptions": {
              "noColors": false,
              "showControls": true,
              "showChat": true,
              "showLineNumbers": true,
              "useMonospaceFont": false,
              "userName": false,
              "userColor": false,
              "rtl": false,
              "alwaysShowChat": false,
              "chatAndUsers": false,
              "lang": "en-gb"
            },

            "suppressErrorsInPadText" : false,
            "requireSession" : false,
            "editOnly" : false,
            "sessionNoPassword" : false,
            "minify" : true,
            "maxAge" : 21600,
            "abiword" : null,
            "soffice" : "${libreoffice}/bin/soffice",
            "tidyHtml" : "${pkgs.html-tidy}/bin/tidy",
            "allowUnknownFileEnds" : true,
            "requireAuthentication" : false,
            "requireAuthorization" : false,
            "trustProxy" : false,
            "disableIPlogging" : false,
            "automaticReconnectionTimeout" : 0,
            "scrollWhenFocusLineIsOutOfViewport": {
              "percentage": {
                "editionAboveViewport": 0,
                "editionBelowViewport": 0
              },
              "duration": 0,
              "scrollWhenCaretIsInTheLastLineOfViewport": false,
              "percentageToScrollWhenUserPressesArrowUp": 0
            },
            "users": {
              "ldapauth": {
                "url": "ldaps://${env.ldap.host}",
                "accountBase": "${env.ldap.base}",
                "accountPattern": "(&(memberOf=cn=users,cn=etherpad,ou=services,dc=immae,dc=eu)(uid={{username}}))",
                "displayNameAttribute": "cn",
                "searchDN": "cn=etherpad,ou=services,dc=immae,dc=eu",
                "searchPWD": "${env.ldap.password}",
                "groupSearchBase": "${env.ldap.base}",
                "groupAttribute": "member",
                "groupAttributeIsDN": true,
                "searchScope": "sub",
                "groupSearch": "(memberOf=cn=groups,cn=etherpad,ou=services,dc=immae,dc=eu)",
                "anonymousReadonly": false
              }
            },
            "socketTransportProtocols" : ["xhr-polling", "jsonp-polling", "htmlfile"],
            "loadTest": false,
            "indentationOnNewLine": false,
            "toolbar": {
              "left": [
                ["bold", "italic", "underline", "strikethrough"],
                ["orderedlist", "unorderedlist", "indent", "outdent"],
                ["undo", "redo"],
                ["clearauthorship"]
              ],
              "right": [
                ["importexport", "timeslider", "savedrevision"],
                ["settings", "embed"],
                ["showusers"]
              ],
              "timeslider": [
                ["timeslider_export", "timeslider_returnToPad"]
              ]
            },
            "loglevel": "INFO",
            "logconfig" : { "appenders": [ { "type": "console" } ] }
          }
        '';
      }
    ];
    systemd.services.etherpad-lite = {
      description = "Etherpad-lite";
      wantedBy = [ "multi-user.target" ];
      after = [ "network.target" "postgresql.service" ];
      wants = [ "postgresql.service" ];

      environment.NODE_ENV = "production";
      environment.HOME = etherpad;

      path = [ pkgs.nodejs ];

      script = ''
        exec ${pkgs.nodejs}/bin/node ${etherpad}/src/node/server.js \
          --sessionkey /var/secrets/webapps/tools-etherpad-sessionkey \
          --apikey /var/secrets/webapps/tools-etherpad-apikey \
          --settings /var/secrets/webapps/tools-etherpad
      '';

      serviceConfig = {
        DynamicUser = true;
        User = "etherpad-lite";
        Group = "etherpad-lite";
        SupplementaryGroups = "keys";
        WorkingDirectory = etherpad;
        PrivateTmp = true;
        NoNewPrivileges = true;
        PrivateDevices = true;
        ProtectHome = true;
        ProtectControlGroups = true;
        ProtectKernelModules = true;
        Restart = "always";
        Type = "simple";
        TimeoutSec = 60;
        # Use ReadWritePaths= instead if varDir is outside of /var/lib
        StateDirectory="etherpad-lite";
        ExecStartPre = [
          "+${pkgs.coreutils}/bin/install -d -m 0755 -o etherpad-lite -g etherpad-lite ${varDir}/ep_initialized"
          "+${pkgs.coreutils}/bin/chown -R etherpad-lite:etherpad-lite ${varDir} /var/secrets/webapps/tools-etherpad /var/secrets/webapps/tools-etherpad-sessionkey /var/secrets/webapps/tools-etherpad-apikey"
        ];
      };
    };

    services.myWebsites.tools.modules = [
      "headers" "proxy" "proxy_http" "proxy_wstunnel"
    ];
    security.acme.certs."eldiron".extraDomains."ether.immae.eu" = null;
    services.myWebsites.tools.vhostConfs.etherpad-lite = {
      certName    = "eldiron";
      hosts       = [ "ether.immae.eu" ];
      root        = null;
      extraConfig = [ ''
        Header always set Strict-Transport-Security "max-age=31536000; includeSubdomains;"
        RequestHeader set X-Forwarded-Proto "https"

        RewriteEngine On

        RewriteMap  redirects "txt:${pkgs.writeText "redirects.txt" myconfig.env.tools.etherpad-lite.redirects}"
        RewriteCond %{QUERY_STRING}         "!noredirect"
        RewriteCond %{REQUEST_URI}          "^(.*)$"
        RewriteCond ''${redirects:$1|Unknown} "!Unknown"
        RewriteRule "^(.*)$"                ''${redirects:$1}  [L,NE,R=301,QSD]

        RewriteCond %{REQUEST_URI}  ^/socket.io            [NC]
        RewriteCond %{QUERY_STRING} transport=websocket    [NC]
        RewriteRule /(.*)           ws://localhost:${env.listenPort}/$1 [P,L]

        <IfModule mod_proxy.c>
          ProxyVia On
          ProxyRequests Off
          ProxyPreserveHost On
          ProxyPass         / http://localhost:${env.listenPort}/
          ProxyPassReverse  / http://localhost:${env.listenPort}/
          <Proxy *>
            Options FollowSymLinks MultiViews
            AllowOverride None
            Require all granted
          </Proxy>
        </IfModule>
      '' ];
    };
  };
}