Merge branch 'master' of https://github.com/owncloud/core into downstream-160611
This commit is contained in:
commit
42c66efea5
|
@ -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);");
|
||||
|
|
|
@ -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);"
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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)))
|
||||
|
@ -667,6 +677,23 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
|
|||
return '"' . $extraData['etag'] . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
|
@ -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,
|
||||
'firstOccurence' => is_null($firstOccurrence) ? null : max(0, $firstOccurrence),
|
||||
'lastOccurence' => $lastOccurrence,
|
||||
'uid' => $uid,
|
||||
'classification' => $classification
|
||||
];
|
||||
|
||||
}
|
||||
|
|
|
@ -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']);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
@ -95,20 +96,29 @@ 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) {
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -141,6 +141,7 @@ class Server {
|
|||
$this->server->tree,
|
||||
$view,
|
||||
\OC::$server->getConfig(),
|
||||
$this->request,
|
||||
false,
|
||||
!\OC::$server->getConfig()->getSystemValue('debug', false)
|
||||
)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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']);
|
||||
}
|
||||
}
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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));");
|
||||
|
|
|
@ -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));"
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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" : "حجم",
|
||||
|
|
|
@ -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" : "حجم",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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));");
|
||||
|
|
|
@ -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));"
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
$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 {
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"],
|
||||
|
|
|
@ -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"],
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ Feature: webdav-related
|
|||
And As an "admin"
|
||||
When Downloading file "/welcome.txt"
|
||||
Then The following headers should be set
|
||||
|Content-Disposition|attachment|
|
||||
|Content-Disposition|attachment; filename*=UTF-8''welcome.txt; filename="welcome.txt"|
|
||||
|Content-Security-Policy|default-src 'none';|
|
||||
|X-Content-Type-Options |nosniff|
|
||||
|X-Download-Options|noopen|
|
||||
|
@ -97,7 +97,7 @@ Feature: webdav-related
|
|||
And As an "admin"
|
||||
When Downloading file "/welcome.txt"
|
||||
Then The following headers should be set
|
||||
|Content-Disposition|attachment|
|
||||
|Content-Disposition|attachment; filename*=UTF-8''welcome.txt; filename="welcome.txt"|
|
||||
|Content-Security-Policy|default-src 'none';|
|
||||
|X-Content-Type-Options |nosniff|
|
||||
|X-Download-Options|noopen|
|
||||
|
|
|
@ -106,7 +106,12 @@ class Install extends Command {
|
|||
$dbUser = $input->getOption('database-user');
|
||||
$dbPass = $input->getOption('database-pass');
|
||||
$dbName = $input->getOption('database-name');
|
||||
if ($db === 'oci') {
|
||||
// an empty hostname needs to be read from the raw parameters
|
||||
$dbHost = $input->getParameterOption('--database-host', '');
|
||||
} else {
|
||||
$dbHost = $input->getOption('database-host');
|
||||
}
|
||||
$dbTablePrefix = 'oc_';
|
||||
if ($input->hasParameterOption('--database-table-prefix')) {
|
||||
$dbTablePrefix = (string) $input->getOption('database-table-prefix');
|
||||
|
|
|
@ -171,6 +171,7 @@ class LoginController extends Controller {
|
|||
* @return RedirectResponse
|
||||
*/
|
||||
public function tryLogin($user, $password, $redirect_url) {
|
||||
$originalUser = $user;
|
||||
// TODO: Add all the insane error handling
|
||||
/* @var $loginResult IUser */
|
||||
$loginResult = $this->userManager->checkPassword($user, $password);
|
||||
|
@ -186,8 +187,8 @@ class LoginController extends Controller {
|
|||
$this->session->set('loginMessages', [
|
||||
['invalidpassword']
|
||||
]);
|
||||
// Read current user and append if possible
|
||||
$args = !is_null($user) ? ['user' => $user] : [];
|
||||
// Read current user and append if possible - we need to return the unmodified user otherwise we will leak the login name
|
||||
$args = !is_null($user) ? ['user' => $originalUser] : [];
|
||||
return new RedirectResponse($this->urlGenerator->linkToRoute('core.login.showLoginForm', $args));
|
||||
}
|
||||
// TODO: remove password checks from above and let the user session handle failures
|
||||
|
|
|
@ -298,6 +298,7 @@ OC.L10N.register(
|
|||
"Thank you for your patience." : "Vielen Dank für Deine Geduld.",
|
||||
"Two-step verification" : "Bestätigung in zwei Schritten",
|
||||
"Enhanced security has been enabled for your account. Please authenticate using a second factor." : "Die erweiterte Sicherheit wurde für dich Konto aktiviert. Bitte authentifiziere dich mit einem zweiten Faktor. ",
|
||||
"Cancel login" : "Anmelden abbrechen",
|
||||
"Please authenticate using the selected factor." : "Bitte authentifiziere dich mit dem ausgewählten zweiten Faktor. ",
|
||||
"An error occured while verifying the token" : "Es ist ein Fehler bei der Verifizierung des Tokens aufgetreten",
|
||||
"You are accessing the server from an untrusted domain." : "Du greifst von einer nicht vertrauenswürdigen Domain auf den Server zu.",
|
||||
|
|
|
@ -296,6 +296,7 @@
|
|||
"Thank you for your patience." : "Vielen Dank für Deine Geduld.",
|
||||
"Two-step verification" : "Bestätigung in zwei Schritten",
|
||||
"Enhanced security has been enabled for your account. Please authenticate using a second factor." : "Die erweiterte Sicherheit wurde für dich Konto aktiviert. Bitte authentifiziere dich mit einem zweiten Faktor. ",
|
||||
"Cancel login" : "Anmelden abbrechen",
|
||||
"Please authenticate using the selected factor." : "Bitte authentifiziere dich mit dem ausgewählten zweiten Faktor. ",
|
||||
"An error occured while verifying the token" : "Es ist ein Fehler bei der Verifizierung des Tokens aufgetreten",
|
||||
"You are accessing the server from an untrusted domain." : "Du greifst von einer nicht vertrauenswürdigen Domain auf den Server zu.",
|
||||
|
|
|
@ -298,6 +298,7 @@ OC.L10N.register(
|
|||
"Thank you for your patience." : "Vielen Dank für Ihre Geduld.",
|
||||
"Two-step verification" : "Bestätigung in zwei Schritten",
|
||||
"Enhanced security has been enabled for your account. Please authenticate using a second factor." : "Die erweiterte Sicherheit wurde für Ihr Konto aktiviert. Bitte authentifizieren Sie sich mit einem zweiten Faktor. ",
|
||||
"Cancel login" : "Anmelden abbrechen",
|
||||
"Please authenticate using the selected factor." : "Bitte authentifizieren Sie sich mit dem ausgewählten zweiten Faktor. ",
|
||||
"An error occured while verifying the token" : "Es ist ein Fehler bei der Verifizierung des Tokens aufgetreten",
|
||||
"You are accessing the server from an untrusted domain." : "Sie greifen von einer nicht vertrauenswürdigen Domain auf den Server zu.",
|
||||
|
|
|
@ -296,6 +296,7 @@
|
|||
"Thank you for your patience." : "Vielen Dank für Ihre Geduld.",
|
||||
"Two-step verification" : "Bestätigung in zwei Schritten",
|
||||
"Enhanced security has been enabled for your account. Please authenticate using a second factor." : "Die erweiterte Sicherheit wurde für Ihr Konto aktiviert. Bitte authentifizieren Sie sich mit einem zweiten Faktor. ",
|
||||
"Cancel login" : "Anmelden abbrechen",
|
||||
"Please authenticate using the selected factor." : "Bitte authentifizieren Sie sich mit dem ausgewählten zweiten Faktor. ",
|
||||
"An error occured while verifying the token" : "Es ist ein Fehler bei der Verifizierung des Tokens aufgetreten",
|
||||
"You are accessing the server from an untrusted domain." : "Sie greifen von einer nicht vertrauenswürdigen Domain auf den Server zu.",
|
||||
|
|
|
@ -298,6 +298,7 @@ OC.L10N.register(
|
|||
"Thank you for your patience." : "Thank you for your patience.",
|
||||
"Two-step verification" : "Two-step verification",
|
||||
"Enhanced security has been enabled for your account. Please authenticate using a second factor." : "Enhanced security has been enabled for your account. Please authenticate using a second factor.",
|
||||
"Cancel login" : "Cancel login",
|
||||
"Please authenticate using the selected factor." : "Please authenticate using the selected factor.",
|
||||
"An error occured while verifying the token" : "An error occured while verifying the token",
|
||||
"You are accessing the server from an untrusted domain." : "You are accessing the server from an untrusted domain.",
|
||||
|
|
|
@ -296,6 +296,7 @@
|
|||
"Thank you for your patience." : "Thank you for your patience.",
|
||||
"Two-step verification" : "Two-step verification",
|
||||
"Enhanced security has been enabled for your account. Please authenticate using a second factor." : "Enhanced security has been enabled for your account. Please authenticate using a second factor.",
|
||||
"Cancel login" : "Cancel login",
|
||||
"Please authenticate using the selected factor." : "Please authenticate using the selected factor.",
|
||||
"An error occured while verifying the token" : "An error occured while verifying the token",
|
||||
"You are accessing the server from an untrusted domain." : "You are accessing the server from an untrusted domain.",
|
||||
|
|
|
@ -187,6 +187,7 @@ OC.L10N.register(
|
|||
"Warning" : "Varoitus",
|
||||
"Error while sending notification" : "Virhe ilmoitusta lähettäessä",
|
||||
"Non-existing tag #{tag}" : "Ei olemassa oleva tunniste #{tag}",
|
||||
"restricted" : "rajoitettu",
|
||||
"invisible" : "näkymätön",
|
||||
"({scope})" : "({scope})",
|
||||
"Delete" : "Poista",
|
||||
|
@ -289,6 +290,7 @@ OC.L10N.register(
|
|||
"Thank you for your patience." : "Kiitos kärsivällisyydestäsi.",
|
||||
"Two-step verification" : "Kaksivaiheinen vahvistus",
|
||||
"Enhanced security has been enabled for your account. Please authenticate using a second factor." : "Tililläsi on käytössä lisäturvatoimia. Tunnistaudu käyttäen kaksivaiheista vahvistusta.",
|
||||
"Cancel login" : "Peru kirjautuminen",
|
||||
"Please authenticate using the selected factor." : "Tunnistaudu käyttäen valittua vahvistusta.",
|
||||
"You are accessing the server from an untrusted domain." : "Olet yhteydessä palvelimeen epäluotettavasta verkko-osoitteesta.",
|
||||
"Please contact your administrator. If you are an administrator of this instance, configure the \"trusted_domains\" setting in config/config.php. An example configuration is provided in config/config.sample.php." : "Ota yhteys ylläpitoon. Jos olet tämän asennuksen ylläpitäjä, määritä \"trusted_domains\"-asetus config/config.php-tiedostossa. Esimerkkimääritys on tarjolla tiedostossa config/config.sample.php.",
|
||||
|
|
|
@ -185,6 +185,7 @@
|
|||
"Warning" : "Varoitus",
|
||||
"Error while sending notification" : "Virhe ilmoitusta lähettäessä",
|
||||
"Non-existing tag #{tag}" : "Ei olemassa oleva tunniste #{tag}",
|
||||
"restricted" : "rajoitettu",
|
||||
"invisible" : "näkymätön",
|
||||
"({scope})" : "({scope})",
|
||||
"Delete" : "Poista",
|
||||
|
@ -287,6 +288,7 @@
|
|||
"Thank you for your patience." : "Kiitos kärsivällisyydestäsi.",
|
||||
"Two-step verification" : "Kaksivaiheinen vahvistus",
|
||||
"Enhanced security has been enabled for your account. Please authenticate using a second factor." : "Tililläsi on käytössä lisäturvatoimia. Tunnistaudu käyttäen kaksivaiheista vahvistusta.",
|
||||
"Cancel login" : "Peru kirjautuminen",
|
||||
"Please authenticate using the selected factor." : "Tunnistaudu käyttäen valittua vahvistusta.",
|
||||
"You are accessing the server from an untrusted domain." : "Olet yhteydessä palvelimeen epäluotettavasta verkko-osoitteesta.",
|
||||
"Please contact your administrator. If you are an administrator of this instance, configure the \"trusted_domains\" setting in config/config.php. An example configuration is provided in config/config.sample.php." : "Ota yhteys ylläpitoon. Jos olet tämän asennuksen ylläpitäjä, määritä \"trusted_domains\"-asetus config/config.php-tiedostossa. Esimerkkimääritys on tarjolla tiedostossa config/config.sample.php.",
|
||||
|
|
|
@ -298,6 +298,7 @@ OC.L10N.register(
|
|||
"Thank you for your patience." : "Grazie per la pazienza.",
|
||||
"Two-step verification" : "Verifica in due fasi",
|
||||
"Enhanced security has been enabled for your account. Please authenticate using a second factor." : "La sicurezza migliorata è stata abilitata per il tuo account. Autenticati utilizzando un secondo fattore.",
|
||||
"Cancel login" : "Annulla l'accesso",
|
||||
"Please authenticate using the selected factor." : "Autentica utilizzando il fattore selezionato.",
|
||||
"An error occured while verifying the token" : "Si è verificato un errore durante la verifica del token",
|
||||
"You are accessing the server from an untrusted domain." : "Stai accedendo al server da un dominio non attendibile.",
|
||||
|
|
|
@ -296,6 +296,7 @@
|
|||
"Thank you for your patience." : "Grazie per la pazienza.",
|
||||
"Two-step verification" : "Verifica in due fasi",
|
||||
"Enhanced security has been enabled for your account. Please authenticate using a second factor." : "La sicurezza migliorata è stata abilitata per il tuo account. Autenticati utilizzando un secondo fattore.",
|
||||
"Cancel login" : "Annulla l'accesso",
|
||||
"Please authenticate using the selected factor." : "Autentica utilizzando il fattore selezionato.",
|
||||
"An error occured while verifying the token" : "Si è verificato un errore durante la verifica del token",
|
||||
"You are accessing the server from an untrusted domain." : "Stai accedendo al server da un dominio non attendibile.",
|
||||
|
|
|
@ -298,6 +298,7 @@ OC.L10N.register(
|
|||
"Thank you for your patience." : "Obrigado pela sua paciência.",
|
||||
"Two-step verification" : "Verificação em dois passos",
|
||||
"Enhanced security has been enabled for your account. Please authenticate using a second factor." : "Segurança reforçada foi ativada para sua conta. Por favor autenticar usando um segundo fator.",
|
||||
"Cancel login" : "Cancelar o login",
|
||||
"Please authenticate using the selected factor." : "Por favor autenticar usando o fator selecionado.",
|
||||
"An error occured while verifying the token" : "Ocorreu um erro ao verificar o token",
|
||||
"You are accessing the server from an untrusted domain." : "Você está acessando o servidor a partir de um domínio não confiável.",
|
||||
|
|
|
@ -296,6 +296,7 @@
|
|||
"Thank you for your patience." : "Obrigado pela sua paciência.",
|
||||
"Two-step verification" : "Verificação em dois passos",
|
||||
"Enhanced security has been enabled for your account. Please authenticate using a second factor." : "Segurança reforçada foi ativada para sua conta. Por favor autenticar usando um segundo fator.",
|
||||
"Cancel login" : "Cancelar o login",
|
||||
"Please authenticate using the selected factor." : "Por favor autenticar usando o fator selecionado.",
|
||||
"An error occured while verifying the token" : "Ocorreu um erro ao verificar o token",
|
||||
"You are accessing the server from an untrusted domain." : "Você está acessando o servidor a partir de um domínio não confiável.",
|
||||
|
|
|
@ -8,23 +8,37 @@ OC.L10N.register(
|
|||
"Unknown filetype" : "Tip fișier necunoscut",
|
||||
"Invalid image" : "Imagine invalidă",
|
||||
"An error occurred. Please contact your admin." : "A apărut o eroare. Te rugăm să contactezi administratorul.",
|
||||
"No temporary profile picture available, try again" : "Nu este disponibilă nicio imagine temporară a profilului, încearcă din nou",
|
||||
"%s password reset" : "%s resetare parola",
|
||||
"Couldn't send reset email. Please contact your administrator." : "Expedierea email-ului de resetare a eşuat. Vă rugăm să contactaţi administratorul dvs.",
|
||||
"Error loading tags" : "Eroare la încărcarea etichetelor",
|
||||
"Tag already exists" : "Eticheta deja există",
|
||||
"Error deleting tag(s)" : "Eroare la ștergerea etichetei(-lor)",
|
||||
"Error tagging" : "Eroare la etichetare",
|
||||
"Error untagging" : "Eroare la scoaterea etichetei",
|
||||
"Error favoriting" : "Eroare la adăugarea la favorite",
|
||||
"Error unfavoriting" : "Eroare la scoaterea de la favorite",
|
||||
"Couldn't send mail to following users: %s " : "Nu s-a putut trimite mesajul către următorii utilizatori: %s",
|
||||
"Preparing update" : "Se pregătește actualizarea",
|
||||
"[%d / %d]: %s" : "[%d / %d]: %s",
|
||||
"Repair warning: " : "Alerte reparare:",
|
||||
"Repair error: " : "Eroare de reparare:",
|
||||
"[%d / %d]: Checking table %s" : "[%d / %d]: Se verifică tabela %s",
|
||||
"Turned on maintenance mode" : "Modul mentenanță a fost activat",
|
||||
"Turned off maintenance mode" : "Modul mentenanță a fost dezactivat",
|
||||
"Maintenance mode is kept active" : "Modul de mentenanță este menținut activ",
|
||||
"Updating database schema" : "Se actualizează schema bazei de date",
|
||||
"Updated database" : "Bază de date actualizată",
|
||||
"Checking whether the database schema can be updated (this can take a long time depending on the database size)" : "Se verifică dacă schema bazei de date poate fi actualizată (această verificare poate lua mult timp în funcție de mărimea bazei de date)",
|
||||
"Checking updates of apps" : "Se verifică actualizările aplicațiilor",
|
||||
"Updated \"%s\" to %s" : "\"%s\" a fost actualizat până la %s",
|
||||
"Set log level to debug" : "Setează nivelul de logare la \"debug\"",
|
||||
"Reset log level" : "Resetează nivelul de logare",
|
||||
"Starting code integrity check" : "Începe verificarea integrității codului",
|
||||
"Finished code integrity check" : "Verificarea integrității codului a fost finalizată",
|
||||
"%s (3rdparty)" : "%s (terță parte)",
|
||||
"%s (incompatible)" : "%s (incompatibil)",
|
||||
"Following apps have been disabled: %s" : "Următoarele aplicații au fost dezactivate: %s",
|
||||
"Already up to date" : "Deja actualizat",
|
||||
"Sunday" : "Duminică",
|
||||
"Monday" : "Luni",
|
||||
|
@ -71,9 +85,11 @@ OC.L10N.register(
|
|||
"Oct." : "Oct.",
|
||||
"Nov." : "Noi.",
|
||||
"Dec." : "Dec.",
|
||||
"<a href=\"{docUrl}\">There were problems with the code integrity check. More information…</a>" : "<a href=\"{docUrl}\">Au apărut probleme la verificarea integrității codului. Mai multe informații…</a>",
|
||||
"Settings" : "Setări",
|
||||
"Problem loading page, reloading in 5 seconds" : "A apărut o problemă la încărcarea paginii, se reîncearcă în 5 secunde",
|
||||
"Saving..." : "Se salvează...",
|
||||
"Dismiss" : "Înlătură",
|
||||
"seconds ago" : "secunde în urmă",
|
||||
"I know what I'm doing" : "Eu știu ce fac",
|
||||
"Password can not be changed. Please contact your administrator." : "Parola nu poate fi modificată. Vă rugăm să contactați administratorul dvs.",
|
||||
|
@ -135,24 +151,39 @@ OC.L10N.register(
|
|||
"access control" : "control acces",
|
||||
"Could not unshare" : "Nu s-a putut elimina partajarea",
|
||||
"Share details could not be loaded for this item." : "Nu s-au putut încărca detaliile de partajare pentru acest element.",
|
||||
"An error occurred. Please try again" : "A apărut o eroare. Încearcă din nou",
|
||||
"Share" : "Partajează",
|
||||
"Share with people on other ownClouds using the syntax username@example.com/owncloud" : "Partajează cu persoane din alte instanțe ownCloud folosind sintaxa nume_utilizator@exemplu.com/owncloud",
|
||||
"Share with users…" : "Partajează cu utilizatori...",
|
||||
"Share with users or groups…" : "Partajează cu utilizatori sau grupuri...",
|
||||
"Error removing share" : "Eroare la înlăturarea elementului partajat",
|
||||
"Warning" : "Atenție",
|
||||
"Error while sending notification" : "Eroare la trimiterea notificării",
|
||||
"Non-existing tag #{tag}" : "Etichetă inexistentă #{tag}",
|
||||
"restricted" : "restricționat",
|
||||
"invisible" : "invizibil",
|
||||
"Delete" : "Șterge",
|
||||
"Rename" : "Redenumește",
|
||||
"Collaborative tags" : "Etichete colaborative",
|
||||
"The object type is not specified." : "Tipul obiectului nu este specificat.",
|
||||
"Enter new" : "Introducere nou",
|
||||
"Add" : "Adaugă",
|
||||
"Edit tags" : "Editează etichete",
|
||||
"No tags selected for deletion." : "Nu au fost selectate etichete pentru ștergere.",
|
||||
"unknown text" : "text necunoscut",
|
||||
"Hello world!" : "Hello world!",
|
||||
"sunny" : "însorit",
|
||||
"Hello {name}" : "Salut {name}",
|
||||
"new" : "nou",
|
||||
"The upgrade is in progress, leaving this page might interrupt the process in some environments." : "Actualizarea este în progres, părăsirea acestei pagini ar putea duce la întreruperea procesului în unele medii.",
|
||||
"Updating to {version}" : "Actualizare la {version}",
|
||||
"An error occurred." : "A apărut o eroare.",
|
||||
"Please reload the page." : "Te rugăm să reîncarci pagina.",
|
||||
"The update was unsuccessful. Please report this issue to the <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud community</a>." : "Actualizarea a eșuat! Raportați problema către <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">comunitatea ownCloud</a>.",
|
||||
"The update was successful. There were warnings." : "Actualizarea nu a avut loc cu succes. Au existat avertismente.",
|
||||
"The update was successful. Redirecting you to ownCloud now." : "Actualizare reușită. Ești redirecționat către ownCloud.",
|
||||
"Searching other places" : "Se caută în alte locuri",
|
||||
"No search results in other folders" : "Nu există rezultate ale căutării în alte directoare",
|
||||
"Personal" : "Personal",
|
||||
"Users" : "Utilizatori",
|
||||
"Apps" : "Aplicații",
|
||||
|
@ -160,8 +191,12 @@ OC.L10N.register(
|
|||
"Help" : "Ajutor",
|
||||
"Access forbidden" : "Acces restricționat",
|
||||
"File not found" : "Fișierul nu a fost găsit",
|
||||
"The specified document has not been found on the server." : "Documentul specificat nu a fost găsit pe server.",
|
||||
"You can click here to return to %s." : "Poți da click aici pentru a te întoarce la %s.",
|
||||
"The share will expire on %s." : "Partajarea va expira în data de %s.",
|
||||
"Cheers!" : "Noroc!",
|
||||
"Internal Server Error" : "Eroare internă a serverului",
|
||||
"The server encountered an internal error and was unable to complete your request." : "Serverul a întâmpinat o eroare și nu îți poate îndeplini cererea.",
|
||||
"Technical details" : "Detalii tehnice",
|
||||
"Type: %s" : "Tip: %s",
|
||||
"Code: %s" : "Cod: %s",
|
||||
|
@ -190,16 +225,35 @@ OC.L10N.register(
|
|||
"See the documentation" : "Vezi documentația",
|
||||
"Log out" : "Ieșire",
|
||||
"Search" : "Căutare",
|
||||
"Please contact your administrator." : "Contactează-ți administratorul.",
|
||||
"An internal error occurred." : "A apărut o eroare internă.",
|
||||
"Please try again or contact your administrator." : "Încearcă din nou sau contactează-ți administratorul.",
|
||||
"Username or email" : "Nume de utilizator sau adresă email",
|
||||
"Log in" : "Autentificare",
|
||||
"Wrong password. Reset it?" : "Parolă greșită. O resetezi?",
|
||||
"Wrong password." : "Parolă greșită.",
|
||||
"Stay logged in" : "Rămâi autentificat",
|
||||
"Alternative Logins" : "Conectări alternative",
|
||||
"Use the following link to reset your password: {link}" : "Folosește următorul link pentru a reseta parola: {link}",
|
||||
"New password" : "Noua parolă",
|
||||
"New Password" : "Noua parolă",
|
||||
"Reset password" : "Resetează parola",
|
||||
"Thank you for your patience." : "Îți mulțumim pentru răbdare.",
|
||||
"Two-step verification" : "Verificare în doi pași",
|
||||
"Cancel login" : "Anulează autentificarea",
|
||||
"Please authenticate using the selected factor." : "Autentifică-te folosind factorul ales.",
|
||||
"An error occured while verifying the token" : "A apărut o eroare la verificarea jetonului",
|
||||
"You are accessing the server from an untrusted domain." : "Accesezi serverul dintr-un domeniu care nu a fost configurat ca fiind de încredere.",
|
||||
"Start update" : "Începe actualizarea"
|
||||
"Add \"%s\" as trusted domain" : "Adaugă \"%s\" ca domeniu de încredere",
|
||||
"App update required" : "E necesară o actualizare a aplicației",
|
||||
"%s will be updated to version %s" : "%s va fi actualizat la versiunea %s",
|
||||
"These apps will be updated:" : "Aceste aplicații vor fi actualizate:",
|
||||
"These incompatible apps will be disabled:" : "Aceste aplicații incompatibile vor fi dezactivate:",
|
||||
"The theme %s has been disabled." : "Tema %s a fost dezactivată.",
|
||||
"Start update" : "Începe actualizarea",
|
||||
"Detailed logs" : "Loguri detaliate",
|
||||
"Update needed" : "E necesară actualizarea",
|
||||
"Please use the command line updater because you have a big instance." : "Folosește actualizarea din linia de comandă deoarece ai o instanță mare.",
|
||||
"This %s instance is currently in maintenance mode, which may take a while." : "Instanța %s este acum în modul de mentenanță, ceea ce ar putea dura o vreme."
|
||||
},
|
||||
"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));");
|
||||
|
|
|
@ -6,23 +6,37 @@
|
|||
"Unknown filetype" : "Tip fișier necunoscut",
|
||||
"Invalid image" : "Imagine invalidă",
|
||||
"An error occurred. Please contact your admin." : "A apărut o eroare. Te rugăm să contactezi administratorul.",
|
||||
"No temporary profile picture available, try again" : "Nu este disponibilă nicio imagine temporară a profilului, încearcă din nou",
|
||||
"%s password reset" : "%s resetare parola",
|
||||
"Couldn't send reset email. Please contact your administrator." : "Expedierea email-ului de resetare a eşuat. Vă rugăm să contactaţi administratorul dvs.",
|
||||
"Error loading tags" : "Eroare la încărcarea etichetelor",
|
||||
"Tag already exists" : "Eticheta deja există",
|
||||
"Error deleting tag(s)" : "Eroare la ștergerea etichetei(-lor)",
|
||||
"Error tagging" : "Eroare la etichetare",
|
||||
"Error untagging" : "Eroare la scoaterea etichetei",
|
||||
"Error favoriting" : "Eroare la adăugarea la favorite",
|
||||
"Error unfavoriting" : "Eroare la scoaterea de la favorite",
|
||||
"Couldn't send mail to following users: %s " : "Nu s-a putut trimite mesajul către următorii utilizatori: %s",
|
||||
"Preparing update" : "Se pregătește actualizarea",
|
||||
"[%d / %d]: %s" : "[%d / %d]: %s",
|
||||
"Repair warning: " : "Alerte reparare:",
|
||||
"Repair error: " : "Eroare de reparare:",
|
||||
"[%d / %d]: Checking table %s" : "[%d / %d]: Se verifică tabela %s",
|
||||
"Turned on maintenance mode" : "Modul mentenanță a fost activat",
|
||||
"Turned off maintenance mode" : "Modul mentenanță a fost dezactivat",
|
||||
"Maintenance mode is kept active" : "Modul de mentenanță este menținut activ",
|
||||
"Updating database schema" : "Se actualizează schema bazei de date",
|
||||
"Updated database" : "Bază de date actualizată",
|
||||
"Checking whether the database schema can be updated (this can take a long time depending on the database size)" : "Se verifică dacă schema bazei de date poate fi actualizată (această verificare poate lua mult timp în funcție de mărimea bazei de date)",
|
||||
"Checking updates of apps" : "Se verifică actualizările aplicațiilor",
|
||||
"Updated \"%s\" to %s" : "\"%s\" a fost actualizat până la %s",
|
||||
"Set log level to debug" : "Setează nivelul de logare la \"debug\"",
|
||||
"Reset log level" : "Resetează nivelul de logare",
|
||||
"Starting code integrity check" : "Începe verificarea integrității codului",
|
||||
"Finished code integrity check" : "Verificarea integrității codului a fost finalizată",
|
||||
"%s (3rdparty)" : "%s (terță parte)",
|
||||
"%s (incompatible)" : "%s (incompatibil)",
|
||||
"Following apps have been disabled: %s" : "Următoarele aplicații au fost dezactivate: %s",
|
||||
"Already up to date" : "Deja actualizat",
|
||||
"Sunday" : "Duminică",
|
||||
"Monday" : "Luni",
|
||||
|
@ -69,9 +83,11 @@
|
|||
"Oct." : "Oct.",
|
||||
"Nov." : "Noi.",
|
||||
"Dec." : "Dec.",
|
||||
"<a href=\"{docUrl}\">There were problems with the code integrity check. More information…</a>" : "<a href=\"{docUrl}\">Au apărut probleme la verificarea integrității codului. Mai multe informații…</a>",
|
||||
"Settings" : "Setări",
|
||||
"Problem loading page, reloading in 5 seconds" : "A apărut o problemă la încărcarea paginii, se reîncearcă în 5 secunde",
|
||||
"Saving..." : "Se salvează...",
|
||||
"Dismiss" : "Înlătură",
|
||||
"seconds ago" : "secunde în urmă",
|
||||
"I know what I'm doing" : "Eu știu ce fac",
|
||||
"Password can not be changed. Please contact your administrator." : "Parola nu poate fi modificată. Vă rugăm să contactați administratorul dvs.",
|
||||
|
@ -133,24 +149,39 @@
|
|||
"access control" : "control acces",
|
||||
"Could not unshare" : "Nu s-a putut elimina partajarea",
|
||||
"Share details could not be loaded for this item." : "Nu s-au putut încărca detaliile de partajare pentru acest element.",
|
||||
"An error occurred. Please try again" : "A apărut o eroare. Încearcă din nou",
|
||||
"Share" : "Partajează",
|
||||
"Share with people on other ownClouds using the syntax username@example.com/owncloud" : "Partajează cu persoane din alte instanțe ownCloud folosind sintaxa nume_utilizator@exemplu.com/owncloud",
|
||||
"Share with users…" : "Partajează cu utilizatori...",
|
||||
"Share with users or groups…" : "Partajează cu utilizatori sau grupuri...",
|
||||
"Error removing share" : "Eroare la înlăturarea elementului partajat",
|
||||
"Warning" : "Atenție",
|
||||
"Error while sending notification" : "Eroare la trimiterea notificării",
|
||||
"Non-existing tag #{tag}" : "Etichetă inexistentă #{tag}",
|
||||
"restricted" : "restricționat",
|
||||
"invisible" : "invizibil",
|
||||
"Delete" : "Șterge",
|
||||
"Rename" : "Redenumește",
|
||||
"Collaborative tags" : "Etichete colaborative",
|
||||
"The object type is not specified." : "Tipul obiectului nu este specificat.",
|
||||
"Enter new" : "Introducere nou",
|
||||
"Add" : "Adaugă",
|
||||
"Edit tags" : "Editează etichete",
|
||||
"No tags selected for deletion." : "Nu au fost selectate etichete pentru ștergere.",
|
||||
"unknown text" : "text necunoscut",
|
||||
"Hello world!" : "Hello world!",
|
||||
"sunny" : "însorit",
|
||||
"Hello {name}" : "Salut {name}",
|
||||
"new" : "nou",
|
||||
"The upgrade is in progress, leaving this page might interrupt the process in some environments." : "Actualizarea este în progres, părăsirea acestei pagini ar putea duce la întreruperea procesului în unele medii.",
|
||||
"Updating to {version}" : "Actualizare la {version}",
|
||||
"An error occurred." : "A apărut o eroare.",
|
||||
"Please reload the page." : "Te rugăm să reîncarci pagina.",
|
||||
"The update was unsuccessful. Please report this issue to the <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud community</a>." : "Actualizarea a eșuat! Raportați problema către <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">comunitatea ownCloud</a>.",
|
||||
"The update was successful. There were warnings." : "Actualizarea nu a avut loc cu succes. Au existat avertismente.",
|
||||
"The update was successful. Redirecting you to ownCloud now." : "Actualizare reușită. Ești redirecționat către ownCloud.",
|
||||
"Searching other places" : "Se caută în alte locuri",
|
||||
"No search results in other folders" : "Nu există rezultate ale căutării în alte directoare",
|
||||
"Personal" : "Personal",
|
||||
"Users" : "Utilizatori",
|
||||
"Apps" : "Aplicații",
|
||||
|
@ -158,8 +189,12 @@
|
|||
"Help" : "Ajutor",
|
||||
"Access forbidden" : "Acces restricționat",
|
||||
"File not found" : "Fișierul nu a fost găsit",
|
||||
"The specified document has not been found on the server." : "Documentul specificat nu a fost găsit pe server.",
|
||||
"You can click here to return to %s." : "Poți da click aici pentru a te întoarce la %s.",
|
||||
"The share will expire on %s." : "Partajarea va expira în data de %s.",
|
||||
"Cheers!" : "Noroc!",
|
||||
"Internal Server Error" : "Eroare internă a serverului",
|
||||
"The server encountered an internal error and was unable to complete your request." : "Serverul a întâmpinat o eroare și nu îți poate îndeplini cererea.",
|
||||
"Technical details" : "Detalii tehnice",
|
||||
"Type: %s" : "Tip: %s",
|
||||
"Code: %s" : "Cod: %s",
|
||||
|
@ -188,16 +223,35 @@
|
|||
"See the documentation" : "Vezi documentația",
|
||||
"Log out" : "Ieșire",
|
||||
"Search" : "Căutare",
|
||||
"Please contact your administrator." : "Contactează-ți administratorul.",
|
||||
"An internal error occurred." : "A apărut o eroare internă.",
|
||||
"Please try again or contact your administrator." : "Încearcă din nou sau contactează-ți administratorul.",
|
||||
"Username or email" : "Nume de utilizator sau adresă email",
|
||||
"Log in" : "Autentificare",
|
||||
"Wrong password. Reset it?" : "Parolă greșită. O resetezi?",
|
||||
"Wrong password." : "Parolă greșită.",
|
||||
"Stay logged in" : "Rămâi autentificat",
|
||||
"Alternative Logins" : "Conectări alternative",
|
||||
"Use the following link to reset your password: {link}" : "Folosește următorul link pentru a reseta parola: {link}",
|
||||
"New password" : "Noua parolă",
|
||||
"New Password" : "Noua parolă",
|
||||
"Reset password" : "Resetează parola",
|
||||
"Thank you for your patience." : "Îți mulțumim pentru răbdare.",
|
||||
"Two-step verification" : "Verificare în doi pași",
|
||||
"Cancel login" : "Anulează autentificarea",
|
||||
"Please authenticate using the selected factor." : "Autentifică-te folosind factorul ales.",
|
||||
"An error occured while verifying the token" : "A apărut o eroare la verificarea jetonului",
|
||||
"You are accessing the server from an untrusted domain." : "Accesezi serverul dintr-un domeniu care nu a fost configurat ca fiind de încredere.",
|
||||
"Start update" : "Începe actualizarea"
|
||||
"Add \"%s\" as trusted domain" : "Adaugă \"%s\" ca domeniu de încredere",
|
||||
"App update required" : "E necesară o actualizare a aplicației",
|
||||
"%s will be updated to version %s" : "%s va fi actualizat la versiunea %s",
|
||||
"These apps will be updated:" : "Aceste aplicații vor fi actualizate:",
|
||||
"These incompatible apps will be disabled:" : "Aceste aplicații incompatibile vor fi dezactivate:",
|
||||
"The theme %s has been disabled." : "Tema %s a fost dezactivată.",
|
||||
"Start update" : "Începe actualizarea",
|
||||
"Detailed logs" : "Loguri detaliate",
|
||||
"Update needed" : "E necesară actualizarea",
|
||||
"Please use the command line updater because you have a big instance." : "Folosește actualizarea din linia de comandă deoarece ai o instanță mare.",
|
||||
"This %s instance is currently in maintenance mode, which may take a while." : "Instanța %s este acum în modul de mentenanță, ceea ce ar putea dura o vreme."
|
||||
},"pluralForm" :"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"
|
||||
}
|
|
@ -298,6 +298,7 @@ OC.L10N.register(
|
|||
"Thank you for your patience." : "Спасибо за терпение.",
|
||||
"Two-step verification" : "Двухшаговая проверка",
|
||||
"Enhanced security has been enabled for your account. Please authenticate using a second factor." : "Для вашей учётной записи включена повышенная безопасность. Пожалуйста, аутентифицируйтесь через второй фактор.",
|
||||
"Cancel login" : "Отменить вход",
|
||||
"Please authenticate using the selected factor." : "Пожалуйста, аутентифицируйтесь выбранным фактором.",
|
||||
"An error occured while verifying the token" : "При проверке токена возникла ошибка.",
|
||||
"You are accessing the server from an untrusted domain." : "Вы пытаетесь получить доступ к серверу с недоверенного домена.",
|
||||
|
|
|
@ -296,6 +296,7 @@
|
|||
"Thank you for your patience." : "Спасибо за терпение.",
|
||||
"Two-step verification" : "Двухшаговая проверка",
|
||||
"Enhanced security has been enabled for your account. Please authenticate using a second factor." : "Для вашей учётной записи включена повышенная безопасность. Пожалуйста, аутентифицируйтесь через второй фактор.",
|
||||
"Cancel login" : "Отменить вход",
|
||||
"Please authenticate using the selected factor." : "Пожалуйста, аутентифицируйтесь выбранным фактором.",
|
||||
"An error occured while verifying the token" : "При проверке токена возникла ошибка.",
|
||||
"You are accessing the server from an untrusted domain." : "Вы пытаетесь получить доступ к серверу с недоверенного домена.",
|
||||
|
|
|
@ -298,6 +298,7 @@ OC.L10N.register(
|
|||
"Thank you for your patience." : "Ju faleminderit për durimin.",
|
||||
"Two-step verification" : "Verifikim dyhapësh",
|
||||
"Enhanced security has been enabled for your account. Please authenticate using a second factor." : "Siguria e zgjeruar është aktivizuar për llogarinë tuaj. Ju lutemi, bëni mirëfilltësimin duke përdorur një faktor të dytë.",
|
||||
"Cancel login" : "Anuloje hyrjen",
|
||||
"Please authenticate using the selected factor." : "Ju lutemi, bëni mirëfilltësimin duke përdorur faktorin e përzgjedhur.",
|
||||
"An error occured while verifying the token" : "Ndodhi një gabim gjatë verifikimit të token-it",
|
||||
"You are accessing the server from an untrusted domain." : "Po hyni në shërbyes nga një përkatësi jo e besuar.",
|
||||
|
|
|
@ -296,6 +296,7 @@
|
|||
"Thank you for your patience." : "Ju faleminderit për durimin.",
|
||||
"Two-step verification" : "Verifikim dyhapësh",
|
||||
"Enhanced security has been enabled for your account. Please authenticate using a second factor." : "Siguria e zgjeruar është aktivizuar për llogarinë tuaj. Ju lutemi, bëni mirëfilltësimin duke përdorur një faktor të dytë.",
|
||||
"Cancel login" : "Anuloje hyrjen",
|
||||
"Please authenticate using the selected factor." : "Ju lutemi, bëni mirëfilltësimin duke përdorur faktorin e përzgjedhur.",
|
||||
"An error occured while verifying the token" : "Ndodhi një gabim gjatë verifikimit të token-it",
|
||||
"You are accessing the server from an untrusted domain." : "Po hyni në shërbyes nga një përkatësi jo e besuar.",
|
||||
|
|
|
@ -30,6 +30,7 @@ OC.L10N.register(
|
|||
"_%n minute ago_::_%n minutes ago_" : ["%n minute temu","%n minut temu","%n minut temu"],
|
||||
"seconds ago" : "sekund temu",
|
||||
"Empty filename is not allowed" : "Pusta nazwa nie jest dozwolona.",
|
||||
"4-byte characters are not supported in file names" : "Znaki 4-bajtowe są niedozwolone w nazwach plików",
|
||||
"File name contains at least one invalid character" : "Nazwa pliku zawiera co najmniej jeden nieprawidłowy znak",
|
||||
"File name is too long" : "Nazwa pliku zbyt długa",
|
||||
"App directory already exists" : "Katalog aplikacji już isnieje",
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
"_%n minute ago_::_%n minutes ago_" : ["%n minute temu","%n minut temu","%n minut temu"],
|
||||
"seconds ago" : "sekund temu",
|
||||
"Empty filename is not allowed" : "Pusta nazwa nie jest dozwolona.",
|
||||
"4-byte characters are not supported in file names" : "Znaki 4-bajtowe są niedozwolone w nazwach plików",
|
||||
"File name contains at least one invalid character" : "Nazwa pliku zawiera co najmniej jeden nieprawidłowy znak",
|
||||
"File name is too long" : "Nazwa pliku zbyt długa",
|
||||
"App directory already exists" : "Katalog aplikacji już isnieje",
|
||||
|
|
|
@ -18,12 +18,12 @@ OC.L10N.register(
|
|||
"Following platforms are supported: %s" : "São suportadas as seguintes plataformas: %s",
|
||||
"ownCloud %s or higher is required." : "É necessário ownCloud %s ou superior.",
|
||||
"ownCloud %s or lower is required." : "É necessário ownCloud %s ou inferior.",
|
||||
"Unknown filetype" : "Ficheiro desconhecido",
|
||||
"Unknown filetype" : "Tipo de ficheiro desconhecido",
|
||||
"Invalid image" : "Imagem inválida",
|
||||
"today" : "hoje",
|
||||
"yesterday" : "ontem",
|
||||
"_%n day ago_::_%n days ago_" : ["%n dia atrás","%n dias atrás"],
|
||||
"last month" : "ultímo mês",
|
||||
"last month" : "ultimo mês",
|
||||
"last year" : "ano passado",
|
||||
"_%n year ago_::_%n years ago_" : ["%n ano atrás","%n anos atrás"],
|
||||
"seconds ago" : "Minutos atrás",
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
"Following platforms are supported: %s" : "São suportadas as seguintes plataformas: %s",
|
||||
"ownCloud %s or higher is required." : "É necessário ownCloud %s ou superior.",
|
||||
"ownCloud %s or lower is required." : "É necessário ownCloud %s ou inferior.",
|
||||
"Unknown filetype" : "Ficheiro desconhecido",
|
||||
"Unknown filetype" : "Tipo de ficheiro desconhecido",
|
||||
"Invalid image" : "Imagem inválida",
|
||||
"today" : "hoje",
|
||||
"yesterday" : "ontem",
|
||||
"_%n day ago_::_%n days ago_" : ["%n dia atrás","%n dias atrás"],
|
||||
"last month" : "ultímo mês",
|
||||
"last month" : "ultimo mês",
|
||||
"last year" : "ano passado",
|
||||
"_%n year ago_::_%n years ago_" : ["%n ano atrás","%n anos atrás"],
|
||||
"seconds ago" : "Minutos atrás",
|
||||
|
|
|
@ -273,7 +273,9 @@ class AppConfig implements IAppConfig {
|
|||
->from('appconfig');
|
||||
$result = $sql->execute();
|
||||
|
||||
while ($row = $result->fetch()) {
|
||||
// we are going to store the result in memory anyway
|
||||
$rows = $result->fetchAll();
|
||||
foreach ($rows as $row) {
|
||||
if (!isset($this->cache[$row['appid']])) {
|
||||
$this->cache[$row['appid']] = [];
|
||||
}
|
||||
|
|
|
@ -104,6 +104,10 @@ class ConnectionFactory {
|
|||
break;
|
||||
case 'oci':
|
||||
$eventManager->addEventSubscriber(new OracleSessionInit);
|
||||
// the driverOptions are unused in dbal and need to be mapped to the parameters
|
||||
if (isset($additionalConnectionParams['driverOptions'])) {
|
||||
$additionalConnectionParams = array_merge($additionalConnectionParams, $additionalConnectionParams['driverOptions']);
|
||||
}
|
||||
break;
|
||||
case 'sqlite3':
|
||||
$journalMode = $additionalConnectionParams['sqlite.journal_mode'];
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
namespace OC\Encryption;
|
||||
|
||||
use OC\Cache\CappedMemoryCache;
|
||||
|
||||
class File implements \OCP\Encryption\IFile {
|
||||
|
||||
/** @var Util */
|
||||
|
@ -36,6 +38,7 @@ class File implements \OCP\Encryption\IFile {
|
|||
|
||||
public function __construct(Util $util) {
|
||||
$this->util = $util;
|
||||
$this->cache = new CappedMemoryCache();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,10 @@ use OCP\IDBConnection;
|
|||
* Propagate etags and mtimes within the storage
|
||||
*/
|
||||
class Propagator implements IPropagator {
|
||||
private $inBatch = false;
|
||||
|
||||
private $batch = [];
|
||||
|
||||
/**
|
||||
* @var \OC\Files\Storage\Storage
|
||||
*/
|
||||
|
@ -59,6 +63,13 @@ class Propagator implements IPropagator {
|
|||
|
||||
$parents = $this->getParents($internalPath);
|
||||
|
||||
if ($this->inBatch) {
|
||||
foreach ($parents as $parent) {
|
||||
$this->addToBatch($parent, $time, $sizeDifference);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$parentHashes = array_map('md5', $parents);
|
||||
$etag = uniqid(); // since we give all folders the same etag we don't ask the storage for the etag
|
||||
|
||||
|
@ -68,7 +79,7 @@ class Propagator implements IPropagator {
|
|||
}, $parentHashes);
|
||||
|
||||
$builder->update('filecache')
|
||||
->set('mtime', $builder->createFunction('GREATEST(`mtime`, ' . $builder->createNamedParameter($time) . ')'))
|
||||
->set('mtime', $builder->createFunction('GREATEST(`mtime`, ' . $builder->createNamedParameter($time, IQueryBuilder::PARAM_INT) . ')'))
|
||||
->set('etag', $builder->createNamedParameter($etag, IQueryBuilder::PARAM_STR))
|
||||
->where($builder->expr()->eq('storage', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($builder->expr()->in('path_hash', $hashParams));
|
||||
|
@ -98,4 +109,79 @@ class Propagator implements IPropagator {
|
|||
}
|
||||
return $parents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the beginning of a propagation batch
|
||||
*
|
||||
* Note that not all cache setups support propagation in which case this will be a noop
|
||||
*
|
||||
* Batching for cache setups that do support it has to be explicit since the cache state is not fully consistent
|
||||
* before the batch is committed.
|
||||
*/
|
||||
public function beginBatch() {
|
||||
$this->inBatch = true;
|
||||
}
|
||||
|
||||
private function addToBatch($internalPath, $time, $sizeDifference) {
|
||||
if (!isset($this->batch[$internalPath])) {
|
||||
$this->batch[$internalPath] = [
|
||||
'hash' => md5($internalPath),
|
||||
'time' => $time,
|
||||
'size' => $sizeDifference
|
||||
];
|
||||
} else {
|
||||
$this->batch[$internalPath]['size'] += $sizeDifference;
|
||||
if ($time > $this->batch[$internalPath]['time']) {
|
||||
$this->batch[$internalPath]['time'] = $time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the active propagation batch
|
||||
*/
|
||||
public function commitBatch() {
|
||||
if (!$this->inBatch) {
|
||||
throw new \BadMethodCallException('Not in batch');
|
||||
}
|
||||
$this->inBatch = false;
|
||||
|
||||
$this->connection->beginTransaction();
|
||||
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
$storageId = (int)$this->storage->getStorageCache()->getNumericId();
|
||||
|
||||
$query->update('filecache')
|
||||
->set('mtime', $query->createFunction('GREATEST(`mtime`, ' . $query->createParameter('time') . ')'))
|
||||
->set('etag', $query->expr()->literal(uniqid()))
|
||||
->where($query->expr()->eq('storage', $query->expr()->literal($storageId, IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($query->expr()->eq('path_hash', $query->createParameter('hash')));
|
||||
|
||||
$sizeQuery = $this->connection->getQueryBuilder();
|
||||
$sizeQuery->update('filecache')
|
||||
->set('size', $sizeQuery->createFunction('`size` + ' . $sizeQuery->createParameter('size')))
|
||||
->where($query->expr()->eq('storage', $query->expr()->literal($storageId, IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($query->expr()->eq('path_hash', $query->createParameter('hash')))
|
||||
->andWhere($sizeQuery->expr()->gt('size', $sizeQuery->expr()->literal(-1, IQueryBuilder::PARAM_INT)));
|
||||
|
||||
foreach ($this->batch as $item) {
|
||||
$query->setParameter('time', $item['time'], IQueryBuilder::PARAM_INT);
|
||||
$query->setParameter('hash', $item['hash']);
|
||||
|
||||
$query->execute();
|
||||
|
||||
if ($item['size']) {
|
||||
$sizeQuery->setParameter('size', $item['size'], IQueryBuilder::PARAM_INT);
|
||||
$sizeQuery->setParameter('hash', $item['hash']);
|
||||
|
||||
$sizeQuery->execute();
|
||||
}
|
||||
}
|
||||
|
||||
$this->batch = [];
|
||||
|
||||
$this->connection->commit();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -138,7 +138,9 @@ class Scanner extends PublicEmitter {
|
|||
$this->triggerPropagator($storage, $path);
|
||||
});
|
||||
|
||||
$storage->getPropagator()->beginBatch();
|
||||
$scanner->backgroundScan();
|
||||
$storage->getPropagator()->commitBatch();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,12 +189,14 @@ class Scanner extends PublicEmitter {
|
|||
$this->db->beginTransaction();
|
||||
}
|
||||
try {
|
||||
$storage->getPropagator()->beginBatch();
|
||||
$scanner->scan($relativePath, \OC\Files\Cache\Scanner::SCAN_RECURSIVE, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE);
|
||||
$cache = $storage->getCache();
|
||||
if ($cache instanceof Cache) {
|
||||
// only re-calculate for the root folder we scanned, anything below that is taken care of by the scanner
|
||||
$cache->correctFolderSize($relativePath);
|
||||
}
|
||||
$storage->getPropagator()->commitBatch();
|
||||
} catch (StorageNotAvailableException $e) {
|
||||
$this->logger->error('Storage ' . $storage->getId() . ' not available');
|
||||
$this->logger->logException($e);
|
||||
|
|
|
@ -29,11 +29,13 @@
|
|||
namespace OC;
|
||||
|
||||
use OC\Repair\AssetCache;
|
||||
use OC\Repair\AvatarPermissions;
|
||||
use OC\Repair\CleanTags;
|
||||
use OC\Repair\Collation;
|
||||
use OC\Repair\DropOldJobs;
|
||||
use OC\Repair\OldGroupMembershipShares;
|
||||
use OC\Repair\RemoveGetETagEntries;
|
||||
use OC\Repair\RemoveOldShares;
|
||||
use OC\Repair\SharePropagation;
|
||||
use OC\Repair\SqliteAutoincrement;
|
||||
use OC\Repair\DropOldTables;
|
||||
|
@ -132,6 +134,8 @@ class Repair implements IOutput{
|
|||
new UpdateOutdatedOcsIds(\OC::$server->getConfig()),
|
||||
new RepairInvalidShares(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()),
|
||||
new SharePropagation(\OC::$server->getConfig()),
|
||||
new RemoveOldShares(\OC::$server->getDatabaseConnection()),
|
||||
new AvatarPermissions(\OC::$server->getDatabaseConnection()),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Roeland Jago Douma <rullzer@owncloud.com>
|
||||
*
|
||||
* @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 OC\Repair;
|
||||
|
||||
use Doctrine\DBAL\Platforms\OraclePlatform;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\Migration\IOutput;
|
||||
use OCP\Migration\IRepairStep;
|
||||
|
||||
/**
|
||||
* Class AvatarPermissions
|
||||
*
|
||||
* @package OC\Repair
|
||||
*/
|
||||
class AvatarPermissions implements IRepairStep {
|
||||
/** @var IDBConnection */
|
||||
private $connection;
|
||||
|
||||
/**
|
||||
* AvatarPermissions constructor.
|
||||
*
|
||||
* @param IDBConnection $connection
|
||||
*/
|
||||
public function __construct(IDBConnection $connection) {
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
return 'Fix permissions so avatars can be stored again';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IOutput $output
|
||||
*/
|
||||
public function run(IOutput $output) {
|
||||
$output->startProgress(2);
|
||||
$this->fixUserRootPermissions();
|
||||
$output->advance();
|
||||
$this->fixAvatarPermissions();
|
||||
$output->finishProgress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure all user roots have permissions 23 (all but share)
|
||||
*/
|
||||
protected function fixUserRootPermissions() {
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$qb2 = $this->connection->getQueryBuilder();
|
||||
|
||||
$qb->select('numeric_id')
|
||||
->from('storages')
|
||||
->where($qb->expr()->like('id', $qb2->createParameter('like')));
|
||||
|
||||
if ($this->connection->getDatabasePlatform() instanceof OraclePlatform) {
|
||||
// '' is null on oracle
|
||||
$path = $qb2->expr()->isNull('path');
|
||||
} else {
|
||||
$path = $qb2->expr()->eq('path', $qb2->createNamedParameter(''));
|
||||
}
|
||||
|
||||
$qb2->update('filecache')
|
||||
->set('permissions', $qb2->createNamedParameter(23))
|
||||
->where($path)
|
||||
->andWhere($qb2->expr()->in('storage', $qb2->createFunction($qb->getSQL())))
|
||||
->andWhere($qb2->expr()->neq('permissions', $qb2->createNamedParameter(23)))
|
||||
->setParameter('like', 'home::%');
|
||||
|
||||
|
||||
$qb2->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure all avatar files in the user roots have permission 27
|
||||
*/
|
||||
protected function fixAvatarPermissions() {
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$qb2 = $this->connection->getQueryBuilder();
|
||||
|
||||
$qb->select('numeric_id')
|
||||
->from('storages')
|
||||
->where($qb->expr()->like('id', $qb2->createParameter('like')));
|
||||
|
||||
$qb2->update('filecache')
|
||||
->set('permissions', $qb2->createNamedParameter(27))
|
||||
->where($qb2->expr()->like('path', $qb2->createNamedParameter('avatar.%')))
|
||||
->andWhere($qb2->expr()->in('storage', $qb2->createFunction($qb->getSQL())))
|
||||
->andWhere($qb2->expr()->neq('permissions', $qb2->createNamedParameter(27)))
|
||||
->setParameter('like', 'home::%');
|
||||
|
||||
$qb2->execute();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Roeland Jago Douma <rullzer@owncloud.com>
|
||||
*
|
||||
* @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 OC\Repair;
|
||||
|
||||
use OCP\IDBConnection;
|
||||
use OCP\Migration\IOutput;
|
||||
use OCP\Migration\IRepairStep;
|
||||
|
||||
/**
|
||||
* Class RemoveOldShares
|
||||
*
|
||||
* @package OC\Repair
|
||||
*/
|
||||
class RemoveOldShares implements IRepairStep {
|
||||
|
||||
/** @var IDBConnection */
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* RemoveOldCalendarShares constructor.
|
||||
*
|
||||
* @param IDBConnection $db
|
||||
*/
|
||||
public function __construct(IDBConnection $connection) {
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
return 'Remove old (< 9.0) calendar/contact shares';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IOutput $output
|
||||
*/
|
||||
public function run(IOutput $output) {
|
||||
$output->startProgress(4);
|
||||
|
||||
$this->removeCalendarShares($output);
|
||||
$this->removeContactShares($output);
|
||||
|
||||
$output->finishProgress();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IOutput $output
|
||||
*/
|
||||
private function removeCalendarShares(IOutput $output) {
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$qb->delete('share')
|
||||
->where($qb->expr()->eq('item_type', $qb->createNamedParameter('calendar')));
|
||||
$qb->execute();
|
||||
|
||||
$output->advance();
|
||||
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$qb->delete('share')
|
||||
->where($qb->expr()->eq('item_type', $qb->createNamedParameter('event')));
|
||||
$qb->execute();
|
||||
|
||||
$output->advance();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IOutput $output
|
||||
*/
|
||||
private function removeContactShares(IOutput $output) {
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$qb->delete('share')
|
||||
->where($qb->expr()->eq('item_type', $qb->createNamedParameter('contact')));
|
||||
$qb->execute();
|
||||
|
||||
$output->advance();
|
||||
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
$qb->delete('share')
|
||||
->where($qb->expr()->eq('item_type', $qb->createNamedParameter('addressbook')));
|
||||
$qb->execute();
|
||||
|
||||
$output->advance();
|
||||
}
|
||||
}
|
||||
|
|
@ -64,7 +64,9 @@ class OC_JSON{
|
|||
* @deprecated Use annotation based ACLs from the AppFramework instead
|
||||
*/
|
||||
public static function checkLoggedIn() {
|
||||
if( !OC_User::isLoggedIn()) {
|
||||
$twoFactorAuthManger = \OC::$server->getTwoFactorAuthManager();
|
||||
if( !OC_User::isLoggedIn()
|
||||
|| $twoFactorAuthManger->needsSecondFactor()) {
|
||||
$l = \OC::$server->getL10N('lib');
|
||||
http_response_code(\OCP\AppFramework\Http::STATUS_UNAUTHORIZED);
|
||||
self::error(array( 'data' => array( 'message' => $l->t('Authentication error'), 'error' => 'authentication_error' )));
|
||||
|
|
|
@ -970,6 +970,11 @@ class OC_Util {
|
|||
);
|
||||
exit();
|
||||
}
|
||||
// Redirect to index page if 2FA challenge was not solved yet
|
||||
if (\OC::$server->getTwoFactorAuthManager()->needsSecondFactor()) {
|
||||
header('Location: ' . \OCP\Util::linkToAbsolute('', 'index.php'));
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue