Skip to content

Commit

Permalink
Add calendar sharing
Browse files Browse the repository at this point in the history
  • Loading branch information
DeepDiver1975 committed Jan 27, 2016
1 parent 0f51851 commit 0dcdb3d
Show file tree
Hide file tree
Showing 20 changed files with 487 additions and 120 deletions.
2 changes: 1 addition & 1 deletion apps/dav/appinfo/register_command.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@

/** @var Symfony\Component\Console\Application $application */
$application->add(new CreateAddressBook($userManager, $groupManager, $dbConnection, $logger));
$application->add(new CreateCalendar($userManager, $dbConnection));
$application->add(new CreateCalendar($userManager, $groupManager, $dbConnection));
$application->add(new SyncSystemAddressBook($app->getSyncService()));
15 changes: 13 additions & 2 deletions apps/dav/command/createcalendar.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
namespace OCA\DAV\Command;

use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\Connector\Sabre\Principal;
use OCP\IDBConnection;
use OCP\IGroupManager;
use OCP\IUserManager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
Expand All @@ -33,16 +35,20 @@ class CreateCalendar extends Command {
/** @var IUserManager */
protected $userManager;

/** @var IGroupManager $groupManager */
private $groupManager;

/** @var \OCP\IDBConnection */
protected $dbConnection;

/**
* @param IUserManager $userManager
* @param IDBConnection $dbConnection
*/
function __construct(IUserManager $userManager, IDBConnection $dbConnection) {
function __construct(IUserManager $userManager, IGroupManager $groupManager, IDBConnection $dbConnection) {
parent::__construct();
$this->userManager = $userManager;
$this->groupManager = $groupManager;
$this->dbConnection = $dbConnection;
}

Expand All @@ -63,8 +69,13 @@ protected function execute(InputInterface $input, OutputInterface $output) {
if (!$this->userManager->userExists($user)) {
throw new \InvalidArgumentException("User <$user> in unknown.");
}
$principalBackend = new Principal(
$this->userManager,
$this->groupManager
);

$name = $input->getArgument('name');
$caldav = new CalDavBackend($this->dbConnection);
$caldav = new CalDavBackend($this->dbConnection, $principalBackend);
$caldav->createCalendar("principals/users/$user", $name, []);
}
}
83 changes: 82 additions & 1 deletion apps/dav/lib/caldav/caldavbackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
namespace OCA\DAV\CalDAV;

use OCP\DB\QueryBuilder\IQueryBuilder;
use OCA\DAV\Connector\Sabre\Principal;
use OCA\DAV\DAV\Sharing\Backend;
use Sabre\CalDAV\Backend\AbstractBackend;
use Sabre\CalDAV\Backend\SchedulingSupport;
use Sabre\CalDAV\Backend\SubscriptionSupport;
Expand Down Expand Up @@ -86,8 +88,24 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
'{http://calendarserver.org/ns/}subscribed-strip-attachments' => 'stripattachments',
];

public function __construct(\OCP\IDBConnection $db) {
/** @var \OCP\IDBConnection */
private $db;

/** @var Backend */
private $sharingBackend;

/** @var Principal */
private $principalBackend;

/**
* CalDavBackend constructor.
*
* @param \OCP\IDBConnection $db
*/
public function __construct(\OCP\IDBConnection $db, Principal $principalBackend) {
$this->db = $db;
$this->principalBackend = $principalBackend;
$this->sharingBackend = new Backend($this->db, 'calendar');
}

/**
Expand Down Expand Up @@ -156,6 +174,56 @@ function getCalendarsForUser($principalUri) {
$calendars[] = $calendar;
}

$stmt->closeCursor();

// query for shared calendars
$principals = $this->principalBackend->getGroupMembership($principalUri);
$principals[]= $principalUri;

$fields = array_values($this->propertyMap);
$fields[] = 'a.id';
$fields[] = 'a.uri';
$fields[] = 'a.synctoken';
$fields[] = 'a.components';
$fields[] = 'a.principaluri';
$fields[] = 'a.transparent';
$fields[] = 's.access';
$query = $this->db->getQueryBuilder();
$result = $query->select($fields)
->from('dav_shares', 's')
->join('s', 'calendars', 'a', $query->expr()->eq('s.resourceid', 'a.id'))
->where($query->expr()->in('s.principaluri', $query->createParameter('principaluri')))
->andWhere($query->expr()->eq('s.type', $query->createParameter('type')))
->setParameter('type', 'calendar')
->setParameter('principaluri', $principals, \Doctrine\DBAL\Connection::PARAM_STR_ARRAY)
->execute();

while($row = $result->fetch()) {
$components = [];
if ($row['components']) {
$components = explode(',',$row['components']);
}
$calendar = [
'id' => $row['id'],
'uri' => $row['uri'],
'principaluri' => $principalUri,
'{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
'{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
'{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $row['principaluri'],
'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => $row['access'] === Backend::ACCESS_READ,
];

foreach($this->propertyMap as $xmlName=>$dbName) {
$calendar[$xmlName] = $row[$dbName];
}

$calendars[]= $calendar;
}
$result->closeCursor();


return $calendars;
}

Expand Down Expand Up @@ -1173,4 +1241,17 @@ private function readBlob($cardData) {

return $cardData;
}

public function updateShares($shareable, $add, $remove) {
$this->sharingBackend->updateShares($shareable, $add, $remove);
}

public function getShares($resourceId) {
return $this->sharingBackend->getShares($resourceId);
}

public function applyShareAcl($addressBookId, $acl) {
return $this->sharingBackend->applyShareAcl($addressBookId, $acl);
}

}
97 changes: 97 additions & 0 deletions apps/dav/lib/caldav/calendar.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

namespace OCA\DAV\CalDAV;

use OCA\DAV\DAV\Sharing\IShareable;

class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {

/**
* Updates the list of shares.
*
* The first array is a list of people that are to be added to the
* resource.
*
* Every element in the add array has the following properties:
* * href - A url. Usually a mailto: address
* * commonName - Usually a first and last name, or false
* * summary - A description of the share, can also be false
* * readOnly - A boolean value
*
* Every element in the remove array is just the address string.
*
* @param array $add
* @param array $remove
* @return void
*/
function updateShares(array $add, array $remove) {
/** @var CalDavBackend $calDavBackend */
$calDavBackend = $this->caldavBackend;
$calDavBackend->updateShares($this, $add, $remove);
}

/**
* Returns the list of people whom this resource is shared with.
*
* Every element in this array should have the following properties:
* * href - Often a mailto: address
* * commonName - Optional, for example a first + last name
* * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
* * readOnly - boolean
* * summary - Optional, a description for the share
*
* @return array
*/
function getShares() {
/** @var CalDavBackend $caldavBackend */
$caldavBackend = $this->caldavBackend;
return $caldavBackend->getShares($this->getResourceId());
}

/**
* @return int
*/
public function getResourceId() {
return $this->calendarInfo['id'];
}

function getACL() {
$acl = parent::getACL();

// add the current user
if (isset($this->calendarInfo['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal'])) {
$owner = $this->calendarInfo['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal'];
$acl[] = [
'privilege' => '{DAV:}read',
'principal' => $owner,
'protected' => true,
];
if ($this->calendarInfo['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only']) {
$acl[] = [
'privilege' => '{DAV:}write',
'principal' => $owner,
'protected' => true,
];
}
}

/** @var CalDavBackend $caldavBackend */
$caldavBackend = $this->caldavBackend;
return $caldavBackend->applyShareAcl($this->getResourceId(), $acl);
}

function getChildACL() {
$acl = parent::getChildACL();

/** @var CalDavBackend $caldavBackend */
$caldavBackend = $this->caldavBackend;
return $caldavBackend->applyShareAcl($this->getResourceId(), $acl);
}

function getOwner() {
if (isset($this->calendarInfo['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal'])) {
return $this->calendarInfo['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal'];
}
return parent::getOwner();
}
}
78 changes: 78 additions & 0 deletions apps/dav/lib/caldav/calendarhome.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

namespace OCA\DAV\CalDAV;

use Sabre\CalDAV\Backend\NotificationSupport;
use Sabre\CalDAV\Backend\SchedulingSupport;
use Sabre\CalDAV\Backend\SubscriptionSupport;
use Sabre\CalDAV\Schedule\Inbox;
use Sabre\CalDAV\Schedule\Outbox;
use Sabre\CalDAV\Subscriptions\Subscription;
use Sabre\DAV\Exception\NotFound;

class CalendarHome extends \Sabre\CalDAV\CalendarHome {

/**
* @inheritdoc
*/
function getChildren() {
$calendars = $this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']);
$objs = [];
foreach ($calendars as $calendar) {
$objs[] = new Calendar($this->caldavBackend, $calendar);
}

if ($this->caldavBackend instanceof SchedulingSupport) {
$objs[] = new Inbox($this->caldavBackend, $this->principalInfo['uri']);
$objs[] = new Outbox($this->principalInfo['uri']);
}

// We're adding a notifications node, if it's supported by the backend.
if ($this->caldavBackend instanceof NotificationSupport) {
$objs[] = new \Sabre\CalDAV\Notifications\Collection($this->caldavBackend, $this->principalInfo['uri']);
}

// If the backend supports subscriptions, we'll add those as well,
if ($this->caldavBackend instanceof SubscriptionSupport) {
foreach ($this->caldavBackend->getSubscriptionsForUser($this->principalInfo['uri']) as $subscription) {
$objs[] = new Subscription($this->caldavBackend, $subscription);
}
}

return $objs;
}

/**
* @inheritdoc
*/
function getChild($name) {
// Special nodes
if ($name === 'inbox' && $this->caldavBackend instanceof SchedulingSupport) {
return new Inbox($this->caldavBackend, $this->principalInfo['uri']);
}
if ($name === 'outbox' && $this->caldavBackend instanceof SchedulingSupport) {
return new Outbox($this->principalInfo['uri']);
}
if ($name === 'notifications' && $this->caldavBackend instanceof NotificationSupport) {
return new \Sabre\CalDAv\Notifications\Collection($this->caldavBackend, $this->principalInfo['uri']);
}

// Calendars
foreach ($this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']) as $calendar) {
if ($calendar['uri'] === $name) {
return new Calendar($this->caldavBackend, $calendar);
}
}

if ($this->caldavBackend instanceof SubscriptionSupport) {
foreach ($this->caldavBackend->getSubscriptionsForUser($this->principalInfo['uri']) as $subscription) {
if ($subscription['uri'] === $name) {
return new Subscription($this->caldavBackend, $subscription);
}
}

}

throw new NotFound('Node with name \'' . $name . '\' could not be found');
}
}
10 changes: 10 additions & 0 deletions apps/dav/lib/caldav/calendarroot.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace OCA\DAV\CalDAV;

class CalendarRoot extends \Sabre\CalDAV\CalendarRoot {

function getChildForPrincipal(array $principal) {
return new CalendarHome($this->caldavBackend, $principal);
}
}
18 changes: 1 addition & 17 deletions apps/dav/lib/carddav/carddavbackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -920,22 +920,6 @@ protected function getCardId($uri) {
* @return array
*/
public function applyShareAcl($addressBookId, $acl) {

$shares = $this->getShares($addressBookId);
foreach ($shares as $share) {
$acl[] = [
'privilege' => '{DAV:}read',
'principal' => $share['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}principal'],
'protected' => true,
];
if (!$share['readOnly']) {
$acl[] = [
'privilege' => '{DAV:}write',
'principal' => $share['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}principal'],
'protected' => true,
];
}
}
return $acl;
$this->sharingBackend->applyShareAcl($addressBookId, $acl);
}
}
2 changes: 1 addition & 1 deletion apps/dav/lib/rootcollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public function __construct() {
$systemPrincipals->disableListing = $disableListing;
$filesCollection = new Files\RootCollection($userPrincipalBackend, 'principals/users');
$filesCollection->disableListing = $disableListing;
$caldavBackend = new CalDavBackend($db);
$caldavBackend = new CalDavBackend($db, $userPrincipalBackend);
$calendarRoot = new CalendarRoot($userPrincipalBackend, $caldavBackend, 'principals/users');
$calendarRoot->disableListing = $disableListing;

Expand Down
1 change: 1 addition & 0 deletions apps/dav/tests/travis/caldav/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ fi
cd "$SCRIPTPATH/../../../../../"
OC_PASS=user01 php occ user:add --password-from-env user01
php occ dav:create-calendar user01 calendar
php occ dav:create-calendar user01 shared
OC_PASS=user02 php occ user:add --password-from-env user02
php occ dav:create-calendar user02 calendar
cd "$SCRIPTPATH/../../../../../"
Loading

0 comments on commit 0dcdb3d

Please sign in to comment.