summaryrefslogtreecommitdiff
path: root/Omni/Cloud
diff options
context:
space:
mode:
authorBen Sima <ben@bsima.me>2025-03-21 23:34:31 -0400
committerBen Sima <ben@bsima.me>2025-04-11 12:30:29 -0400
commita95231a35106193a68d29a48e5dc23999232af9f (patch)
tree9e443c5985d5c0d99b5da09f3ba1b82d77510765 /Omni/Cloud
parentae011f80c7e85d23edc185876e3d026704221454 (diff)
Factor out radicale and fix shared calendar
Having this in its own file makes it easier to work on. Then I was able to figure out (with lots of debugging and trial+error with Claude) the actual permissions settings that result in a shared calendar. It's very fiddly because it is matching on usernames and directories using regex, and I think it's order-dependent as well.
Diffstat (limited to 'Omni/Cloud')
-rw-r--r--Omni/Cloud/Cal.nix81
-rw-r--r--Omni/Cloud/Web.nix56
2 files changed, 81 insertions, 56 deletions
diff --git a/Omni/Cloud/Cal.nix b/Omni/Cloud/Cal.nix
new file mode 100644
index 0000000..3c3c46c
--- /dev/null
+++ b/Omni/Cloud/Cal.nix
@@ -0,0 +1,81 @@
+{config, ...}: let
+ ports = import ./Ports.nix;
+ rootDomain = config.networking.domain;
+in {
+ networking.firewall.allowedTCPPorts = [ports.radicale];
+
+ services.radicale = {
+ enable = true;
+ rights = {
+ # Allow reading root collection for authenticated users
+ root = {
+ user = ".*";
+ collection = "";
+ permissions = "R";
+ };
+ # Allow reading and writing principal collection (same as username)
+ principal = {
+ user = ".+";
+ collection = "{user}";
+ permissions = "RW";
+ };
+ # Make shared collection visible as part of root listing
+ shared_principal = {
+ user = ".+";
+ collection = "shared";
+ permissions = "RW";
+ };
+ # Allow reading and writing calendars and address books that are direct
+ # children of the principal collection
+ calendars = {
+ user = ".+";
+ collection = "{user}/[^/]+";
+ permissions = "rw";
+ };
+ # Allow ben full access to shared/ben, repeat this for other shared
+ # calendars as needed.
+ ben_shared = {
+ user = "ben";
+ collection = "shared/ben(/.+)?";
+ permissions = "rwD";
+ };
+ # Must be authed to write to the shared collections
+ shared_write = {
+ user = ".+";
+ collection = "shared/[^/]+";
+ permissions = "rw";
+ };
+ # Allow any user to read the shared collection
+ shared_read = {
+ user = ".+";
+ collection = "shared(/.*)?";
+ permissions = "r";
+ };
+ };
+ settings = {
+ server = {
+ hosts = [
+ "0.0.0.0:${toString ports.radicale}"
+ "[::]:${toString ports.radicale}"
+ ];
+ };
+ auth = {
+ type = "htpasswd";
+ htpasswd_filename = "/etc/radicale/users";
+ htpasswd_encryption = "plain";
+ };
+ };
+ };
+
+ services.nginx.virtualHosts."cal.${rootDomain}" = {
+ locations."/".proxyPass = "http://localhost:${toString ports.radicale}";
+ forceSSL = true;
+ useACMEHost = rootDomain;
+ extraConfig = ''
+ proxy_set_header X-Script-Name "";
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header Host $host;
+ proxy_pass_header Authorization;
+ '';
+ };
+}
diff --git a/Omni/Cloud/Web.nix b/Omni/Cloud/Web.nix
index b87da38..d11fc80 100644
--- a/Omni/Cloud/Web.nix
+++ b/Omni/Cloud/Web.nix
@@ -36,50 +36,6 @@ in {
port = ports.invidious;
};
- radicale = {
- enable = true;
- rights = {
- # Allow reading root collection for authenticated users
- root = {
- user = ".+";
- collection = "";
- permissions = "R";
- };
- # Allow reading and writing principal collection (same as username)
- principal = {
- user = ".+";
- collection = "{user}";
- permissions = "RW";
- };
- # Allow reading and writing calendars and address books that are direct
- # children of the principal collection
- calendars = {
- user = ".+";
- collection = "{user}/[^/]+";
- permissions = "rw";
- };
- # Allow any authenticated user to modify the public collection
- public = {
- user = ".*";
- collection = "public/.*";
- permissions = "rw";
- };
- };
- settings = {
- server = {
- hosts = [
- "0.0.0.0:${toString ports.radicale}"
- "[::]:${toString ports.radicale}"
- ];
- };
- auth = {
- type = "htpasswd";
- htpasswd_filename = "/etc/radicale/users";
- htpasswd_encryption = "plain";
- };
- };
- };
-
gmnisrv = {
enable = false;
listen = "0.0.0.0:${toString ports.gemini} [::]:${toString ports.gemini}";
@@ -162,18 +118,6 @@ in {
useACMEHost = rootDomain;
};
- "cal.${rootDomain}" = {
- locations."/".proxyPass = "http://localhost:${toString ports.radicale}";
- forceSSL = true;
- useACMEHost = rootDomain;
- extraConfig = ''
- proxy_set_header X-Script-Name /radicale;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header Host $host;
- proxy_pass_header Authorization;
- '';
- };
-
"youtube.${rootDomain}" = {
locations."/".proxyPass = "http://localhost:${toString ports.invidious}";
forceSSL = true;