Signed-off-by: Joas Schilling <coding@schilljs.com>tags/v11.0RC2
@@ -46,10 +46,12 @@ $principalBackend = new Principal( | |||
'principals/' | |||
); | |||
$db = \OC::$server->getDatabaseConnection(); | |||
$config = \OC::$server->getConfig(); | |||
$userManager = \OC::$server->getUserManager(); | |||
$random = \OC::$server->getSecureRandom(); | |||
$calDavBackend = new CalDavBackend($db, $principalBackend, $userManager, $config, $random); | |||
$groupManager = \OC::$server->getGroupManager(); | |||
$activityManager = \OC::$server->getActivityManager(); | |||
$userSession = \OC::$server->getUserSession(); | |||
$calDavBackend = new CalDavBackend($db, $principalBackend, $userManager, $groupManager, $random, $activityManager, $userSession); | |||
$debugging = \OC::$server->getConfig()->getSystemValue('debug', false); | |||
@@ -24,7 +24,7 @@ | |||
*/ | |||
namespace OCA\DAV\AppInfo; | |||
use OCA\DAV\CalDAV\Activity; | |||
use OCA\DAV\CalDAV\Activity\Extension; | |||
use OCA\DAV\CalDAV\BirthdayService; | |||
use OCA\DAV\Capabilities; | |||
use OCA\DAV\CardDAV\ContactsManager; | |||
@@ -92,7 +92,7 @@ class Application extends App { | |||
$aM = $this->getContainer()->getServer()->getActivityManager(); | |||
$aM->registerExtension(function() { | |||
return $this->getContainer()->query(Activity::class); | |||
return $this->getContainer()->query(Extension::class); | |||
}); | |||
} | |||
@@ -0,0 +1,396 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com> | |||
* | |||
* @license GNU AGPL version 3 or any later version | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License as | |||
* published by the Free Software Foundation, either version 3 of the | |||
* License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
* | |||
*/ | |||
namespace OCA\DAV\CalDAV\Activity; | |||
use OCA\DAV\CalDAV\CalDavBackend; | |||
use OCA\DAV\CalDAV\Calendar; | |||
use OCP\Activity\IEvent; | |||
use OCP\Activity\IManager as IActivityManager; | |||
use OCP\IGroup; | |||
use OCP\IGroupManager; | |||
use OCP\IUser; | |||
use OCP\IUserSession; | |||
/** | |||
* Class Backend | |||
* | |||
* @package OCA\DAV\CalDAV\Activity | |||
*/ | |||
class Backend { | |||
/** @var CalDavBackend */ | |||
protected $calDavBackend; | |||
/** @var IActivityManager */ | |||
protected $activityManager; | |||
/** @var IGroupManager */ | |||
protected $groupManager; | |||
/** @var IUserSession */ | |||
protected $userSession; | |||
/** | |||
* @param CalDavBackend $calDavBackend | |||
* @param IActivityManager $activityManager | |||
* @param IGroupManager $groupManager | |||
* @param IUserSession $userSession | |||
*/ | |||
public function __construct(CalDavBackend $calDavBackend, IActivityManager $activityManager, IGroupManager $groupManager, IUserSession $userSession) { | |||
$this->calDavBackend = $calDavBackend; | |||
$this->activityManager = $activityManager; | |||
$this->groupManager = $groupManager; | |||
$this->userSession = $userSession; | |||
} | |||
/** | |||
* Creates activities when a calendar was creates | |||
* | |||
* @param int $calendarId | |||
* @param array $properties | |||
*/ | |||
public function addCalendar($calendarId, array $properties) { | |||
$this->triggerActivity(Extension::SUBJECT_ADD, $calendarId, $properties); | |||
} | |||
/** | |||
* Creates activities when a calendar was updated | |||
* | |||
* @param int $calendarId | |||
* @param array $properties | |||
*/ | |||
public function updateCalendar($calendarId, array $properties) { | |||
$this->triggerActivity(Extension::SUBJECT_UPDATE, $calendarId, $properties); | |||
} | |||
/** | |||
* Creates activities when a calendar was deleted | |||
* | |||
* @param int $calendarId | |||
*/ | |||
public function deleteCalendar($calendarId) { | |||
$this->triggerActivity(Extension::SUBJECT_DELETE, $calendarId); | |||
} | |||
/** | |||
* Creates activities for all related users when a calendar was touched | |||
* | |||
* @param string $action | |||
* @param int $calendarId | |||
* @param array $changedProperties | |||
*/ | |||
protected function triggerActivity($action, $calendarId, array $changedProperties = []) { | |||
$properties = $this->calDavBackend->getCalendarById($calendarId); | |||
if (!isset($properties['principaluri'])) { | |||
return; | |||
} | |||
$principal = explode('/', $properties['principaluri']); | |||
$owner = $principal[2]; | |||
$currentUser = $this->userSession->getUser(); | |||
if ($currentUser instanceof IUser) { | |||
$currentUser = $currentUser->getUID(); | |||
} else { | |||
$currentUser = $owner; | |||
} | |||
$event = $this->activityManager->generateEvent(); | |||
$event->setApp('dav') | |||
->setObject(Extension::CALENDAR, $calendarId) | |||
->setType(Extension::CALENDAR) | |||
->setAuthor($currentUser); | |||
$changedVisibleInformation = array_intersect([ | |||
'{DAV:}displayname', | |||
'{http://apple.com/ns/ical/}calendar-color' | |||
], array_keys($changedProperties)); | |||
if ($action === Extension::SUBJECT_UPDATE && empty($changedVisibleInformation)) { | |||
$users = [$owner]; | |||
} else { | |||
$users = $this->getUsersForCalendar($calendarId); | |||
$users[] = $owner; | |||
} | |||
foreach ($users as $user) { | |||
$event->setAffectedUser($user) | |||
->setSubject( | |||
$user === $currentUser ? $action . '_self' : $action, | |||
[ | |||
$currentUser, | |||
$properties['{DAV:}displayname'], | |||
] | |||
); | |||
$this->activityManager->publish($event); | |||
} | |||
} | |||
/** | |||
* Creates activities for all related users when a calendar was (un-)shared | |||
* | |||
* @param Calendar $calendar | |||
* @param array $add | |||
* @param array $remove | |||
*/ | |||
public function updateCalendarShares(Calendar $calendar, array $add, array $remove) { | |||
$calendarId = $calendar->getResourceId(); | |||
$shares = $this->calDavBackend->getShares($calendarId); | |||
$properties = $this->calDavBackend->getCalendarById($calendarId); | |||
$principal = explode('/', $properties['principaluri']); | |||
$owner = $principal[2]; | |||
$currentUser = $this->userSession->getUser(); | |||
if ($currentUser instanceof IUser) { | |||
$currentUser = $currentUser->getUID(); | |||
} else { | |||
$currentUser = $owner; | |||
} | |||
$event = $this->activityManager->generateEvent(); | |||
$event->setApp('dav') | |||
->setObject(Extension::CALENDAR, $calendarId) | |||
->setType(Extension::CALENDAR) | |||
->setAuthor($currentUser); | |||
foreach ($remove as $principal) { | |||
// principal:principals/users/test | |||
$parts = explode(':', $principal, 2); | |||
if ($parts[0] !== 'principal') { | |||
continue; | |||
} | |||
$principal = explode('/', $parts[1]); | |||
if ($principal[1] === 'users') { | |||
$this->triggerActivityUser( | |||
$principal[2], | |||
$event, | |||
$properties, | |||
Extension::SUBJECT_UNSHARE_USER, | |||
Extension::SUBJECT_DELETE . '_self' | |||
); | |||
if ($owner !== $principal[2]) { | |||
$parameters = [ | |||
$principal[2], | |||
$properties['{DAV:}displayname'], | |||
]; | |||
if ($owner === $event->getAuthor()) { | |||
$subject = Extension::SUBJECT_UNSHARE_USER . '_you'; | |||
} else if ($principal[2] === $event->getAuthor()) { | |||
$subject = Extension::SUBJECT_UNSHARE_USER . '_self'; | |||
} else { | |||
$event->setAffectedUser($event->getAuthor()) | |||
->setSubject(Extension::SUBJECT_UNSHARE_USER . '_you', $parameters); | |||
$this->activityManager->publish($event); | |||
$subject = Extension::SUBJECT_UNSHARE_USER . '_by'; | |||
$parameters[] = $event->getAuthor(); | |||
} | |||
$event->setAffectedUser($owner) | |||
->setSubject($subject, $parameters); | |||
$this->activityManager->publish($event); | |||
} | |||
} else if ($principal[1] === 'groups') { | |||
$this->triggerActivityGroup($principal[2], $event, $properties, Extension::SUBJECT_UNSHARE_USER); | |||
$parameters = [ | |||
$principal[2], | |||
$properties['{DAV:}displayname'], | |||
]; | |||
if ($owner === $event->getAuthor()) { | |||
$subject = Extension::SUBJECT_UNSHARE_GROUP . '_you'; | |||
} else { | |||
$event->setAffectedUser($event->getAuthor()) | |||
->setSubject(Extension::SUBJECT_UNSHARE_GROUP . '_you', $parameters); | |||
$this->activityManager->publish($event); | |||
$subject = Extension::SUBJECT_UNSHARE_GROUP . '_by'; | |||
$parameters[] = $event->getAuthor(); | |||
} | |||
$event->setAffectedUser($owner) | |||
->setSubject($subject, $parameters); | |||
$this->activityManager->publish($event); | |||
} | |||
} | |||
foreach ($add as $share) { | |||
if ($this->isAlreadyShared($share['href'], $shares)) { | |||
continue; | |||
} | |||
// principal:principals/users/test | |||
$parts = explode(':', $share['href'], 2); | |||
if ($parts[0] !== 'principal') { | |||
continue; | |||
} | |||
$principal = explode('/', $parts[1]); | |||
if ($principal[1] === 'users') { | |||
$this->triggerActivityUser($principal[2], $event, $properties, Extension::SUBJECT_SHARE_USER); | |||
if ($owner !== $principal[2]) { | |||
$parameters = [ | |||
$principal[2], | |||
$properties['{DAV:}displayname'], | |||
]; | |||
if ($owner === $event->getAuthor()) { | |||
$subject = Extension::SUBJECT_SHARE_USER . '_you'; | |||
} else { | |||
$event->setAffectedUser($event->getAuthor()) | |||
->setSubject(Extension::SUBJECT_SHARE_USER . '_you', $parameters); | |||
$this->activityManager->publish($event); | |||
$subject = Extension::SUBJECT_SHARE_USER . '_by'; | |||
$parameters[] = $event->getAuthor(); | |||
} | |||
$event->setAffectedUser($owner) | |||
->setSubject($subject, $parameters); | |||
$this->activityManager->publish($event); | |||
} | |||
} else if ($principal[1] === 'groups') { | |||
$this->triggerActivityGroup($principal[2], $event, $properties, Extension::SUBJECT_SHARE_USER); | |||
$parameters = [ | |||
$principal[2], | |||
$properties['{DAV:}displayname'], | |||
]; | |||
if ($owner === $event->getAuthor()) { | |||
$subject = Extension::SUBJECT_SHARE_GROUP . '_you'; | |||
} else { | |||
$event->setAffectedUser($event->getAuthor()) | |||
->setSubject(Extension::SUBJECT_SHARE_GROUP . '_you', $parameters); | |||
$this->activityManager->publish($event); | |||
$subject = Extension::SUBJECT_SHARE_GROUP . '_by'; | |||
$parameters[] = $event->getAuthor(); | |||
} | |||
$event->setAffectedUser($owner) | |||
->setSubject($subject, $parameters); | |||
$this->activityManager->publish($event); | |||
} | |||
} | |||
} | |||
/** | |||
* Checks if a calendar is already shared with a principal | |||
* | |||
* @param string $principal | |||
* @param array[] $shares | |||
* @return bool | |||
*/ | |||
protected function isAlreadyShared($principal, $shares) { | |||
foreach ($shares as $share) { | |||
if ($principal === $share['href']) { | |||
return true; | |||
} | |||
} | |||
return false; | |||
} | |||
/** | |||
* Creates the given activity for all members of the given group | |||
* | |||
* @param string $gid | |||
* @param IEvent $event | |||
* @param array $properties | |||
* @param string $subject | |||
*/ | |||
protected function triggerActivityGroup($gid, IEvent $event, array $properties, $subject) { | |||
$group = $this->groupManager->get($gid); | |||
if ($group instanceof IGroup) { | |||
foreach ($group->getUsers() as $user) { | |||
// Exclude current user | |||
if ($user->getUID() !== $event->getAuthor()) { | |||
$this->triggerActivityUser($user->getUID(), $event, $properties, $subject); | |||
} | |||
} | |||
} | |||
} | |||
/** | |||
* Creates the given activity for the given user | |||
* | |||
* @param string $user | |||
* @param IEvent $event | |||
* @param array $properties | |||
* @param string $subject | |||
* @param string $subjectSelf | |||
*/ | |||
protected function triggerActivityUser($user, IEvent $event, array $properties, $subject, $subjectSelf = '') { | |||
$event->setAffectedUser($user) | |||
->setSubject( | |||
$user === $event->getAuthor() && $subjectSelf ? $subjectSelf : $subject, | |||
[ | |||
$event->getAuthor(), | |||
$properties['{DAV:}displayname'], | |||
] | |||
); | |||
$this->activityManager->publish($event); | |||
} | |||
/** | |||
* Get all users that have access to a given calendar | |||
* | |||
* @param int $calendarId | |||
* @return string[] | |||
*/ | |||
protected function getUsersForCalendar($calendarId) { | |||
$users = $groups = []; | |||
$shares = $this->calDavBackend->getShares($calendarId); | |||
foreach ($shares as $share) { | |||
$prinical = explode('/', $share['{http://owncloud.org/ns}principal']); | |||
if ($prinical[1] === 'users') { | |||
$users[] = $prinical[2]; | |||
} else if ($prinical[1] === 'groups') { | |||
$groups[] = $prinical[2]; | |||
} | |||
} | |||
if (!empty($groups)) { | |||
foreach ($groups as $gid) { | |||
$group = $this->groupManager->get($gid); | |||
if ($group instanceof IGroup) { | |||
foreach ($group->getUsers() as $user) { | |||
$users[] = $user->getUID(); | |||
} | |||
} | |||
} | |||
} | |||
return $users; | |||
} | |||
} |
@@ -19,22 +19,19 @@ | |||
* | |||
*/ | |||
namespace OCA\DAV\CalDAV; | |||
namespace OCA\DAV\CalDAV\Activity; | |||
use OCP\Activity\IExtension; | |||
use OCP\IURLGenerator; | |||
use OCP\L10N\IFactory; | |||
class Activity implements IExtension { | |||
class Extension implements IExtension { | |||
const APP = 'dav'; | |||
/** | |||
* Filter with all sharing related activities | |||
*/ | |||
const CALENDAR = 'calendar'; | |||
/** | |||
* Activity types known to this extension | |||
*/ | |||
const SUBJECT_ADD = 'calendar_add'; | |||
const SUBJECT_UPDATE = 'calendar_update'; | |||
const SUBJECT_DELETE = 'calendar_delete'; | |||
@@ -43,10 +40,6 @@ class Activity implements IExtension { | |||
const SUBJECT_UNSHARE_USER = 'calendar_user_unshare'; | |||
const SUBJECT_UNSHARE_GROUP = 'calendar_group_unshare'; | |||
/** | |||
* Subject keys for translation of the subjections | |||
*/ | |||
/** @var IFactory */ | |||
protected $languageFactory; | |||
@@ -26,16 +26,16 @@ | |||
namespace OCA\DAV\CalDAV; | |||
use OCA\DAV\DAV\Sharing\IShareable; | |||
use OCP\Activity\IEvent; | |||
use OCA\DAV\CalDAV\Activity\Backend as ActivityBackend; | |||
use OCP\Activity\IManager as IActivityManager; | |||
use OCP\DB\QueryBuilder\IQueryBuilder; | |||
use OCA\DAV\Connector\Sabre\Principal; | |||
use OCA\DAV\DAV\Sharing\Backend; | |||
use OCP\IConfig; | |||
use OCP\IDBConnection; | |||
use OCP\IGroup; | |||
use OCP\IGroupManager; | |||
use OCP\IUser; | |||
use OCP\IUserManager; | |||
use OCP\IUserSession; | |||
use OCP\Security\ISecureRandom; | |||
use Sabre\CalDAV\Backend\AbstractBackend; | |||
use Sabre\CalDAV\Backend\SchedulingSupport; | |||
@@ -127,32 +127,37 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription | |||
/** @var IUserManager */ | |||
private $userManager; | |||
/** @var IConfig */ | |||
private $config; | |||
/** @var ISecureRandom */ | |||
private $random; | |||
/** @var ActivityBackend */ | |||
private $activityBackend; | |||
/** | |||
* CalDavBackend constructor. | |||
* | |||
* @param IDBConnection $db | |||
* @param Principal $principalBackend | |||
* @param IUserManager $userManager | |||
* @param IConfig $config | |||
* @param IGroupManager $groupManager | |||
* @param ISecureRandom $random | |||
* @param IActivityManager $activityManager | |||
* @param IUserSession $userSession | |||
*/ | |||
public function __construct(IDBConnection $db, | |||
Principal $principalBackend, | |||
IUserManager $userManager, | |||
IConfig $config, | |||
ISecureRandom $random) { | |||
IGroupManager $groupManager, | |||
ISecureRandom $random, | |||
IActivityManager $activityManager, | |||
IUserSession $userSession) { | |||
$this->db = $db; | |||
$this->principalBackend = $principalBackend; | |||
$this->userManager = $userManager; | |||
$this->userManager = $groupManager; | |||
$this->sharingBackend = new Backend($this->db, $principalBackend, 'calendar'); | |||
$this->config = $config; | |||
$this->activityBackend = new ActivityBackend($this, $activityManager, $groupManager, $userSession); | |||
$this->random = $random; | |||
} | |||
@@ -618,7 +623,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription | |||
$query->execute(); | |||
$calendarId = $query->getLastInsertId(); | |||
$this->triggerActivity(Activity::SUBJECT_ADD, $calendarId, $values); | |||
$this->activityBackend->addCalendar($calendarId, $values); | |||
return $calendarId; | |||
} | |||
@@ -668,7 +673,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription | |||
$this->addChange($calendarId, "", 2); | |||
$this->triggerActivity(Activity::SUBJECT_UPDATE, $calendarId, $mutations); | |||
$this->activityBackend->updateCalendar($calendarId, $mutations); | |||
return true; | |||
}); | |||
@@ -681,7 +686,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription | |||
* @return void | |||
*/ | |||
function deleteCalendar($calendarId) { | |||
$this->triggerActivity(Activity::SUBJECT_DELETE, $calendarId); | |||
$this->activityBackend->deleteCalendar($calendarId); | |||
$stmt = $this->db->prepare('DELETE FROM `*PREFIX*calendarobjects` WHERE `calendarid` = ?'); | |||
$stmt->execute([$calendarId]); | |||
@@ -1660,8 +1665,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription | |||
*/ | |||
public function updateShares($shareable, $add, $remove) { | |||
/** @var Calendar $shareable */ | |||
$this->triggerActivitySharing($shareable, $add, $remove); | |||
$this->activityBackend->updateCalendarShares($shareable, $add, $remove); | |||
$this->sharingBackend->updateShares($shareable, $add, $remove); | |||
} | |||
@@ -1736,276 +1740,4 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription | |||
} | |||
return $principalUri; | |||
} | |||
protected function triggerActivity($action, $calendarId, array $changedProperties = []) { | |||
$aM = \OC::$server->getActivityManager(); | |||
$userSession = \OC::$server->getUserSession(); | |||
$properties = $this->getCalendarById($calendarId); | |||
if (!isset($properties['principaluri'])) { | |||
return; | |||
} | |||
$principal = explode('/', $properties['principaluri']); | |||
$owner = $principal[2]; | |||
$currentUser = $userSession->getUser(); | |||
if ($currentUser instanceof IUser) { | |||
$currentUser = $currentUser->getUID(); | |||
} else { | |||
$currentUser = $owner; | |||
} | |||
$event = $aM->generateEvent(); | |||
$event->setApp('dav') | |||
->setObject(Activity::CALENDAR, $calendarId) | |||
->setType(Activity::CALENDAR) | |||
->setAuthor($currentUser); | |||
$changedVisibleInformation = array_intersect([ | |||
'{DAV:}displayname', | |||
'{http://apple.com/ns/ical/}calendar-color' | |||
], array_keys($changedProperties)); | |||
if ($action === Activity::SUBJECT_UPDATE && empty($changedVisibleInformation)) { | |||
$users = [$owner]; | |||
} else { | |||
$users = $this->getUsersForCalendar($calendarId); | |||
$users[] = $owner; | |||
} | |||
foreach ($users as $user) { | |||
$event->setAffectedUser($user) | |||
->setSubject( | |||
$user === $currentUser ? $action . '_self' : $action, | |||
[ | |||
$currentUser, | |||
$properties['{DAV:}displayname'], | |||
] | |||
); | |||
$aM->publish($event); | |||
} | |||
} | |||
protected function triggerActivitySharing(Calendar $calendar, array $add, array $remove) { | |||
$aM = \OC::$server->getActivityManager(); | |||
$userSession = \OC::$server->getUserSession(); | |||
$calendarId = $calendar->getResourceId(); | |||
$shares = $this->sharingBackend->getShares($calendarId); | |||
$properties = $this->getCalendarById($calendarId); | |||
$principal = explode('/', $properties['principaluri']); | |||
$owner = $principal[2]; | |||
$currentUser = $userSession->getUser(); | |||
if ($currentUser instanceof IUser) { | |||
$currentUser = $currentUser->getUID(); | |||
} else { | |||
$currentUser = $owner; | |||
} | |||
$event = $aM->generateEvent(); | |||
$event->setApp('dav') | |||
->setObject(Activity::CALENDAR, $calendarId) | |||
->setType(Activity::CALENDAR) | |||
->setAuthor($currentUser); | |||
foreach ($remove as $principal) { | |||
// principal:principals/users/test | |||
$parts = explode(':', $principal, 2); | |||
if ($parts[0] !== 'principal') { | |||
continue; | |||
} | |||
$principal = explode('/', $parts[1]); | |||
if ($principal[1] === 'users') { | |||
$this->triggerActivityUnshareUser( | |||
$principal[2], | |||
$event, | |||
$properties, | |||
Activity::SUBJECT_UNSHARE_USER, | |||
Activity::SUBJECT_DELETE . '_self' | |||
); | |||
if ($owner !== $principal[2]) { | |||
$parameters = [ | |||
$principal[2], | |||
$properties['{DAV:}displayname'], | |||
]; | |||
if ($owner === $event->getAuthor()) { | |||
$subject = Activity::SUBJECT_UNSHARE_USER . '_you'; | |||
} else if ($principal[2] === $event->getAuthor()) { | |||
$subject = Activity::SUBJECT_UNSHARE_USER . '_self'; | |||
} else { | |||
$event->setAffectedUser($event->getAuthor()) | |||
->setSubject(Activity::SUBJECT_UNSHARE_USER . '_you', $parameters); | |||
$aM->publish($event); | |||
$subject = Activity::SUBJECT_UNSHARE_USER . '_by'; | |||
$parameters[] = $event->getAuthor(); | |||
} | |||
$event->setAffectedUser($owner) | |||
->setSubject($subject, $parameters); | |||
$aM->publish($event); | |||
} | |||
} else if ($principal[1] === 'groups') { | |||
$this->triggerActivityUnshareGroup($principal[2], $event, $properties, Activity::SUBJECT_UNSHARE_USER); | |||
$parameters = [ | |||
$principal[2], | |||
$properties['{DAV:}displayname'], | |||
]; | |||
if ($owner === $event->getAuthor()) { | |||
$subject = Activity::SUBJECT_UNSHARE_GROUP . '_you'; | |||
} else { | |||
$event->setAffectedUser($event->getAuthor()) | |||
->setSubject(Activity::SUBJECT_UNSHARE_GROUP . '_you', $parameters); | |||
$aM->publish($event); | |||
$subject = Activity::SUBJECT_UNSHARE_GROUP . '_by'; | |||
$parameters[] = $event->getAuthor(); | |||
} | |||
$event->setAffectedUser($owner) | |||
->setSubject($subject, $parameters); | |||
$aM->publish($event); | |||
} | |||
} | |||
foreach ($add as $share) { | |||
if ($this->isAlreadyShared($share['href'], $shares)) { | |||
continue; | |||
} | |||
// principal:principals/users/test | |||
$parts = explode(':', $share['href'], 2); | |||
if ($parts[0] !== 'principal') { | |||
continue; | |||
} | |||
$principal = explode('/', $parts[1]); | |||
if ($principal[1] === 'users') { | |||
$this->triggerActivityUnshareUser($principal[2], $event, $properties, Activity::SUBJECT_SHARE_USER); | |||
if ($owner !== $principal[2]) { | |||
$parameters = [ | |||
$principal[2], | |||
$properties['{DAV:}displayname'], | |||
]; | |||
if ($owner === $event->getAuthor()) { | |||
$subject = Activity::SUBJECT_SHARE_USER . '_you'; | |||
} else { | |||
$event->setAffectedUser($event->getAuthor()) | |||
->setSubject(Activity::SUBJECT_SHARE_USER . '_you', $parameters); | |||
$aM->publish($event); | |||
$subject = Activity::SUBJECT_SHARE_USER . '_by'; | |||
$parameters[] = $event->getAuthor(); | |||
} | |||
$event->setAffectedUser($owner) | |||
->setSubject($subject, $parameters); | |||
$aM->publish($event); | |||
} | |||
} else if ($principal[1] === 'groups') { | |||
$this->triggerActivityUnshareGroup($principal[2], $event, $properties, Activity::SUBJECT_SHARE_USER); | |||
$parameters = [ | |||
$principal[2], | |||
$properties['{DAV:}displayname'], | |||
]; | |||
if ($owner === $event->getAuthor()) { | |||
$subject = Activity::SUBJECT_SHARE_GROUP . '_you'; | |||
} else { | |||
$event->setAffectedUser($event->getAuthor()) | |||
->setSubject(Activity::SUBJECT_SHARE_GROUP . '_you', $parameters); | |||
$aM->publish($event); | |||
$subject = Activity::SUBJECT_SHARE_GROUP . '_by'; | |||
$parameters[] = $event->getAuthor(); | |||
} | |||
$event->setAffectedUser($owner) | |||
->setSubject($subject, $parameters); | |||
$aM->publish($event); | |||
} | |||
} | |||
} | |||
protected function isAlreadyShared($principal, $shares) { | |||
foreach ($shares as $share) { | |||
if ($principal === $share['href']) { | |||
return true; | |||
} | |||
} | |||
return false; | |||
} | |||
protected function triggerActivityUnshareGroup($gid, IEvent $event, array $properties, $subject) { | |||
$gM = \OC::$server->getGroupManager(); | |||
$group = $gM->get($gid); | |||
if ($group instanceof IGroup) { | |||
foreach ($group->getUsers() as $user) { | |||
// Exclude current user | |||
if ($user->getUID() !== $event->getAuthor()) { | |||
$this->triggerActivityUnshareUser($user->getUID(), $event, $properties, $subject); | |||
} | |||
} | |||
} | |||
} | |||
protected function triggerActivityUnshareUser($user, IEvent $event, array $properties, $subject, $subjectSelf = '') { | |||
$aM = \OC::$server->getActivityManager(); | |||
$event->setAffectedUser($user) | |||
->setSubject( | |||
$user === $event->getAuthor() && $subjectSelf ? $subjectSelf : $subject, | |||
[ | |||
$event->getAuthor(), | |||
$properties['{DAV:}displayname'], | |||
] | |||
); | |||
$aM->publish($event); | |||
} | |||
/** | |||
* Get all users that have access to a given calendar | |||
* | |||
* @param int $calendarId | |||
* @return string[] | |||
*/ | |||
protected function getUsersForCalendar($calendarId) { | |||
$gM = \OC::$server->getGroupManager(); | |||
$users = $groups = []; | |||
$shares = $this->getShares($calendarId); | |||
foreach ($shares as $share) { | |||
$prinical = explode('/', $share['{http://owncloud.org/ns}principal']); | |||
if ($prinical[1] === 'users') { | |||
$users[] = $prinical[2]; | |||
} else if ($prinical[1] === 'groups') { | |||
$groups[] = $prinical[2]; | |||
} | |||
} | |||
if (!empty($groups)) { | |||
foreach ($groups as $gid) { | |||
$group = $gM->get($gid); | |||
if ($group instanceof IGroup) { | |||
foreach ($group->getUsers() as $user) { | |||
$users[] = $user->getUID(); | |||
} | |||
} | |||
} | |||
} | |||
return $users; | |||
} | |||
} |
@@ -75,11 +75,12 @@ class CreateCalendar extends Command { | |||
$this->userManager, | |||
$this->groupManager | |||
); | |||
$config = \OC::$server->getConfig(); | |||
$random = \OC::$server->getSecureRandom(); | |||
$activityManager = \OC::$server->getActivityManager(); | |||
$userSession = \OC::$server->getUserSession(); | |||
$name = $input->getArgument('name'); | |||
$caldav = new CalDavBackend($this->dbConnection, $principalBackend, $this->userManager, $config, $random); | |||
$caldav = new CalDavBackend($this->dbConnection, $principalBackend, $this->userManager, $this->groupManager, $random, $activityManager, $userSession); | |||
$caldav->createCalendar("principals/users/$user", $name, []); | |||
} | |||
} |
@@ -41,6 +41,9 @@ class RootCollection extends SimpleCollection { | |||
$config = \OC::$server->getConfig(); | |||
$random = \OC::$server->getSecureRandom(); | |||
$userManager = \OC::$server->getUserManager(); | |||
$groupManager = \OC::$server->getGroupManager(); | |||
$activityManager = \OC::$server->getActivityManager(); | |||
$userSession = \OC::$server->getUserSession(); | |||
$db = \OC::$server->getDatabaseConnection(); | |||
$dispatcher = \OC::$server->getEventDispatcher(); | |||
$userPrincipalBackend = new Principal( | |||
@@ -62,7 +65,7 @@ class RootCollection extends SimpleCollection { | |||
$systemPrincipals->disableListing = $disableListing; | |||
$filesCollection = new Files\RootCollection($userPrincipalBackend, 'principals/users'); | |||
$filesCollection->disableListing = $disableListing; | |||
$caldavBackend = new CalDavBackend($db, $userPrincipalBackend, $userManager, $config, $random); | |||
$caldavBackend = new CalDavBackend($db, $userPrincipalBackend, $userManager, $groupManager, $random, $activityManager, $userSession); | |||
$calendarRoot = new CalendarRoot($userPrincipalBackend, $caldavBackend, 'principals/users'); | |||
$calendarRoot->disableListing = $disableListing; | |||
$publicCalendarRoot = new PublicCalendarRoot($caldavBackend); |
@@ -22,18 +22,15 @@ | |||
namespace OCA\DAV\Tests\unit\CalDAV; | |||
use DateTime; | |||
use DateTimeZone; | |||
use OCA\DAV\CalDAV\Activity\Backend as ActivityBackend; | |||
use OCA\DAV\CalDAV\CalDavBackend; | |||
use OCA\DAV\CalDAV\Calendar; | |||
use OCA\DAV\Connector\Sabre\Principal; | |||
use OCP\IL10N; | |||
use OCP\IConfig; | |||
use OCP\Activity\IManager as IActivityManager; | |||
use OCP\IGroupManager; | |||
use OCP\IUserManager; | |||
use OCP\IUserSession; | |||
use OCP\Security\ISecureRandom; | |||
use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet; | |||
use Sabre\DAV\PropPatch; | |||
use Sabre\DAV\Xml\Property\Href; | |||
use Sabre\DAVACL\IACL; | |||
use Test\TestCase; | |||
/** | |||
@@ -50,12 +47,10 @@ abstract class AbstractCalDavBackendTest extends TestCase { | |||
/** @var Principal | \PHPUnit_Framework_MockObject_MockObject */ | |||
protected $principal; | |||
/** @var \OCP\IUserManager|\PHPUnit_Framework_MockObject_MockObject */ | |||
/** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */ | |||
protected $userManager; | |||
/** var OCP\IConfig */ | |||
protected $config; | |||
/** @var ActivityBackend|\PHPUnit_Framework_MockObject_MockObject */ | |||
protected $activityBackend; | |||
/** @var ISecureRandom */ | |||
private $random; | |||
@@ -67,9 +62,10 @@ abstract class AbstractCalDavBackendTest extends TestCase { | |||
public function setUp() { | |||
parent::setUp(); | |||
$this->userManager = $this->getMockBuilder('OCP\IUserManager') | |||
->disableOriginalConstructor() | |||
->getMock(); | |||
$this->userManager = $this->createMock(IUserManager::class); | |||
$groupManager = $this->createMock(IGroupManager::class); | |||
$activityManager = $this->createMock(IActivityManager::class); | |||
$userSession = $this->createMock(IUserSession::class); | |||
$this->principal = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Principal') | |||
->disableOriginalConstructor() | |||
->setMethods(['getPrincipalByPath', 'getGroupMembership']) | |||
@@ -83,15 +79,21 @@ abstract class AbstractCalDavBackendTest extends TestCase { | |||
->willReturn([self::UNIT_TEST_GROUP]); | |||
$db = \OC::$server->getDatabaseConnection(); | |||
$this->config = \OC::$server->getConfig(); | |||
$this->random = \OC::$server->getSecureRandom(); | |||
$this->backend = new CalDavBackend($db, $this->principal, $this->userManager, $this->config, $this->random); | |||
$this->tearDown(); | |||
$this->backend = new CalDavBackend($db, $this->principal, $this->userManager, $groupManager, $this->random, $activityManager, $userSession); | |||
$this->activityBackend = $this->createMock(ActivityBackend::class); | |||
$this->invokePrivate($this->backend, 'activityBackend', [$this->activityBackend]); | |||
$this->cleanUpBackend(); | |||
} | |||
public function tearDown() { | |||
$this->cleanUpBackend(); | |||
parent::tearDown(); | |||
} | |||
public function cleanUpBackend() { | |||
if (is_null($this->backend)) { | |||
return; | |||
} |
@@ -357,10 +357,8 @@ EOD; | |||
$calendar->setPublishStatus(false); | |||
$this->assertEquals(false, $calendar->getPublishStatus()); | |||
$publicCalendarURI = md5($this->config->getSystemValue('secret', '') . $calendar->getResourceId()); | |||
$this->setExpectedException('Sabre\DAV\Exception\NotFound'); | |||
$publicCalendar = $this->backend->getPublicCalendar($publicCalendarURI); | |||
$this->backend->getPublicCalendar($publicCalendarURI); | |||
} | |||
public function testSubscriptions() { |
@@ -2,12 +2,16 @@ | |||
namespace OCA\DAV\Tests\unit\CalDAV; | |||
use OCA\DAV\CalDAV\Activity\Backend as ActivityBackend; | |||
use OCA\DAV\CalDAV\Calendar; | |||
use OCA\DAV\Connector\Sabre\Principal; | |||
use OCP\Activity\IManager as IActivityManager; | |||
use OCP\IGroupManager; | |||
use OCP\IL10N; | |||
use OCA\DAV\CalDAV\CalDavBackend; | |||
use OCA\DAV\CalDAV\PublicCalendarRoot; | |||
use OCP\IUserManager; | |||
use OCP\IUserSession; | |||
use OCP\Security\ISecureRandom; | |||
use Test\TestCase; | |||
@@ -27,12 +31,19 @@ class PublicCalendarRootTest extends TestCase { | |||
private $publicCalendarRoot; | |||
/** @var IL10N */ | |||
private $l10n; | |||
/** @var IUserManager */ | |||
private $userManager; | |||
/** @var Principal */ | |||
/** @var Principal|\PHPUnit_Framework_MockObject_MockObject */ | |||
private $principal; | |||
/** var IConfig */ | |||
protected $config; | |||
/** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */ | |||
protected $userManager; | |||
/** @var IGroupManager|\PHPUnit_Framework_MockObject_MockObject */ | |||
protected $groupManager; | |||
/** @var IActivityManager|\PHPUnit_Framework_MockObject_MockObject */ | |||
protected $activityManager; | |||
/** @var IUserSession|\PHPUnit_Framework_MockObject_MockObject */ | |||
protected $userSession; | |||
/** @var ActivityBackend|\PHPUnit_Framework_MockObject_MockObject */ | |||
protected $activityBackend; | |||
/** @var ISecureRandom */ | |||
private $random; | |||
@@ -40,21 +51,26 @@ class PublicCalendarRootTest extends TestCase { | |||
parent::setUp(); | |||
$db = \OC::$server->getDatabaseConnection(); | |||
$this->principal = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Principal') | |||
->disableOriginalConstructor() | |||
->getMock(); | |||
$this->config = \OC::$server->getConfig(); | |||
$this->userManager = $this->getMockBuilder('\OCP\IUserManager')->getMock(); | |||
$this->principal = $this->createMock('OCA\DAV\Connector\Sabre\Principal'); | |||
$this->userManager = $this->createMock(IUserManager::class); | |||
$groupManager = $this->createMock(IGroupManager::class); | |||
$activityManager = $this->createMock(IActivityManager::class); | |||
$userSession = $this->createMock(IUserSession::class); | |||
$this->random = \OC::$server->getSecureRandom(); | |||
$this->backend = new CalDavBackend( | |||
$db, | |||
$this->principal, | |||
$this->userManager, | |||
$this->config, | |||
$this->random | |||
$groupManager, | |||
$this->random, | |||
$activityManager, | |||
$userSession | |||
); | |||
$this->activityBackend = $this->createMock(ActivityBackend::class); | |||
$this->invokePrivate($this->backend, 'activityBackend', [$this->activityBackend]); | |||
$this->publicCalendarRoot = new PublicCalendarRoot($this->backend); | |||
$this->l10n = $this->getMockBuilder('\OCP\IL10N') | |||
@@ -79,6 +95,14 @@ class PublicCalendarRootTest extends TestCase { | |||
} | |||
public function testGetChild() { | |||
$this->activityBackend->expects($this->exactly(1)) | |||
->method('addCalendar'); | |||
$this->activityBackend->expects($this->never()) | |||
->method('updateCalendar'); | |||
$this->activityBackend->expects($this->never()) | |||
->method('deleteCalendar'); | |||
$this->activityBackend->expects($this->never()) | |||
->method('updateCalendarShares'); | |||
$calendar = $this->createPublicCalendar(); | |||
@@ -93,6 +117,15 @@ class PublicCalendarRootTest extends TestCase { | |||
} | |||
public function testGetChildren() { | |||
$this->activityBackend->expects($this->exactly(1)) | |||
->method('addCalendar'); | |||
$this->activityBackend->expects($this->never()) | |||
->method('updateCalendar'); | |||
$this->activityBackend->expects($this->never()) | |||
->method('deleteCalendar'); | |||
$this->activityBackend->expects($this->never()) | |||
->method('updateCalendarShares'); | |||
$this->createPublicCalendar(); | |||
$publicCalendars = $this->backend->getPublicCalendars(); |