Merge "Add gerrit" into main
diff --git a/flake.nix b/flake.nix
index 11b4c88..8c3be8b 100644
--- a/flake.nix
+++ b/flake.nix
@@ -67,6 +67,7 @@
               ./modules/loginctl-linger.nix
               ./modules/matrix.nix
               ./modules/mongodb.nix
+              ./modules/nextcloud.nix
               ./modules/node.nix
               ./modules/postgres.nix
               ./modules/privatebin.nix
diff --git a/modules/caddy.nix b/modules/caddy.nix
index eddcf80..26e0a58 100644
--- a/modules/caddy.nix
+++ b/modules/caddy.nix
@@ -1,5 +1,6 @@
 { base, config, pkgs, lib, ... }: lib.recursiveUpdate
 {
+  services.nginx.enable = false; # PrivateBin, nextcloud etc. attempts to enable nginx but we already use caddy
   services.caddy.enable = true;
   services.caddy.configFile = lib.pipe ./caddy/caddyfile.nix [
     import
diff --git a/modules/caddy/caddyfile.nix b/modules/caddy/caddyfile.nix
index 4334549..9f6bf49 100644
--- a/modules/caddy/caddyfile.nix
+++ b/modules/caddy/caddyfile.nix
@@ -386,6 +386,11 @@
             "${pkgs.privatebin}/share/privatebin"
             "unix/${config.services.phpfpm.pools.privatebin.socket}"
           )
+          (PHPRoute
+            [ "cloud.clicks.codes" "nextcloud.clicks.codes" "docs.clicks.codes" ]
+            "${config.services.nextcloud.package}"
+            "unix/${config.services.phpfpm.pools.nextcloud.socket}"
+          )
         ];
       };
       srv1 = {
diff --git a/modules/matrix.nix b/modules/matrix.nix
index d3d46f5..7441390 100644
--- a/modules/matrix.nix
+++ b/modules/matrix.nix
@@ -14,6 +14,8 @@
       auto_join_rooms = [ "#general:${server_name}" ];
       enable_registration = true;
       registration_requires_token = true;
+      allow_public_rooms_over_federation = true;
+      allow_device_name_lookup_over_federation = true;
       registration_shared_secret = "!!registration_shared_secret!!";
       public_baseurl = "https://matrix-backend.coded.codes/";
       max_upload_size = "100M";
@@ -39,6 +41,31 @@
         "turns:turn.coded.codes:5349?transport=tcp" */
       ]; # Please use matrix.org turn
       # turn_shared_secret = "!!turn_shared_secret!!";
+
+      log_config = lib.pipe {
+        version = 1;
+        formatters = {
+          precise = {
+            format =
+              "%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s";
+          };
+        };
+        handlers = {
+          console = {
+            class = "logging.StreamHandler";
+            formatter = "precise";
+          };
+        };
+        loggers = { "synapse.storage.SQL" = { level = "WARNING"; }; };
+        root = {
+          level = "ERROR";
+          handlers = [ "console" ];
+        };
+        "disable_existing_loggers" = false;
+      } [
+        builtins.toJSON
+        (builtins.toFile "logcfg.yaml")
+      ];
     };
   };
 
diff --git a/modules/nextcloud.nix b/modules/nextcloud.nix
new file mode 100644
index 0000000..9605bfc
--- /dev/null
+++ b/modules/nextcloud.nix
@@ -0,0 +1,48 @@
+{config, pkgs, lib, ...}: {
+    sops.secrets.clicks_nextcloud_db_password = {
+        mode = lib.mkForce "0440";
+        group = lib.mkForce "nextcloud";
+    };
+
+    users.users.nextcloud = {
+        isSystemUser = true;
+        createHome = true;
+        home = "/var/lib/nextcloud";
+        group = config.users.groups.nextcloud.name;
+        shell = pkgs.bashInteractive;
+    };
+    users.groups.nextcloud = {};
+
+
+    services.nextcloud.enable = true;
+    services.nextcloud.config.adminpassFile = config.sops.secrets.nextcloud_admin_password.path;
+    services.nextcloud.hostName = "cloud.clicks.codes";
+    services.nextcloud.package = pkgs.nextcloud27;
+    services.nextcloud.poolSettings = {
+        pm = "dynamic";
+        "pm.max_children" = "32";
+        "pm.max_requests" = "500";
+        "pm.max_spare_servers" = "4";
+        "pm.min_spare_servers" = "2";
+        "pm.start_servers" = "2";
+        "listen.owner" = config.users.users.nextcloud.name;
+        "listen.group" = config.users.users.nextcloud.group;
+    };
+
+    services.nextcloud.config = {
+        dbtype = "pgsql";
+        dbport = config.services.postgresql.port;
+        dbpassFile = config.sops.secrets.clicks_nextcloud_db_password.path;
+        dbname = "nextcloud";
+        dbhost = "localhost";
+        extraTrustedDomains = [ "nextcloud.clicks.codes" "docs.clicks.codes" ];
+    };
+
+    sops.secrets.nextcloud_admin_password = {
+        mode = "0600";
+        owner = config.users.users.nextcloud.name;
+        group = config.users.users.nextcloud.group;
+        sopsFile = ../secrets/nextcloud.json;
+        format = "json";
+    };
+}
\ No newline at end of file
diff --git a/modules/postgres.nix b/modules/postgres.nix
index d1f8a31..2ae67bb 100644
--- a/modules/postgres.nix
+++ b/modules/postgres.nix
@@ -97,6 +97,7 @@
       { user = "gerrit"; passwordFile = config.sops.secrets.clicks_gerrit_db_password.path; }
       { user = "vaultwarden"; passwordFile = config.sops.secrets.clicks_bitwarden_db_password.path; }
       { user = "privatebin"; passwordFile = config.sops.secrets.clicks_privatebin_db_password.path; }
+      { user = "nextcloud"; passwordFile = config.sops.secrets.clicks_nextcloud_db_password.path; }
     ] [
       (map (userData: ''
         $PSQL -tAc "ALTER USER ${userData.user} PASSWORD '$(cat ${userData.passwordFile})';"
@@ -111,6 +112,7 @@
     "clicks_gerrit_db_password"
     "clicks_bitwarden_db_password"
     "clicks_privatebin_db_password"
+    "clicks_nextcloud_db_password"
   ] [
     (map (name: {
       inherit name;
diff --git a/modules/privatebin.nix b/modules/privatebin.nix
index 5dd6a28..e82c389 100644
--- a/modules/privatebin.nix
+++ b/modules/privatebin.nix
@@ -1,7 +1,6 @@
 { config, lib, base, ... }:
 lib.recursiveUpdate
 {
-  services.nginx.enable = false; # PrivateBin attempts to enable nginx but we already use caddy
   services.privatebin = {
     enable = true;
     settings = {
@@ -17,7 +16,7 @@
 
         info = ''Powered by <a href="https://privatebin.info/">PrivateBin</a>. Provided as a service free-of-charge by Clicks. Come chat with us <a href="https://matrix.to/#/#global:coded.codes"> on Matrix</a>'';
         notice = "This service has no guarantee of uptime, and pastes are not backed up. If you need somewhere to host the last words of your wise old grandfather for time immemorial this is not the place.";
-        
+
         langaugeselection = true;
       };
 
diff --git a/modules/syncthing.nix b/modules/syncthing.nix
index d9f482c..cea1012 100644
--- a/modules/syncthing.nix
+++ b/modules/syncthing.nix
@@ -1,6 +1,4 @@
 { pkgs, ... }: {
-  environment.systemPackages = with pkgs; [ syncthing ];
-
   services.syncthing.enable = true;
   services.syncthing.openDefaultPorts = true;
 
diff --git a/secrets/nextcloud.json b/secrets/nextcloud.json
new file mode 100644
index 0000000..e31d61d
--- /dev/null
+++ b/secrets/nextcloud.json
@@ -0,0 +1,28 @@
+{
+	"nextcloud_admin_password": "ENC[AES256_GCM,data:fVg/Kt+oQBWSAwTT+j4RZNimMZSXfoxD4oNOosFy6F1+YIFVuxajmm05k2FHS9cUcmHcpF1oqoBrroLgMvWVGn7ZkFOa26KwT7Is3IOlnsNaL96dsLh1biYw4dCSftfbPvIiWdS1lZnqXWU99/yleq3qpS9qcb8tNq2TCHecZco=,iv:VMEoabNI5lGum+pFW93JHa9+C0OGZMxnG4J4/15D5No=,tag:E5eOVADG8EwH3WM5oh1hig==,type:str]",
+	"sops": {
+		"kms": null,
+		"gcp_kms": null,
+		"azure_kv": null,
+		"hc_vault": null,
+		"age": [
+			{
+				"recipient": "age15mv77dpnh5762gk5rsw2u79uza4tg8cu6r3nlwjudlzmdqqck3ss6mg9dy",
+				"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4T2dxSmN3YkxzZGthaHpR\ndVN6NWtPcGFmMlBwcjJKWG94Yjk2eTR2VHhvCmc5YXJlSUdxOFJVdm0yVmlsSDc4\ndjlXL3h0eHFhUml5bEYyT003cnFVTWMKLS0tIEE4dzllVzlsWjhFbFBhWElrZEJP\nazBneU0rYTFlTCtiZW9RU09hZnZua3MKl4ubpy7xRx4BCQ6A1SawLKMNID9Xd3N2\nhctRsfaMISWwFnw8yOO14zT02bxXXy1NS8vpQSQyuybv++FoUAklxQ==\n-----END AGE ENCRYPTED FILE-----\n"
+			},
+			{
+				"recipient": "age1m7k864feyuezllp2hj4edkccn36rthrvfw969j6f0l3c0mhh5emsnfx6pd",
+				"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBScytCcHJXM2dzTlA1bW4w\nLzhvOXNxSkpVeTJHN2JERWgyNEw0US9ibVQ0CjB4d09mclFhVkxJYmVjZk56REY3\nY1lpNnJvakFqamhwM3lKeiszSkV1YUUKLS0tIGM1SnlCWGFpL1BjMk01Tllmb3BI\ncUc5Y0xWbnJvZVFpZlBjT3BzZnFvN28KBB/erTTzn44j1dLHqXOg9KmH7srvoDIW\n105QKYsU40h2qtROVscxB5vcpPjxgcacsHFi89wRhUqy1n45nAkNhg==\n-----END AGE ENCRYPTED FILE-----\n"
+			},
+			{
+				"recipient": "age1fxxnmkeuqhhct93c43pwkzhuzzq8857s5hye6pgfpku70kjn4ecqtamfqr",
+				"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4dTZWN0wreHAzNGFlTVJo\nZnAxZ3ZQYzFHTGdTUVNnVmVuS1I4YVZqRENvClY3QzVaZGwxRVk1c0JrbDhObzF1\nMFErbFpmMFBpYWhZK3N0ZGtkeklMcm8KLS0tIEpNUFNqa0RRV3RiUnRjTXN6ZnVa\nLzBOenFydE4vSkdQZ0FpamY4VC95THMK796rEHXR0K1VrNZofw7nk6SlvJx9cQcU\nswcrNrGBSrSO2mOX+fRKqBMfP0BMsCdk/jmdwl/RjTqPPQI4/hwaTw==\n-----END AGE ENCRYPTED FILE-----\n"
+			}
+		],
+		"lastmodified": "2023-10-07T21:36:03Z",
+		"mac": "ENC[AES256_GCM,data:w4wB57MrB/1h36VBK6wjG9RbUVf+MUlJyUnkBo83isBnMROZb8SOab3DcUQLl0hysCvvMnSuiLg/OCKi/w2cLGsYb+NELJ9oW02BoEv7SPymfCznmn37l9Tk8ri10V8LJ7hXVp9brJWyIA8HTwcr6EhNJMWhXyiZwQEMwppycHU=,iv:BI6f001a9fXRuVVXUcU8tc3Lb9J5rNV/HInauLMF5o8=,tag:ZzZSqo9iKWyKVDyghq7ORw==,type:str]",
+		"pgp": null,
+		"unencrypted_suffix": "_unencrypted",
+		"version": "3.7.3"
+	}
+}
\ No newline at end of file