Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support free-busy-related requests #34

Open
liZe opened this issue May 16, 2013 · 30 comments
Open

Support free-busy-related requests #34

liZe opened this issue May 16, 2013 · 30 comments
Labels
Milestone

Comments

@liZe
Copy link
Member

liZe commented May 16, 2013

No description provided.

@lpirl
Copy link

lpirl commented Jan 6, 2014

+1

@mike-perdide
Copy link
Contributor

For future reference: http://tools.ietf.org/html/rfc4791#section-6.1.1

I am very new to the CalDAV protocol, but it looks like it could be something that can be dealt with in the rights management: you'd have R access, W access, and free-busy access. Apparently it's a privilege that allows reading on some fields.

@WhyNotHugo
Copy link

@mike-perdide is right, free-busy access level isn't implemented, but it seems that the report isn't implemented either: I'm getting a 500 even with rw access.

Here's my test script (the request is literally copy-pasted from rfc4791#7.10.1):

#!/usr/bin/env python3

from base64 import b64encode
from http.client import HTTPSConnection

body = """<?xml version="1.0" encoding="utf-8" ?>
        <C:free-busy-query xmlns:C="urn:ietf:params:xml:ns:caldav">
            <C:time-range start="20060104T140000Z" end="20060105T220000Z"/>
        </C:free-busy-query>
"""
user_and_pass = b64encode(b'hugo:MYPASSWORD').decode('ascii')
headers = {'Authorization': 'Basic %s' % user_and_pass}

conn = HTTPSConnection('calendar.barrera.io')
req = conn.request('REPORT', '/hugo/work/', body, headers=headers)
resp = conn.getresponse()

print(resp.status)
print(resp.reason)
print(resp.getheaders())
print(resp.read())

Output:

$ python freebusy.py
500
Internal Server Error
[('Server', 'nginx/1.7.10'), ('Date', 'Sat, 09 May 2015 17:55:51 GMT'), ('Content-Type', 'text/plain'), ('Content-Length', '59'), ('Connection', 'keep-alive')]
b'A server error occurred.  Please contact the administrator.'

Server log:

REPORT request at /hugo/work/ received
Request headers:
{'CONTENT_LENGTH': '213',
 'CONTENT_TYPE': 'text/plain',
 'GATEWAY_INTERFACE': 'CGI/1.1',
 'HTTP_ACCEPT_ENCODING': 'identity',
 'HTTP_AUTHORIZATION': 'Basic REDACTED',
 'HTTP_CONNECTION': 'close',
 'HTTP_HOST': 'localhost:5232',
 'PATH_INFO': '/hugo/work/',
 'QUERY_STRING': '',
 'REMOTE_ADDR': '127.0.0.1',
 'REMOTE_HOST': 'localhost',
 'REQUEST_METHOD': 'REPORT',
 'SCRIPT_NAME': '',
 'SERVER_NAME': 'elysion.barrera.io',
 'SERVER_PORT': '5232',
 'SERVER_PROTOCOL': 'HTTP/1.0',
 'SERVER_SOFTWARE': 'WSGIServer/0.1 Python/2.7.9',
 'wsgi.errors': <open file '<stderr>', mode 'w' at 0x74635da1e0>,
 'wsgi.file_wrapper': <class wsgiref.util.FileWrapper at 0x741f62fb48>,
 'wsgi.input': <socket._fileobject object at 0x74790cac50>,
 'wsgi.multiprocess': False,
 'wsgi.multithread': True,
 'wsgi.run_once': False,
 'wsgi.url_scheme': 'http',
 'wsgi.version': (1, 0)}
Sanitized path: /hugo/work/
Request content:
<?xml version="1.0" encoding="utf-8" ?>
        <C:free-busy-query xmlns:C="urn:ietf:params:xml:ns:caldav">
            <C:time-range start="20060104T140000Z" end="20060105T220000Z"/>
        </C:free-busy-query>

Rights type 'owner_only'
Test if 'hugo:hugo/work' matches against '.+:^hugo(/.*)?$' from section 'rw'
Section 'rw' matches
hugo has read access to collection hugo/work/
Rights type 'owner_only'
Test if 'hugo:hugo/work' matches against '.+:^hugo(/.*)?$' from section 'rw'
Section 'rw' matches
hugo has write access to collection hugo/work/
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/wsgiref/handlers.py", line 85, in run
    self.result = application(self.environ, self.start_response)
  File "/usr/local/lib/python2.7/site-packages/radicale/__init__.py", line 306, in __call__
    user)
  File "/usr/local/lib/python2.7/site-packages/radicale/__init__.py", line 583, in report
    answer = xmlutils.report(environ["PATH_INFO"], content, collection)
  File "/usr/local/lib/python2.7/site-packages/radicale/xmlutils.py", line 470, in report
    props = [prop.tag for prop in prop_element]
TypeError: 'NoneType' object is not iterable

@Jaikant
Copy link

Jaikant commented May 11, 2015

The report method is implemented, I tried your script with an http connection and default authorization (none) and the method executed.

@WhyNotHugo
Copy link

@Jaikant Are you sure about this? It failed for me, so I assumed it was not implemented.

I also took a quick glance at the source and it doesn't even seem to contain the term "free-busy" [1].

Did you get the expected results client-side?

@Jaikant
Copy link

Jaikant commented May 13, 2015

@hobarrera A basic report method is implemented in init.py. It is able to query the VEVENT. The filters for free-busy query is not implemented yet is my guess. I can work on this, but need some guidance as I am new to python. Anyone?

@WhyNotHugo
Copy link

@Jaikant: That's exactly what I originally said, and the almost opposite of what you replied:

The report method is implemented, I tried your script with an http connection and default authorization (none) and the method executed.

Strictly speaking, yes. The script runs. It'll always run if you have python installed. I meant the script did not run successfully. The method did execute, but returned 500. I think my original point was clear enough, especially with all the included output: The script does not run successfully, and the server did not return the expected response.

However, the free-busy report is not implemented, which is what matters.

@Jaikant
Copy link

Jaikant commented May 13, 2015

@hobarrera I got a 200 OK with the script. As I said there is an implementation for the report method. Look at the end of the xmlutils.py file for the details of what is implemented. And like I said earlier, maybe I was not clear. the implementation does not cover the full rfc.

@WhyNotHugo
Copy link

As I said there is an implementation for the report method. Look at the end of the xmlutils.py file for the details of what is implemented.

The free-busy report is not implemented. other reports are implemented, but that's really out-of-scope in this discussing. Stop trying to confuse people! This is not being productive at all, and is merely adding noise to this issue.

@Jaikant
Copy link

Jaikant commented May 16, 2015

I think it was your test report which was incorrect. Glad to know that you realize what is and is not more clearly now. You want to help getting the free-busy implemented?

@WhyNotHugo
Copy link

You want to help getting the free-busy implemented?

Having some busy time with exams, and a few other things, but when time allows, I'd be willing to jump in on this (probably in two or three weeks time). I actually really need this feature. :)

@liZe liZe modified the milestones: 3.0, 2.0 Mar 14, 2016
@liZe liZe mentioned this issue Apr 4, 2016
39 tasks
@Unrud
Copy link
Collaborator

Unrud commented May 25, 2016

The Davical wiki states that free-busy-query is not supported by any client.

"Scheduling Extensions to CalDAV" seems to be the favoured method. The relevant RFC are 6638 and 5546. For support for scheduling across different servers 6047 is also required.

Additional a mapping between users and email addresses would be required in Radicale. Scheduling messages are addressed by email.

@liZe
Copy link
Member Author

liZe commented Jul 13, 2016

"Scheduling Extensions to CalDAV" seems to be the favoured method. The relevant RFC are 6638 and 5546. For support for scheduling across different servers 6047 is also required.

That's huge. Let's keep this feature for later then…

@liZe liZe modified the milestones: 3.0, 2.0 Jul 13, 2016
@vinayguptagit
Copy link

does radicale support free-busy feature now.

Thanks in advance

@liZe
Copy link
Member Author

liZe commented Mar 14, 2017

does radicale support free-busy feature now.

No.

@srepmub
Copy link

srepmub commented Sep 18, 2017

hi,

I've been reading a bit into this, and I'm not sure that it would require a huge effort, really.. the sabredav implementation here seems to be only about 840 SLOC:

https://github.com/fruux/sabre-dav/tree/master/lib/CalDAV/Schedule

most is in Plugin.php, so that's for both the scheduling and freebusy stuff. I'm tempted to try and add this myself, though I'm sure one of you guys could do a much better/faster job.

@Unrud
Copy link
Collaborator

Unrud commented Sep 19, 2017

As mentioned before, this is not (widely) supported by clients.

@srepmub
Copy link

srepmub commented Sep 22, 2017

for us at least (kopano.com), Apple iCalendar is an important client, and it seems to require this as of Yosemite..

@Unrud
Copy link
Collaborator

Unrud commented Sep 26, 2017

Apple iCalendar is an important client

What doesn't work with iCalendar?

@srepmub
Copy link

srepmub commented Sep 27, 2017

as of yosemite, it seems to assume that RFC6638 is in place, whether or not 'calendar-auto-schedule' is supported by the server:

https://discussions.apple.com/thread/6663683?start=0&tstart=0

@Unrud
Copy link
Collaborator

Unrud commented Oct 5, 2017

I think that RFC 6638 is out of scope. It seems like a major hassle for little gain.

@nlincke
Copy link

nlincke commented Dec 13, 2017

+1
Anyway, i think this feature would be appreciated by a lot of people....

@ThomasChiroux
Copy link

The python-caldav project support free-busy request and as i'm porting this project into aiohttp for async support: aiocaldav, i'm interrested in adding this feature to radicale.

I think we can add the feature without a lot of pain: without RFC 6638 (which I agree is out of scope), i think free/busy is kind of a subset of the calendar-query REPORT with only some changes in the query and return values.

If you're ok, i'll look into this.

@kfred
Copy link

kfred commented Jul 12, 2018

@ThomasChiroux I have been trying to make a free-busy request with python-caldav unsuccessfully. Have you been able to successfully make make a free-busy request with python-caldav?

@ThomasChiroux
Copy link

I've not tried extensively python-caldav before porting it to asyncio.
But i've rewritten some tests in aiocaldav with free-busy requests.
They work against davical. You can have a look here for some samples, eaysily adaptable to python-caldav: https://github.com/ThomasChiroux/aiocaldav/blob/master/tests/test_freebusy.py

@kfred
Copy link

kfred commented Jul 13, 2018

@ThomasChiroux Thanks, I took a look. I'm not sure why, but I keep getting the following error when trying to use python-caldav's freebusy_request() method:

caldav.lib.error.ReportError: 406 Not Acceptable

I know it's not permission based because I am able to successfully get a response when manually making an HTTPSConnection request using an xml free-busy-query payload.

<?xml version='1.0' encoding='utf-8'?>
<C:free-busy-query xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:D="DAV">
    <C:time-range start="20180711T140000Z" end="20180712T220000Z"/>
</C:free-busy-query>

I guess I will continue to construct these freebusy requests myself for now. I've opened an issue in the python-caldav project but don't have time to troubleshoot the library myself.

@wepanx
Copy link

wepanx commented Jan 15, 2019

Any news on this?

@tobixen
Copy link
Contributor

tobixen commented Jan 24, 2021

I've opened an issue in the python-caldav project but don't have time to troubleshoot the library myself.

What is the issue number? I must have overlooked that one (I'm the primary maintainer of the library). The RFC states that free-busy requests MUST be supported by the server, yet the caldav client library test fails at several servers. I've always thought it was a problem at the server side, but I should probably look more into it.

EDIT: found it - python-caldav/caldav#31 - closed due to lack of feedback. I will reopen it.

@tobixen
Copy link
Contributor

tobixen commented Jan 27, 2021

Radicale 3.0.6 is in use, so the newest released version.

Here is from the debug logs (I realize I should put some efforts into better debugging output from caldav):

caldav: DEBUG: sending request - method=REPORT, url=http://localhost:5232/user1/pythoncaldav-test/, headers={'User-Agent': 'Mozilla/5.0', 'Content-Type': 'application/xml; charset="utf-8"', 'Accept': 'text/xml, text/calendar', 'Depth': '1'}
body:
<?xml version='1.0' encoding='utf-8'?>
<C:free-busy-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav"><C:time-range start="20070713T150000Z" end="20070715T150000Z"/></C:free-busy-query>
radicale: INFO: REPORT request for '/user1/pythoncaldav-test/' with depth '1' received from ::1 using 'Mozilla/5.0'
radicale: DEBUG: Sanitized script name: ''
radicale: DEBUG: Sanitized path: '/user1/pythoncaldav-test/'
radicale: INFO: Successful login: 'user1'
radicale: DEBUG: Request content:
<?xml version="1.0"?>
<C:free-busy-query xmlns:C="urn:ietf:params:xml:ns:caldav">
  <C:time-range start="20070713T150000Z" end="20070715T150000Z" />
</C:free-busy-query>

radicale: DEBUG: Response content:
<?xml version="1.0"?>
<multistatus xmlns="DAV:">
  <response>
    <href>/user1/pythoncaldav-test/20010712T182145Z-123401%40example.com.ics</href>
  </response>
</multistatus>

There is an example at https://tools.ietf.org/html/rfc4791#section-7.10.1 ... my request is quite similar to the example code there. The response is quite far off from the example (the response should be icalendar, not xml). It seems to me radicale is recognizing the request not as a freebusy-request, but as a report-request towards the calendar.

The RFC states ...

The CALDAV:free-busy-query REPORT request can only be run against a collection (either a regular collection or a calendar collection). An attempt to run the report on a calendar object resource MUST fail and return a 403 (Forbidden) status value.

I'm doing a REPORT towards a calendar collection here, so it seems correct to me.

The RFC states ...

The response body for a successful request MUST be an iCalendar object that contains exactly one VFREEBUSY component that describes the busy time intervals for the calendar object resources containing VEVENT, or VFREEBUSY components that satisfy the Depth value and for which the current user is at least granted the CALDAV:read-free-busy privilege. If no calendar object resources are found to satisfy these conditions, a VFREEBUSY component with no FREEBUSY property MUST be returned

And the response from Radicale clearly breaks with that.

So it seems to me that Radicale is doing something wrong while I'm doing something right. I actually hope that I'm wrong - because support for free-busy-requests is mandatory according to the RFC, but freebusy-requests sent through my library works towards quite few calendar implementations. It would be nice if I could just fix the bug on my side, rather than realizing that very few caldav-servers supports the caldav-standard...

@OdinVex
Copy link

OdinVex commented Feb 15, 2023

Very anxious to get this working, too. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests