'principals/'
);
$db = \OC::$server->getDatabaseConnection();
-$calDavBackend = new CalDavBackend($db, $principalBackend, \OC::$server->getUserManager());
+$config = \OC::$server->getConfig();
+$calDavBackend = new CalDavBackend($db, $principalBackend, \OC::$server->getUserManager(), $config);
$debugging = \OC::$server->getConfig()->getSystemValue('debug', false);
/**
* Application constructor.
*/
- public function __construct() {
- parent::__construct('dav');
+ public function __construct (array $urlParams=array()) {
+ parent::__construct('dav', $urlParams);
+
+ $container = $this->getContainer();
+ $container->registerService('ContactsManager', function($c) {
+ /** @var IAppContainer $c */
+ return new ContactsManager(
+ $c->query('CardDavBackend')
+ );
+ });
+
+ $container->registerService('HookManager', function($c) {
+ /** @var IAppContainer $c */
+ return new HookManager(
+ $c->getServer()->getUserManager(),
+ $c->query('SyncService'),
+ $c->query('CalDavBackend'),
+ $c->query('CardDavBackend')
+ );
+ });
+
+ $container->registerService('SyncService', function($c) {
+ /** @var IAppContainer $c */
+ return new SyncService(
+ $c->query('CardDavBackend'),
+ $c->getServer()->getUserManager(),
+ $c->getServer()->getLogger()
+ );
+ });
+
+ $container->registerService('CardDavBackend', function($c) {
+ /** @var IAppContainer $c */
+ $db = $c->getServer()->getDatabaseConnection();
+ $dispatcher = $c->getServer()->getEventDispatcher();
+ $principal = new Principal(
+ $c->getServer()->getUserManager(),
+ $c->getServer()->getGroupManager()
+ );
+ return new CardDavBackend($db, $principal, $c->getServer()->getUserManager(), $dispatcher);
+ });
+
+ $container->registerService('CalDavBackend', function($c) {
+ /** @var IAppContainer $c */
+ $db = $c->getServer()->getDatabaseConnection();
+ $config = $c->getServer()->getConfig();
+ $principal = new Principal(
+ $c->getServer()->getUserManager(),
+ $c->getServer()->getGroupManager()
+ );
+ return new CalDavBackend($db, $principal, $c->getServer()->getUserManager(), $config);
+ });
+
+ $container->registerService('BirthdayService', function($c) {
+ /** @var IAppContainer $c */
+ $g = new GroupPrincipalBackend(
+ $c->getServer()->getGroupManager()
+ );
+ return new BirthdayService(
+ $c->query('CalDavBackend'),
+ $c->query('CardDavBackend'),
+ $g
+ );
+ });
+
+ $container->registerService('OCA\DAV\Migration\Classification', function ($c) {
+ /** @var IAppContainer $c */
+ return new Classification(
+ $c->query('CalDavBackend'),
+ $c->getServer()->getUserManager()
+ );
+ });
+
+ $container->registerService('OCA\DAV\Migration\GenerateBirthdays', function ($c) {
+ /** @var IAppContainer $c */
+ /** @var BirthdayService $b */
+ $b = $c->query('BirthdayService');
+ return new GenerateBirthdays(
+ $b,
+ $c->getServer()->getUserManager()
+ );
+ });
}
/**
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\IUser;
use OCP\IUserManager;
/** @var IUserManager */
private $userManager;
- /** @var \OCP\IConfig */
+ /** @var IConfig */
private $config;
/**
* @param IDBConnection $db
* @param Principal $principalBackend
* @param IUserManager $userManager
+ * @param IConfig $config
*/
- public function __construct(IDBConnection $db, Principal $principalBackend, IUserManager $userManager) {
+ public function __construct(IDBConnection $db, Principal $principalBackend, IUserManager $userManager, IConfig $config) {
$this->db = $db;
$this->principalBackend = $principalBackend;
$this->userManager = $userManager;
$this->sharingBackend = new Backend($this->db, $principalBackend, 'calendar');
- // TODO: inject
- $this->config = \OC::$server->getConfig();
+ $this->config = $config;
}
/**
}
/**
- * @param boolean $value
- * @param \OCA\DAV\CalDAV\Calendar $calendar
- */
- public function setPublishStatus($value, $calendar) {
- $query = $this->db->getQueryBuilder();
- if ($value) {
- $query->insert('dav_shares')
- ->values([
- 'principaluri' => $query->createNamedParameter($calendar->getPrincipalURI()),
- 'type' => $query->createNamedParameter('calendar'),
- 'access' => $query->createNamedParameter(self::ACCESS_PUBLIC),
- 'resourceid' => $query->createNamedParameter($calendar->getResourceId())
- ]);
- } else {
- $query->delete('dav_shares')
- ->Where($query->expr()->eq('resourceid', $query->createNamedParameter($calendar->getResourceId())))
- ->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC)));
- }
- $query->execute();
- }
+ * @param boolean $value
+ * @param \OCA\DAV\CalDAV\Calendar $calendar
+ */
+ public function setPublishStatus($value, $calendar) {
+ $query = $this->db->getQueryBuilder();
+ if ($value) {
+ $query->insert('dav_shares')
+ ->values([
+ 'principaluri' => $query->createNamedParameter($calendar->getPrincipalURI()),
+ 'type' => $query->createNamedParameter('calendar'),
+ 'access' => $query->createNamedParameter(self::ACCESS_PUBLIC),
+ 'resourceid' => $query->createNamedParameter($calendar->getResourceId())
+ ]);
+ } else {
+ $query->delete('dav_shares')
+ ->where($query->expr()->eq('resourceid', $query->createNamedParameter($calendar->getResourceId())))
+ ->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC)));
+ }
+ $query->execute();
+ }
/**
* @param \OCA\DAV\CalDAV\Calendar $calendar
namespace OCA\DAV\CalDAV;
use Sabre\DAV\Collection;
+use Sabre\DAV\Exception\NotFound;
class PublicCalendarRoot extends Collection {
/** @var CalDavBackend */
protected $caldavBackend;
+ /** @var \OCP\IL10N */
+ protected $l10n;
+
function __construct(CalDavBackend $caldavBackend) {
$this->caldavBackend = $caldavBackend;
+ $this->l10n = \OC::$server->getL10N('dav');
}
/**
return 'public-calendars';
}
+ /**
+ * @inheritdoc
+ */
function getChild($name) {
- // TODO: for performance reason this needs to have a custom implementation
- return parent::getChild($name);
+ foreach ($this->caldavBackend->getPublicCalendars() as $calendar) {
+ if ($calendar['uri'] === $name) {
+ // TODO: maybe implement a new class PublicCalendar ???
+ return new Calendar($this->caldavBackend, $calendar, $this->l10n);
+ }
+ }
+ throw new NotFound('Node with name \'' . $name . '\' could not be found');
}
/**
* @inheritdoc
*/
function getChildren() {
- $l10n = \OC::$server->getL10N('dav');
$calendars = $this->caldavBackend->getPublicCalendars();
$children = [];
foreach ($calendars as $calendar) {
// TODO: maybe implement a new class PublicCalendar ???
- $children[] = new Calendar($this->caldavBackend, $calendar, $l10n);
+ $children[] = new Calendar($this->caldavBackend, $calendar, $this->l10n);
}
return $children;
class PublishPlugin extends ServerPlugin
{
- const NS_CALENDARSERVER = 'http://calendarserver.org/ns/';
+ const NS_CALENDARSERVER = 'http://calendarserver.org/ns/';
- /**
+ /**
* Reference to SabreDAV server object.
*
* @var \Sabre\DAV\Server
/**
* Config instance to get instance secret.
*
- * @var OCP\IConfig
+ * @var IConfig
*/
protected $config;
/**
* URL Generator for absolute URLs.
*
- * @var OCP\IURLGenerator
+ * @var IURLGenerator
*/
protected $urlGenerator;
- /**
- * PublishPlugin constructor.
- *
- * @param IURLGenerator $urlGenerator
- */
+ /**
+ * PublishPlugin constructor.
+ *
+ * @param IConfig $config
+ * @param IURLGenerator $urlGenerator
+ */
public function __construct(IConfig $config, IURLGenerator $urlGenerator)
{
$this->config = $config;
$this->urlGenerator = $urlGenerator;
}
- /**
+ /**
* This method should return a list of server-features.
*
* This is for example 'versioning' and is added to the DAV: header
*
* @return string[]
*/
- public function getFeatures()
+ public function getFeatures()
{
return ['oc-calendar-publishing']; // May have to be changed to be detected
}
$this->server->on('method:POST', [$this, 'httpPost']);
$this->server->on('propFind', [$this, 'propFind']);
-// $this->server->on('method:OPTIONS', [$this, 'httpOptions'], 5);
}
- public function propFind(PropFind $propFind, INode $node)
+ public function propFind(PropFind $propFind, INode $node)
{
if ($node instanceof Calendar) {
$token = md5($this->config->getSystemValue('secret', '').$node->getResourceId());
$propFind->handle('{'.self::NS_CALENDARSERVER.'}publish-url', function () use ($node, $publishUrl) {
if ($node->getPublishStatus()) {
- return new Publisher($publishUrl, true); // We return the publish-url only if the calendar is published.
+ // We return the publish-url only if the calendar is published.
+ return new Publisher($publishUrl, true);
}
});
$propFind->handle('{'.self::NS_CALENDARSERVER.'}pre-publish-url', function () use ($node, $publishUrl) {
- return new Publisher($publishUrl, false); // The pre-publish-url is always returned
+ // The pre-publish-url is always returned
+ return new Publisher($publishUrl, false);
});
}
}
- /**
- * We intercept this to handle POST requests on calendars.
- *
- * @param RequestInterface $request
- * @param ResponseInterface $response
- *
- * @return null|bool
- */
- public function httpPost(RequestInterface $request, ResponseInterface $response)
- {
- $path = $request->getPath();
+ /**
+ * We intercept this to handle POST requests on calendars.
+ *
+ * @param RequestInterface $request
+ * @param ResponseInterface $response
+ *
+ * @return null|bool
+ */
+ public function httpPost(RequestInterface $request, ResponseInterface $response)
+ {
+ $path = $request->getPath();
- // Only handling xml
- $contentType = $request->getHeader('Content-Type');
- if (strpos($contentType, 'application/xml') === false && strpos($contentType, 'text/xml') === false) {
- return;
- }
+ // Only handling xml
+ $contentType = $request->getHeader('Content-Type');
+ if (strpos($contentType, 'application/xml') === false && strpos($contentType, 'text/xml') === false) {
+ return;
+ }
- // Making sure the node exists
- try {
- $node = $this->server->tree->getNodeForPath($path);
- } catch (NotFound $e) {
- return;
- }
+ // Making sure the node exists
+ try {
+ $node = $this->server->tree->getNodeForPath($path);
+ } catch (NotFound $e) {
+ return;
+ }
- $requestBody = $request->getBodyAsString();
+ $requestBody = $request->getBodyAsString();
- // If this request handler could not deal with this POST request, it
- // will return 'null' and other plugins get a chance to handle the
- // request.
- //
- // However, we already requested the full body. This is a problem,
- // because a body can only be read once. This is why we preemptively
- // re-populated the request body with the existing data.
- $request->setBody($requestBody);
+ // If this request handler could not deal with this POST request, it
+ // will return 'null' and other plugins get a chance to handle the
+ // request.
+ //
+ // However, we already requested the full body. This is a problem,
+ // because a body can only be read once. This is why we preemptively
+ // re-populated the request body with the existing data.
+ $request->setBody($requestBody);
- $message = $this->server->xml->parse($requestBody, $request->getUrl(), $documentType);
+ $this->server->xml->parse($requestBody, $request->getUrl(), $documentType);
- switch ($documentType) {
+ switch ($documentType) {
- case '{'.self::NS_CALENDARSERVER.'}publish-calendar' :
+ case '{'.self::NS_CALENDARSERVER.'}publish-calendar' :
- // We can only deal with IShareableCalendar objects
- if (!$node instanceof Calendar) {
- return;
- }
- $this->server->transactionType = 'post-publish-calendar';
+ // We can only deal with IShareableCalendar objects
+ if (!$node instanceof Calendar) {
+ return;
+ }
+ $this->server->transactionType = 'post-publish-calendar';
- // Getting ACL info
- $acl = $this->server->getPlugin('acl');
+ // Getting ACL info
+ $acl = $this->server->getPlugin('acl');
- // If there's no ACL support, we allow everything
- if ($acl) {
- $acl->checkPrivileges($path, '{DAV:}write');
- }
+ // If there's no ACL support, we allow everything
+ if ($acl) {
+ $acl->checkPrivileges($path, '{DAV:}write');
+ }
- $node->setPublishStatus(true);
+ $node->setPublishStatus(true);
- // iCloud sends back the 202, so we will too.
- $response->setStatus(202);
+ // iCloud sends back the 202, so we will too.
+ $response->setStatus(202);
- // Adding this because sending a response body may cause issues,
- // and I wanted some type of indicator the response was handled.
- $response->setHeader('X-Sabre-Status', 'everything-went-well');
+ // Adding this because sending a response body may cause issues,
+ // and I wanted some type of indicator the response was handled.
+ $response->setHeader('X-Sabre-Status', 'everything-went-well');
- // Breaking the event chain
- return false;
+ // Breaking the event chain
+ return false;
- case '{'.self::NS_CALENDARSERVER.'}unpublish-calendar' :
+ case '{'.self::NS_CALENDARSERVER.'}unpublish-calendar' :
- // We can only deal with IShareableCalendar objects
- if (!$node instanceof Calendar) {
- return;
- }
- $this->server->transactionType = 'post-unpublish-calendar';
+ // We can only deal with IShareableCalendar objects
+ if (!$node instanceof Calendar) {
+ return;
+ }
+ $this->server->transactionType = 'post-unpublish-calendar';
- // Getting ACL info
- $acl = $this->server->getPlugin('acl');
+ // Getting ACL info
+ $acl = $this->server->getPlugin('acl');
- // If there's no ACL support, we allow everything
- if ($acl) {
- $acl->checkPrivileges($path, '{DAV:}write');
- }
+ // If there's no ACL support, we allow everything
+ if ($acl) {
+ $acl->checkPrivileges($path, '{DAV:}write');
+ }
- $node->setPublishStatus(false);
+ $node->setPublishStatus(false);
- $response->setStatus(200);
+ $response->setStatus(200);
- // Adding this because sending a response body may cause issues,
- // and I wanted some type of indicator the response was handled.
- $response->setHeader('X-Sabre-Status', 'everything-went-well');
+ // Adding this because sending a response body may cause issues,
+ // and I wanted some type of indicator the response was handled.
+ $response->setHeader('X-Sabre-Status', 'everything-went-well');
- // Breaking the event chain
- return false;
+ // Breaking the event chain
+ return false;
- }
- }
-
- public function httpOptions(RequestInterface $request, ResponseInterface $response) {
- if ($request->getPath() == 'public-calendars') {
- $methods = $this->server->getAllowedMethods($request->getPath());
-
- $response->setHeader('Allow', strtoupper(implode(', ', $methods)));
- $features = ['1', '3', 'extended-mkcol'];
-
- $response->setHeader('DAV', implode(', ', $features));
- $response->setHeader('MS-Author-Via', 'DAV');
- $response->setHeader('Accept-Ranges', 'bytes');
- $response->setHeader('Content-Length', '0');
- $response->setStatus(200);
-
- // Sending back false will interupt the event chain and tell the server
- // we've handled this method.
- return false;
- }
- }
+ }
+ }
}
class Publisher implements XmlSerializable {
- /**
- * @var string $publishUrl
- */
- protected $publishUrl;
+ /**
+ * @var string $publishUrl
+ */
+ protected $publishUrl;
- /**
- * @var boolean $isPublished
- */
- protected $isPublished;
+ /**
+ * @var boolean $isPublished
+ */
+ protected $isPublished;
- /**
- * @param string $publishUrl
- * @param boolean $isPublished
- */
- function __construct($publishUrl, $isPublished) {
- $this->publishUrl = $publishUrl;
- $this->isPublished = $isPublished;
- }
+ /**
+ * @param string $publishUrl
+ * @param boolean $isPublished
+ */
+ function __construct($publishUrl, $isPublished) {
+ $this->publishUrl = $publishUrl;
+ $this->isPublished = $isPublished;
+ }
- /**
- * @return string
- */
- function getValue() {
- return $this->publishUrl;
- }
+ /**
+ * @return string
+ */
+ function getValue() {
+ return $this->publishUrl;
+ }
- /**
- * The xmlSerialize metod is called during xml writing.
- *
- * Use the $writer argument to write its own xml serialization.
- *
- * An important note: do _not_ create a parent element. Any element
- * implementing XmlSerializble should only ever write what's considered
- * its 'inner xml'.
- *
- * The parent of the current element is responsible for writing a
- * containing element.
- *
- * This allows serializers to be re-used for different element names.
- *
- * If you are opening new elements, you must also close them again.
- *
- * @param Writer $writer
- * @return void
- */
- function xmlSerialize(Writer $writer) {
- if (!$this->isPublished) {
- $writer->write($this->publishUrl); // for pre-publish-url
- } else {
- $writer->writeElement('{DAV:}href', $this->publishUrl); // for publish-url
- }
-
- }
+ /**
+ * The xmlSerialize metod is called during xml writing.
+ *
+ * Use the $writer argument to write its own xml serialization.
+ *
+ * An important note: do _not_ create a parent element. Any element
+ * implementing XmlSerializble should only ever write what's considered
+ * its 'inner xml'.
+ *
+ * The parent of the current element is responsible for writing a
+ * containing element.
+ *
+ * This allows serializers to be re-used for different element names.
+ *
+ * If you are opening new elements, you must also close them again.
+ *
+ * @param Writer $writer
+ * @return void
+ */
+ function xmlSerialize(Writer $writer) {
+ if (!$this->isPublished) {
+ // for pre-publish-url
+ $writer->write($this->publishUrl);
+ } else {
+ // for publish-url
+ $writer->writeElement('{DAV:}href', $this->publishUrl);
+ }
+ }
}
/**
* @param IUserManager $userManager
+ * @param IGroupManager $groupManager
* @param IDBConnection $dbConnection
*/
function __construct(IUserManager $userManager, IGroupManager $groupManager, IDBConnection $dbConnection) {
$this->userManager,
$this->groupManager
);
+ $config = \OC::$server->getConfig();
$name = $input->getArgument('name');
- $caldav = new CalDavBackend($this->dbConnection, $principalBackend, $this->userManager);
+ $caldav = new CalDavBackend($this->dbConnection, $principalBackend, $this->userManager, $config);
$caldav->createCalendar("principals/users/$user", $name, []);
}
}
* @param ResponseInterface $response
*/
function httpGet(RequestInterface $request, ResponseInterface $response) {
- // Exclude published calendars
- // TODO : Find a better way to do this
- if (explode('/', $request->getPath())[0] === 'public-calendars') return;
-
// Only handle valid files
$node = $this->tree->getNodeForPath($request->getPath());
if (!($node instanceof IFile)) return;
$systemPrincipals->disableListing = $disableListing;
$filesCollection = new Files\RootCollection($userPrincipalBackend, 'principals/users');
$filesCollection->disableListing = $disableListing;
- $caldavBackend = new CalDavBackend($db, $userPrincipalBackend, \OC::$server->getUserManager());
+ $caldavBackend = new CalDavBackend($db, $userPrincipalBackend, \OC::$server->getUserManager(), $config);
$calendarRoot = new CalendarRoot($userPrincipalBackend, $caldavBackend, 'principals/users');
$calendarRoot->disableListing = $disableListing;
$publicCalendarRoot = new PublicCalendarRoot($caldavBackend);
->willReturn([self::UNIT_TEST_GROUP]);
$db = \OC::$server->getDatabaseConnection();
- $this->backend = new CalDavBackend($db, $this->principal, $this->userManager);
+ $config = \OC::$server->getConfig();
+ $this->backend = new CalDavBackend($db, $this->principal, $this->userManager, $config);
$this->tearDown();
}
use OCA\DAV\CalDAV\Calendar;
use OCA\DAV\CalDAV\Publishing\PublishPlugin;
-use OCA\DAV\Connector\Sabre\Auth;
use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\IConfig;
public function setUp() {
parent::setUp();
- /** @var Auth | \PHPUnit_Framework_MockObject_MockObject $authBackend */
- $authBackend = $this->getMockBuilder('OCA\DAV\DAV\PublicAuth')->disableOriginalConstructor()->getMock();
- $authBackend->method('isDavAuthenticated')->willReturn(true);
-
- $this->config = $this->getMock('\OCP\IConfig');
+ $this->config = $this->getMockBuilder('\OCP\IConfig')->
+ disableOriginalConstructor()->
+ getMock();
$this->config->expects($this->any())->method('getSystemValue')
->with($this->equalTo('secret'))
->willReturn('mysecret');
- $this->urlGenerator = $this->getMock('OCP\IURLGenerator');
+ $this->urlGenerator = $this->getMockBuilder('OCP\IURLGenerator')->
+ disableOriginalConstructor()->
+ getMock();
/** @var IRequest $request */
$this->plugin = new PublishPlugin($this->config, $this->urlGenerator);
$this->server = new Server($root);
/** @var SimpleCollection $node */
$this->book = $this->getMockBuilder('OCA\DAV\CalDAV\Calendar')->
- disableOriginalConstructor()->
- getMock();
+ disableOriginalConstructor()->
+ getMock();
$this->book->method('getName')->willReturn('cal1');
$root->addChild($this->book);
$this->plugin->initialize($this->server);
$node = $this->getMockBuilder('\OCA\DAV\Connector\Sabre\Node')
->disableOriginalConstructor()
->getMock();
- $node->expects($this->at(0))
+ $node->expects($this->once())
->method('getFileInfo')
->willReturn($fileInfoFolderATestTXT);
->getMock();
$request
- ->expects($this->at(1))
+ ->expects($this->once())
->method('getPath')
->will($this->returnValue('test/somefile.xml'));