Merge branch 'master' of https://github.com/owncloud/core into downstream-160611

This commit is contained in:
Arthur Schiwon 2016-06-11 15:34:43 +02:00
commit 42c66efea5
No known key found for this signature in database
GPG Key ID: 7424F1874854DF23
109 changed files with 2151 additions and 219 deletions

View File

@ -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);");

View File

@ -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);"
}

View File

@ -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>

View File

@ -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>

View File

@ -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();

View File

@ -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()
);
});
}
/**

View File

@ -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,
'uid' => $uid,
'etag' => md5($calendarData),
'size' => strlen($calendarData),
'componentType' => $componentType,
'firstOccurence' => is_null($firstOccurrence) ? null : max(0, $firstOccurrence),
'lastOccurence' => $lastOccurrence,
'uid' => $uid,
'classification' => $classification
];
}

View File

@ -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']);
}
}

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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();
}
/**

View File

@ -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) {

View 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)
)

View File

@ -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();
}
}

View File

@ -141,6 +141,7 @@ class Server {
$this->server->tree,
$view,
\OC::$server->getConfig(),
$this->request,
false,
!\OC::$server->getConfig()->getSystemValue('debug', false)
)

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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]
];
}
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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']);
}
}

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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));");

View File

@ -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));"
}

View File

@ -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();
}
/**

View File

@ -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" : "حجم",

View File

@ -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" : "حجم",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -21,6 +21,7 @@ OC.L10N.register(
"Invalid directory." : "Drejtori e pavlefshme.",
"Files" : "Kartela",
"All files" : "Krejt kartelat",
"File could not be found" : "Kartela su gjet dot",
"Home" : "Kreu",
"Close" : "Mbylle",
"Favorites" : "Të parapëlqyera",

View File

@ -19,6 +19,7 @@
"Invalid directory." : "Drejtori e pavlefshme.",
"Files" : "Kartela",
"All files" : "Krejt kartelat",
"File could not be found" : "Kartela su gjet dot",
"Home" : "Kreu",
"Close" : "Mbylle",
"Favorites" : "Të parapëlqyera",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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));");

View File

@ -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));"
}

View File

@ -100,15 +100,8 @@ class Share20OCS {
*/
protected function formatShare(\OCP\Share\IShare $share) {
$sharedBy = $this->userManager->get($share->getSharedBy());
// for federated shares the owner can be a remote user, in this
// case we use the initiator
if ($this->userManager->userExists($share->getShareOwner())) {
$shareOwner = $this->userManager->get($share->getShareOwner());
$localUser = $share->getShareOwner();
} else {
$shareOwner = $this->userManager->get($share->getSharedBy());
$localUser = $share->getSharedBy();
}
$shareOwner = $this->userManager->get($share->getShareOwner());
$result = [
'id' => $share->getId(),
'share_type' => $share->getShareType(),
@ -123,8 +116,16 @@ class Share20OCS {
'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
];
$node = $share->getNode();
$result['path'] = $this->rootFolder->getUserFolder($localUser)->getRelativePath($node->getPath());
$userFolder = $this->rootFolder->getUserFolder($this->currentUser->getUID());
$nodes = $userFolder->getById($share->getNodeId());
if (empty($nodes)) {
throw new NotFoundException();
}
$node = $nodes[0];
$result['path'] = $userFolder->getRelativePath($node->getPath());
if ($node instanceOf \OCP\Files\Folder) {
$result['item_type'] = 'folder';
} else {
@ -536,7 +537,6 @@ class Share20OCS {
$shares = array_merge($shares, $federatedShares);
}
$formatted = [];
foreach ($shares as $share) {
try {

View File

@ -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]);

View File

@ -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);

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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"],

View File

@ -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"],

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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|

View File

@ -106,7 +106,12 @@ class Install extends Command {
$dbUser = $input->getOption('database-user');
$dbPass = $input->getOption('database-pass');
$dbName = $input->getOption('database-name');
$dbHost = $input->getOption('database-host');
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');

View File

@ -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

View File

@ -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.",

View File

@ -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.",

View File

@ -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.",

View File

@ -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.",

View File

@ -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.",

View File

@ -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.",

View File

@ -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.",

View File

@ -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.",

View File

@ -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.",

View File

@ -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.",

View File

@ -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.",

View File

@ -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.",

View File

@ -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));");

View File

@ -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));"
}

View File

@ -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." : "Вы пытаетесь получить доступ к серверу с недоверенного домена.",

View File

@ -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." : "Вы пытаетесь получить доступ к серверу с недоверенного домена.",

View File

@ -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.",

View File

@ -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.",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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']] = [];
}

View File

@ -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'];

View File

@ -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();
}

View File

@ -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();
}
}

View File

@ -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);

View File

@ -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()),
];
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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' )));

View File

@ -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