xref: /plugin/davcal/vendor/sabre/dav/lib/CalDAV/Backend/SharingSupport.php (revision a1a3b6794e0e143a4a8b51d3185ce2d339be61ab)
1*a1a3b679SAndreas Boehler<?php
2*a1a3b679SAndreas Boehler
3*a1a3b679SAndreas Boehlernamespace Sabre\CalDAV\Backend;
4*a1a3b679SAndreas Boehler
5*a1a3b679SAndreas Boehler/**
6*a1a3b679SAndreas Boehler * Adds support for sharing features to a CalDAV server.
7*a1a3b679SAndreas Boehler *
8*a1a3b679SAndreas Boehler * Note: This feature is experimental, and may change in between different
9*a1a3b679SAndreas Boehler * SabreDAV versions.
10*a1a3b679SAndreas Boehler *
11*a1a3b679SAndreas Boehler * Early warning: Currently SabreDAV provides no implementation for this. This
12*a1a3b679SAndreas Boehler * is, because in it's current state there is no elegant way to do this.
13*a1a3b679SAndreas Boehler * The problem lies in the fact that a real CalDAV server with sharing support
14*a1a3b679SAndreas Boehler * would first need email support (with invite notifications), and really also
15*a1a3b679SAndreas Boehler * a browser-frontend that allows people to accept or reject these shares.
16*a1a3b679SAndreas Boehler *
17*a1a3b679SAndreas Boehler * In addition, the CalDAV backends are currently kept as independent as
18*a1a3b679SAndreas Boehler * possible, and should not be aware of principals, email addresses or
19*a1a3b679SAndreas Boehler * accounts.
20*a1a3b679SAndreas Boehler *
21*a1a3b679SAndreas Boehler * Adding an implementation for Sharing to standard-sabredav would contradict
22*a1a3b679SAndreas Boehler * these goals, so for this reason this is currently not implemented, although
23*a1a3b679SAndreas Boehler * it may very well in the future; but probably not before SabreDAV 2.0.
24*a1a3b679SAndreas Boehler *
25*a1a3b679SAndreas Boehler * The interface works however, so if you implement all this, and do it
26*a1a3b679SAndreas Boehler * correctly sharing _will_ work. It's not particularly easy, and I _urge you_
27*a1a3b679SAndreas Boehler * to make yourself acquainted with the following document first:
28*a1a3b679SAndreas Boehler *
29*a1a3b679SAndreas Boehler * https://trac.calendarserver.org/browser/CalendarServer/trunk/doc/Extensions/caldav-sharing.txt
30*a1a3b679SAndreas Boehler *
31*a1a3b679SAndreas Boehler * An overview
32*a1a3b679SAndreas Boehler * ===========
33*a1a3b679SAndreas Boehler *
34*a1a3b679SAndreas Boehler * Implementing this interface will allow a user to share his or her calendars
35*a1a3b679SAndreas Boehler * to other users. Effectively, when a calendar is shared the calendar will
36*a1a3b679SAndreas Boehler * show up in both the Sharer's and Sharee's calendar-home root.
37*a1a3b679SAndreas Boehler * This interface adds a few methods that ensure that this happens, and there
38*a1a3b679SAndreas Boehler * are also a number of new requirements in the base-class you must now follow.
39*a1a3b679SAndreas Boehler *
40*a1a3b679SAndreas Boehler *
41*a1a3b679SAndreas Boehler * How it works
42*a1a3b679SAndreas Boehler * ============
43*a1a3b679SAndreas Boehler *
44*a1a3b679SAndreas Boehler * When a user shares a calendar, the updateShares() method will be called with
45*a1a3b679SAndreas Boehler * a list of sharees that are now added, and a list of sharees that have been
46*a1a3b679SAndreas Boehler * removed.
47*a1a3b679SAndreas Boehler * Removal is instant, but when a sharee is added the sharee first gets a
48*a1a3b679SAndreas Boehler * chance to accept or reject the invitation for a share.
49*a1a3b679SAndreas Boehler *
50*a1a3b679SAndreas Boehler * After a share is accepted, the calendar will be returned from
51*a1a3b679SAndreas Boehler * getUserCalendars for both the sharer, and the sharee.
52*a1a3b679SAndreas Boehler *
53*a1a3b679SAndreas Boehler * If the sharee deletes the calendar, only their share gets deleted. When the
54*a1a3b679SAndreas Boehler * owner deletes a calendar, it will be removed for everybody.
55*a1a3b679SAndreas Boehler *
56*a1a3b679SAndreas Boehler *
57*a1a3b679SAndreas Boehler * Notifications
58*a1a3b679SAndreas Boehler * =============
59*a1a3b679SAndreas Boehler *
60*a1a3b679SAndreas Boehler * During all these sharing operations, a lot of notifications are sent back
61*a1a3b679SAndreas Boehler * and forward.
62*a1a3b679SAndreas Boehler *
63*a1a3b679SAndreas Boehler * Whenever the list of sharees for a calendar has been changed (they have been
64*a1a3b679SAndreas Boehler * added, removed or modified) all sharees should get a notification for this
65*a1a3b679SAndreas Boehler * change.
66*a1a3b679SAndreas Boehler * This notification is always represented by:
67*a1a3b679SAndreas Boehler *
68*a1a3b679SAndreas Boehler * Sabre\CalDAV\Notifications\Notification\Invite
69*a1a3b679SAndreas Boehler *
70*a1a3b679SAndreas Boehler * In the case of an invite, the sharee may reply with an 'accept' or
71*a1a3b679SAndreas Boehler * 'decline'. These are always represented by:
72*a1a3b679SAndreas Boehler *
73*a1a3b679SAndreas Boehler * Sabre\CalDAV\Notifications\Notification\InviteReply
74*a1a3b679SAndreas Boehler *
75*a1a3b679SAndreas Boehler *
76*a1a3b679SAndreas Boehler * Calendar access by sharees
77*a1a3b679SAndreas Boehler * ==========================
78*a1a3b679SAndreas Boehler *
79*a1a3b679SAndreas Boehler * As mentioned earlier, shared calendars must now also be returned for
80*a1a3b679SAndreas Boehler * getCalendarsForUser for sharees. A few things change though.
81*a1a3b679SAndreas Boehler *
82*a1a3b679SAndreas Boehler * The following properties must be specified:
83*a1a3b679SAndreas Boehler *
84*a1a3b679SAndreas Boehler * 1. {http://calendarserver.org/ns/}shared-url
85*a1a3b679SAndreas Boehler *
86*a1a3b679SAndreas Boehler * This property MUST contain the url to the original calendar, that is.. the
87*a1a3b679SAndreas Boehler * path to the calendar from the owner.
88*a1a3b679SAndreas Boehler *
89*a1a3b679SAndreas Boehler * 2. {http://sabredav.org/ns}owner-principal
90*a1a3b679SAndreas Boehler *
91*a1a3b679SAndreas Boehler * This is a url to to the principal who is sharing the calendar.
92*a1a3b679SAndreas Boehler *
93*a1a3b679SAndreas Boehler * 3. {http://sabredav.org/ns}read-only
94*a1a3b679SAndreas Boehler *
95*a1a3b679SAndreas Boehler * This should be either 0 or 1, depending on if the user has read-only or
96*a1a3b679SAndreas Boehler * read-write access to the calendar.
97*a1a3b679SAndreas Boehler *
98*a1a3b679SAndreas Boehler * Only when this is done, the calendar will correctly be marked as a calendar
99*a1a3b679SAndreas Boehler * that's shared to him, thus allowing clients to display the correct interface
100*a1a3b679SAndreas Boehler * and ACL enforcement.
101*a1a3b679SAndreas Boehler *
102*a1a3b679SAndreas Boehler * If a sharee deletes their calendar, only their instance of the calendar
103*a1a3b679SAndreas Boehler * should be deleted, the original should still exists.
104*a1a3b679SAndreas Boehler * Pretty much any 'dead' WebDAV properties on these shared calendars should be
105*a1a3b679SAndreas Boehler * specific to a user. This means that if the displayname is changed by a
106*a1a3b679SAndreas Boehler * sharee, the original is not affected. This is also true for:
107*a1a3b679SAndreas Boehler *   * The description
108*a1a3b679SAndreas Boehler *   * The color
109*a1a3b679SAndreas Boehler *   * The order
110*a1a3b679SAndreas Boehler *   * And any other dead properties.
111*a1a3b679SAndreas Boehler *
112*a1a3b679SAndreas Boehler * Properties like a ctag should not be different for multiple instances of the
113*a1a3b679SAndreas Boehler * calendar.
114*a1a3b679SAndreas Boehler *
115*a1a3b679SAndreas Boehler * Lastly, objects *within* calendars should also have user-specific data. The
116*a1a3b679SAndreas Boehler * two things that are user-specific are:
117*a1a3b679SAndreas Boehler *   * VALARM objects
118*a1a3b679SAndreas Boehler *   * The TRANSP property
119*a1a3b679SAndreas Boehler *
120*a1a3b679SAndreas Boehler * This _also_ implies that if a VALARM is deleted by a sharee for some event,
121*a1a3b679SAndreas Boehler * this has no effect on the original VALARM.
122*a1a3b679SAndreas Boehler *
123*a1a3b679SAndreas Boehler * Understandably, the this last requirement is one of the hardest.
124*a1a3b679SAndreas Boehler * Realisticly, I can see people ignoring this part of the spec, but that could
125*a1a3b679SAndreas Boehler * cause a different set of issues.
126*a1a3b679SAndreas Boehler *
127*a1a3b679SAndreas Boehler *
128*a1a3b679SAndreas Boehler * Publishing
129*a1a3b679SAndreas Boehler * ==========
130*a1a3b679SAndreas Boehler *
131*a1a3b679SAndreas Boehler * When a user publishes a url, the server should generate a 'publish url'.
132*a1a3b679SAndreas Boehler * This is a read-only url, anybody can use to consume the calendar feed.
133*a1a3b679SAndreas Boehler *
134*a1a3b679SAndreas Boehler * Calendars are in one of two states:
135*a1a3b679SAndreas Boehler *   * published
136*a1a3b679SAndreas Boehler *   * unpublished
137*a1a3b679SAndreas Boehler *
138*a1a3b679SAndreas Boehler * If a calendar is published, the following property should be returned
139*a1a3b679SAndreas Boehler * for each calendar in getCalendarsForUser.
140*a1a3b679SAndreas Boehler *
141*a1a3b679SAndreas Boehler * {http://calendarserver.org/ns/}publish-url
142*a1a3b679SAndreas Boehler *
143*a1a3b679SAndreas Boehler * This element should contain a {DAV:}href element, which points to the
144*a1a3b679SAndreas Boehler * public url that does not require authentication. Unlike every other href,
145*a1a3b679SAndreas Boehler * this url must be absolute.
146*a1a3b679SAndreas Boehler *
147*a1a3b679SAndreas Boehler * Ideally, the following property is always returned
148*a1a3b679SAndreas Boehler *
149*a1a3b679SAndreas Boehler * {http://calendarserver.org/ns/}pre-publish-url
150*a1a3b679SAndreas Boehler *
151*a1a3b679SAndreas Boehler * This property should contain the url that the calendar _would_ have, if it
152*a1a3b679SAndreas Boehler * were to be published. iCal uses this to display the url, before the user
153*a1a3b679SAndreas Boehler * will actually publish it.
154*a1a3b679SAndreas Boehler *
155*a1a3b679SAndreas Boehler *
156*a1a3b679SAndreas Boehler * Selectively disabling publish or share feature
157*a1a3b679SAndreas Boehler * ==============================================
158*a1a3b679SAndreas Boehler *
159*a1a3b679SAndreas Boehler * If Sabre\CalDAV\Property\AllowedSharingModes is returned from
160*a1a3b679SAndreas Boehler * getCalendarsForUser, this allows the server to specify whether either sharing,
161*a1a3b679SAndreas Boehler * or publishing is supported.
162*a1a3b679SAndreas Boehler *
163*a1a3b679SAndreas Boehler * This allows a client to determine in advance which features are available,
164*a1a3b679SAndreas Boehler * and update the interface appropriately. If this property is not returned by
165*a1a3b679SAndreas Boehler * the backend, the SharingPlugin automatically injects it and assumes both
166*a1a3b679SAndreas Boehler * features are available.
167*a1a3b679SAndreas Boehler *
168*a1a3b679SAndreas Boehler * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
169*a1a3b679SAndreas Boehler * @author Evert Pot (http://evertpot.com/)
170*a1a3b679SAndreas Boehler * @license http://sabre.io/license/ Modified BSD License
171*a1a3b679SAndreas Boehler */
172*a1a3b679SAndreas Boehlerinterface SharingSupport extends NotificationSupport {
173*a1a3b679SAndreas Boehler
174*a1a3b679SAndreas Boehler    /**
175*a1a3b679SAndreas Boehler     * Updates the list of shares.
176*a1a3b679SAndreas Boehler     *
177*a1a3b679SAndreas Boehler     * The first array is a list of people that are to be added to the
178*a1a3b679SAndreas Boehler     * calendar.
179*a1a3b679SAndreas Boehler     *
180*a1a3b679SAndreas Boehler     * Every element in the add array has the following properties:
181*a1a3b679SAndreas Boehler     *   * href - A url. Usually a mailto: address
182*a1a3b679SAndreas Boehler     *   * commonName - Usually a first and last name, or false
183*a1a3b679SAndreas Boehler     *   * summary - A description of the share, can also be false
184*a1a3b679SAndreas Boehler     *   * readOnly - A boolean value
185*a1a3b679SAndreas Boehler     *
186*a1a3b679SAndreas Boehler     * Every element in the remove array is just the address string.
187*a1a3b679SAndreas Boehler     *
188*a1a3b679SAndreas Boehler     * Note that if the calendar is currently marked as 'not shared' by and
189*a1a3b679SAndreas Boehler     * this method is called, the calendar should be 'upgraded' to a shared
190*a1a3b679SAndreas Boehler     * calendar.
191*a1a3b679SAndreas Boehler     *
192*a1a3b679SAndreas Boehler     * @param mixed $calendarId
193*a1a3b679SAndreas Boehler     * @param array $add
194*a1a3b679SAndreas Boehler     * @param array $remove
195*a1a3b679SAndreas Boehler     * @return void
196*a1a3b679SAndreas Boehler     */
197*a1a3b679SAndreas Boehler    function updateShares($calendarId, array $add, array $remove);
198*a1a3b679SAndreas Boehler
199*a1a3b679SAndreas Boehler    /**
200*a1a3b679SAndreas Boehler     * Returns the list of people whom this calendar is shared with.
201*a1a3b679SAndreas Boehler     *
202*a1a3b679SAndreas Boehler     * Every element in this array should have the following properties:
203*a1a3b679SAndreas Boehler     *   * href - Often a mailto: address
204*a1a3b679SAndreas Boehler     *   * commonName - Optional, for example a first + last name
205*a1a3b679SAndreas Boehler     *   * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
206*a1a3b679SAndreas Boehler     *   * readOnly - boolean
207*a1a3b679SAndreas Boehler     *   * summary - Optional, a description for the share
208*a1a3b679SAndreas Boehler     *
209*a1a3b679SAndreas Boehler     * This method may be called by either the original instance of the
210*a1a3b679SAndreas Boehler     * calendar, as well as the shared instances. In the case of the shared
211*a1a3b679SAndreas Boehler     * instances, it is perfectly acceptable to return an empty array in case
212*a1a3b679SAndreas Boehler     * there are privacy concerns.
213*a1a3b679SAndreas Boehler     *
214*a1a3b679SAndreas Boehler     * @param mixed $calendarId
215*a1a3b679SAndreas Boehler     * @return array
216*a1a3b679SAndreas Boehler     */
217*a1a3b679SAndreas Boehler    function getShares($calendarId);
218*a1a3b679SAndreas Boehler
219*a1a3b679SAndreas Boehler    /**
220*a1a3b679SAndreas Boehler     * This method is called when a user replied to a request to share.
221*a1a3b679SAndreas Boehler     *
222*a1a3b679SAndreas Boehler     * If the user chose to accept the share, this method should return the
223*a1a3b679SAndreas Boehler     * newly created calendar url.
224*a1a3b679SAndreas Boehler     *
225*a1a3b679SAndreas Boehler     * @param string href The sharee who is replying (often a mailto: address)
226*a1a3b679SAndreas Boehler     * @param int status One of the SharingPlugin::STATUS_* constants
227*a1a3b679SAndreas Boehler     * @param string $calendarUri The url to the calendar thats being shared
228*a1a3b679SAndreas Boehler     * @param string $inReplyTo The unique id this message is a response to
229*a1a3b679SAndreas Boehler     * @param string $summary A description of the reply
230*a1a3b679SAndreas Boehler     * @return null|string
231*a1a3b679SAndreas Boehler     */
232*a1a3b679SAndreas Boehler    function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null);
233*a1a3b679SAndreas Boehler
234*a1a3b679SAndreas Boehler    /**
235*a1a3b679SAndreas Boehler     * Publishes a calendar
236*a1a3b679SAndreas Boehler     *
237*a1a3b679SAndreas Boehler     * @param mixed $calendarId
238*a1a3b679SAndreas Boehler     * @param bool $value
239*a1a3b679SAndreas Boehler     * @return void
240*a1a3b679SAndreas Boehler     */
241*a1a3b679SAndreas Boehler    function setPublishStatus($calendarId, $value);
242*a1a3b679SAndreas Boehler
243*a1a3b679SAndreas Boehler}
244