summaryrefslogtreecommitdiffstats
path: root/apps/dav/lib
diff options
context:
space:
mode:
authorAchim Königs <garfonso@mobo.info>2016-03-26 14:27:38 +0100
committerAchim Königs <garfonso@mobo.info>2016-03-26 14:27:38 +0100
commit596a8416c2c36449c7b9842e95ea05720c88fca3 (patch)
tree4de43af057270ce30cd601015fee752f22bfbaa3 /apps/dav/lib
parent4b2f9e40275826c36bc1b225f321274f3b3bc2f1 (diff)
parent3e33b686b18b9e698ed16bf4466666357be0c407 (diff)
downloadnextcloud-server-596a8416c2c36449c7b9842e95ea05720c88fca3.tar.gz
nextcloud-server-596a8416c2c36449c7b9842e95ea05720c88fca3.zip
Merge branch 'master' into alarms_for_birthdayevents
Diffstat (limited to 'apps/dav/lib')
-rw-r--r--apps/dav/lib/caldav/caldavbackend.php5
-rw-r--r--apps/dav/lib/caldav/calendar.php40
-rw-r--r--apps/dav/lib/carddav/addressbook.php55
-rw-r--r--apps/dav/lib/carddav/card.php45
-rw-r--r--apps/dav/lib/carddav/carddavbackend.php8
-rw-r--r--apps/dav/lib/connector/legacydavacl.php15
-rw-r--r--apps/dav/lib/connector/sabre/auth.php82
-rw-r--r--apps/dav/lib/connector/sabre/principal.php5
-rw-r--r--apps/dav/lib/connector/sabre/sharesplugin.php3
9 files changed, 156 insertions, 102 deletions
diff --git a/apps/dav/lib/caldav/caldavbackend.php b/apps/dav/lib/caldav/caldavbackend.php
index bb50100d9a2..5f82db10b39 100644
--- a/apps/dav/lib/caldav/caldavbackend.php
+++ b/apps/dav/lib/caldav/caldavbackend.php
@@ -138,6 +138,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
* @return array
*/
function getCalendarsForUser($principalUri) {
+ $principalUriOriginal = $principalUri;
$principalUri = $this->convertPrincipal($principalUri, true);
$fields = array_values($this->propertyMap);
$fields[] = 'id';
@@ -184,7 +185,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
$stmt->closeCursor();
// query for shared calendars
- $principals = $this->principalBackend->getGroupMembership($principalUri);
+ $principals = $this->principalBackend->getGroupMembership($principalUriOriginal, true);
$principals[]= $principalUri;
$fields = array_values($this->propertyMap);
@@ -194,6 +195,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
$fields[] = 'a.components';
$fields[] = 'a.principaluri';
$fields[] = 'a.transparent';
+ $fields[] = 's.access';
$query = $this->db->getQueryBuilder();
$result = $query->select($fields)
->from('dav_shares', 's')
@@ -221,6 +223,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
'{' . 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' => (int)$row['access'] === Backend::ACCESS_READ,
];
foreach($this->propertyMap as $xmlName=>$dbName) {
diff --git a/apps/dav/lib/caldav/calendar.php b/apps/dav/lib/caldav/calendar.php
index 1e87f9b4333..5072d96107e 100644
--- a/apps/dav/lib/caldav/calendar.php
+++ b/apps/dav/lib/caldav/calendar.php
@@ -86,7 +86,31 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
}
function getACL() {
- $acl = parent::getACL();
+ $acl = [
+ [
+ 'privilege' => '{DAV:}read',
+ 'principal' => $this->getOwner(),
+ 'protected' => true,
+ ]];
+ $acl[] = [
+ 'privilege' => '{DAV:}write',
+ 'principal' => $this->getOwner(),
+ 'protected' => true,
+ ];
+ if ($this->getOwner() !== parent::getOwner()) {
+ $acl[] = [
+ 'privilege' => '{DAV:}read',
+ 'principal' => parent::getOwner(),
+ 'protected' => true,
+ ];
+ if ($this->canWrite()) {
+ $acl[] = [
+ 'privilege' => '{DAV:}write',
+ 'principal' => parent::getOwner(),
+ 'protected' => true,
+ ];
+ }
+ }
/** @var CalDavBackend $calDavBackend */
$calDavBackend = $this->caldavBackend;
@@ -94,11 +118,7 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
}
function getChildACL() {
- $acl = parent::getChildACL();
-
- /** @var CalDavBackend $calDavBackend */
- $calDavBackend = $this->caldavBackend;
- return $calDavBackend->applyShareAcl($this->getResourceId(), $acl);
+ return $this->getACL();
}
function getOwner() {
@@ -137,4 +157,12 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
}
parent::propPatch($propPatch);
}
+
+ private function canWrite() {
+ if (isset($this->calendarInfo['{http://owncloud.org/ns}read-only'])) {
+ return !$this->calendarInfo['{http://owncloud.org/ns}read-only'];
+ }
+ return true;
+ }
+
}
diff --git a/apps/dav/lib/carddav/addressbook.php b/apps/dav/lib/carddav/addressbook.php
index bb9d13b981e..8b1b600ec3d 100644
--- a/apps/dav/lib/carddav/addressbook.php
+++ b/apps/dav/lib/carddav/addressbook.php
@@ -21,6 +21,7 @@
namespace OCA\DAV\CardDAV;
use OCA\DAV\DAV\Sharing\IShareable;
+use Sabre\CardDAV\Card;
use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\PropPatch;
@@ -70,39 +71,31 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable {
}
function getACL() {
- $acl = parent::getACL();
- if ($this->getOwner() === 'principals/system/system') {
- $acl[] = [
- 'privilege' => '{DAV:}read',
- 'principal' => '{DAV:}authenticated',
- 'protected' => true,
+ $acl = [
+ [
+ 'privilege' => '{DAV:}read',
+ 'principal' => $this->getOwner(),
+ 'protected' => true,
+ ]];
+ $acl[] = [
+ 'privilege' => '{DAV:}write',
+ 'principal' => $this->getOwner(),
+ 'protected' => true,
];
- }
-
- // add the current user
- if (isset($this->addressBookInfo['{http://owncloud.org/ns}owner-principal'])) {
- $owner = $this->addressBookInfo['{http://owncloud.org/ns}owner-principal'];
- $acl[] = [
+ if ($this->getOwner() !== parent::getOwner()) {
+ $acl[] = [
'privilege' => '{DAV:}read',
- 'principal' => $owner,
+ 'principal' => parent::getOwner(),
'protected' => true,
];
- if ($this->addressBookInfo['{http://owncloud.org/ns}read-only']) {
+ if ($this->canWrite()) {
$acl[] = [
'privilege' => '{DAV:}write',
- 'principal' => $owner,
+ 'principal' => parent::getOwner(),
'protected' => true,
];
}
}
-
- /** @var CardDavBackend $carddavBackend */
- $carddavBackend = $this->carddavBackend;
- return $carddavBackend->applyShareAcl($this->getResourceId(), $acl);
- }
-
- function getChildACL() {
- $acl = parent::getChildACL();
if ($this->getOwner() === 'principals/system/system') {
$acl[] = [
'privilege' => '{DAV:}read',
@@ -116,12 +109,19 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable {
return $carddavBackend->applyShareAcl($this->getResourceId(), $acl);
}
+ function getChildACL() {
+ return $this->getACL();
+ }
+
function getChild($name) {
- $obj = $this->carddavBackend->getCard($this->getResourceId(), $name);
+
+ $obj = $this->carddavBackend->getCard($this->addressBookInfo['id'], $name);
if (!$obj) {
throw new NotFound('Card not found');
}
+ $obj['acl'] = $this->getChildACL();
return new Card($this->carddavBackend, $this->addressBookInfo, $obj);
+
}
/**
@@ -172,4 +172,11 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable {
return $cardDavBackend->collectCardProperties($this->getResourceId(), 'CATEGORIES');
}
+
+ private function canWrite() {
+ if (isset($this->addressBookInfo['{http://owncloud.org/ns}read-only'])) {
+ return !$this->addressBookInfo['{http://owncloud.org/ns}read-only'];
+ }
+ return true;
+ }
}
diff --git a/apps/dav/lib/carddav/card.php b/apps/dav/lib/carddav/card.php
deleted file mode 100644
index d848f2e28ec..00000000000
--- a/apps/dav/lib/carddav/card.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-/**
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\DAV\CardDAV;
-
-class Card extends \Sabre\CardDAV\Card {
-
- function getACL() {
- $acl = parent::getACL();
- if ($this->getOwner() === 'principals/system/system') {
- $acl[] = [
- 'privilege' => '{DAV:}read',
- 'principal' => '{DAV:}authenticated',
- 'protected' => true,
- ];
- }
-
- /** @var CardDavBackend $carddavBackend */
- $carddavBackend = $this->carddavBackend;
- return $carddavBackend->applyShareAcl($this->getBookId(), $acl);
- }
-
- private function getBookId() {
- return $this->addressBookInfo['id'];
- }
-
-}
diff --git a/apps/dav/lib/carddav/carddavbackend.php b/apps/dav/lib/carddav/carddavbackend.php
index bfb6ea82ad7..650623225e3 100644
--- a/apps/dav/lib/carddav/carddavbackend.php
+++ b/apps/dav/lib/carddav/carddavbackend.php
@@ -62,10 +62,6 @@ class CardDavBackend implements BackendInterface, SyncSupport {
'BDAY', 'UID', 'N', 'FN', 'TITLE', 'ROLE', 'NOTE', 'NICKNAME',
'ORG', 'CATEGORIES', 'EMAIL', 'TEL', 'IMPP', 'ADR', 'URL', 'GEO', 'CLOUD');
- const ACCESS_OWNER = 1;
- const ACCESS_READ_WRITE = 2;
- const ACCESS_READ = 3;
-
/** @var EventDispatcherInterface */
private $dispatcher;
@@ -126,7 +122,7 @@ class CardDavBackend implements BackendInterface, SyncSupport {
$result->closeCursor();
// query for shared calendars
- $principals = $this->principalBackend->getGroupMembership($principalUri);
+ $principals = $this->principalBackend->getGroupMembership($principalUri, true);
$principals[]= $principalUri;
$query = $this->db->getQueryBuilder();
@@ -153,7 +149,7 @@ class CardDavBackend implements BackendInterface, SyncSupport {
'{http://calendarserver.org/ns/}getctag' => $row['synctoken'],
'{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $row['principaluri'],
- '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => $row['access'] === self::ACCESS_READ,
+ '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => (int)$row['access'] === Backend::ACCESS_READ,
];
}
}
diff --git a/apps/dav/lib/connector/legacydavacl.php b/apps/dav/lib/connector/legacydavacl.php
index 07aefa1b863..eb6ca1fd7d5 100644
--- a/apps/dav/lib/connector/legacydavacl.php
+++ b/apps/dav/lib/connector/legacydavacl.php
@@ -23,7 +23,10 @@
namespace OCA\DAV\Connector;
use OCA\DAV\Connector\Sabre\DavAclPlugin;
+use Sabre\DAV\INode;
+use Sabre\DAV\PropFind;
use Sabre\HTTP\URLUtil;
+use Sabre\DAVACL\Xml\Property\Principal;
class LegacyDAVACL extends DavAclPlugin {
@@ -67,4 +70,16 @@ class LegacyDAVACL extends DavAclPlugin {
}
return "principals/$name";
}
+
+ function propFind(PropFind $propFind, INode $node) {
+ /* Overload current-user-principal */
+ $propFind->handle('{DAV:}current-user-principal', function () {
+ if ($url = parent::getCurrentUserPrincipal()) {
+ return new Principal(Principal::HREF, $url . '/');
+ } else {
+ return new Principal(Principal::UNAUTHENTICATED);
+ }
+ });
+ parent::propFind($propFind, $node);
+ }
}
diff --git a/apps/dav/lib/connector/sabre/auth.php b/apps/dav/lib/connector/sabre/auth.php
index 8c09c9fdc1c..b63efa3a1ba 100644
--- a/apps/dav/lib/connector/sabre/auth.php
+++ b/apps/dav/lib/connector/sabre/auth.php
@@ -30,6 +30,7 @@
namespace OCA\DAV\Connector\Sabre;
use Exception;
+use OC\AppFramework\Http\Request;
use OCP\IRequest;
use OCP\ISession;
use OCP\IUserSession;
@@ -48,6 +49,8 @@ class Auth extends AbstractBasic {
private $userSession;
/** @var IRequest */
private $request;
+ /** @var string */
+ private $currentUser;
/**
* @param ISession $session
@@ -130,7 +133,46 @@ class Auth extends AbstractBasic {
$msg = $e->getMessage();
throw new ServiceUnavailable("$class: $msg");
}
- }
+ }
+
+ /**
+ * Checks whether a CSRF check is required on the request
+ *
+ * @return bool
+ */
+ private function requiresCSRFCheck() {
+ // GET requires no check at all
+ if($this->request->getMethod() === 'GET') {
+ return false;
+ }
+
+ // Official ownCloud clients require no checks
+ if($this->request->isUserAgent([
+ Request::USER_AGENT_OWNCLOUD_DESKTOP,
+ Request::USER_AGENT_OWNCLOUD_ANDROID,
+ Request::USER_AGENT_OWNCLOUD_IOS,
+ ])) {
+ return false;
+ }
+
+ // If not logged-in no check is required
+ if(!$this->userSession->isLoggedIn()) {
+ return false;
+ }
+
+ // POST always requires a check
+ if($this->request->getMethod() === 'POST') {
+ return true;
+ }
+
+ // If logged-in AND DAV authenticated no check is required
+ if($this->userSession->isLoggedIn() &&
+ $this->isDavAuthenticated($this->userSession->getUser()->getUID())) {
+ return false;
+ }
+
+ return true;
+ }
/**
* @param RequestInterface $request
@@ -139,27 +181,33 @@ class Auth extends AbstractBasic {
* @throws NotAuthenticated
*/
private function auth(RequestInterface $request, ResponseInterface $response) {
- // If request is not GET and not authenticated via WebDAV a requesttoken is required
- if($this->userSession->isLoggedIn() &&
- $this->request->getMethod() !== 'GET' &&
- !$this->isDavAuthenticated($this->userSession->getUser()->getUID())) {
- if(!$this->request->passesCSRFCheck()) {
+ $forcedLogout = false;
+ if(!$this->request->passesCSRFCheck() &&
+ $this->requiresCSRFCheck()) {
+ // In case of a fail with POST we need to recheck the credentials
+ if($this->request->getMethod() === 'POST') {
+ $forcedLogout = true;
+ } else {
$response->setStatus(401);
throw new \Sabre\DAV\Exception\NotAuthenticated('CSRF check not passed.');
}
}
- if (\OC_User::handleApacheAuth() ||
- //Fix for broken webdav clients
- ($this->userSession->isLoggedIn() && is_null($this->session->get(self::DAV_AUTHENTICATED))) ||
- //Well behaved clients that only send the cookie are allowed
- ($this->userSession->isLoggedIn() && $this->session->get(self::DAV_AUTHENTICATED) === $this->userSession->getUser()->getUID() && $request->getHeader('Authorization') === null)
- ) {
- $user = $this->userSession->getUser()->getUID();
- \OC_Util::setupFS($user);
- $this->currentUser = $user;
- $this->session->close();
- return [true, $this->principalPrefix . $user];
+ if($forcedLogout) {
+ $this->userSession->logout();
+ } else {
+ if (\OC_User::handleApacheAuth() ||
+ //Fix for broken webdav clients
+ ($this->userSession->isLoggedIn() && is_null($this->session->get(self::DAV_AUTHENTICATED))) ||
+ //Well behaved clients that only send the cookie are allowed
+ ($this->userSession->isLoggedIn() && $this->session->get(self::DAV_AUTHENTICATED) === $this->userSession->getUser()->getUID() && $request->getHeader('Authorization') === null)
+ ) {
+ $user = $this->userSession->getUser()->getUID();
+ \OC_Util::setupFS($user);
+ $this->currentUser = $user;
+ $this->session->close();
+ return [true, $this->principalPrefix . $user];
+ }
}
if (!$this->userSession->isLoggedIn() && in_array('XMLHttpRequest', explode(',', $request->getHeader('X-Requested-With')))) {
diff --git a/apps/dav/lib/connector/sabre/principal.php b/apps/dav/lib/connector/sabre/principal.php
index 31de4e5bad1..18f28a916f1 100644
--- a/apps/dav/lib/connector/sabre/principal.php
+++ b/apps/dav/lib/connector/sabre/principal.php
@@ -132,10 +132,11 @@ class Principal implements BackendInterface {
* Returns the list of groups a principal is a member of
*
* @param string $principal
+ * @param bool $needGroups
* @return array
* @throws Exception
*/
- public function getGroupMembership($principal) {
+ public function getGroupMembership($principal, $needGroups = false) {
list($prefix, $name) = URLUtil::splitPath($principal);
if ($prefix === $this->principalPrefix) {
@@ -144,7 +145,7 @@ class Principal implements BackendInterface {
throw new Exception('Principal not found');
}
- if ($this->hasGroups) {
+ if ($this->hasGroups || $needGroups) {
$groups = $this->groupManager->getUserGroups($user);
$groups = array_map(function($group) {
/** @var IGroup $group */
diff --git a/apps/dav/lib/connector/sabre/sharesplugin.php b/apps/dav/lib/connector/sabre/sharesplugin.php
index f75c1378718..c76068969e9 100644
--- a/apps/dav/lib/connector/sabre/sharesplugin.php
+++ b/apps/dav/lib/connector/sabre/sharesplugin.php
@@ -116,7 +116,8 @@ class SharesPlugin extends \Sabre\DAV\ServerPlugin {
$requestedShareTypes = [
\OCP\Share::SHARE_TYPE_USER,
\OCP\Share::SHARE_TYPE_GROUP,
- \OCP\Share::SHARE_TYPE_LINK
+ \OCP\Share::SHARE_TYPE_LINK,
+ \OCP\Share::SHARE_TYPE_REMOTE
];
foreach ($requestedShareTypes as $requestedShareType) {
// one of each type is enough to find out about the types