404 not found when trying to subscribe to a calendar
Radicale version: 3.2.0 OS: Debian 12 (bookworm)
I've have the following users:
-
shared_user -
admin1 -
admin2 -
user1
I'm trying to setup two calendars owned by user shared_user
- events: This calendar should be read-only for all users including non-authencated users, and read/write for
admin1andadmin2. - meetings: This calendar should be read-only for authenticated(admin1, admin2, user1) users, and read/write for
admin1andadmin2.
The error I get when trying to add a new Subscribe from web calendar in outlook.office.com is:
Jun 03 12:43:24 application radicale[2099082]: [2099082/Thread-1 (process_request_thread)] [INFO] GET response status for '/shared_user/events.ics' in 0.010 seconds: 404 Not Found
Directory structure
# Create directories for each user
sudo mkdir /var/lib/radicale/collections
sudo chown radicale:radicale /var/lib/radicale/collections/
sudo -u radicale mkdir -p /var/lib/radicale/collections/{shared_user,admin1,admin2,user1}
# Create files for shared_user's calendars
sudo -u radicale touch /var/lib/radicale/collections/shared_user/{meetings,events}.ics
[drwxr-xr-x root root ] /etc/radicale/
├── [-rw-r--r-- root root ] config
├── [-rw-r--r-- root root ] rights
└── [-rw-r--r-- radicale radicale] users
[drwxr-xr-x root root ] /var/lib/radicale/
└── [drwxr-xr-x radicale radicale] collections
├── [drwxr-xr-x radicale radicale] admin1
├── [drwxr-xr-x radicale radicale] admin2
├── [drwxr-x--- radicale radicale] collection-root
├── [drwxr-xr-x radicale radicale] shared_user
│ ├── [-rw-r--r-- radicale radicale] events.ics
│ └── [-rw-r--r-- radicale radicale] meetings.ics
└── [drwxr-xr-x radicale radicale] user1
/etc/radicale/config
[server]
hosts = 127.0.0.1:5232
[encoding]
[auth]
type = htpasswd
htpasswd_filename = /etc/radicale/users
htpasswd_encryption = bcrypt
[rights]
type = from_file
file = /etc/radicale/rights
[storage]
type = multifilesystem
filesystem_folder = /var/lib/radicale/collections
[web]
type = internal
[logging]
level = debug
/etc/radicale/rights
# Allow reading root collection for authenticated users
[root]
user: .+
collection:
permissions: Rr
# Allow reading and writing principal collection
# (same as user name)
[owner_write]
user: .*
collection: {user}/.*
permissions: rw
# Allow reading and writing calendars and address books
# that are direct children of the principal collection
[owner_write_children]
user: .+
collection: {user}/[^/]+
permissions: RWrw
# Admins reading and writing shared calendars.
[shared_write]
user: admin1|admin2
collection: shared_user/(meetings|events)
permissions: rw
# Authenticated users reading shared calendars.
[shared_read]
user: user1
collection: shared_user/(meetings|events)
permissions: r
# Non-authenticated reading shared calendars.
[public_read]
user: .*
collection: shared_user/events.ics
permissions: r
nginx conf
server {
server_name calendar.WITHHELD.se;
listen 80;
return 301 https://$host$request_uri;
}
server {
server_name calendar.WITHHELD.se;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/calendar.WITHHELD.se/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/calendar.WITHHELD.se/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
add_header Strict-Transport-Security "max-age=31536000" always; # managed by Certbot
ssl_trusted_certificate /etc/letsencrypt/live/calendar.WITHHELD.se/chain.pem; # managed by Certbot
ssl_stapling on; # managed by Certbot
ssl_stapling_verify on; # managed by Certbot
location / {
proxy_pass http://127.0.0.1:5232;
proxy_set_header Host $host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
radicale debug output
Jun 03 12:43:24 application radicale[2099082]: [2099082/Thread-1 (process_request_thread)] [INFO] GET request for '/shared_user/events.ics' received from 127.0.0.1 (forwarded for 'WITHHELD')
Jun 03 12:43:24 application radicale[2099082]: [2099082/Thread-1 (process_request_thread)] [DEBUG] Request headers:
{'CONTENT_LENGTH': '',
'CONTENT_TYPE': 'text/plain',
'GATEWAY_INTERFACE': 'CGI/1.1',
'HTTP_CONNECTION': 'close',
'HTTP_HOST': 'calendar.WITHHELD.se',
'HTTP_RANGE': 'bytes=0-511',
'HTTP_X_FORWARDED_FOR': 'WITHHELD',
'HTTP_X_FORWARDED_PROTO': 'https',
'HTTP_X_REAL_IP': 'WITHHELD',
'PATH_INFO': '/shared_user/events.ics',
'QUERY_STRING': '',
'REMOTE_ADDR': '127.0.0.1',
'REMOTE_HOST': '',
'REQUEST_METHOD': 'GET',
'SCRIPT_NAME': '',
'SERVER_NAME': 'localhost',
'SERVER_PORT': '5232',
'SERVER_PROTOCOL': 'HTTP/1.0',
'SERVER_SOFTWARE': 'WSGIServer/0.2',
'wsgi.errors': <_io.TextIOWrapper name='
Hmm, I've implemented this by softlinking shared calendars to the user directory and restricting permissions to the names of the softlinks per user. And starting point of an exposed collection is always below "collection-root", so you have to move directories also.
I'm trying to add the shared calender as a unauthenticated user to outlook, so I'm using the url:
https://calendar.domain.se/shared_user/events.ics
Also when recreating the directories and putting them under collection-root as follows:
[drwxr-xr-x root root ] /etc/radicale/
├── [-rw-r--r-- root root ] config
├── [-rw-r--r-- root root ] rights
└── [-rw-r--r-- radicale radicale] users
[drwxr-xr-x root root ] /var/lib/radicale/
└── [drwxr-xr-x radicale radicale] collections
└── [drwxr-xr-x radicale radicale] collection-root
├── [drwxr-xr-x radicale radicale] admin1
├── [drwxr-xr-x radicale radicale] admin2
├── [drwxr-xr-x radicale radicale] shared_user
│ ├── [-rw-r--r-- radicale radicale] events.ics
│ └── [-rw-r--r-- radicale radicale] meetings.ics
└── [drwxr-xr-x radicale radicale] user1
I get the following error when I try and subscribe to the events calendar:
Jun 07 12:11:49 application radicale[2182722]: [2182722/Thread-1 (process_request_thread)] [ERROR] An exception occurred during GET request on '/shared_user/events.ics': Failed to load item 'events.ics' in 'shared_user': Item contains 0 components
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/radicale/storage/multifilesystem/get.py", line 96, in _get
radicale_item.check_and_sanitize_items(
File "/usr/lib/python3/dist-packages/radicale/item/__init__.py", line 97, in check_and_sanitize_items
raise ValueError("Item contains %d components" % len(vobject_items))
ValueError: Item contains 0 components
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/radicale/app/__init__.py", line 108, in __call__
status_text, headers, answers = self._handle_request(environ)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/radicale/app/__init__.py", line 290, in _handle_request
status, headers, answer = function(
^^^^^^^^^
File "/usr/lib/python3/dist-packages/radicale/app/get.py", line 80, in do_GET
item = next(iter(self._storage.discover(path)), None)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/radicale/storage/multifilesystem/discover.py", line 75, in discover
item = collection._get(href)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/radicale/storage/multifilesystem/get.py", line 104, in _get
raise RuntimeError("Failed to load item %r in %r: %s" %
RuntimeError: Failed to load item 'events.ics' in 'shared_user': Item contains 0 components
Can it be that there is a misunderstanding how collections are working related to directory setup?
Where are the related/required .Radicale.props files?
I have documented a example storage layout, potentially this helps
https://github.com/Kozea/Radicale/wiki/Collection-Storage
no further feedback received, closing now