summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorArthur Schiwon <blizzz@arthur-schiwon.de>2016-06-11 15:34:43 +0200
committerArthur Schiwon <blizzz@arthur-schiwon.de>2016-06-11 15:34:43 +0200
commit42c66efea5ef512d3a3442112f820168e6499265 (patch)
tree97ef44632d653656608e71e096fd537bbd609936 /apps
parent75f37f550bb7895757325d3f9a3215bcc4471065 (diff)
parent52a0c939ab8674857bbfe9a9fb0ee7308eee960e (diff)
downloadnextcloud-server-42c66efea5ef512d3a3442112f820168e6499265.tar.gz
nextcloud-server-42c66efea5ef512d3a3442112f820168e6499265.zip
Merge branch 'master' of https://github.com/owncloud/core into downstream-160611
Diffstat (limited to 'apps')
-rw-r--r--apps/comments/l10n/bg_BG.js13
-rw-r--r--apps/comments/l10n/bg_BG.json13
-rw-r--r--apps/dav/appinfo/database.xml6
-rw-r--r--apps/dav/appinfo/info.xml7
-rw-r--r--apps/dav/appinfo/v1/publicwebdav.php9
-rw-r--r--apps/dav/lib/AppInfo/Application.php10
-rw-r--r--apps/dav/lib/CalDAV/CalDavBackend.php90
-rw-r--r--apps/dav/lib/CalDAV/Calendar.php77
-rw-r--r--apps/dav/lib/CalDAV/CalendarObject.php92
-rw-r--r--apps/dav/lib/Connector/PublicAuth.php9
-rw-r--r--apps/dav/lib/Connector/Sabre/Auth.php4
-rw-r--r--apps/dav/lib/Connector/Sabre/FilesPlugin.php23
-rw-r--r--apps/dav/lib/Connector/Sabre/ServerFactory.php4
-rw-r--r--apps/dav/lib/Migration/Classification.php93
-rw-r--r--apps/dav/lib/Server.php1
-rw-r--r--apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php163
-rw-r--r--apps/dav/tests/unit/CalDAV/CalDavBackendTest.php141
-rw-r--r--apps/dav/tests/unit/CalDAV/CalendarTest.php150
-rw-r--r--apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php66
-rw-r--r--apps/dav/tests/unit/Connector/Sabre/FilesReportPluginTest.php3
-rw-r--r--apps/dav/tests/unit/Migration/ClassificationTest.php75
-rw-r--r--apps/encryption/l10n/pl.js2
-rw-r--r--apps/encryption/l10n/pl.json2
-rw-r--r--apps/federatedfilesharing/l10n/hu_HU.js4
-rw-r--r--apps/federatedfilesharing/l10n/hu_HU.json4
-rw-r--r--apps/federation/l10n/pt_PT.js2
-rw-r--r--apps/federation/l10n/pt_PT.json2
-rw-r--r--apps/federation/l10n/ro.js8
-rw-r--r--apps/federation/l10n/ro.json8
-rw-r--r--apps/federation/lib/DAV/FedAuth.php4
-rw-r--r--apps/files/l10n/ar.js6
-rw-r--r--apps/files/l10n/ar.json6
-rw-r--r--apps/files/l10n/de.js1
-rw-r--r--apps/files/l10n/de.json1
-rw-r--r--apps/files/l10n/de_DE.js1
-rw-r--r--apps/files/l10n/de_DE.json1
-rw-r--r--apps/files/l10n/en_GB.js1
-rw-r--r--apps/files/l10n/en_GB.json1
-rw-r--r--apps/files/l10n/fi_FI.js1
-rw-r--r--apps/files/l10n/fi_FI.json1
-rw-r--r--apps/files/l10n/it.js1
-rw-r--r--apps/files/l10n/it.json1
-rw-r--r--apps/files/l10n/pl.js2
-rw-r--r--apps/files/l10n/pl.json2
-rw-r--r--apps/files/l10n/pt_BR.js1
-rw-r--r--apps/files/l10n/pt_BR.json1
-rw-r--r--apps/files/l10n/sq.js1
-rw-r--r--apps/files/l10n/sq.json1
-rw-r--r--apps/files_external/l10n/pl.js1
-rw-r--r--apps/files_external/l10n/pl.json1
-rw-r--r--apps/files_sharing/l10n/pl.js3
-rw-r--r--apps/files_sharing/l10n/pl.json3
-rw-r--r--apps/files_sharing/l10n/ro.js22
-rw-r--r--apps/files_sharing/l10n/ro.json22
-rw-r--r--apps/files_sharing/lib/API/Share20OCS.php24
-rw-r--r--apps/files_sharing/tests/API/Share20OCSTest.php21
-rw-r--r--apps/files_sharing/tests/ApiTest.php41
-rw-r--r--apps/systemtags/l10n/hu_HU.js1
-rw-r--r--apps/systemtags/l10n/hu_HU.json1
-rw-r--r--apps/updatenotification/l10n/hu_HU.js3
-rw-r--r--apps/updatenotification/l10n/hu_HU.json3
-rw-r--r--apps/user_ldap/l10n/pl.js1
-rw-r--r--apps/user_ldap/l10n/pl.json1
-rw-r--r--apps/user_ldap/lib/Group_LDAP.php2
-rw-r--r--apps/user_ldap/tests/Group_LDAPTest.php53
65 files changed, 1122 insertions, 196 deletions
diff --git a/apps/comments/l10n/bg_BG.js b/apps/comments/l10n/bg_BG.js
index e63aedf80db..c5fbba69f7b 100644
--- a/apps/comments/l10n/bg_BG.js
+++ b/apps/comments/l10n/bg_BG.js
@@ -1,8 +1,19 @@
OC.L10N.register(
"comments",
{
+ "Type in a new comment..." : "Напиши нов коментар...",
+ "Delete comment" : "Изтрий коментар",
"Cancel" : "Отказ",
+ "Edit comment" : "Редактирай коментра",
+ "[Deleted user]" : "[Изтрит потребител]",
+ "Comments" : "Коментари",
+ "No other comments available" : "Няма други коментари",
+ "More comments..." : "Още коментари...",
"Save" : "Запазване",
- "Comment" : "Коментар"
+ "Allowed characters {count} of {max}" : "Позволени символи {count} от {max}",
+ "{count} unread comments" : "{count} нечетени коментари",
+ "Comment" : "Коментар",
+ "<strong>Comments</strong> for files <em>(always listed in stream)</em>" : "<strong>Коментари</strong> на файлове <em>(винаги изписвани в stream-а)</em>",
+ "You commented" : "Вие коментирахте"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/comments/l10n/bg_BG.json b/apps/comments/l10n/bg_BG.json
index 78ad0b57d4c..64f516861ca 100644
--- a/apps/comments/l10n/bg_BG.json
+++ b/apps/comments/l10n/bg_BG.json
@@ -1,6 +1,17 @@
{ "translations": {
+ "Type in a new comment..." : "Напиши нов коментар...",
+ "Delete comment" : "Изтрий коментар",
"Cancel" : "Отказ",
+ "Edit comment" : "Редактирай коментра",
+ "[Deleted user]" : "[Изтрит потребител]",
+ "Comments" : "Коментари",
+ "No other comments available" : "Няма други коментари",
+ "More comments..." : "Още коментари...",
"Save" : "Запазване",
- "Comment" : "Коментар"
+ "Allowed characters {count} of {max}" : "Позволени символи {count} от {max}",
+ "{count} unread comments" : "{count} нечетени коментари",
+ "Comment" : "Коментар",
+ "<strong>Comments</strong> for files <em>(always listed in stream)</em>" : "<strong>Коментари</strong> на файлове <em>(винаги изписвани в stream-а)</em>",
+ "You commented" : "Вие коментирахте"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/dav/appinfo/database.xml b/apps/dav/appinfo/database.xml
index f79ea07ae76..9578526a705 100644
--- a/apps/dav/appinfo/database.xml
+++ b/apps/dav/appinfo/database.xml
@@ -272,6 +272,12 @@ CREATE TABLE calendarobjects (
<type>text</type>
<length>255</length>
</field>
+ <field>
+ <comments>0 - public, 1 - private, 2 - confidential</comments>
+ <name>classification</name>
+ <type>integer</type>
+ <default>0</default>
+ </field>
<index>
<name>calobjects_index</name>
<unique>true</unique>
diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml
index ca456b03089..26e37e6bb86 100644
--- a/apps/dav/appinfo/info.xml
+++ b/apps/dav/appinfo/info.xml
@@ -5,7 +5,7 @@
<description>ownCloud WebDAV endpoint</description>
<licence>AGPL</licence>
<author>owncloud.org</author>
- <version>0.2.4</version>
+ <version>0.2.5</version>
<default_enable/>
<types>
<filesystem/>
@@ -20,4 +20,9 @@
<background-jobs>
<job>OCA\DAV\CardDAV\Sync\SyncJob</job>
</background-jobs>
+ <repair-steps>
+ <post-migration>
+ <job>OCA\DAV\Migration\Classification</job>
+ </post-migration>
+ </repair-steps>
</info>
diff --git a/apps/dav/appinfo/v1/publicwebdav.php b/apps/dav/appinfo/v1/publicwebdav.php
index c6c319aa36d..261a4d4b96d 100644
--- a/apps/dav/appinfo/v1/publicwebdav.php
+++ b/apps/dav/appinfo/v1/publicwebdav.php
@@ -66,7 +66,6 @@ $server = $serverFactory->createServer($baseuri, $requestUri, $authBackend, func
$share = $authBackend->getShare();
$owner = $share->getShareOwner();
- $isWritable = $share->getPermissions() & (\OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_CREATE);
$isReadable = $share->getPermissions() & \OCP\Constants::PERMISSION_READ;
$fileId = $share->getNodeId();
@@ -74,11 +73,9 @@ $server = $serverFactory->createServer($baseuri, $requestUri, $authBackend, func
return false;
}
- if (!$isWritable) {
- \OC\Files\Filesystem::addStorageWrapper('readonly', function ($mountPoint, $storage) {
- return new \OC\Files\Storage\Wrapper\PermissionsMask(array('storage' => $storage, 'mask' => \OCP\Constants::PERMISSION_READ + \OCP\Constants::PERMISSION_SHARE));
- });
- }
+ \OC\Files\Filesystem::addStorageWrapper('sharePermissions', function ($mountPoint, $storage) use ($share) {
+ return new \OC\Files\Storage\Wrapper\PermissionsMask(array('storage' => $storage, 'mask' => $share->getPermissions() | \OCP\Constants::PERMISSION_SHARE));
+ });
OC_Util::setupFS($owner);
$ownerView = \OC\Files\Filesystem::getView();
diff --git a/apps/dav/lib/AppInfo/Application.php b/apps/dav/lib/AppInfo/Application.php
index ba0ef421f97..9e0d2da4e17 100644
--- a/apps/dav/lib/AppInfo/Application.php
+++ b/apps/dav/lib/AppInfo/Application.php
@@ -31,10 +31,12 @@ use OCA\DAV\CardDAV\SyncService;
use OCA\DAV\Connector\Sabre\Principal;
use OCA\DAV\DAV\GroupPrincipalBackend;
use OCA\DAV\HookManager;
+use OCA\DAV\Migration\Classification;
use \OCP\AppFramework\App;
use OCP\AppFramework\IAppContainer;
use OCP\Contacts\IManager;
use OCP\IUser;
+use Sabre\VObject\Reader;
use Symfony\Component\EventDispatcher\GenericEvent;
class Application extends App {
@@ -106,6 +108,14 @@ class Application extends App {
$g
);
});
+
+ $container->registerService('OCA\DAV\Migration\Classification', function ($c) {
+ /** @var IAppContainer $c */
+ return new Classification(
+ $c->query('CalDavBackend'),
+ $c->getServer()->getUserManager()
+ );
+ });
}
/**
diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php
index 64fdf0f7ebe..ce494082976 100644
--- a/apps/dav/lib/CalDAV/CalDavBackend.php
+++ b/apps/dav/lib/CalDAV/CalDavBackend.php
@@ -37,10 +37,11 @@ use Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp;
use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet;
use Sabre\DAV;
use Sabre\DAV\Exception\Forbidden;
+use Sabre\DAV\PropPatch;
use Sabre\HTTP\URLUtil;
use Sabre\VObject\DateTimeParser;
use Sabre\VObject\Reader;
-use Sabre\VObject\RecurrenceIterator;
+use Sabre\VObject\Recur\EventIterator;
/**
* Class CalDavBackend
@@ -61,6 +62,10 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
*/
const MAX_DATE = '2038-01-01';
+ const CLASSIFICATION_PUBLIC = 0;
+ const CLASSIFICATION_PRIVATE = 1;
+ const CLASSIFICATION_CONFIDENTIAL = 2;
+
/**
* List of CalDAV properties, and how they map to database field names
* Add your own properties by simply adding on to this array.
@@ -395,10 +400,10 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
*
* Read the PropPatch documentation for more info and examples.
*
- * @param \Sabre\DAV\PropPatch $propPatch
+ * @param PropPatch $propPatch
* @return void
*/
- function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch) {
+ function updateCalendar($calendarId, PropPatch $propPatch) {
$supportedProperties = array_keys($this->propertyMap);
$supportedProperties[] = '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp';
@@ -484,7 +489,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
*/
function getCalendarObjects($calendarId) {
$query = $this->db->getQueryBuilder();
- $query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'componenttype'])
+ $query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'componenttype', 'classification'])
->from('calendarobjects')
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)));
$stmt = $query->execute();
@@ -499,6 +504,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
'calendarid' => $row['calendarid'],
'size' => (int)$row['size'],
'component' => strtolower($row['componenttype']),
+ 'classification'=> (int)$row['classification']
];
}
@@ -524,7 +530,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
function getCalendarObject($calendarId, $objectUri) {
$query = $this->db->getQueryBuilder();
- $query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype'])
+ $query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification'])
->from('calendarobjects')
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
->andWhere($query->expr()->eq('uri', $query->createNamedParameter($objectUri)));
@@ -542,6 +548,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
'size' => (int)$row['size'],
'calendardata' => $this->readBlob($row['calendardata']),
'component' => strtolower($row['componenttype']),
+ 'classification'=> (int)$row['classification']
];
}
@@ -559,7 +566,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
*/
function getMultipleCalendarObjects($calendarId, array $uris) {
$query = $this->db->getQueryBuilder();
- $query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype'])
+ $query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification'])
->from('calendarobjects')
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
->andWhere($query->expr()->in('uri', $query->createParameter('uri')))
@@ -579,6 +586,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
'size' => (int)$row['size'],
'calendardata' => $this->readBlob($row['calendardata']),
'component' => strtolower($row['componenttype']),
+ 'classification' => (int)$row['classification']
];
}
@@ -618,6 +626,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
'componenttype' => $query->createNamedParameter($extraData['componentType']),
'firstoccurence' => $query->createNamedParameter($extraData['firstOccurence']),
'lastoccurence' => $query->createNamedParameter($extraData['lastOccurence']),
+ 'classification' => $query->createNamedParameter($extraData['classification']),
'uid' => $query->createNamedParameter($extraData['uid']),
])
->execute();
@@ -657,6 +666,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
->set('componenttype', $query->createNamedParameter($extraData['componentType']))
->set('firstoccurence', $query->createNamedParameter($extraData['firstOccurence']))
->set('lastoccurence', $query->createNamedParameter($extraData['lastOccurence']))
+ ->set('classification', $query->createNamedParameter($extraData['classification']))
->set('uid', $query->createNamedParameter($extraData['uid']))
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
->andWhere($query->expr()->eq('uri', $query->createNamedParameter($objectUri)))
@@ -668,6 +678,23 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
}
/**
+ * @param int $calendarObjectId
+ * @param int $classification
+ */
+ public function setClassification($calendarObjectId, $classification) {
+ if (!in_array($classification, [
+ self::CLASSIFICATION_PUBLIC, self::CLASSIFICATION_PRIVATE, self::CLASSIFICATION_CONFIDENTIAL
+ ])) {
+ throw new \InvalidArgumentException();
+ }
+ $query = $this->db->getQueryBuilder();
+ $query->update('calendarobjects')
+ ->set('classification', $query->createNamedParameter($classification))
+ ->where($query->expr()->eq('id', $query->createNamedParameter($calendarObjectId)))
+ ->execute();
+ }
+
+ /**
* Deletes an existing calendar object.
*
* The object uri is only the basename, or filename and not a full path.
@@ -1086,10 +1113,10 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
* Read the PropPatch documentation for more info and examples.
*
* @param mixed $subscriptionId
- * @param \Sabre\DAV\PropPatch $propPatch
+ * @param PropPatch $propPatch
* @return void
*/
- function updateSubscription($subscriptionId, DAV\PropPatch $propPatch) {
+ function updateSubscription($subscriptionId, PropPatch $propPatch) {
$supportedProperties = array_keys($this->subscriptionPropertyMap);
$supportedProperties[] = '{http://calendarserver.org/ns/}source';
@@ -1280,14 +1307,15 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
* @param string $calendarData
* @return array
*/
- protected function getDenormalizedData($calendarData) {
+ public function getDenormalizedData($calendarData) {
$vObject = Reader::read($calendarData);
$componentType = null;
$component = null;
- $firstOccurence = null;
- $lastOccurence = null;
+ $firstOccurrence = null;
+ $lastOccurrence = null;
$uid = null;
+ $classification = self::CLASSIFICATION_PUBLIC;
foreach($vObject->getComponents() as $component) {
if ($component->name!=='VTIMEZONE') {
$componentType = $component->name;
@@ -1299,27 +1327,27 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
throw new \Sabre\DAV\Exception\BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component');
}
if ($componentType === 'VEVENT' && $component->DTSTART) {
- $firstOccurence = $component->DTSTART->getDateTime()->getTimeStamp();
+ $firstOccurrence = $component->DTSTART->getDateTime()->getTimeStamp();
// Finding the last occurrence is a bit harder
if (!isset($component->RRULE)) {
if (isset($component->DTEND)) {
- $lastOccurence = $component->DTEND->getDateTime()->getTimeStamp();
+ $lastOccurrence = $component->DTEND->getDateTime()->getTimeStamp();
} elseif (isset($component->DURATION)) {
$endDate = clone $component->DTSTART->getDateTime();
$endDate->add(DateTimeParser::parse($component->DURATION->getValue()));
- $lastOccurence = $endDate->getTimeStamp();
+ $lastOccurrence = $endDate->getTimeStamp();
} elseif (!$component->DTSTART->hasTime()) {
$endDate = clone $component->DTSTART->getDateTime();
$endDate->modify('+1 day');
- $lastOccurence = $endDate->getTimeStamp();
+ $lastOccurrence = $endDate->getTimeStamp();
} else {
- $lastOccurence = $firstOccurence;
+ $lastOccurrence = $firstOccurrence;
}
} else {
- $it = new RecurrenceIterator($vObject, (string)$component->UID);
+ $it = new EventIterator($vObject, (string)$component->UID);
$maxDate = new \DateTime(self::MAX_DATE);
if ($it->isInfinite()) {
- $lastOccurence = $maxDate->getTimeStamp();
+ $lastOccurrence = $maxDate->getTimeStamp();
} else {
$end = $it->getDtEnd();
while($it->valid() && $end < $maxDate) {
@@ -1327,19 +1355,31 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
$it->next();
}
- $lastOccurence = $end->getTimeStamp();
+ $lastOccurrence = $end->getTimeStamp();
}
}
}
+ if ($component->CLASS) {
+ $classification = CalDavBackend::CLASSIFICATION_PRIVATE;
+ switch ($component->CLASS->getValue()) {
+ case 'PUBLIC':
+ $classification = CalDavBackend::CLASSIFICATION_PUBLIC;
+ break;
+ case 'CONFIDENTIAL':
+ $classification = CalDavBackend::CLASSIFICATION_CONFIDENTIAL;
+ break;
+ }
+ }
return [
- 'etag' => md5($calendarData),
- 'size' => strlen($calendarData),
- 'componentType' => $componentType,
- 'firstOccurence' => is_null($firstOccurence) ? null : max(0, $firstOccurence),
- 'lastOccurence' => $lastOccurence,
- 'uid' => $uid,
+ 'etag' => md5($calendarData),
+ 'size' => strlen($calendarData),
+ 'componentType' => $componentType,
+ 'firstOccurence' => is_null($firstOccurrence) ? null : max(0, $firstOccurrence),
+ 'lastOccurence' => $lastOccurrence,
+ 'uid' => $uid,
+ 'classification' => $classification
];
}
diff --git a/apps/dav/lib/CalDAV/Calendar.php b/apps/dav/lib/CalDAV/Calendar.php
index 73b3957a9b0..785bb5699e2 100644
--- a/apps/dav/lib/CalDAV/Calendar.php
+++ b/apps/dav/lib/CalDAV/Calendar.php
@@ -26,6 +26,7 @@ use OCA\DAV\DAV\Sharing\IShareable;
use OCP\IL10N;
use Sabre\CalDAV\Backend\BackendInterface;
use Sabre\DAV\Exception\Forbidden;
+use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\PropPatch;
class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
@@ -162,6 +163,78 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
parent::propPatch($propPatch);
}
+ function getChild($name) {
+
+ $obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'], $name);
+
+ if (!$obj) {
+ throw new NotFound('Calendar object not found');
+ }
+
+ if ($this->isShared() && $obj['classification'] === CalDavBackend::CLASSIFICATION_PRIVATE) {
+ throw new NotFound('Calendar object not found');
+ }
+
+ $obj['acl'] = $this->getChildACL();
+
+ return new CalendarObject($this->caldavBackend, $this->calendarInfo, $obj);
+
+ }
+
+ function getChildren() {
+
+ $objs = $this->caldavBackend->getCalendarObjects($this->calendarInfo['id']);
+ $children = [];
+ foreach ($objs as $obj) {
+ if ($this->isShared() && $obj['classification'] === CalDavBackend::CLASSIFICATION_PRIVATE) {
+ continue;
+ }
+ $obj['acl'] = $this->getChildACL();
+ $children[] = new CalendarObject($this->caldavBackend, $this->calendarInfo, $obj);
+ }
+ return $children;
+
+ }
+
+ function getMultipleChildren(array $paths) {
+
+ $objs = $this->caldavBackend->getMultipleCalendarObjects($this->calendarInfo['id'], $paths);
+ $children = [];
+ foreach ($objs as $obj) {
+ if ($this->isShared() && $obj['classification'] === CalDavBackend::CLASSIFICATION_PRIVATE) {
+ continue;
+ }
+ $obj['acl'] = $this->getChildACL();
+ $children[] = new CalendarObject($this->caldavBackend, $this->calendarInfo, $obj);
+ }
+ return $children;
+
+ }
+
+ function childExists($name) {
+ $obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'], $name);
+ if (!$obj) {
+ return false;
+ }
+ if ($this->isShared() && $obj['classification'] === CalDavBackend::CLASSIFICATION_PRIVATE) {
+ return false;
+ }
+
+ return true;
+ }
+
+ function calendarQuery(array $filters) {
+
+ $uris = $this->caldavBackend->calendarQuery($this->calendarInfo['id'], $filters);
+ if ($this->isShared()) {
+ return array_filter($uris, function ($uri) {
+ return $this->childExists($uri);
+ });
+ }
+
+ return $uris;
+ }
+
private function canWrite() {
if (isset($this->calendarInfo['{http://owncloud.org/ns}read-only'])) {
return !$this->calendarInfo['{http://owncloud.org/ns}read-only'];
@@ -169,4 +242,8 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
return true;
}
+ private function isShared() {
+ return isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal']);
+ }
+
}
diff --git a/apps/dav/lib/CalDAV/CalendarObject.php b/apps/dav/lib/CalDAV/CalendarObject.php
new file mode 100644
index 00000000000..b4a58b52093
--- /dev/null
+++ b/apps/dav/lib/CalDAV/CalendarObject.php
@@ -0,0 +1,92 @@
+<?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\CalDAV;
+
+
+use Sabre\VObject\Component;
+use Sabre\VObject\Property;
+use Sabre\VObject\Reader;
+
+class CalendarObject extends \Sabre\CalDAV\CalendarObject {
+
+ /**
+ * @inheritdoc
+ */
+ function get() {
+ $data = parent::get();
+ if ($this->isShared() && $this->objectData['classification'] === CalDavBackend::CLASSIFICATION_CONFIDENTIAL) {
+ return $this->createConfidentialObject($data);
+ }
+ return $data;
+ }
+
+ private function isShared() {
+ return isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal']);
+ }
+
+ /**
+ * @param string $calData
+ * @return string
+ */
+ private static function createConfidentialObject($calData) {
+
+ $vObject = Reader::read($calData);
+
+ /** @var Component $vElement */
+ $vElement = null;
+ if(isset($vObject->VEVENT)) {
+ $vElement = $vObject->VEVENT;
+ }
+ if(isset($vObject->VJOURNAL)) {
+ $vElement = $vObject->VJOURNAL;
+ }
+ if(isset($vObject->VTODO)) {
+ $vElement = $vObject->VTODO;
+ }
+ if(!is_null($vElement)) {
+ foreach ($vElement->children as &$property) {
+ /** @var Property $property */
+ switch($property->name) {
+ case 'CREATED':
+ case 'DTSTART':
+ case 'RRULE':
+ case 'DURATION':
+ case 'DTEND':
+ case 'CLASS':
+ case 'UID':
+ break;
+ case 'SUMMARY':
+ $property->setValue('Busy');
+ break;
+ default:
+ $vElement->__unset($property->name);
+ unset($property);
+ break;
+ }
+ }
+ }
+
+ return $vObject->serialize();
+ }
+
+}
diff --git a/apps/dav/lib/Connector/PublicAuth.php b/apps/dav/lib/Connector/PublicAuth.php
index 2716ca29107..4e63ca1d29e 100644
--- a/apps/dav/lib/Connector/PublicAuth.php
+++ b/apps/dav/lib/Connector/PublicAuth.php
@@ -31,13 +31,14 @@ use OCP\IRequest;
use OCP\ISession;
use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\IManager;
+use Sabre\DAV\Auth\Backend\AbstractBasic;
/**
* Class PublicAuth
*
* @package OCA\DAV\Connector
*/
-class PublicAuth extends \Sabre\DAV\Auth\Backend\AbstractBasic {
+class PublicAuth extends AbstractBasic {
/** @var \OCP\Share\IShare */
private $share;
@@ -62,6 +63,10 @@ class PublicAuth extends \Sabre\DAV\Auth\Backend\AbstractBasic {
$this->request = $request;
$this->shareManager = $shareManager;
$this->session = $session;
+
+ // setup realm
+ $defaults = new \OC_Defaults();
+ $this->realm = $defaults->getName();
}
/**
@@ -99,7 +104,7 @@ class PublicAuth extends \Sabre\DAV\Auth\Backend\AbstractBasic {
if (in_array('XMLHttpRequest', explode(',', $this->request->getHeader('X-Requested-With')))) {
// do not re-authenticate over ajax, use dummy auth name to prevent browser popup
http_response_code(401);
- header('WWW-Authenticate', 'DummyBasic real="ownCloud"');
+ header('WWW-Authenticate','DummyBasic realm="' . $this->realm . '"');
throw new \Sabre\DAV\Exception\NotAuthenticated('Cannot authenticate over ajax calls');
}
return false;
diff --git a/apps/dav/lib/Connector/Sabre/Auth.php b/apps/dav/lib/Connector/Sabre/Auth.php
index 27900cc1cad..653da10bc3c 100644
--- a/apps/dav/lib/Connector/Sabre/Auth.php
+++ b/apps/dav/lib/Connector/Sabre/Auth.php
@@ -74,6 +74,10 @@ class Auth extends AbstractBasic {
$this->twoFactorManager = $twoFactorManager;
$this->request = $request;
$this->principalPrefix = $principalPrefix;
+
+ // setup realm
+ $defaults = new \OC_Defaults();
+ $this->realm = $defaults->getName();
}
/**
diff --git a/apps/dav/lib/Connector/Sabre/FilesPlugin.php b/apps/dav/lib/Connector/Sabre/FilesPlugin.php
index dc47416cca8..0a2e6713cb4 100644
--- a/apps/dav/lib/Connector/Sabre/FilesPlugin.php
+++ b/apps/dav/lib/Connector/Sabre/FilesPlugin.php
@@ -42,6 +42,7 @@ use \Sabre\HTTP\RequestInterface;
use \Sabre\HTTP\ResponseInterface;
use OCP\Files\StorageNotAvailableException;
use OCP\IConfig;
+use OCP\IRequest;
class FilesPlugin extends ServerPlugin {
@@ -96,19 +97,28 @@ class FilesPlugin extends ServerPlugin {
private $config;
/**
+ * @var IRequest
+ */
+ private $request;
+
+ /**
* @param Tree $tree
* @param View $view
+ * @param IConfig $config
+ * @param IRequest $request
* @param bool $isPublic
* @param bool $downloadAttachment
*/
public function __construct(Tree $tree,
View $view,
IConfig $config,
+ IRequest $request,
$isPublic = false,
$downloadAttachment = true) {
$this->tree = $tree;
$this->fileView = $view;
$this->config = $config;
+ $this->request = $request;
$this->isPublic = $isPublic;
$this->downloadAttachment = $downloadAttachment;
}
@@ -225,7 +235,18 @@ class FilesPlugin extends ServerPlugin {
// adds a 'Content-Disposition: attachment' header
if ($this->downloadAttachment) {
- $response->addHeader('Content-Disposition', 'attachment');
+ $filename = $node->getName();
+ if ($this->request->isUserAgent(
+ [
+ \OC\AppFramework\Http\Request::USER_AGENT_IE,
+ \OC\AppFramework\Http\Request::USER_AGENT_ANDROID_MOBILE_CHROME,
+ \OC\AppFramework\Http\Request::USER_AGENT_FREEBOX,
+ ])) {
+ $response->addHeader('Content-Disposition', 'attachment; filename="' . rawurlencode($filename) . '"');
+ } else {
+ $response->addHeader('Content-Disposition', 'attachment; filename*=UTF-8\'\'' . rawurlencode($filename)
+ . '; filename="' . rawurlencode($filename) . '"');
+ }
}
if ($node instanceof \OCA\DAV\Connector\Sabre\File) {
diff --git a/apps/dav/lib/Connector/Sabre/ServerFactory.php b/apps/dav/lib/Connector/Sabre/ServerFactory.php
index b193bfc76c7..c5b4f6a9352 100644
--- a/apps/dav/lib/Connector/Sabre/ServerFactory.php
+++ b/apps/dav/lib/Connector/Sabre/ServerFactory.php
@@ -100,10 +100,9 @@ class ServerFactory {
$server->setBaseUri($baseUri);
// Load plugins
- $defaults = new \OC_Defaults();
$server->addPlugin(new \OCA\DAV\Connector\Sabre\MaintenancePlugin($this->config));
$server->addPlugin(new \OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin($this->config));
- $server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend, $defaults->getName()));
+ $server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend));
// FIXME: The following line is a workaround for legacy components relying on being able to send a GET to /
$server->addPlugin(new \OCA\DAV\Connector\Sabre\DummyGetResponsePlugin());
$server->addPlugin(new \OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin('webdav', $this->logger));
@@ -144,6 +143,7 @@ class ServerFactory {
$objectTree,
$view,
$this->config,
+ $this->request,
false,
!$this->config->getSystemValue('debug', false)
)
diff --git a/apps/dav/lib/Migration/Classification.php b/apps/dav/lib/Migration/Classification.php
new file mode 100644
index 00000000000..b793f790af5
--- /dev/null
+++ b/apps/dav/lib/Migration/Classification.php
@@ -0,0 +1,93 @@
+<?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\Migration;
+
+use OCA\DAV\CalDAV\CalDavBackend;
+use OCP\IUser;
+use OCP\IUserManager;
+use OCP\Migration\IOutput;
+use OCP\Migration\IRepairStep;
+
+class Classification implements IRepairStep {
+
+ /** @var CalDavBackend */
+ private $calDavBackend;
+
+ /** @var IUserManager */
+ private $userManager;
+
+ /**
+ * Classification constructor.
+ *
+ * @param CalDavBackend $calDavBackend
+ */
+ public function __construct(CalDavBackend $calDavBackend, IUserManager $userManager) {
+ $this->calDavBackend = $calDavBackend;
+ $this->userManager = $userManager;
+ }
+
+ /**
+ * @param IUser $user
+ */
+ public function runForUser($user) {
+ $principal = 'principals/users/' . $user->getUID();
+ $calendars = $this->calDavBackend->getCalendarsForUser($principal);
+ foreach ($calendars as $calendar) {
+ $objects = $this->calDavBackend->getCalendarObjects($calendar['id']);
+ foreach ($objects as $object) {
+ $calObject = $this->calDavBackend->getCalendarObject($calendar['id'], $object['uri']);
+ $classification = $this->extractClassification($calObject['calendardata']);
+ $this->calDavBackend->setClassification($object['id'], $classification);
+ }
+ }
+ }
+
+ /**
+ * @param $calendarData
+ * @return integer
+ * @throws \Sabre\DAV\Exception\BadRequest
+ */
+ protected function extractClassification($calendarData) {
+ return $this->calDavBackend->getDenormalizedData($calendarData)['classification'];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getName() {
+ return 'Fix classification for calendar objects';
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function run(IOutput $output) {
+ $output->startProgress();
+ $this->userManager->callForAllUsers(function($user) use ($output) {
+ /** @var IUser $user */
+ $output->advance(1, $user->getDisplayName());
+ $this->runForUser($user);
+ });
+ $output->finishProgress();
+ }
+}
diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php
index 179558e97ae..e150f441b82 100644
--- a/apps/dav/lib/Server.php
+++ b/apps/dav/lib/Server.php
@@ -141,6 +141,7 @@ class Server {
$this->server->tree,
$view,
\OC::$server->getConfig(),
+ $this->request,
false,
!\OC::$server->getConfig()->getSystemValue('debug', false)
)
diff --git a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php
new file mode 100644
index 00000000000..49e5e5a2bcc
--- /dev/null
+++ b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackendTest.php
@@ -0,0 +1,163 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ * @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\Tests\unit\CalDAV;
+
+use DateTime;
+use DateTimeZone;
+use OCA\DAV\CalDAV\CalDavBackend;
+use OCA\DAV\CalDAV\Calendar;
+use OCA\DAV\Connector\Sabre\Principal;
+use OCP\IL10N;
+use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet;
+use Sabre\DAV\PropPatch;
+use Sabre\DAV\Xml\Property\Href;
+use Sabre\DAVACL\IACL;
+use Test\TestCase;
+
+/**
+ * Class CalDavBackendTest
+ *
+ * @group DB
+ *
+ * @package OCA\DAV\Tests\unit\CalDAV
+ */
+abstract class AbstractCalDavBackendTest extends TestCase {
+
+ /** @var CalDavBackend */
+ protected $backend;
+
+ /** @var Principal | \PHPUnit_Framework_MockObject_MockObject */
+ protected $principal;
+
+ const UNIT_TEST_USER = 'principals/users/caldav-unit-test';
+ const UNIT_TEST_USER1 = 'principals/users/caldav-unit-test1';
+ const UNIT_TEST_GROUP = 'principals/groups/caldav-unit-test-group';
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->principal = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Principal')
+ ->disableOriginalConstructor()
+ ->setMethods(['getPrincipalByPath', 'getGroupMembership'])
+ ->getMock();
+ $this->principal->expects($this->any())->method('getPrincipalByPath')
+ ->willReturn([
+ 'uri' => 'principals/best-friend'
+ ]);
+ $this->principal->expects($this->any())->method('getGroupMembership')
+ ->withAnyParameters()
+ ->willReturn([self::UNIT_TEST_GROUP]);
+
+ $db = \OC::$server->getDatabaseConnection();
+ $this->backend = new CalDavBackend($db, $this->principal);
+
+ $this->tearDown();
+ }
+
+ public function tearDown() {
+ parent::tearDown();
+
+ if (is_null($this->backend)) {
+ return;
+ }
+ $books = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
+ foreach ($books as $book) {
+ $this->backend->deleteCalendar($book['id']);
+ }
+ $subscriptions = $this->backend->getSubscriptionsForUser(self::UNIT_TEST_USER);
+ foreach ($subscriptions as $subscription) {
+ $this->backend->deleteSubscription($subscription['id']);
+ }
+ }
+
+ protected function createTestCalendar() {
+ $this->backend->createCalendar(self::UNIT_TEST_USER, 'Example', [
+ '{http://apple.com/ns/ical/}calendar-color' => '#1C4587FF'
+ ]);
+ $calendars = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
+ $this->assertEquals(1, count($calendars));
+ $this->assertEquals(self::UNIT_TEST_USER, $calendars[0]['principaluri']);
+ /** @var SupportedCalendarComponentSet $components */
+ $components = $calendars[0]['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set'];
+ $this->assertEquals(['VEVENT','VTODO'], $components->getValue());
+ $color = $calendars[0]['{http://apple.com/ns/ical/}calendar-color'];
+ $this->assertEquals('#1C4587FF', $color);
+ $this->assertEquals('Example', $calendars[0]['uri']);
+ $this->assertEquals('Example', $calendars[0]['{DAV:}displayname']);
+ $calendarId = $calendars[0]['id'];
+
+ return $calendarId;
+ }
+
+ protected function createEvent($calendarId, $start = '20130912T130000Z', $end = '20130912T140000Z') {
+
+ $calData = <<<EOD
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:ownCloud Calendar
+BEGIN:VEVENT
+CREATED;VALUE=DATE-TIME:20130910T125139Z
+UID:47d15e3ec8
+LAST-MODIFIED;VALUE=DATE-TIME:20130910T125139Z
+DTSTAMP;VALUE=DATE-TIME:20130910T125139Z
+SUMMARY:Test Event
+DTSTART;VALUE=DATE-TIME:$start
+DTEND;VALUE=DATE-TIME:$end
+CLASS:PUBLIC
+END:VEVENT
+END:VCALENDAR
+EOD;
+ $uri0 = $this->getUniqueID('event');
+ $this->backend->createCalendarObject($calendarId, $uri0, $calData);
+
+ return $uri0;
+ }
+
+ protected function assertAcl($principal, $privilege, $acl) {
+ foreach($acl as $a) {
+ if ($a['principal'] === $principal && $a['privilege'] === $privilege) {
+ $this->assertTrue(true);
+ return;
+ }
+ }
+ $this->fail("ACL does not contain $principal / $privilege");
+ }
+
+ protected function assertNotAcl($principal, $privilege, $acl) {
+ foreach($acl as $a) {
+ if ($a['principal'] === $principal && $a['privilege'] === $privilege) {
+ $this->fail("ACL contains $principal / $privilege");
+ return;
+ }
+ }
+ $this->assertTrue(true);
+ }
+
+ protected function assertAccess($shouldHaveAcl, $principal, $privilege, $acl) {
+ if ($shouldHaveAcl) {
+ $this->assertAcl($principal, $privilege, $acl);
+ } else {
+ $this->assertNotAcl($principal, $privilege, $acl);
+ }
+ }
+}
diff --git a/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php b/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php
index c3e32e436d9..977bdf15c8e 100644
--- a/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php
+++ b/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php
@@ -26,13 +26,10 @@ use DateTime;
use DateTimeZone;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\Calendar;
-use OCA\DAV\Connector\Sabre\Principal;
use OCP\IL10N;
-use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet;
use Sabre\DAV\PropPatch;
use Sabre\DAV\Xml\Property\Href;
use Sabre\DAVACL\IACL;
-use Test\TestCase;
/**
* Class CalDavBackendTest
@@ -41,54 +38,7 @@ use Test\TestCase;
*
* @package OCA\DAV\Tests\unit\CalDAV
*/
-class CalDavBackendTest extends TestCase {
-
- /** @var CalDavBackend */
- private $backend;
-
- /** @var Principal | \PHPUnit_Framework_MockObject_MockObject */
- private $principal;
-
- const UNIT_TEST_USER = 'principals/users/caldav-unit-test';
- const UNIT_TEST_USER1 = 'principals/users/caldav-unit-test1';
- const UNIT_TEST_GROUP = 'principals/groups/caldav-unit-test-group';
-
- public function setUp() {
- parent::setUp();
-
- $this->principal = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Principal')
- ->disableOriginalConstructor()
- ->setMethods(['getPrincipalByPath', 'getGroupMembership'])
- ->getMock();
- $this->principal->expects($this->any())->method('getPrincipalByPath')
- ->willReturn([
- 'uri' => 'principals/best-friend'
- ]);
- $this->principal->expects($this->any())->method('getGroupMembership')
- ->withAnyParameters()
- ->willReturn([self::UNIT_TEST_GROUP]);
-
- $db = \OC::$server->getDatabaseConnection();
- $this->backend = new CalDavBackend($db, $this->principal);
-
- $this->tearDown();
- }
-
- public function tearDown() {
- parent::tearDown();
-
- if (is_null($this->backend)) {
- return;
- }
- $books = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
- foreach ($books as $book) {
- $this->backend->deleteCalendar($book['id']);
- }
- $subscriptions = $this->backend->getSubscriptionsForUser(self::UNIT_TEST_USER);
- foreach ($subscriptions as $subscription) {
- $this->backend->deleteSubscription($subscription['id']);
- }
- }
+class CalDavBackendTest extends AbstractCalDavBackendTest {
public function testCalendarOperations() {
@@ -232,6 +182,7 @@ EOD;
$calendarObjects = $this->backend->getCalendarObjects($calendarId);
$this->assertEquals(1, count($calendarObjects));
$this->assertEquals($calendarId, $calendarObjects[0]['calendarid']);
+ $this->assertArrayHasKey('classification', $calendarObjects[0]);
// get the cards
$calendarObject = $this->backend->getCalendarObject($calendarId, $uri);
@@ -241,6 +192,7 @@ EOD;
$this->assertArrayHasKey('lastmodified', $calendarObject);
$this->assertArrayHasKey('etag', $calendarObject);
$this->assertArrayHasKey('size', $calendarObject);
+ $this->assertArrayHasKey('classification', $calendarObject);
$this->assertEquals($calData, $calendarObject['calendardata']);
// update the card
@@ -310,6 +262,7 @@ EOD;
$this->assertArrayHasKey('lastmodified', $card);
$this->assertArrayHasKey('etag', $card);
$this->assertArrayHasKey('size', $card);
+ $this->assertArrayHasKey('classification', $card);
$this->assertEquals($calData, $card['calendardata']);
}
@@ -363,49 +316,6 @@ EOD;
];
}
- private function createTestCalendar() {
- $this->backend->createCalendar(self::UNIT_TEST_USER, 'Example', [
- '{http://apple.com/ns/ical/}calendar-color' => '#1C4587FF'
- ]);
- $calendars = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
- $this->assertEquals(1, count($calendars));
- $this->assertEquals(self::UNIT_TEST_USER, $calendars[0]['principaluri']);
- /** @var SupportedCalendarComponentSet $components */
- $components = $calendars[0]['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set'];
- $this->assertEquals(['VEVENT','VTODO'], $components->getValue());
- $color = $calendars[0]['{http://apple.com/ns/ical/}calendar-color'];
- $this->assertEquals('#1C4587FF', $color);
- $this->assertEquals('Example', $calendars[0]['uri']);
- $this->assertEquals('Example', $calendars[0]['{DAV:}displayname']);
- $calendarId = $calendars[0]['id'];
-
- return $calendarId;
- }
-
- private function createEvent($calendarId, $start = '20130912T130000Z', $end = '20130912T140000Z') {
-
- $calData = <<<EOD
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:ownCloud Calendar
-BEGIN:VEVENT
-CREATED;VALUE=DATE-TIME:20130910T125139Z
-UID:47d15e3ec8
-LAST-MODIFIED;VALUE=DATE-TIME:20130910T125139Z
-DTSTAMP;VALUE=DATE-TIME:20130910T125139Z
-SUMMARY:Test Event
-DTSTART;VALUE=DATE-TIME:$start
-DTEND;VALUE=DATE-TIME:$end
-CLASS:PUBLIC
-END:VEVENT
-END:VCALENDAR
-EOD;
- $uri0 = $this->getUniqueID('event');
- $this->backend->createCalendarObject($calendarId, $uri0, $calData);
-
- return $uri0;
- }
-
public function testSyncSupport() {
$calendarId = $this->createTestCalendar();
@@ -464,43 +374,20 @@ EOD;
/**
* @dataProvider providesCalDataForGetDenormalizedData
*/
- public function testGetDenormalizedData($expectedFirstOccurance, $calData) {
- $actual = $this->invokePrivate($this->backend, 'getDenormalizedData', [$calData]);
- $this->assertEquals($expectedFirstOccurance, $actual['firstOccurence']);
+ public function testGetDenormalizedData($expected, $key, $calData) {
+ $actual = $this->backend->getDenormalizedData($calData);
+ $this->assertEquals($expected, $actual[$key]);
}
public function providesCalDataForGetDenormalizedData() {
return [
- [0, "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:413F269B-B51B-46B1-AFB6-40055C53A4DC\r\nDTSTAMP:20160309T095056Z\r\nDTSTART;VALUE=DATE:16040222\r\nDTEND;VALUE=DATE:16040223\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:SUMMARY\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"],
- [null, "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:413F269B-B51B-46B1-AFB6-40055C53A4DC\r\nDTSTAMP:20160309T095056Z\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:SUMMARY\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"]
+ 'first occurrence before unix epoch starts' => [0, 'firstOccurence', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:413F269B-B51B-46B1-AFB6-40055C53A4DC\r\nDTSTAMP:20160309T095056Z\r\nDTSTART;VALUE=DATE:16040222\r\nDTEND;VALUE=DATE:16040223\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:SUMMARY\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"],
+ 'no first occurrence because yearly' => [null, 'firstOccurence', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:413F269B-B51B-46B1-AFB6-40055C53A4DC\r\nDTSTAMP:20160309T095056Z\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:SUMMARY\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"],
+ 'CLASS:PRIVATE' => [CalDavBackend::CLASSIFICATION_PRIVATE, 'classification', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//dmfs.org//mimedir.icalendar//EN\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nX-LIC-LOCATION:Europe/Berlin\r\nBEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0200\r\nTZNAME:CEST\r\nDTSTART:19700329T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0100\r\nTZNAME:CET\r\nDTSTART:19701025T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nDTSTART;TZID=Europe/Berlin:20160419T130000\r\nSUMMARY:Test\r\nCLASS:PRIVATE\r\nTRANSP:OPAQUE\r\nSTATUS:CONFIRMED\r\nDTEND;TZID=Europe/Berlin:20160419T140000\r\nLAST-MODIFIED:20160419T074202Z\r\nDTSTAMP:20160419T074202Z\r\nCREATED:20160419T074202Z\r\nUID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310\r\nEND:VEVENT\r\nEND:VCALENDAR"],
+ 'CLASS:PUBLIC' => [CalDavBackend::CLASSIFICATION_PUBLIC, 'classification', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//dmfs.org//mimedir.icalendar//EN\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nX-LIC-LOCATION:Europe/Berlin\r\nBEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0200\r\nTZNAME:CEST\r\nDTSTART:19700329T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0100\r\nTZNAME:CET\r\nDTSTART:19701025T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nDTSTART;TZID=Europe/Berlin:20160419T130000\r\nSUMMARY:Test\r\nCLASS:PUBLIC\r\nTRANSP:OPAQUE\r\nSTATUS:CONFIRMED\r\nDTEND;TZID=Europe/Berlin:20160419T140000\r\nLAST-MODIFIED:20160419T074202Z\r\nDTSTAMP:20160419T074202Z\r\nCREATED:20160419T074202Z\r\nUID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310\r\nEND:VEVENT\r\nEND:VCALENDAR"],
+ 'CLASS:CONFIDENTIAL' => [CalDavBackend::CLASSIFICATION_CONFIDENTIAL, 'classification', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//dmfs.org//mimedir.icalendar//EN\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nX-LIC-LOCATION:Europe/Berlin\r\nBEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0200\r\nTZNAME:CEST\r\nDTSTART:19700329T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0100\r\nTZNAME:CET\r\nDTSTART:19701025T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nDTSTART;TZID=Europe/Berlin:20160419T130000\r\nSUMMARY:Test\r\nCLASS:CONFIDENTIAL\r\nTRANSP:OPAQUE\r\nSTATUS:CONFIRMED\r\nDTEND;TZID=Europe/Berlin:20160419T140000\r\nLAST-MODIFIED:20160419T074202Z\r\nDTSTAMP:20160419T074202Z\r\nCREATED:20160419T074202Z\r\nUID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310\r\nEND:VEVENT\r\nEND:VCALENDAR"],
+ 'no class set -> public' => [CalDavBackend::CLASSIFICATION_PUBLIC, 'classification', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//dmfs.org//mimedir.icalendar//EN\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nX-LIC-LOCATION:Europe/Berlin\r\nBEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0200\r\nTZNAME:CEST\r\nDTSTART:19700329T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0100\r\nTZNAME:CET\r\nDTSTART:19701025T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nDTSTART;TZID=Europe/Berlin:20160419T130000\r\nSUMMARY:Test\r\nTRANSP:OPAQUE\r\nDTEND;TZID=Europe/Berlin:20160419T140000\r\nLAST-MODIFIED:20160419T074202Z\r\nDTSTAMP:20160419T074202Z\r\nCREATED:20160419T074202Z\r\nUID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310\r\nEND:VEVENT\r\nEND:VCALENDAR"],
+ 'unknown class -> private' => [CalDavBackend::CLASSIFICATION_PRIVATE, 'classification', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//dmfs.org//mimedir.icalendar//EN\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nX-LIC-LOCATION:Europe/Berlin\r\nBEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0200\r\nTZNAME:CEST\r\nDTSTART:19700329T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0100\r\nTZNAME:CET\r\nDTSTART:19701025T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nDTSTART;TZID=Europe/Berlin:20160419T130000\r\nSUMMARY:Test\r\nCLASS:VERTRAULICH\r\nTRANSP:OPAQUE\r\nSTATUS:CONFIRMED\r\nDTEND;TZID=Europe/Berlin:20160419T140000\r\nLAST-MODIFIED:20160419T074202Z\r\nDTSTAMP:20160419T074202Z\r\nCREATED:20160419T074202Z\r\nUID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310\r\nEND:VEVENT\r\nEND:VCALENDAR"],
];
}
-
- private function assertAcl($principal, $privilege, $acl) {
- foreach($acl as $a) {
- if ($a['principal'] === $principal && $a['privilege'] === $privilege) {
- $this->assertTrue(true);
- return;
- }
- }
- $this->fail("ACL does not contain $principal / $privilege");
- }
-
- private function assertNotAcl($principal, $privilege, $acl) {
- foreach($acl as $a) {
- if ($a['principal'] === $principal && $a['privilege'] === $privilege) {
- $this->fail("ACL contains $principal / $privilege");
- return;
- }
- }
- $this->assertTrue(true);
- }
-
- private function assertAccess($shouldHaveAcl, $principal, $privilege, $acl) {
- if ($shouldHaveAcl) {
- $this->assertAcl($principal, $privilege, $acl);
- } else {
- $this->assertNotAcl($principal, $privilege, $acl);
- }
- }
}
diff --git a/apps/dav/tests/unit/CalDAV/CalendarTest.php b/apps/dav/tests/unit/CalDAV/CalendarTest.php
index 73d85e82bbc..56a2d4fcba7 100644
--- a/apps/dav/tests/unit/CalDAV/CalendarTest.php
+++ b/apps/dav/tests/unit/CalDAV/CalendarTest.php
@@ -27,6 +27,7 @@ use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\Calendar;
use OCP\IL10N;
use Sabre\DAV\PropPatch;
+use Sabre\VObject\Reader;
use Test\TestCase;
class CalendarTest extends TestCase {
@@ -189,4 +190,153 @@ class CalendarTest extends TestCase {
'birthday calendar' => [false, false, false, BirthdayService::BIRTHDAY_CALENDAR_URI]
];
}
+
+ /**
+ * @dataProvider providesConfidentialClassificationData
+ * @param $expectedChildren
+ * @param $isShared
+ */
+ public function testPrivateClassification($expectedChildren, $isShared) {
+
+ $calObject0 = ['uri' => 'event-0', 'classification' => CalDavBackend::CLASSIFICATION_PUBLIC];
+ $calObject1 = ['uri' => 'event-1', 'classification' => CalDavBackend::CLASSIFICATION_CONFIDENTIAL];
+ $calObject2 = ['uri' => 'event-2', 'classification' => CalDavBackend::CLASSIFICATION_PRIVATE];
+
+ /** @var \PHPUnit_Framework_MockObject_MockObject | CalDavBackend $backend */
+ $backend = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend')->disableOriginalConstructor()->getMock();
+ $backend->expects($this->any())->method('getCalendarObjects')->willReturn([
+ $calObject0, $calObject1, $calObject2
+ ]);
+ $backend->expects($this->any())->method('getMultipleCalendarObjects')
+ ->with(666, ['event-0', 'event-1', 'event-2'])
+ ->willReturn([
+ $calObject0, $calObject1, $calObject2
+ ]);
+ $backend->expects($this->any())->method('getCalendarObject')
+ ->willReturn($calObject2)->with(666, 'event-2');
+
+ $calendarInfo = [
+ 'principaluri' => 'user2',
+ 'id' => 666,
+ 'uri' => 'cal',
+ ];
+
+ if ($isShared) {
+ $calendarInfo['{http://owncloud.org/ns}owner-principal'] = 'user1';
+
+ }
+ $c = new Calendar($backend, $calendarInfo, $this->l10n);
+ $children = $c->getChildren();
+ $this->assertEquals($expectedChildren, count($children));
+ $children = $c->getMultipleChildren(['event-0', 'event-1', 'event-2']);
+ $this->assertEquals($expectedChildren, count($children));
+
+ $this->assertEquals(!$isShared, $c->childExists('event-2'));
+ }
+
+ /**
+ * @dataProvider providesConfidentialClassificationData
+ * @param $expectedChildren
+ * @param $isShared
+ */
+ public function testConfidentialClassification($expectedChildren, $isShared) {
+ $start = '20160609';
+ $end = '20160610';
+
+ $calData = <<<EOD
+BEGIN:VCALENDAR
+PRODID:-//ownCloud calendar v1.2.2
+BEGIN:VEVENT
+CREATED:20160602T133732
+DTSTAMP:20160602T133732
+LAST-MODIFIED:20160602T133732
+UID:wej2z68l9h
+SUMMARY:Test Event
+LOCATION:Somewhere ...
+ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;CUTYPE=INDIVIDUAL;CN=de
+ epdiver:MAILTO:thomas.mueller@tmit.eu
+ORGANIZER;CN=deepdiver:MAILTO:thomas.mueller@tmit.eu
+DESCRIPTION:maybe ....
+DTSTART;TZID=Europe/Berlin;VALUE=DATE:$start
+DTEND;TZID=Europe/Berlin;VALUE=DATE:$end
+RRULE:FREQ=DAILY
+BEGIN:VALARM
+ACTION:AUDIO
+TRIGGER:-PT15M
+END:VALARM
+END:VEVENT
+BEGIN:VTIMEZONE
+TZID:Europe/Berlin
+BEGIN:DAYLIGHT
+DTSTART:19810329T020000
+RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
+TZNAME:MESZ
+TZOFFSETFROM:+0100
+TZOFFSETTO:+0200
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:19961027T030000
+RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
+TZNAME:MEZ
+TZOFFSETFROM:+0200
+TZOFFSETTO:+0100
+END:STANDARD
+END:VTIMEZONE
+END:VCALENDAR
+EOD;
+
+ $calObject0 = ['uri' => 'event-0', 'classification' => CalDavBackend::CLASSIFICATION_PUBLIC];
+ $calObject1 = ['uri' => 'event-1', 'classification' => CalDavBackend::CLASSIFICATION_CONFIDENTIAL, 'calendardata' => $calData];
+ $calObject2 = ['uri' => 'event-2', 'classification' => CalDavBackend::CLASSIFICATION_PRIVATE];
+
+ /** @var \PHPUnit_Framework_MockObject_MockObject | CalDavBackend $backend */
+ $backend = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend')->disableOriginalConstructor()->getMock();
+ $backend->expects($this->any())->method('getCalendarObjects')->willReturn([
+ $calObject0, $calObject1, $calObject2
+ ]);
+ $backend->expects($this->any())->method('getMultipleCalendarObjects')
+ ->with(666, ['event-0', 'event-1', 'event-2'])
+ ->willReturn([
+ $calObject0, $calObject1, $calObject2
+ ]);
+ $backend->expects($this->any())->method('getCalendarObject')
+ ->willReturn($calObject1)->with(666, 'event-1');
+
+ $calendarInfo = [
+ 'principaluri' => 'user2',
+ 'id' => 666,
+ 'uri' => 'cal',
+ ];
+
+ if ($isShared) {
+ $calendarInfo['{http://owncloud.org/ns}owner-principal'] = 'user1';
+
+ }
+ $c = new Calendar($backend, $calendarInfo, $this->l10n);
+
+ // test private event
+ $privateEvent = $c->getChild('event-1');
+ $calData = $privateEvent->get();
+ $event = Reader::read($calData);
+
+ $this->assertEquals($start, $event->VEVENT->DTSTART->getValue());
+ $this->assertEquals($end, $event->VEVENT->DTEND->getValue());
+
+ if ($isShared) {
+ $this->assertEquals('Busy', $event->VEVENT->SUMMARY->getValue());
+ $this->assertArrayNotHasKey('ATTENDEE', $event->VEVENT);
+ $this->assertArrayNotHasKey('LOCATION', $event->VEVENT);
+ $this->assertArrayNotHasKey('DESCRIPTION', $event->VEVENT);
+ $this->assertArrayNotHasKey('ORGANIZER', $event->VEVENT);
+ } else {
+ $this->assertEquals('Test Event', $event->VEVENT->SUMMARY->getValue());
+ }
+ }
+
+ public function providesConfidentialClassificationData() {
+ return [
+ [3, false],
+ [2, true]
+ ];
+ }
}
diff --git a/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php
index 80f284e470e..2b3f3e15d1a 100644
--- a/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php
+++ b/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php
@@ -73,6 +73,11 @@ class FilesPluginTest extends TestCase {
*/
private $config;
+ /**
+ * @var \OCP\IRequest | \PHPUnit_Framework_MockObject_MockObject
+ */
+ private $request;
+
public function setUp() {
parent::setUp();
$this->server = $this->getMockBuilder('\Sabre\DAV\Server')
@@ -88,11 +93,13 @@ class FilesPluginTest extends TestCase {
$this->config->expects($this->any())->method('getSystemValue')
->with($this->equalTo('data-fingerprint'), $this->equalTo(''))
->willReturn('my_fingerprint');
+ $this->request = $this->getMock('\OCP\IRequest');
$this->plugin = new FilesPlugin(
$this->tree,
$this->view,
- $this->config
+ $this->config,
+ $this->request
);
$this->plugin->initialize($this->server);
}
@@ -268,6 +275,7 @@ class FilesPluginTest extends TestCase {
$this->tree,
$this->view,
$this->config,
+ $this->getMock('\OCP\IRequest'),
true);
$this->plugin->initialize($this->server);
@@ -484,4 +492,60 @@ class FilesPluginTest extends TestCase {
$this->plugin->checkMove('FolderA/test.txt', 'test.txt');
}
+
+ public function downloadHeadersProvider() {
+ return [
+ [
+ false,
+ 'attachment; filename*=UTF-8\'\'somefile.xml; filename="somefile.xml"'
+ ],
+ [
+ true,
+ 'attachment; filename="somefile.xml"'
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider downloadHeadersProvider
+ */
+ public function testDownloadHeaders($isClumsyAgent, $contentDispositionHeader) {
+ $request = $this->getMockBuilder('Sabre\HTTP\RequestInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $response = $this->getMockBuilder('Sabre\HTTP\ResponseInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $request
+ ->expects($this->once())
+ ->method('getPath')
+ ->will($this->returnValue('test/somefile.xml'));
+
+ $node = $this->getMockBuilder('\OCA\DAV\Connector\Sabre\File')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $node
+ ->expects($this->once())
+ ->method('getName')
+ ->will($this->returnValue('somefile.xml'));
+
+ $this->tree
+ ->expects($this->once())
+ ->method('getNodeForPath')
+ ->with('test/somefile.xml')
+ ->will($this->returnValue($node));
+
+ $this->request
+ ->expects($this->once())
+ ->method('isUserAgent')
+ ->will($this->returnValue($isClumsyAgent));
+
+ $response
+ ->expects($this->once())
+ ->method('addHeader')
+ ->with('Content-Disposition', $contentDispositionHeader);
+
+ $this->plugin->httpGet($request, $response);
+ }
}
diff --git a/apps/dav/tests/unit/Connector/Sabre/FilesReportPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/FilesReportPluginTest.php
index 41d44efd89c..baf4259b215 100644
--- a/apps/dav/tests/unit/Connector/Sabre/FilesReportPluginTest.php
+++ b/apps/dav/tests/unit/Connector/Sabre/FilesReportPluginTest.php
@@ -343,7 +343,8 @@ class FilesReportPluginTest extends \Test\TestCase {
new \OCA\DAV\Connector\Sabre\FilesPlugin(
$this->tree,
$this->view,
- $config
+ $config,
+ $this->getMock('\OCP\IRequest')
)
);
$this->plugin->initialize($this->server);
diff --git a/apps/dav/tests/unit/Migration/ClassificationTest.php b/apps/dav/tests/unit/Migration/ClassificationTest.php
new file mode 100644
index 00000000000..5c7fa627226
--- /dev/null
+++ b/apps/dav/tests/unit/Migration/ClassificationTest.php
@@ -0,0 +1,75 @@
+<?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\Tests\unit\DAV\Migration;
+
+use OCA\DAV\CalDAV\CalDavBackend;
+use OCA\DAV\Migration\Classification;
+use OCA\DAV\Tests\unit\CalDAV\AbstractCalDavBackendTest;
+use OCP\IUser;
+
+/**
+ * Class ClassificationTest
+ *
+ * @group DB
+ *
+ * @package OCA\DAV\Tests\unit\DAV
+ */
+class ClassificationTest extends AbstractCalDavBackendTest {
+
+ /** @var \PHPUnit_Framework_MockObject_MockObject | \OCP\IUserManager */
+ private $userManager;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->userManager = $this->getMockBuilder('OCP\IUserManager')
+ ->disableOriginalConstructor()->getMock();
+ }
+
+ public function test() {
+ // setup data
+ $calendarId = $this->createTestCalendar();
+ $eventUri = $this->createEvent($calendarId, '20130912T130000Z', '20130912T140000Z');
+ $object = $this->backend->getCalendarObject($calendarId, $eventUri);
+
+ // assert proper classification
+ $this->assertEquals(CalDavBackend::CLASSIFICATION_PUBLIC, $object['classification']);
+ $this->backend->setClassification($object['id'], CalDavBackend::CLASSIFICATION_CONFIDENTIAL);
+ $object = $this->backend->getCalendarObject($calendarId, $eventUri);
+ $this->assertEquals(CalDavBackend::CLASSIFICATION_CONFIDENTIAL, $object['classification']);
+
+ // run migration
+ $c = new Classification($this->backend, $this->userManager);
+
+ /** @var IUser | \PHPUnit_Framework_MockObject_MockObject $user */
+ $user = $this->getMockBuilder('OCP\IUser')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $user->expects($this->once())->method('getUID')->willReturn('caldav-unit-test');
+
+ $c->runForUser($user);
+
+ // assert classification after migration
+ $object = $this->backend->getCalendarObject($calendarId, $eventUri);
+ $this->assertEquals(CalDavBackend::CLASSIFICATION_PUBLIC, $object['classification']);
+ }
+}
diff --git a/apps/encryption/l10n/pl.js b/apps/encryption/l10n/pl.js
index 164a4a36d57..17f73e4fdb7 100644
--- a/apps/encryption/l10n/pl.js
+++ b/apps/encryption/l10n/pl.js
@@ -27,6 +27,8 @@ OC.L10N.register(
"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Nie można odszyfrować tego pliku, prawdopodobnie jest to plik udostępniony. Poproś właściciela pliku o ponowne udostępnianie pliku Tobie.",
"The share will expire on %s." : "Ten zasób wygaśnie %s",
"Cheers!" : "Dzięki!",
+ "Enable recovery key" : "Włącz klucz odzyskiwania",
+ "Disable recovery key" : "Wyłącz klucz odzyskiwania",
"Recovery key password" : "Hasło klucza odzyskiwania",
"Repeat recovery key password" : "Powtórz hasło klucza odzyskiwania",
"Change recovery key password:" : "Zmień hasło klucza odzyskiwania",
diff --git a/apps/encryption/l10n/pl.json b/apps/encryption/l10n/pl.json
index 2bd108ba4c6..f1ef3faf44d 100644
--- a/apps/encryption/l10n/pl.json
+++ b/apps/encryption/l10n/pl.json
@@ -25,6 +25,8 @@
"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Nie można odszyfrować tego pliku, prawdopodobnie jest to plik udostępniony. Poproś właściciela pliku o ponowne udostępnianie pliku Tobie.",
"The share will expire on %s." : "Ten zasób wygaśnie %s",
"Cheers!" : "Dzięki!",
+ "Enable recovery key" : "Włącz klucz odzyskiwania",
+ "Disable recovery key" : "Wyłącz klucz odzyskiwania",
"Recovery key password" : "Hasło klucza odzyskiwania",
"Repeat recovery key password" : "Powtórz hasło klucza odzyskiwania",
"Change recovery key password:" : "Zmień hasło klucza odzyskiwania",
diff --git a/apps/federatedfilesharing/l10n/hu_HU.js b/apps/federatedfilesharing/l10n/hu_HU.js
index 0f0ffdd1295..0a4f26cb20d 100644
--- a/apps/federatedfilesharing/l10n/hu_HU.js
+++ b/apps/federatedfilesharing/l10n/hu_HU.js
@@ -1,10 +1,14 @@
OC.L10N.register(
"federatedfilesharing",
{
+ "Federated sharing" : "Egyesített megosztás",
"Invalid Federated Cloud ID" : "Érvénytelen Egyesített Felhő Azonosító",
"Sharing %s failed, because this item is already shared with %s" : "%s megosztása nem sikerült, mert ez már meg van osztva vele: %s",
"Not allowed to create a federated share with the same user" : "Azonos felhasználóval nem lehet létrehozni egyesített megosztást",
+ "File is already shared with %s" : "Fájl már megosztva vele: %s",
"Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "%s megosztása sikertelen, mert %s nem található; talán a szerver jelenleg nem elérhető.",
+ "You received \"/%3$s\" as a remote share from %1$s (on behalf of %2$s)" : "Kapott egy távoli megosztást: \"/%3$s\", innen: %1$s (%2$s nevében)",
+ "You received \"/%3$s\" as a remote share from %1$s" : "Kapott egy távoli megosztást: \"/%3$s\", innen: %1$s",
"Accept" : "Elfogadás",
"Decline" : "Elutasítás",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Ossza meg velem az #ownCloud Egyesített Felhő Azonosító segítségével, lásd %s",
diff --git a/apps/federatedfilesharing/l10n/hu_HU.json b/apps/federatedfilesharing/l10n/hu_HU.json
index 24e25b6aa4c..77a12ece1a8 100644
--- a/apps/federatedfilesharing/l10n/hu_HU.json
+++ b/apps/federatedfilesharing/l10n/hu_HU.json
@@ -1,8 +1,12 @@
{ "translations": {
+ "Federated sharing" : "Egyesített megosztás",
"Invalid Federated Cloud ID" : "Érvénytelen Egyesített Felhő Azonosító",
"Sharing %s failed, because this item is already shared with %s" : "%s megosztása nem sikerült, mert ez már meg van osztva vele: %s",
"Not allowed to create a federated share with the same user" : "Azonos felhasználóval nem lehet létrehozni egyesített megosztást",
+ "File is already shared with %s" : "Fájl már megosztva vele: %s",
"Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "%s megosztása sikertelen, mert %s nem található; talán a szerver jelenleg nem elérhető.",
+ "You received \"/%3$s\" as a remote share from %1$s (on behalf of %2$s)" : "Kapott egy távoli megosztást: \"/%3$s\", innen: %1$s (%2$s nevében)",
+ "You received \"/%3$s\" as a remote share from %1$s" : "Kapott egy távoli megosztást: \"/%3$s\", innen: %1$s",
"Accept" : "Elfogadás",
"Decline" : "Elutasítás",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Ossza meg velem az #ownCloud Egyesített Felhő Azonosító segítségével, lásd %s",
diff --git a/apps/federation/l10n/pt_PT.js b/apps/federation/l10n/pt_PT.js
index 38ec142b689..c227ab490b7 100644
--- a/apps/federation/l10n/pt_PT.js
+++ b/apps/federation/l10n/pt_PT.js
@@ -6,7 +6,7 @@ OC.L10N.register(
"No ownCloud server found" : "Nenhum servidor ownCloud encontrado",
"Could not add server" : "Não foi possível adicionar servidor",
"Federation" : "Federação",
- "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Federação ownCloud permite-lhe conectar-se com outros ownClouds de confiança para partilhar directórios. Por exemplo, isto será utilizado para auto-completar utilizadores externos para partilhas federadas.",
+ "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "A Federação ownCloud permite-lhe conectar-se com outras ownClouds de confiança para partilhar directorias. Por exemplo, isto será utilizado para auto-completar utilizadores externos para partilhas federadas.",
"Add server automatically once a federated share was created successfully" : "Adicionar o servidor automaticamente assim que uma partilha federada tenha sido criada com sucesso",
"Trusted ownCloud Servers" : "Servidores ownCloud de confiança",
"+ Add ownCloud server" : "+ Adicionar servidor ownCloud",
diff --git a/apps/federation/l10n/pt_PT.json b/apps/federation/l10n/pt_PT.json
index 796a2127170..2316af9c253 100644
--- a/apps/federation/l10n/pt_PT.json
+++ b/apps/federation/l10n/pt_PT.json
@@ -4,7 +4,7 @@
"No ownCloud server found" : "Nenhum servidor ownCloud encontrado",
"Could not add server" : "Não foi possível adicionar servidor",
"Federation" : "Federação",
- "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Federação ownCloud permite-lhe conectar-se com outros ownClouds de confiança para partilhar directórios. Por exemplo, isto será utilizado para auto-completar utilizadores externos para partilhas federadas.",
+ "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "A Federação ownCloud permite-lhe conectar-se com outras ownClouds de confiança para partilhar directorias. Por exemplo, isto será utilizado para auto-completar utilizadores externos para partilhas federadas.",
"Add server automatically once a federated share was created successfully" : "Adicionar o servidor automaticamente assim que uma partilha federada tenha sido criada com sucesso",
"Trusted ownCloud Servers" : "Servidores ownCloud de confiança",
"+ Add ownCloud server" : "+ Adicionar servidor ownCloud",
diff --git a/apps/federation/l10n/ro.js b/apps/federation/l10n/ro.js
index e3035955143..19f37f329a1 100644
--- a/apps/federation/l10n/ro.js
+++ b/apps/federation/l10n/ro.js
@@ -4,6 +4,12 @@ OC.L10N.register(
"Server added to the list of trusted ownClouds" : "Server adăugat la lista serverelor ownCloud de încredere",
"Server is already in the list of trusted servers." : "Serverul este deja pe lista celor de încredere.",
"No ownCloud server found" : "Nu s-a găsit niciun server ownCloud",
- "Could not add server" : "Nu s-a putut adăuga serverul"
+ "Could not add server" : "Nu s-a putut adăuga serverul",
+ "Federation" : "Federare",
+ "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Federarea ownCloud îți permite să te conectezi la alte servere ownCloud de încredere pentru a partaja baza de utilizatori. De exemplu, va permite completarea automată a numelor utilizatorilor externi pentru partajarea federată.",
+ "Add server automatically once a federated share was created successfully" : "Adaugă serverul automat odată ce elementul partajat federat a fost creat cu succes",
+ "Trusted ownCloud Servers" : "Servere ownCloud de încredere",
+ "+ Add ownCloud server" : "+ Adaugă server ownCloud",
+ "ownCloud Server" : "Server ownCloud"
},
"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));");
diff --git a/apps/federation/l10n/ro.json b/apps/federation/l10n/ro.json
index 75c514fd8c8..0acb4ebd962 100644
--- a/apps/federation/l10n/ro.json
+++ b/apps/federation/l10n/ro.json
@@ -2,6 +2,12 @@
"Server added to the list of trusted ownClouds" : "Server adăugat la lista serverelor ownCloud de încredere",
"Server is already in the list of trusted servers." : "Serverul este deja pe lista celor de încredere.",
"No ownCloud server found" : "Nu s-a găsit niciun server ownCloud",
- "Could not add server" : "Nu s-a putut adăuga serverul"
+ "Could not add server" : "Nu s-a putut adăuga serverul",
+ "Federation" : "Federare",
+ "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Federarea ownCloud îți permite să te conectezi la alte servere ownCloud de încredere pentru a partaja baza de utilizatori. De exemplu, va permite completarea automată a numelor utilizatorilor externi pentru partajarea federată.",
+ "Add server automatically once a federated share was created successfully" : "Adaugă serverul automat odată ce elementul partajat federat a fost creat cu succes",
+ "Trusted ownCloud Servers" : "Servere ownCloud de încredere",
+ "+ Add ownCloud server" : "+ Adaugă server ownCloud",
+ "ownCloud Server" : "Server ownCloud"
},"pluralForm" :"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"
} \ No newline at end of file
diff --git a/apps/federation/lib/DAV/FedAuth.php b/apps/federation/lib/DAV/FedAuth.php
index bb1041adcdf..21c0d61487c 100644
--- a/apps/federation/lib/DAV/FedAuth.php
+++ b/apps/federation/lib/DAV/FedAuth.php
@@ -36,6 +36,10 @@ class FedAuth extends AbstractBasic {
public function __construct(DbHandler $db) {
$this->db = $db;
$this->principalPrefix = 'principals/system/';
+
+ // setup realm
+ $defaults = new \OC_Defaults();
+ $this->realm = $defaults->getName();
}
/**
diff --git a/apps/files/l10n/ar.js b/apps/files/l10n/ar.js
index a9093c45a96..ae180fca235 100644
--- a/apps/files/l10n/ar.js
+++ b/apps/files/l10n/ar.js
@@ -41,6 +41,12 @@ OC.L10N.register(
"Pending" : "قيد الانتظار",
"Unable to determine date" : "تعذر تحديد التاريخ",
"This operation is forbidden" : "هذة العملية ممنوعة ",
+ "Could not rename \"{fileName}\"" : "إعادة تسمية الملف \"{fileName}\" لم تنجح",
+ "Could not create file \"{file}\"" : "لا يمكن إنشاء الملف\"{file}\"",
+ "Could not create file \"{file}\" because it already exists" : "لا يمكن إنشاء الملف \"{file}\" فهو موجود بالفعل",
+ "Could not create folder \"{dir}\"" : "لا يمكن إنشاء المجلد \"{dir}\"",
+ "Could not create folder \"{dir}\" because it already exists" : "لا يمكن إنشاء المجلد \"{dir}\" فهو موجود بالفعل",
+ "Error deleting file \"{fileName}\"." : "خطأ أثناء حذف الملف \"{fileName}\".",
"No entries in this folder match '{filter}'" : "لا يوجد مدخلات في هذا المجلد تتوافق مع '{filter}'",
"Name" : "اسم",
"Size" : "حجم",
diff --git a/apps/files/l10n/ar.json b/apps/files/l10n/ar.json
index fe07f30c033..257aa4f1bb4 100644
--- a/apps/files/l10n/ar.json
+++ b/apps/files/l10n/ar.json
@@ -39,6 +39,12 @@
"Pending" : "قيد الانتظار",
"Unable to determine date" : "تعذر تحديد التاريخ",
"This operation is forbidden" : "هذة العملية ممنوعة ",
+ "Could not rename \"{fileName}\"" : "إعادة تسمية الملف \"{fileName}\" لم تنجح",
+ "Could not create file \"{file}\"" : "لا يمكن إنشاء الملف\"{file}\"",
+ "Could not create file \"{file}\" because it already exists" : "لا يمكن إنشاء الملف \"{file}\" فهو موجود بالفعل",
+ "Could not create folder \"{dir}\"" : "لا يمكن إنشاء المجلد \"{dir}\"",
+ "Could not create folder \"{dir}\" because it already exists" : "لا يمكن إنشاء المجلد \"{dir}\" فهو موجود بالفعل",
+ "Error deleting file \"{fileName}\"." : "خطأ أثناء حذف الملف \"{fileName}\".",
"No entries in this folder match '{filter}'" : "لا يوجد مدخلات في هذا المجلد تتوافق مع '{filter}'",
"Name" : "اسم",
"Size" : "حجم",
diff --git a/apps/files/l10n/de.js b/apps/files/l10n/de.js
index 068cbe85376..0866279a435 100644
--- a/apps/files/l10n/de.js
+++ b/apps/files/l10n/de.js
@@ -21,6 +21,7 @@ OC.L10N.register(
"Invalid directory." : "Ungültiges Verzeichnis.",
"Files" : "Dateien",
"All files" : "Alle Dateien",
+ "File could not be found" : "Datei konnte nicht gefunden werden",
"Home" : "Home",
"Close" : "Schließen",
"Favorites" : "Favoriten",
diff --git a/apps/files/l10n/de.json b/apps/files/l10n/de.json
index 2169d228295..0f2939217d9 100644
--- a/apps/files/l10n/de.json
+++ b/apps/files/l10n/de.json
@@ -19,6 +19,7 @@
"Invalid directory." : "Ungültiges Verzeichnis.",
"Files" : "Dateien",
"All files" : "Alle Dateien",
+ "File could not be found" : "Datei konnte nicht gefunden werden",
"Home" : "Home",
"Close" : "Schließen",
"Favorites" : "Favoriten",
diff --git a/apps/files/l10n/de_DE.js b/apps/files/l10n/de_DE.js
index 9a349357a99..6a2f0ab1f59 100644
--- a/apps/files/l10n/de_DE.js
+++ b/apps/files/l10n/de_DE.js
@@ -21,6 +21,7 @@ OC.L10N.register(
"Invalid directory." : "Ungültiges Verzeichnis.",
"Files" : "Dateien",
"All files" : "Alle Dateien",
+ "File could not be found" : "Datei konnte nicht gefunden werden",
"Home" : "Zuhause",
"Close" : "Schließen",
"Favorites" : "Favoriten",
diff --git a/apps/files/l10n/de_DE.json b/apps/files/l10n/de_DE.json
index 9df557e8fa4..047299f9510 100644
--- a/apps/files/l10n/de_DE.json
+++ b/apps/files/l10n/de_DE.json
@@ -19,6 +19,7 @@
"Invalid directory." : "Ungültiges Verzeichnis.",
"Files" : "Dateien",
"All files" : "Alle Dateien",
+ "File could not be found" : "Datei konnte nicht gefunden werden",
"Home" : "Zuhause",
"Close" : "Schließen",
"Favorites" : "Favoriten",
diff --git a/apps/files/l10n/en_GB.js b/apps/files/l10n/en_GB.js
index ec8b821c3e7..82ed2364dd6 100644
--- a/apps/files/l10n/en_GB.js
+++ b/apps/files/l10n/en_GB.js
@@ -21,6 +21,7 @@ OC.L10N.register(
"Invalid directory." : "Invalid directory.",
"Files" : "Files",
"All files" : "All files",
+ "File could not be found" : "File could not be found",
"Home" : "Home",
"Close" : "Close",
"Favorites" : "Favourites",
diff --git a/apps/files/l10n/en_GB.json b/apps/files/l10n/en_GB.json
index 6dae8ba41b7..98b3d2000cb 100644
--- a/apps/files/l10n/en_GB.json
+++ b/apps/files/l10n/en_GB.json
@@ -19,6 +19,7 @@
"Invalid directory." : "Invalid directory.",
"Files" : "Files",
"All files" : "All files",
+ "File could not be found" : "File could not be found",
"Home" : "Home",
"Close" : "Close",
"Favorites" : "Favourites",
diff --git a/apps/files/l10n/fi_FI.js b/apps/files/l10n/fi_FI.js
index 325955a5492..8bf1c47612a 100644
--- a/apps/files/l10n/fi_FI.js
+++ b/apps/files/l10n/fi_FI.js
@@ -21,6 +21,7 @@ OC.L10N.register(
"Invalid directory." : "Virheellinen kansio.",
"Files" : "Tiedostot",
"All files" : "Kaikki tiedostot",
+ "File could not be found" : "TIedostoa ei löytynyt",
"Home" : "Koti",
"Close" : "Sulje",
"Favorites" : "Suosikit",
diff --git a/apps/files/l10n/fi_FI.json b/apps/files/l10n/fi_FI.json
index 966ef7074e4..dc8d168ffb5 100644
--- a/apps/files/l10n/fi_FI.json
+++ b/apps/files/l10n/fi_FI.json
@@ -19,6 +19,7 @@
"Invalid directory." : "Virheellinen kansio.",
"Files" : "Tiedostot",
"All files" : "Kaikki tiedostot",
+ "File could not be found" : "TIedostoa ei löytynyt",
"Home" : "Koti",
"Close" : "Sulje",
"Favorites" : "Suosikit",
diff --git a/apps/files/l10n/it.js b/apps/files/l10n/it.js
index 7d85f952ed4..b560e6623ca 100644
--- a/apps/files/l10n/it.js
+++ b/apps/files/l10n/it.js
@@ -21,6 +21,7 @@ OC.L10N.register(
"Invalid directory." : "Cartella non valida.",
"Files" : "File",
"All files" : "Tutti i file",
+ "File could not be found" : "Il file non può essere trovato",
"Home" : "Home",
"Close" : "Chiudi",
"Favorites" : "Preferiti",
diff --git a/apps/files/l10n/it.json b/apps/files/l10n/it.json
index ec7003f7382..253fc5198aa 100644
--- a/apps/files/l10n/it.json
+++ b/apps/files/l10n/it.json
@@ -19,6 +19,7 @@
"Invalid directory." : "Cartella non valida.",
"Files" : "File",
"All files" : "Tutti i file",
+ "File could not be found" : "Il file non può essere trovato",
"Home" : "Home",
"Close" : "Chiudi",
"Favorites" : "Preferiti",
diff --git a/apps/files/l10n/pl.js b/apps/files/l10n/pl.js
index cb243f6bf4d..a366c6a967c 100644
--- a/apps/files/l10n/pl.js
+++ b/apps/files/l10n/pl.js
@@ -32,6 +32,8 @@ OC.L10N.register(
"Could not get result from server." : "Nie można uzyskać wyniku z serwera.",
"Uploading..." : "Wgrywanie....",
"..." : "...",
+ "{seconds} second{plural_s} left" : "Pozostało sekund: {seconds}",
+ "{seconds}s" : "{seconds} s",
"File upload is in progress. Leaving the page now will cancel the upload." : "Wysyłanie pliku jest w toku. Jeśli opuścisz tę stronę, wysyłanie zostanie przerwane.",
"Actions" : "Akcje",
"Download" : "Pobierz",
diff --git a/apps/files/l10n/pl.json b/apps/files/l10n/pl.json
index 60323d0e757..05b65b2f84a 100644
--- a/apps/files/l10n/pl.json
+++ b/apps/files/l10n/pl.json
@@ -30,6 +30,8 @@
"Could not get result from server." : "Nie można uzyskać wyniku z serwera.",
"Uploading..." : "Wgrywanie....",
"..." : "...",
+ "{seconds} second{plural_s} left" : "Pozostało sekund: {seconds}",
+ "{seconds}s" : "{seconds} s",
"File upload is in progress. Leaving the page now will cancel the upload." : "Wysyłanie pliku jest w toku. Jeśli opuścisz tę stronę, wysyłanie zostanie przerwane.",
"Actions" : "Akcje",
"Download" : "Pobierz",
diff --git a/apps/files/l10n/pt_BR.js b/apps/files/l10n/pt_BR.js
index d8a7097161d..7bc2a94deb1 100644
--- a/apps/files/l10n/pt_BR.js
+++ b/apps/files/l10n/pt_BR.js
@@ -21,6 +21,7 @@ OC.L10N.register(
"Invalid directory." : "Diretório inválido.",
"Files" : "Arquivos",
"All files" : "Todos os arquivos",
+ "File could not be found" : "O arquivo não foi encontrado",
"Home" : "Home",
"Close" : "Fechar",
"Favorites" : "Favoritos",
diff --git a/apps/files/l10n/pt_BR.json b/apps/files/l10n/pt_BR.json
index f5fa97a94af..f16c8c374a6 100644
--- a/apps/files/l10n/pt_BR.json
+++ b/apps/files/l10n/pt_BR.json
@@ -19,6 +19,7 @@
"Invalid directory." : "Diretório inválido.",
"Files" : "Arquivos",
"All files" : "Todos os arquivos",
+ "File could not be found" : "O arquivo não foi encontrado",
"Home" : "Home",
"Close" : "Fechar",
"Favorites" : "Favoritos",
diff --git a/apps/files/l10n/sq.js b/apps/files/l10n/sq.js
index c1485c154d7..b104afdd723 100644
--- a/apps/files/l10n/sq.js
+++ b/apps/files/l10n/sq.js
@@ -21,6 +21,7 @@ OC.L10N.register(
"Invalid directory." : "Drejtori e pavlefshme.",
"Files" : "Kartela",
"All files" : "Krejt kartelat",
+ "File could not be found" : "Kartela s’u gjet dot",
"Home" : "Kreu",
"Close" : "Mbylle",
"Favorites" : "Të parapëlqyera",
diff --git a/apps/files/l10n/sq.json b/apps/files/l10n/sq.json
index 9b40e9f7c9d..80e5f104fa6 100644
--- a/apps/files/l10n/sq.json
+++ b/apps/files/l10n/sq.json
@@ -19,6 +19,7 @@
"Invalid directory." : "Drejtori e pavlefshme.",
"Files" : "Kartela",
"All files" : "Krejt kartelat",
+ "File could not be found" : "Kartela s’u gjet dot",
"Home" : "Kreu",
"Close" : "Mbylle",
"Favorites" : "Të parapëlqyera",
diff --git a/apps/files_external/l10n/pl.js b/apps/files_external/l10n/pl.js
index 8c3e394627e..00ae59b27c6 100644
--- a/apps/files_external/l10n/pl.js
+++ b/apps/files_external/l10n/pl.js
@@ -16,6 +16,7 @@ OC.L10N.register(
"Saved" : "Zapisano",
"Username" : "Nazwa użytkownika",
"Password" : "Hasło",
+ "Credentials required" : "Wymagane poświadczenia",
"Save" : "Zapisz",
"Storage with id \"%i\" not found" : "Id magazynu nie został znaleziony",
"Invalid mount point" : "Nieprawidłowy punkt montowania",
diff --git a/apps/files_external/l10n/pl.json b/apps/files_external/l10n/pl.json
index 8e00fc31863..235de7e9d10 100644
--- a/apps/files_external/l10n/pl.json
+++ b/apps/files_external/l10n/pl.json
@@ -14,6 +14,7 @@
"Saved" : "Zapisano",
"Username" : "Nazwa użytkownika",
"Password" : "Hasło",
+ "Credentials required" : "Wymagane poświadczenia",
"Save" : "Zapisz",
"Storage with id \"%i\" not found" : "Id magazynu nie został znaleziony",
"Invalid mount point" : "Nieprawidłowy punkt montowania",
diff --git a/apps/files_sharing/l10n/pl.js b/apps/files_sharing/l10n/pl.js
index ebdfe2aa738..e1bec669533 100644
--- a/apps/files_sharing/l10n/pl.js
+++ b/apps/files_sharing/l10n/pl.js
@@ -25,6 +25,9 @@ OC.L10N.register(
"Invalid ownCloud url" : "Błędny adres URL",
"Shared by" : "Udostępniane przez",
"Sharing" : "Udostępnianie",
+ "Public link sharing is disabled by the administrator" : "Udostępnianie linków publicznych zostało zablokowane przez twojego administratora",
+ "Public upload disabled by the administrator" : "Publiczne wczytywanie zostało zablokowane przez twojego administratora",
+ "Public upload is only possible for publicly shared folders" : "Publiczne wczytywanie jest możliwe wyłącznie do katalogów publicznych",
"A file or folder has been <strong>shared</strong>" : "Plik lub folder stał się <strong>współdzielony</strong>",
"You shared %1$s with %2$s" : "Współdzielisz %1$s z %2$s",
"You shared %1$s with group %2$s" : "Współdzielisz %1$s z grupą %2$s",
diff --git a/apps/files_sharing/l10n/pl.json b/apps/files_sharing/l10n/pl.json
index f5de5dd368c..6190871b16f 100644
--- a/apps/files_sharing/l10n/pl.json
+++ b/apps/files_sharing/l10n/pl.json
@@ -23,6 +23,9 @@
"Invalid ownCloud url" : "Błędny adres URL",
"Shared by" : "Udostępniane przez",
"Sharing" : "Udostępnianie",
+ "Public link sharing is disabled by the administrator" : "Udostępnianie linków publicznych zostało zablokowane przez twojego administratora",
+ "Public upload disabled by the administrator" : "Publiczne wczytywanie zostało zablokowane przez twojego administratora",
+ "Public upload is only possible for publicly shared folders" : "Publiczne wczytywanie jest możliwe wyłącznie do katalogów publicznych",
"A file or folder has been <strong>shared</strong>" : "Plik lub folder stał się <strong>współdzielony</strong>",
"You shared %1$s with %2$s" : "Współdzielisz %1$s z %2$s",
"You shared %1$s with group %2$s" : "Współdzielisz %1$s z grupą %2$s",
diff --git a/apps/files_sharing/l10n/ro.js b/apps/files_sharing/l10n/ro.js
index 2481f77bcc6..5cddb6e8cdf 100644
--- a/apps/files_sharing/l10n/ro.js
+++ b/apps/files_sharing/l10n/ro.js
@@ -12,12 +12,28 @@ OC.L10N.register(
"Shared with others" : "Partajat cu alții",
"Shared by link" : "Partajat prin link",
"Nothing shared with you yet" : "Nimic nu e partajat cu tine încă",
+ "Files and folders others share with you will show up here" : "Fișierele și directoarele partajate cu tine vor apărea aici",
"Nothing shared yet" : "Nimic partajat încă",
+ "Files and folders you share will show up here" : "Fișierele și directoarele pe care le partajezi vor apărea aici",
+ "No shared links" : "Nicio legătură partajată",
+ "Files and folders you share by link will show up here" : "Fișierele și directoarele pe care le partajezi prin legături vor apărea aici",
+ "Remote share" : "Element partajat la distanță",
+ "Remote share password" : "Parolă element partajat la distanță",
"Cancel" : "Anulare",
+ "Add remote share" : "Adaugă element partajat la distanță",
+ "You can upload into this folder" : "Poți încărca în acest director",
"No ownCloud installation (7 or higher) found at {remote}" : "Nu s-a găsit nicio instanță ownCloud (versiunea 7 sau mai mare) la {remote}",
"Invalid ownCloud url" : "URL ownCloud invalid",
"Shared by" : "impartite in ",
"Sharing" : "Partajare",
+ "Share API is disabled" : "API-ul de partajare este dezactivat",
+ "Wrong share ID, share doesn't exist" : "ID greșit al elementului partajat, acesta nu există",
+ "Could not delete share" : "Nu s-a putut șterge elementul partajat",
+ "Please specify a file or folder path" : "Specifică un fișier sau o cale către un director",
+ "Wrong path, file/folder doesn't exist" : "Cale greșită, fișierul/directorul nu există",
+ "Please specify a valid user" : "Specifică un utilizator valid",
+ "Please specify a valid group" : "Specifică un grup valid",
+ "Invalid date, date format must be YYYY-MM-DD" : "Dată invalidă, formatul trebuie să fie AAAA-LL-ZZ",
"Not a directory" : "Nu este un director",
"Could not lock path" : "Calea nu a putut fi blocată",
"Cannot increase permissions" : "Nu se pot extinde permisiunile",
@@ -26,6 +42,9 @@ OC.L10N.register(
"You shared %1$s with group %2$s" : "Ai partajat %1$s cu grupul %2$s",
"You shared %1$s via link" : "Ai partajat %1$s prin legătură",
"%2$s shared %1$s with you" : "%2$s a partajat %1$s cu tine",
+ "Shared with %2$s" : "Partajat cu %2$s",
+ "Shared with %3$s by %2$s" : "Partajat de %2$s cu %3$s",
+ "Shared with group %2$s" : "Partajat cu grupul %2$s",
"Shares" : "Partajări",
"This share is password-protected" : "Această partajare este protejată cu parolă",
"The password is wrong. Try again." : "Parola este incorectă. Încercaţi din nou.",
@@ -38,6 +57,7 @@ OC.L10N.register(
"sharing is disabled" : "Partajare este oprită",
"Add to your ownCloud" : "Adaugă propriul tău ownCloud",
"Download" : "Descarcă",
- "Download %s" : "Descarcă %s"
+ "Download %s" : "Descarcă %s",
+ "Direct link" : "Legătură directă"
},
"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));");
diff --git a/apps/files_sharing/l10n/ro.json b/apps/files_sharing/l10n/ro.json
index e3f9450bcb5..6d0d87037db 100644
--- a/apps/files_sharing/l10n/ro.json
+++ b/apps/files_sharing/l10n/ro.json
@@ -10,12 +10,28 @@
"Shared with others" : "Partajat cu alții",
"Shared by link" : "Partajat prin link",
"Nothing shared with you yet" : "Nimic nu e partajat cu tine încă",
+ "Files and folders others share with you will show up here" : "Fișierele și directoarele partajate cu tine vor apărea aici",
"Nothing shared yet" : "Nimic partajat încă",
+ "Files and folders you share will show up here" : "Fișierele și directoarele pe care le partajezi vor apărea aici",
+ "No shared links" : "Nicio legătură partajată",
+ "Files and folders you share by link will show up here" : "Fișierele și directoarele pe care le partajezi prin legături vor apărea aici",
+ "Remote share" : "Element partajat la distanță",
+ "Remote share password" : "Parolă element partajat la distanță",
"Cancel" : "Anulare",
+ "Add remote share" : "Adaugă element partajat la distanță",
+ "You can upload into this folder" : "Poți încărca în acest director",
"No ownCloud installation (7 or higher) found at {remote}" : "Nu s-a găsit nicio instanță ownCloud (versiunea 7 sau mai mare) la {remote}",
"Invalid ownCloud url" : "URL ownCloud invalid",
"Shared by" : "impartite in ",
"Sharing" : "Partajare",
+ "Share API is disabled" : "API-ul de partajare este dezactivat",
+ "Wrong share ID, share doesn't exist" : "ID greșit al elementului partajat, acesta nu există",
+ "Could not delete share" : "Nu s-a putut șterge elementul partajat",
+ "Please specify a file or folder path" : "Specifică un fișier sau o cale către un director",
+ "Wrong path, file/folder doesn't exist" : "Cale greșită, fișierul/directorul nu există",
+ "Please specify a valid user" : "Specifică un utilizator valid",
+ "Please specify a valid group" : "Specifică un grup valid",
+ "Invalid date, date format must be YYYY-MM-DD" : "Dată invalidă, formatul trebuie să fie AAAA-LL-ZZ",
"Not a directory" : "Nu este un director",
"Could not lock path" : "Calea nu a putut fi blocată",
"Cannot increase permissions" : "Nu se pot extinde permisiunile",
@@ -24,6 +40,9 @@
"You shared %1$s with group %2$s" : "Ai partajat %1$s cu grupul %2$s",
"You shared %1$s via link" : "Ai partajat %1$s prin legătură",
"%2$s shared %1$s with you" : "%2$s a partajat %1$s cu tine",
+ "Shared with %2$s" : "Partajat cu %2$s",
+ "Shared with %3$s by %2$s" : "Partajat de %2$s cu %3$s",
+ "Shared with group %2$s" : "Partajat cu grupul %2$s",
"Shares" : "Partajări",
"This share is password-protected" : "Această partajare este protejată cu parolă",
"The password is wrong. Try again." : "Parola este incorectă. Încercaţi din nou.",
@@ -36,6 +55,7 @@
"sharing is disabled" : "Partajare este oprită",
"Add to your ownCloud" : "Adaugă propriul tău ownCloud",
"Download" : "Descarcă",
- "Download %s" : "Descarcă %s"
+ "Download %s" : "Descarcă %s",
+ "Direct link" : "Legătură directă"
},"pluralForm" :"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"
} \ No newline at end of file
diff --git a/apps/files_sharing/lib/API/Share20OCS.php b/apps/files_sharing/lib/API/Share20OCS.php
index b10c51ce2c9..3d6a715be99 100644
--- a/apps/files_sharing/lib/API/Share20OCS.php
+++ b/apps/files_sharing/lib/API/Share20OCS.php
@@ -100,15 +100,8 @@ class Share20OCS {
*/
protected function formatShare(\OCP\Share\IShare $share) {
$sharedBy = $this->userManager->get($share->getSharedBy());
- // for federated shares the owner can be a remote user, in this
- // case we use the initiator
- if ($this->userManager->userExists($share->getShareOwner())) {
- $shareOwner = $this->userManager->get($share->getShareOwner());
- $localUser = $share->getShareOwner();
- } else {
- $shareOwner = $this->userManager->get($share->getSharedBy());
- $localUser = $share->getSharedBy();
- }
+ $shareOwner = $this->userManager->get($share->getShareOwner());
+
$result = [
'id' => $share->getId(),
'share_type' => $share->getShareType(),
@@ -123,8 +116,16 @@ class Share20OCS {
'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
];
- $node = $share->getNode();
- $result['path'] = $this->rootFolder->getUserFolder($localUser)->getRelativePath($node->getPath());
+ $userFolder = $this->rootFolder->getUserFolder($this->currentUser->getUID());
+ $nodes = $userFolder->getById($share->getNodeId());
+
+ if (empty($nodes)) {
+ throw new NotFoundException();
+ }
+
+ $node = $nodes[0];
+
+ $result['path'] = $userFolder->getRelativePath($node->getPath());
if ($node instanceOf \OCP\Files\Folder) {
$result['item_type'] = 'folder';
} else {
@@ -536,7 +537,6 @@ class Share20OCS {
$shares = array_merge($shares, $federatedShares);
}
-
$formatted = [];
foreach ($shares as $share) {
try {
diff --git a/apps/files_sharing/tests/API/Share20OCSTest.php b/apps/files_sharing/tests/API/Share20OCSTest.php
index 02b16d7bf88..b760a0f47a0 100644
--- a/apps/files_sharing/tests/API/Share20OCSTest.php
+++ b/apps/files_sharing/tests/API/Share20OCSTest.php
@@ -433,8 +433,12 @@ class Share20OCSTest extends \Test\TestCase {
->method('getRelativePath')
->will($this->returnArgument(0));
+ $userFolder->method('getById')
+ ->with($share->getNodeId())
+ ->willReturn([$share->getNode()]);
+
$this->rootFolder->method('getUserFolder')
- ->with($share->getShareOwner())
+ ->with($this->currentUser->getUID())
->willReturn($userFolder);
$this->urlGenerator
@@ -2006,8 +2010,19 @@ class Share20OCSTest extends \Test\TestCase {
->willReturn('myLink');
- $this->rootFolder->method('getUserFolder')->with($share->getShareOwner())->will($this->returnSelf());
- $this->rootFolder->method('getRelativePath')->will($this->returnArgument(0));
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser->getUID())
+ ->will($this->returnSelf());
+
+ if (!$exception) {
+ $this->rootFolder->method('getById')
+ ->with($share->getNodeId())
+ ->willReturn([$share->getNode()]);
+
+ $this->rootFolder->method('getRelativePath')
+ ->with($share->getNode()->getPath())
+ ->will($this->returnArgument(0));
+ }
try {
$result = $this->invokePrivate($this->ocs, 'formatShare', [$share]);
diff --git a/apps/files_sharing/tests/ApiTest.php b/apps/files_sharing/tests/ApiTest.php
index f44c346236e..058b0c4758c 100644
--- a/apps/files_sharing/tests/ApiTest.php
+++ b/apps/files_sharing/tests/ApiTest.php
@@ -764,8 +764,7 @@ class ApiTest extends TestCase {
// we should get exactly one result
$this->assertCount(1, $data);
- $expectedPath = $this->folder . $this->subfolder;
- $this->assertEquals($expectedPath, $data[0]['path']);
+ $this->assertEquals($this->subfolder, $data[0]['path']);
$this->shareManager->deleteShare($share2);
$this->shareManager->deleteShare($share1);
@@ -801,6 +800,9 @@ class ApiTest extends TestCase {
->setPermissions(1);
$share3 = $this->shareManager->createShare($share3);
+ /*
+ * Test as recipient
+ */
$request = $this->createRequest(['path' => '/', 'subfiles' => 'true']);
$ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER3);
$result = $ocs->getShares();
@@ -811,9 +813,37 @@ class ApiTest extends TestCase {
// we should get exactly one result
$this->assertCount(1, $data);
+ $this->assertEquals($this->subsubfolder, $data[0]['path']);
- $expectedPath = $this->folder . $this->subfolder . $this->subsubfolder;
- $this->assertEquals($expectedPath, $data[0]['path']);
+ /*
+ * Test for first owner/initiator
+ */
+ $request = $this->createRequest([]);
+ $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->getShares();
+ $this->assertTrue($result->succeeded());
+
+ // test should return one share within $this->folder
+ $data = $result->getData();
+
+ // we should get exactly one result
+ $this->assertCount(1, $data);
+ $this->assertEquals($this->folder . $this->subfolder, $data[0]['path']);
+
+ /*
+ * Test for second initiator
+ */
+ $request = $this->createRequest([]);
+ $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER2);
+ $result = $ocs->getShares();
+ $this->assertTrue($result->succeeded());
+
+ // test should return one share within $this->folder
+ $data = $result->getData();
+
+ // we should get exactly one result
+ $this->assertCount(1, $data);
+ $this->assertEquals($this->subfolder . $this->subsubfolder, $data[0]['path']);
$this->shareManager->deleteShare($share1);
$this->shareManager->deleteShare($share2);
@@ -922,8 +952,7 @@ class ApiTest extends TestCase {
// we should get exactly one result
$this->assertCount(1, $data);
- $expectedPath = $this->folder.$this->subfolder.$this->filename;
- $this->assertEquals($expectedPath, $data[0]['path']);
+ $this->assertEquals($this->filename, $data[0]['path']);
$this->shareManager->deleteShare($share1);
$this->shareManager->deleteShare($share2);
diff --git a/apps/systemtags/l10n/hu_HU.js b/apps/systemtags/l10n/hu_HU.js
index 13d1705ff1c..783b90ece8a 100644
--- a/apps/systemtags/l10n/hu_HU.js
+++ b/apps/systemtags/l10n/hu_HU.js
@@ -21,6 +21,7 @@ OC.L10N.register(
"%1$s assigned system tag %3$s to %2$s" : "%1$s hozzárendelte ezt a rendszer címkét: %3$s neki: %2$s",
"You unassigned system tag %3$s from %2$s" : "%3$s rendszer címke hozzárendelést elvette tőle: %2$s",
"%1$s unassigned system tag %3$s from %2$s" : "%1$s elvette ezt a rendszer címkét %3$s tőle: %2$s",
+ "%s (restricted)" : "%s (korlátozott)",
"%s (invisible)" : "%s (láthatatlan)",
"No files in here" : "Itt nincsenek fájlok",
"No entries found in this folder" : "Nincsenek bejegyzések ebben a könyvtárban",
diff --git a/apps/systemtags/l10n/hu_HU.json b/apps/systemtags/l10n/hu_HU.json
index 6408b3a5314..f89da5d3dfd 100644
--- a/apps/systemtags/l10n/hu_HU.json
+++ b/apps/systemtags/l10n/hu_HU.json
@@ -19,6 +19,7 @@
"%1$s assigned system tag %3$s to %2$s" : "%1$s hozzárendelte ezt a rendszer címkét: %3$s neki: %2$s",
"You unassigned system tag %3$s from %2$s" : "%3$s rendszer címke hozzárendelést elvette tőle: %2$s",
"%1$s unassigned system tag %3$s from %2$s" : "%1$s elvette ezt a rendszer címkét %3$s tőle: %2$s",
+ "%s (restricted)" : "%s (korlátozott)",
"%s (invisible)" : "%s (láthatatlan)",
"No files in here" : "Itt nincsenek fájlok",
"No entries found in this folder" : "Nincsenek bejegyzések ebben a könyvtárban",
diff --git a/apps/updatenotification/l10n/hu_HU.js b/apps/updatenotification/l10n/hu_HU.js
index 1df38a6746f..cce4549f01e 100644
--- a/apps/updatenotification/l10n/hu_HU.js
+++ b/apps/updatenotification/l10n/hu_HU.js
@@ -1,8 +1,11 @@
OC.L10N.register(
"updatenotification",
{
+ "Update notifications" : "Frissítési értesítés",
"{version} is available. Get more information on how to update." : "{version} rendelkezésre áll. További információ a frissítéshez.",
"Updated channel" : "Frissített csatorna",
+ "ownCloud core" : "ownCloud mag",
+ "Update for %1$s to version %2$s is available." : "%1$s frissíthető %2$s verzióra.",
"Updater" : "Frissítéskezelő",
"A new version is available: %s" : "Új verzió érhető el: %s",
"Open updater" : "Frissítő megnyitása",
diff --git a/apps/updatenotification/l10n/hu_HU.json b/apps/updatenotification/l10n/hu_HU.json
index eb953669ab1..952b499d52a 100644
--- a/apps/updatenotification/l10n/hu_HU.json
+++ b/apps/updatenotification/l10n/hu_HU.json
@@ -1,6 +1,9 @@
{ "translations": {
+ "Update notifications" : "Frissítési értesítés",
"{version} is available. Get more information on how to update." : "{version} rendelkezésre áll. További információ a frissítéshez.",
"Updated channel" : "Frissített csatorna",
+ "ownCloud core" : "ownCloud mag",
+ "Update for %1$s to version %2$s is available." : "%1$s frissíthető %2$s verzióra.",
"Updater" : "Frissítéskezelő",
"A new version is available: %s" : "Új verzió érhető el: %s",
"Open updater" : "Frissítő megnyitása",
diff --git a/apps/user_ldap/l10n/pl.js b/apps/user_ldap/l10n/pl.js
index de8f1f49ad3..a75b38fc12f 100644
--- a/apps/user_ldap/l10n/pl.js
+++ b/apps/user_ldap/l10n/pl.js
@@ -31,6 +31,7 @@ OC.L10N.register(
"Confirm Deletion" : "Potwierdź usunięcie",
"Mappings cleared successfully!" : "Mapowanie wyczyszczone!",
"Error while clearing the mappings." : "Błąd podczas czyszczenia mapowania.",
+ "Mode switch" : "Przełącznik trybów",
"Select attributes" : "Wybierz atrybuty",
"_%s group found_::_%s groups found_" : ["%s znaleziona grupa","%s znalezionych grup","%s znalezionych grup"],
"_%s user found_::_%s users found_" : ["%s znaleziony użytkownik","%s znalezionych użytkowników","%s znalezionych użytkowników"],
diff --git a/apps/user_ldap/l10n/pl.json b/apps/user_ldap/l10n/pl.json
index 5a853c3abed..472148fa3b0 100644
--- a/apps/user_ldap/l10n/pl.json
+++ b/apps/user_ldap/l10n/pl.json
@@ -29,6 +29,7 @@
"Confirm Deletion" : "Potwierdź usunięcie",
"Mappings cleared successfully!" : "Mapowanie wyczyszczone!",
"Error while clearing the mappings." : "Błąd podczas czyszczenia mapowania.",
+ "Mode switch" : "Przełącznik trybów",
"Select attributes" : "Wybierz atrybuty",
"_%s group found_::_%s groups found_" : ["%s znaleziona grupa","%s znalezionych grup","%s znalezionych grup"],
"_%s user found_::_%s users found_" : ["%s znaleziony użytkownik","%s znalezionych użytkowników","%s znalezionych użytkowników"],
diff --git a/apps/user_ldap/lib/Group_LDAP.php b/apps/user_ldap/lib/Group_LDAP.php
index 7c12613f34d..14d86fb0619 100644
--- a/apps/user_ldap/lib/Group_LDAP.php
+++ b/apps/user_ldap/lib/Group_LDAP.php
@@ -535,7 +535,7 @@ class Group_LDAP extends BackendUtility implements \OCP\GroupInterface {
}
if(isset($this->cachedGroupsByMember[$uid])) {
- $groups[] = $this->cachedGroupsByMember[$uid];
+ $groups = array_merge($groups, $this->cachedGroupsByMember[$uid]);
} else {
$groupsByMember = array_values($this->getGroupsByMember($uid));
$groupsByMember = $this->access->ownCloudGroupNames($groupsByMember);
diff --git a/apps/user_ldap/tests/Group_LDAPTest.php b/apps/user_ldap/tests/Group_LDAPTest.php
index 556c4b0b394..35d525068a6 100644
--- a/apps/user_ldap/tests/Group_LDAPTest.php
+++ b/apps/user_ldap/tests/Group_LDAPTest.php
@@ -454,4 +454,57 @@ class Group_LDAPTest extends \Test\TestCase {
$groupBackend->getUserGroups('userX');
}
+ public function testGetGroupsByMember() {
+ $access = $this->getAccessMock();
+
+ $access->connection->expects($this->any())
+ ->method('__get')
+ ->will($this->returnCallback(function($name) {
+ if($name === 'useMemberOfToDetectMembership') {
+ return 0;
+ } else if($name === 'ldapDynamicGroupMemberURL') {
+ return '';
+ } else if($name === 'ldapNestedGroups') {
+ return false;
+ }
+ return 1;
+ }));
+
+ $dn = 'cn=userX,dc=foobar';
+
+ $access->connection->hasPrimaryGroups = false;
+
+ $access->expects($this->exactly(2))
+ ->method('username2dn')
+ ->will($this->returnValue($dn));
+
+ $access->expects($this->never())
+ ->method('readAttribute')
+ ->with($dn, 'memberOf');
+
+ $group1 = [
+ 'cn' => 'group1',
+ 'dn' => ['cn=group1,ou=groups,dc=domain,dc=com'],
+ ];
+ $group2 = [
+ 'cn' => 'group2',
+ 'dn' => ['cn=group2,ou=groups,dc=domain,dc=com'],
+ ];
+
+ $access->expects($this->once())
+ ->method('ownCloudGroupNames')
+ ->with([$group1, $group2])
+ ->will($this->returnValue(['group1', 'group2']));
+
+ $access->expects($this->once())
+ ->method('fetchListOfGroups')
+ ->will($this->returnValue([$group1, $group2]));
+
+ $groupBackend = new GroupLDAP($access);
+ $groups = $groupBackend->getUserGroups('userX');
+ $this->assertEquals(['group1', 'group2'], $groups);
+
+ $groupsAgain = $groupBackend->getUserGroups('userX');
+ $this->assertEquals(['group1', 'group2'], $groupsAgain);
+ }
}