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