diff options
Diffstat (limited to 'apps')
47 files changed, 698 insertions, 63 deletions
diff --git a/apps/comments/l10n/lb.js b/apps/comments/l10n/lb.js index f63640ac6f7..d7f8c5884ac 100644 --- a/apps/comments/l10n/lb.js +++ b/apps/comments/l10n/lb.js @@ -2,6 +2,7 @@ OC.L10N.register( "comments", { "Cancel" : "Ofbriechen", - "Save" : "Späicheren" + "Save" : "Späicheren", + "Comment" : "Kommentar" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/comments/l10n/lb.json b/apps/comments/l10n/lb.json index c015c4dd2a8..bfa307a7e8d 100644 --- a/apps/comments/l10n/lb.json +++ b/apps/comments/l10n/lb.json @@ -1,5 +1,6 @@ { "translations": { "Cancel" : "Ofbriechen", - "Save" : "Späicheren" + "Save" : "Späicheren", + "Comment" : "Kommentar" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dav/appinfo/v1/carddav.php b/apps/dav/appinfo/v1/carddav.php index 88582d64ee5..fc7aff4a63c 100644 --- a/apps/dav/appinfo/v1/carddav.php +++ b/apps/dav/appinfo/v1/carddav.php @@ -75,6 +75,7 @@ if ($debugging) { } $server->addPlugin(new \Sabre\CardDAV\VCFExportPlugin()); +$server->addPlugin(new \OCA\DAV\CardDAV\ImageExportPlugin(\OC::$server->getLogger())); $server->addPlugin(new ExceptionLoggerPlugin('carddav', \OC::$server->getLogger())); // And off we go! diff --git a/apps/dav/lib/AppInfo/Application.php b/apps/dav/lib/AppInfo/Application.php index de2056ebc35..b7b24ba7632 100644 --- a/apps/dav/lib/AppInfo/Application.php +++ b/apps/dav/lib/AppInfo/Application.php @@ -136,7 +136,8 @@ class Application extends App { public function setupContactsProvider(IManager $contactsManager, $userID) { /** @var ContactsManager $cm */ $cm = $this->getContainer()->query('ContactsManager'); - $cm->setupContactsProvider($contactsManager, $userID); + $urlGenerator = $this->getContainer()->getServer()->getURLGenerator(); + $cm->setupContactsProvider($contactsManager, $userID, $urlGenerator); } public function registerHooks() { diff --git a/apps/dav/lib/CardDAV/AddressBookImpl.php b/apps/dav/lib/CardDAV/AddressBookImpl.php index 310be695185..b26f81766c6 100644 --- a/apps/dav/lib/CardDAV/AddressBookImpl.php +++ b/apps/dav/lib/CardDAV/AddressBookImpl.php @@ -24,6 +24,7 @@ namespace OCA\DAV\CardDAV; use OCP\Constants; use OCP\IAddressBook; +use OCP\IURLGenerator; use Sabre\VObject\Component\VCard; use Sabre\VObject\Property\Text; use Sabre\VObject\Reader; @@ -40,21 +41,27 @@ class AddressBookImpl implements IAddressBook { /** @var AddressBook */ private $addressBook; + /** @var IURLGenerator */ + private $urlGenerator; + /** * AddressBookImpl constructor. * * @param AddressBook $addressBook * @param array $addressBookInfo * @param CardDavBackend $backend + * @param IUrlGenerator $urlGenerator */ public function __construct( AddressBook $addressBook, array $addressBookInfo, - CardDavBackend $backend) { + CardDavBackend $backend, + IURLGenerator $urlGenerator) { $this->addressBook = $addressBook; $this->addressBookInfo = $addressBookInfo; $this->backend = $backend; + $this->urlGenerator = $urlGenerator; } /** @@ -83,11 +90,11 @@ class AddressBookImpl implements IAddressBook { * @since 5.0.0 */ public function search($pattern, $searchProperties, $options) { - $result = $this->backend->search($this->getKey(), $pattern, $searchProperties); + $results = $this->backend->search($this->getKey(), $pattern, $searchProperties); $vCards = []; - foreach ($result as $cardData) { - $vCards[] = $this->vCard2Array($this->readCard($cardData)); + foreach ($results as $result) { + $vCards[] = $this->vCard2Array($result['uri'], $this->readCard($result['carddata'])); } return $vCards; @@ -100,13 +107,12 @@ class AddressBookImpl implements IAddressBook { */ public function createOrUpdate($properties) { $update = false; - if (!isset($properties['UID'])) { // create a new contact + if (!isset($properties['URI'])) { // create a new contact $uid = $this->createUid(); $uri = $uid . '.vcf'; $vCard = $this->createEmptyVCard($uid); } else { // update existing contact - $uid = $properties['UID']; - $uri = $uid . '.vcf'; + $uri = $properties['URI']; $vCardData = $this->backend->getCard($this->getKey(), $uri); $vCard = $this->readCard($vCardData['carddata']); $update = true; @@ -122,7 +128,7 @@ class AddressBookImpl implements IAddressBook { $this->backend->createCard($this->getKey(), $uri, $vCard->serialize()); } - return $this->vCard2Array($vCard); + return $this->vCard2Array($uri, $vCard); } @@ -207,13 +213,31 @@ class AddressBookImpl implements IAddressBook { /** * create array with all vCard properties * + * @param string $uri * @param VCard $vCard * @return array */ - protected function vCard2Array(VCard $vCard) { - $result = []; + protected function vCard2Array($uri, VCard $vCard) { + $result = [ + 'URI' => $uri, + ]; + foreach ($vCard->children as $property) { $result[$property->name] = $property->getValue(); + if ($property->name === 'PHOTO' && $property->getValueType() === 'BINARY') { + $url = $this->urlGenerator->getAbsoluteURL( + $this->urlGenerator->linkTo('', 'remote.php') . '/dav/'); + $url .= implode('/', [ + 'addressbooks', + substr($this->addressBookInfo['principaluri'], 11), //cut off 'principals/' + $this->addressBookInfo['uri'], + $uri + ]) . '?photo'; + + $result['PHOTO'] = 'VALUE=uri:' . $url; + } else { + $result[$property->name] = $property->getValue(); + } } if ($this->addressBookInfo['principaluri'] === 'principals/system/system' && $this->addressBookInfo['uri'] === 'system') { diff --git a/apps/dav/lib/CardDAV/CardDavBackend.php b/apps/dav/lib/CardDAV/CardDavBackend.php index 3d2904df39c..2ad9f4778c9 100644 --- a/apps/dav/lib/CardDAV/CardDavBackend.php +++ b/apps/dav/lib/CardDAV/CardDavBackend.php @@ -780,7 +780,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { } $query2->andWhere($query2->expr()->eq('cp.addressbookid', $query->createNamedParameter($addressBookId))); - $query->select('c.carddata')->from($this->dbCardsTable, 'c') + $query->select('c.carddata', 'c.uri')->from($this->dbCardsTable, 'c') ->where($query->expr()->in('c.id', $query->createFunction($query2->getSQL()))); $result = $query->execute(); @@ -788,8 +788,10 @@ class CardDavBackend implements BackendInterface, SyncSupport { $result->closeCursor(); - return array_map(function($array) {return $this->readBlob($array['carddata']);}, $cards); - + return array_map(function($array) { + $array['carddata'] = $this->readBlob($array['carddata']); + return $array; + }, $cards); } /** diff --git a/apps/dav/lib/CardDAV/ContactsManager.php b/apps/dav/lib/CardDAV/ContactsManager.php index 7900c6ccae0..ad633483fdd 100644 --- a/apps/dav/lib/CardDAV/ContactsManager.php +++ b/apps/dav/lib/CardDAV/ContactsManager.php @@ -22,6 +22,7 @@ namespace OCA\DAV\CardDAV; use OCP\Contacts\IManager; +use OCP\IURLGenerator; class ContactsManager { @@ -37,26 +38,29 @@ class ContactsManager { /** * @param IManager $cm * @param string $userId + * @param IURLGenerator $urlGenerator */ - public function setupContactsProvider(IManager $cm, $userId) { + public function setupContactsProvider(IManager $cm, $userId, IURLGenerator $urlGenerator) { $addressBooks = $this->backend->getAddressBooksForUser("principals/users/$userId"); - $this->register($cm, $addressBooks); + $this->register($cm, $addressBooks, $urlGenerator); $addressBooks = $this->backend->getAddressBooksForUser("principals/system/system"); - $this->register($cm, $addressBooks); + $this->register($cm, $addressBooks, $urlGenerator); } /** * @param IManager $cm * @param $addressBooks + * @param IURLGenerator $urlGenerator */ - private function register(IManager $cm, $addressBooks) { + private function register(IManager $cm, $addressBooks, $urlGenerator) { foreach ($addressBooks as $addressBookInfo) { $addressBook = new \OCA\DAV\CardDAV\AddressBook($this->backend, $addressBookInfo); $cm->registerAddressBook( new AddressBookImpl( $addressBook, $addressBookInfo, - $this->backend + $this->backend, + $urlGenerator ) ); } diff --git a/apps/dav/lib/CardDAV/ImageExportPlugin.php b/apps/dav/lib/CardDAV/ImageExportPlugin.php new file mode 100644 index 00000000000..3f505222491 --- /dev/null +++ b/apps/dav/lib/CardDAV/ImageExportPlugin.php @@ -0,0 +1,146 @@ +<?php +/** + * @author Thomas Müller <thomas.mueller@tmit.eu> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace OCA\DAV\CardDAV; + +use OCP\ILogger; +use Sabre\CardDAV\Card; +use Sabre\DAV\Server; +use Sabre\DAV\ServerPlugin; +use Sabre\HTTP\RequestInterface; +use Sabre\HTTP\ResponseInterface; +use Sabre\VObject\Parameter; +use Sabre\VObject\Property\Binary; +use Sabre\VObject\Reader; + +class ImageExportPlugin extends ServerPlugin { + + /** @var Server */ + protected $server; + /** @var ILogger */ + private $logger; + + public function __construct(ILogger $logger) { + $this->logger = $logger; + } + + /** + * Initializes the plugin and registers event handlers + * + * @param Server $server + * @return void + */ + function initialize(Server $server) { + + $this->server = $server; + $this->server->on('method:GET', [$this, 'httpGet'], 90); + } + + /** + * Intercepts GET requests on addressbook urls ending with ?photo. + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return bool|void + */ + function httpGet(RequestInterface $request, ResponseInterface $response) { + + $queryParams = $request->getQueryParameters(); + // TODO: in addition to photo we should also add logo some point in time + if (!array_key_exists('photo', $queryParams)) { + return true; + } + + $path = $request->getPath(); + $node = $this->server->tree->getNodeForPath($path); + + if (!($node instanceof Card)) { + return true; + } + + $this->server->transactionType = 'carddav-image-export'; + + // Checking ACL, if available. + if ($aclPlugin = $this->server->getPlugin('acl')) { + /** @var \Sabre\DAVACL\Plugin $aclPlugin */ + $aclPlugin->checkPrivileges($path, '{DAV:}read'); + } + + if ($result = $this->getPhoto($node)) { + $response->setHeader('Content-Type', $result['Content-Type']); + $response->setStatus(200); + + $response->setBody($result['body']); + + // Returning false to break the event chain + return false; + } + return true; + } + + function getPhoto(Card $node) { + // TODO: this is kind of expensive - load carddav data from database and parse it + // we might want to build up a cache one day + try { + $vObject = $this->readCard($node->get()); + if (!$vObject->PHOTO) { + return false; + } + + $photo = $vObject->PHOTO; + $type = $this->getType($photo); + + $valType = $photo->getValueType(); + $val = ($valType === 'URI' ? $photo->getRawMimeDirValue() : $photo->getValue()); + return [ + 'Content-Type' => $type, + 'body' => $val + ]; + } catch(\Exception $ex) { + $this->logger->logException($ex); + } + return false; + } + + private function readCard($cardData) { + return Reader::read($cardData); + } + + /** + * @param Binary $photo + * @return Parameter + */ + private function getType($photo) { + $params = $photo->parameters(); + if (isset($params['TYPE']) || isset($params['MEDIATYPE'])) { + /** @var Parameter $typeParam */ + $typeParam = isset($params['TYPE']) ? $params['TYPE'] : $params['MEDIATYPE']; + $type = $typeParam->getValue(); + + if (strpos($type, 'image/') === 0) { + return $type; + } else { + return 'image/' . strtolower($type); + } + } + return ''; + } +} diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php index e150f441b82..7fa1b13783b 100644 --- a/apps/dav/lib/Server.php +++ b/apps/dav/lib/Server.php @@ -25,6 +25,7 @@ namespace OCA\DAV; use OCA\DAV\CalDAV\Schedule\IMipPlugin; +use OCA\DAV\CardDAV\ImageExportPlugin; use OCA\DAV\Connector\Sabre\Auth; use OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin; use OCA\DAV\Connector\Sabre\DavAclPlugin; @@ -103,6 +104,7 @@ class Server { // addressbook plugins $this->server->addPlugin(new \OCA\DAV\CardDAV\Plugin()); $this->server->addPlugin(new VCFExportPlugin()); + $this->server->addPlugin(new ImageExportPlugin(\OC::$server->getLogger())); // system tags plugins $this->server->addPlugin(new \OCA\DAV\SystemTag\SystemTagPlugin( diff --git a/apps/dav/tests/unit/CardDAV/AddressBookImplTest.php b/apps/dav/tests/unit/CardDAV/AddressBookImplTest.php index ddfec3dc3ac..4ccc841157f 100644 --- a/apps/dav/tests/unit/CardDAV/AddressBookImplTest.php +++ b/apps/dav/tests/unit/CardDAV/AddressBookImplTest.php @@ -43,6 +43,9 @@ class AddressBookImplTest extends TestCase { /** @var AddressBook | \PHPUnit_Framework_MockObject_MockObject */ private $addressBook; + /** @var \OCP\IURLGenerator | \PHPUnit_Framework_MockObject_MockObject */ + private $urlGenerator; + /** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject */ private $backend; @@ -61,11 +64,13 @@ class AddressBookImplTest extends TestCase { $this->backend = $this->getMockBuilder('\OCA\DAV\CardDAV\CardDavBackend') ->disableOriginalConstructor()->getMock(); $this->vCard = $this->getMock('Sabre\VObject\Component\VCard'); + $this->urlGenerator = $this->getMock('OCP\IURLGenerator'); $this->addressBookImpl = new AddressBookImpl( $this->addressBook, $this->addressBookInfo, - $this->backend + $this->backend, + $this->urlGenerator ); } @@ -87,7 +92,8 @@ class AddressBookImplTest extends TestCase { [ $this->addressBook, $this->addressBookInfo, - $this->backend + $this->backend, + $this->urlGenerator, ] ) ->setMethods(['vCard2Array', 'readCard']) @@ -100,15 +106,18 @@ class AddressBookImplTest extends TestCase { ->with($this->addressBookInfo['id'], $pattern, $searchProperties) ->willReturn( [ - 'cardData1', - 'cardData2' + ['uri' => 'foo.vcf', 'carddata' => 'cardData1'], + ['uri' => 'bar.vcf', 'carddata' => 'cardData2'] ] ); $addressBookImpl->expects($this->exactly(2))->method('readCard') ->willReturn($this->vCard); $addressBookImpl->expects($this->exactly(2))->method('vCard2Array') - ->with($this->vCard)->willReturn('vCard'); + ->withConsecutive( + ['foo.vcf', $this->vCard], + ['bar.vcf', $this->vCard] + )->willReturn('vCard'); $result = $addressBookImpl->search($pattern, $searchProperties, []); $this->assertTrue((is_array($result))); @@ -130,7 +139,8 @@ class AddressBookImplTest extends TestCase { [ $this->addressBook, $this->addressBookInfo, - $this->backend + $this->backend, + $this->urlGenerator, ] ) ->setMethods(['vCard2Array', 'createUid', 'createEmptyVCard']) @@ -146,7 +156,7 @@ class AddressBookImplTest extends TestCase { $this->backend->expects($this->never())->method('updateCard'); $this->backend->expects($this->never())->method('getCard'); $addressBookImpl->expects($this->once())->method('vCard2Array') - ->with($this->vCard)->willReturn(true); + ->with('uid.vcf', $this->vCard)->willReturn(true); $this->assertTrue($addressBookImpl->createOrUpdate($properties)); } @@ -161,7 +171,8 @@ class AddressBookImplTest extends TestCase { public function testUpdate() { $uid = 'uid'; - $properties = ['UID' => $uid, 'FN' => 'John Doe']; + $uri = 'bla.vcf'; + $properties = ['URI' => $uri, 'UID' => $uid, 'FN' => 'John Doe']; /** @var \PHPUnit_Framework_MockObject_MockObject | AddressBookImpl $addressBookImpl */ $addressBookImpl = $this->getMockBuilder('OCA\DAV\CardDAV\AddressBookImpl') @@ -169,7 +180,8 @@ class AddressBookImplTest extends TestCase { [ $this->addressBook, $this->addressBookInfo, - $this->backend + $this->backend, + $this->urlGenerator, ] ) ->setMethods(['vCard2Array', 'createUid', 'createEmptyVCard', 'readCard']) @@ -178,7 +190,7 @@ class AddressBookImplTest extends TestCase { $addressBookImpl->expects($this->never())->method('createUid'); $addressBookImpl->expects($this->never())->method('createEmptyVCard'); $this->backend->expects($this->once())->method('getCard') - ->with($this->addressBookInfo['id'], $uid . '.vcf') + ->with($this->addressBookInfo['id'], $uri) ->willReturn(['carddata' => 'data']); $addressBookImpl->expects($this->once())->method('readCard') ->with('data')->willReturn($this->vCard); @@ -187,7 +199,7 @@ class AddressBookImplTest extends TestCase { $this->backend->expects($this->never())->method('createCard'); $this->backend->expects($this->once())->method('updateCard'); $addressBookImpl->expects($this->once())->method('vCard2Array') - ->with($this->vCard)->willReturn(true); + ->with($uri, $this->vCard)->willReturn(true); $this->assertTrue($addressBookImpl->createOrUpdate($properties)); } @@ -251,7 +263,8 @@ class AddressBookImplTest extends TestCase { [ $this->addressBook, $this->addressBookInfo, - $this->backend + $this->backend, + $this->urlGenerator, ] ) ->setMethods(['getUid']) diff --git a/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php b/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php index c7cd4a30052..58a93befe68 100644 --- a/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php +++ b/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php @@ -535,8 +535,8 @@ class CardDavBackendTest extends TestCase { $found = []; foreach ($result as $r) { foreach ($expected as $exp) { - if (strpos($r, $exp) > 0) { - $found[$exp] = true; + if ($r['uri'] === $exp[0] && strpos($r['carddata'], $exp[1]) > 0) { + $found[$exp[1]] = true; break; } } @@ -547,11 +547,11 @@ class CardDavBackendTest extends TestCase { public function dataTestSearch() { return [ - ['John', ['FN'], ['John Doe', 'John M. Doe']], - ['M. Doe', ['FN'], ['John M. Doe']], - ['Do', ['FN'], ['John Doe', 'John M. Doe']], - 'check if duplicates are handled correctly' => ['John', ['FN', 'CLOUD'], ['John Doe', 'John M. Doe']], - 'case insensitive' => ['john', ['FN'], ['John Doe', 'John M. Doe']] + ['John', ['FN'], [['uri0', 'John Doe'], ['uri1', 'John M. Doe']]], + ['M. Doe', ['FN'], [['uri1', 'John M. Doe']]], + ['Do', ['FN'], [['uri0', 'John Doe'], ['uri1', 'John M. Doe']]], + 'check if duplicates are handled correctly' => ['John', ['FN', 'CLOUD'], [['uri0', 'John Doe'], ['uri1', 'John M. Doe']]], + 'case insensitive' => ['john', ['FN'], [['uri0', 'John Doe'], ['uri1', 'John M. Doe']]] ]; } diff --git a/apps/dav/tests/unit/CardDAV/ContactsManagerTest.php b/apps/dav/tests/unit/CardDAV/ContactsManagerTest.php index 2abd9da66e7..23a49a1962f 100644 --- a/apps/dav/tests/unit/CardDAV/ContactsManagerTest.php +++ b/apps/dav/tests/unit/CardDAV/ContactsManagerTest.php @@ -32,6 +32,7 @@ class ContactsManagerTest extends TestCase { /** @var IManager | \PHPUnit_Framework_MockObject_MockObject $cm */ $cm = $this->getMockBuilder('OCP\Contacts\IManager')->disableOriginalConstructor()->getMock(); $cm->expects($this->exactly(2))->method('registerAddressBook'); + $urlGenerator = $this->getMockBuilder('OCP\IUrlGenerator')->disableOriginalConstructor()->getMock(); /** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject $backEnd */ $backEnd = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')->disableOriginalConstructor()->getMock(); $backEnd->method('getAddressBooksForUser')->willReturn([ @@ -39,6 +40,6 @@ class ContactsManagerTest extends TestCase { ]); $app = new ContactsManager($backEnd); - $app->setupContactsProvider($cm, 'user01'); + $app->setupContactsProvider($cm, 'user01', $urlGenerator); } } diff --git a/apps/dav/tests/unit/CardDAV/ImageExportPluginTest.php b/apps/dav/tests/unit/CardDAV/ImageExportPluginTest.php new file mode 100644 index 00000000000..8583df0b6f9 --- /dev/null +++ b/apps/dav/tests/unit/CardDAV/ImageExportPluginTest.php @@ -0,0 +1,151 @@ +<?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\CardDAV; + + +use OCA\DAV\CardDAV\ImageExportPlugin; +use OCP\ILogger; +use Sabre\CardDAV\Card; +use Sabre\DAV\Server; +use Sabre\DAV\Tree; +use Sabre\HTTP\RequestInterface; +use Sabre\HTTP\ResponseInterface; +use Test\TestCase; + +class ImageExportPluginTest extends TestCase { + + /** @var ResponseInterface | \PHPUnit_Framework_MockObject_MockObject */ + private $response; + /** @var RequestInterface | \PHPUnit_Framework_MockObject_MockObject */ + private $request; + /** @var ImageExportPlugin | \PHPUnit_Framework_MockObject_MockObject */ + private $plugin; + /** @var Server */ + private $server; + /** @var Tree | \PHPUnit_Framework_MockObject_MockObject */ + private $tree; + /** @var ILogger | \PHPUnit_Framework_MockObject_MockObject */ + private $logger; + + function setUp() { + parent::setUp(); + + $this->request = $this->getMockBuilder('Sabre\HTTP\RequestInterface')->getMock(); + $this->response = $this->getMockBuilder('Sabre\HTTP\ResponseInterface')->getMock(); + $this->server = $this->getMockBuilder('Sabre\DAV\Server')->getMock(); + $this->tree = $this->getMockBuilder('Sabre\DAV\Tree')->disableOriginalConstructor()->getMock(); + $this->server->tree = $this->tree; + $this->logger = $this->getMockBuilder('\OCP\ILogger')->getMock(); + + $this->plugin = $this->getMock('OCA\DAV\CardDAV\ImageExportPlugin', ['getPhoto'], [$this->logger]); + $this->plugin->initialize($this->server); + } + + /** + * @dataProvider providesQueryParams + * @param $param + */ + public function testQueryParams($param) { + $this->request->expects($this->once())->method('getQueryParameters')->willReturn($param); + $result = $this->plugin->httpGet($this->request, $this->response); + $this->assertTrue($result); + } + + public function providesQueryParams() { + return [ + [[]], + [['1']], + [['foo' => 'bar']], + ]; + } + + public function testNotACard() { + $this->request->expects($this->once())->method('getQueryParameters')->willReturn(['photo' => true]); + $this->request->expects($this->once())->method('getPath')->willReturn('/files/welcome.txt'); + $this->tree->expects($this->once())->method('getNodeForPath')->with('/files/welcome.txt')->willReturn(null); + $result = $this->plugin->httpGet($this->request, $this->response); + $this->assertTrue($result); + } + + /** + * @dataProvider providesCardWithOrWithoutPhoto + * @param bool $expected + * @param array $getPhotoResult + */ + public function testCardWithOrWithoutPhoto($expected, $getPhotoResult) { + $this->request->expects($this->once())->method('getQueryParameters')->willReturn(['photo' => true]); + $this->request->expects($this->once())->method('getPath')->willReturn('/files/welcome.txt'); + + $card = $this->getMockBuilder('Sabre\CardDAV\Card')->disableOriginalConstructor()->getMock(); + $this->tree->expects($this->once())->method('getNodeForPath')->with('/files/welcome.txt')->willReturn($card); + + $this->plugin->expects($this->once())->method('getPhoto')->willReturn($getPhotoResult); + + if (!$expected) { + $this->response->expects($this->once())->method('setHeader'); + $this->response->expects($this->once())->method('setStatus'); + $this->response->expects($this->once())->method('setBody'); + } + + $result = $this->plugin->httpGet($this->request, $this->response); + $this->assertEquals($expected, $result); + } + + public function providesCardWithOrWithoutPhoto() { + return [ + [true, null], + [false, ['Content-Type' => 'image/jpeg', 'body' => '1234']], + ]; + } + + /** + * @dataProvider providesPhotoData + * @param $expected + * @param $cardData + */ + public function testGetPhoto($expected, $cardData) { + /** @var Card | \PHPUnit_Framework_MockObject_MockObject $card */ + $card = $this->getMockBuilder('Sabre\CardDAV\Card')->disableOriginalConstructor()->getMock(); + $card->expects($this->once())->method('get')->willReturn($cardData); + + $this->plugin = new ImageExportPlugin($this->logger); + $this->plugin->initialize($this->server); + + $result = $this->plugin->getPhoto($card); + $this->assertEquals($expected, $result); + } + + public function providesPhotoData() { + return [ + 'empty vcard' => [false, ''], + 'vcard without PHOTO' => [false, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nEND:VCARD\r\n"], + 'vcard 3 with PHOTO' => [['Content-Type' => 'image/jpeg', 'body' => '12345'], "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nPHOTO;ENCODING=b;TYPE=JPEG:MTIzNDU=\r\nEND:VCARD\r\n"], + // + // TODO: these three below are not working - needs debugging + // + //'vcard 3 with PHOTO URL' => [['Content-Type' => 'image/jpeg', 'body' => '12345'], "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nPHOTO;TYPE=JPEG:http://example.org/photo.jpg\r\nEND:VCARD\r\n"], + //'vcard 4 with PHOTO' => [['Content-Type' => 'image/jpeg', 'body' => '12345'], "BEGIN:VCARD\r\nVERSION:4.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nPHOTO:data:image/jpeg;MTIzNDU=\r\nEND:VCARD\r\n"], + 'vcard 4 with PHOTO URL' => [['Content-Type' => 'image/jpeg', 'body' => 'http://example.org/photo.jpg'], "BEGIN:VCARD\r\nVERSION:4.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nPHOTO;MEDIATYPE=image/jpeg:http://example.org/photo.jpg\r\nEND:VCARD\r\n"], + ]; + } +} diff --git a/apps/encryption/l10n/sv.js b/apps/encryption/l10n/sv.js index b8541cfbb25..2e00f5d35ff 100644 --- a/apps/encryption/l10n/sv.js +++ b/apps/encryption/l10n/sv.js @@ -20,7 +20,7 @@ OC.L10N.register( "Could not update the private key password." : "Kunde inte uppdatera lösenord för den privata nyckeln", "The old password was not correct, please try again." : "Det gamla lösenordet var inte korrekt. Vänligen försök igen.", "The current log-in password was not correct, please try again." : "Det nuvarande inloggningslösenordet var inte korrekt. Vänligen försök igen.", - "Private key password successfully updated." : "Den privata nyckelns lösenord uppdaterades utan problem.", + "Private key password successfully updated." : "Den privata nyckelns lösenord uppdaterades.", "You need to migrate your encryption keys from the old encryption (ownCloud <= 8.0) to the new one. Please run 'occ encryption:migrate' or contact your administrator" : "Du behöver migrera dina krypteringsnycklar från den gamla krypteringen (ownCloud <= 8.0) till den nya. Kör 'occ encryption:migrate' eller kontakta din administratör", "Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." : "Ogiltig privat nyckel i krypteringsprogrammet. Vänligen uppdatera lösenordet till din privata nyckel under dina personliga inställningar för att återfå tillgång till dina krypterade filer.", "Encryption App is enabled but your keys are not initialized, please log-out and log-in again" : "Krypteringsprogrammet är aktiverat men dina nycklar är inte initierade. Vänligen logga ut och in igen", @@ -30,8 +30,11 @@ OC.L10N.register( "one-time password for server-side-encryption" : "engångslösenord för kryptering på serversidan", "Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Kan ej dekryptera denna fil, förmodligen är det en delad fil. Be ägaren av filen att dela den med dig.", "Can not read this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Filen kan inte läsas, troligtvis är det en delad fil. Be ägaren av filen att dela den med dig igen.", + "Hey there,\n\nthe admin enabled server-side-encryption. Your files were encrypted using the password '%s'.\n\nPlease login to the web interface, go to the section 'ownCloud basic encryption module' of your personal settings and update your encryption password by entering this password into the 'old log-in password' field and your current login-password.\n\n" : "Hej,\n\nadministratören har aktiverat kryptering på servern. Dina filer har krypterats med lösenordet '%s'.\n\nVänligen logga in i webbgränssnittet, gå till \"ownCloud baskrypteringsmodul\" i dina personliga inställningar och uppdatera ditt krypteringslösenord genom att mata in det här lösenordet i fältet \"gamla inloggningslösenordet\" och ditt nuvarande inloggningslösenord.\n\n", "The share will expire on %s." : "Utdelningen kommer att upphöra %s.", "Cheers!" : "Ha de fint!", + "Hey there,<br><br>the admin enabled server-side-encryption. Your files were encrypted using the password <strong>%s</strong>.<br><br>Please login to the web interface, go to the section \"ownCloud basic encryption module\" of your personal settings and update your encryption password by entering this password into the \"old log-in password\" field and your current login-password.<br><br>" : "Hej,<br><br>administratören har aktiverat kryptering på servern. Dina filer har krypterats med lösenordet <strong>%s</strong>.<br><br>Vänligen logga in i webbgränssnittet, gå till \"ownCloud baskrypteringsmodul\" i dina personliga inställningar och uppdatera ditt krypteringslösenord genom att mata in det här lösenordet i fältet \"gamla inloggningslösenordet\" och ditt nuvarande inloggningslösenord.<br><br>", + "Encrypt the home storage" : "Kryptera hemmalagringen", "Enabling this option encrypts all files stored on the main storage, otherwise only files on external storage will be encrypted" : "Aktivering av det här alternativet krypterar alla filer som är lagrade på huvudlagringsplatsen, annars kommer bara filer på extern lagringsplats att krypteras", "Enable recovery key" : "Aktivera återställningsnyckel", "Disable recovery key" : "Inaktivera återställningsnyckel", @@ -43,6 +46,7 @@ OC.L10N.register( "New recovery key password" : "Nytt lösenord för återställningsnyckeln", "Repeat new recovery key password" : "Upprepa nytt lösenord för återställningsnyckeln", "Change Password" : "Byt lösenord", + "ownCloud basic encryption module" : "ownCloud baskrypteringsmodul", "Your private key password no longer matches your log-in password." : "Ditt lösenord för din privata nyckel matchar inte längre ditt inloggningslösenord.", "Set your old private key password to your current log-in password:" : "Sätt ditt gamla privatnyckellösenord till ditt aktuella inloggningslösenord:", " If you don't remember your old password you can ask your administrator to recover your files." : "Om du inte kommer ihåg ditt gamla lösenord kan du be din administratör att återställa dina filer.", diff --git a/apps/encryption/l10n/sv.json b/apps/encryption/l10n/sv.json index 9a6919b4888..b06c1bc9189 100644 --- a/apps/encryption/l10n/sv.json +++ b/apps/encryption/l10n/sv.json @@ -18,7 +18,7 @@ "Could not update the private key password." : "Kunde inte uppdatera lösenord för den privata nyckeln", "The old password was not correct, please try again." : "Det gamla lösenordet var inte korrekt. Vänligen försök igen.", "The current log-in password was not correct, please try again." : "Det nuvarande inloggningslösenordet var inte korrekt. Vänligen försök igen.", - "Private key password successfully updated." : "Den privata nyckelns lösenord uppdaterades utan problem.", + "Private key password successfully updated." : "Den privata nyckelns lösenord uppdaterades.", "You need to migrate your encryption keys from the old encryption (ownCloud <= 8.0) to the new one. Please run 'occ encryption:migrate' or contact your administrator" : "Du behöver migrera dina krypteringsnycklar från den gamla krypteringen (ownCloud <= 8.0) till den nya. Kör 'occ encryption:migrate' eller kontakta din administratör", "Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." : "Ogiltig privat nyckel i krypteringsprogrammet. Vänligen uppdatera lösenordet till din privata nyckel under dina personliga inställningar för att återfå tillgång till dina krypterade filer.", "Encryption App is enabled but your keys are not initialized, please log-out and log-in again" : "Krypteringsprogrammet är aktiverat men dina nycklar är inte initierade. Vänligen logga ut och in igen", @@ -28,8 +28,11 @@ "one-time password for server-side-encryption" : "engångslösenord för kryptering på serversidan", "Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Kan ej dekryptera denna fil, förmodligen är det en delad fil. Be ägaren av filen att dela den med dig.", "Can not read this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Filen kan inte läsas, troligtvis är det en delad fil. Be ägaren av filen att dela den med dig igen.", + "Hey there,\n\nthe admin enabled server-side-encryption. Your files were encrypted using the password '%s'.\n\nPlease login to the web interface, go to the section 'ownCloud basic encryption module' of your personal settings and update your encryption password by entering this password into the 'old log-in password' field and your current login-password.\n\n" : "Hej,\n\nadministratören har aktiverat kryptering på servern. Dina filer har krypterats med lösenordet '%s'.\n\nVänligen logga in i webbgränssnittet, gå till \"ownCloud baskrypteringsmodul\" i dina personliga inställningar och uppdatera ditt krypteringslösenord genom att mata in det här lösenordet i fältet \"gamla inloggningslösenordet\" och ditt nuvarande inloggningslösenord.\n\n", "The share will expire on %s." : "Utdelningen kommer att upphöra %s.", "Cheers!" : "Ha de fint!", + "Hey there,<br><br>the admin enabled server-side-encryption. Your files were encrypted using the password <strong>%s</strong>.<br><br>Please login to the web interface, go to the section \"ownCloud basic encryption module\" of your personal settings and update your encryption password by entering this password into the \"old log-in password\" field and your current login-password.<br><br>" : "Hej,<br><br>administratören har aktiverat kryptering på servern. Dina filer har krypterats med lösenordet <strong>%s</strong>.<br><br>Vänligen logga in i webbgränssnittet, gå till \"ownCloud baskrypteringsmodul\" i dina personliga inställningar och uppdatera ditt krypteringslösenord genom att mata in det här lösenordet i fältet \"gamla inloggningslösenordet\" och ditt nuvarande inloggningslösenord.<br><br>", + "Encrypt the home storage" : "Kryptera hemmalagringen", "Enabling this option encrypts all files stored on the main storage, otherwise only files on external storage will be encrypted" : "Aktivering av det här alternativet krypterar alla filer som är lagrade på huvudlagringsplatsen, annars kommer bara filer på extern lagringsplats att krypteras", "Enable recovery key" : "Aktivera återställningsnyckel", "Disable recovery key" : "Inaktivera återställningsnyckel", @@ -41,6 +44,7 @@ "New recovery key password" : "Nytt lösenord för återställningsnyckeln", "Repeat new recovery key password" : "Upprepa nytt lösenord för återställningsnyckeln", "Change Password" : "Byt lösenord", + "ownCloud basic encryption module" : "ownCloud baskrypteringsmodul", "Your private key password no longer matches your log-in password." : "Ditt lösenord för din privata nyckel matchar inte längre ditt inloggningslösenord.", "Set your old private key password to your current log-in password:" : "Sätt ditt gamla privatnyckellösenord till ditt aktuella inloggningslösenord:", " If you don't remember your old password you can ask your administrator to recover your files." : "Om du inte kommer ihåg ditt gamla lösenord kan du be din administratör att återställa dina filer.", diff --git a/apps/federatedfilesharing/l10n/ast.js b/apps/federatedfilesharing/l10n/ast.js index 4ae5f2b9cc1..3b5affabbb9 100644 --- a/apps/federatedfilesharing/l10n/ast.js +++ b/apps/federatedfilesharing/l10n/ast.js @@ -1,6 +1,9 @@ OC.L10N.register( "federatedfilesharing", { - "Sharing %s failed, because this item is already shared with %s" : "Compartir %s falló, porque esti elementu yá ta compartiéndose con %s" + "Invalid Federated Cloud ID" : "Inválidu ID de Ñube Federada", + "Sharing %s failed, because this item is already shared with %s" : "Compartir %s falló, porque esti elementu yá ta compartiéndose con %s", + "Not allowed to create a federated share with the same user" : "Nun s'almite crear un recursu compartíu federáu col mesmu usuariu", + "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "Compartir %s falló, nun pudo atopase %s, pue qu'el servidor nun seya anguaño algamable." }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/federatedfilesharing/l10n/ast.json b/apps/federatedfilesharing/l10n/ast.json index 70d90ab6578..e5eb10cf14e 100644 --- a/apps/federatedfilesharing/l10n/ast.json +++ b/apps/federatedfilesharing/l10n/ast.json @@ -1,4 +1,7 @@ { "translations": { - "Sharing %s failed, because this item is already shared with %s" : "Compartir %s falló, porque esti elementu yá ta compartiéndose con %s" + "Invalid Federated Cloud ID" : "Inválidu ID de Ñube Federada", + "Sharing %s failed, because this item is already shared with %s" : "Compartir %s falló, porque esti elementu yá ta compartiéndose con %s", + "Not allowed to create a federated share with the same user" : "Nun s'almite crear un recursu compartíu federáu col mesmu usuariu", + "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "Compartir %s falló, nun pudo atopase %s, pue qu'el servidor nun seya anguaño algamable." },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/federatedfilesharing/lib/DiscoveryManager.php b/apps/federatedfilesharing/lib/DiscoveryManager.php index 2a4bb4b7f77..25af0a40fd5 100644 --- a/apps/federatedfilesharing/lib/DiscoveryManager.php +++ b/apps/federatedfilesharing/lib/DiscoveryManager.php @@ -84,7 +84,10 @@ class DiscoveryManager { // Read the data from the response body try { - $response = $this->client->get($remote . '/ocs-provider/'); + $response = $this->client->get($remote . '/ocs-provider/', [ + 'timeout' => 10, + 'connect_timeout' => 10, + ]); if($response->getStatusCode() === 200) { $decodedService = json_decode($response->getBody(), true); if(is_array($decodedService)) { diff --git a/apps/federatedfilesharing/lib/Notifications.php b/apps/federatedfilesharing/lib/Notifications.php index 18212b82c3e..fefa959ba37 100644 --- a/apps/federatedfilesharing/lib/Notifications.php +++ b/apps/federatedfilesharing/lib/Notifications.php @@ -287,7 +287,9 @@ class Notifications { $endpoint = $this->discoveryManager->getShareEndpoint($protocol . $remoteDomain); try { $response = $client->post($protocol . $remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT, [ - 'body' => $fields + 'body' => $fields, + 'timeout' => 10, + 'connect_timeout' => 10, ]); $result['result'] = $response->getBody(); $result['success'] = true; diff --git a/apps/federatedfilesharing/tests/DiscoveryManagerTest.php b/apps/federatedfilesharing/tests/DiscoveryManagerTest.php index 73f79b2c169..a9c324f0244 100644 --- a/apps/federatedfilesharing/tests/DiscoveryManagerTest.php +++ b/apps/federatedfilesharing/tests/DiscoveryManagerTest.php @@ -77,7 +77,10 @@ class DiscoveryManagerTest extends \Test\TestCase { $this->client ->expects($this->once()) ->method('get') - ->with('https://myhost.com/ocs-provider/', []) + ->with('https://myhost.com/ocs-provider/', [ + 'timeout' => 10, + 'connect_timeout' => 10, + ]) ->willReturn($response); $this->cache ->expects($this->at(0)) @@ -111,7 +114,10 @@ class DiscoveryManagerTest extends \Test\TestCase { $this->client ->expects($this->once()) ->method('get') - ->with('https://myhost.com/ocs-provider/', []) + ->with('https://myhost.com/ocs-provider/', [ + 'timeout' => 10, + 'connect_timeout' => 10, + ]) ->willReturn($response); $expectedResult = '/public.php/MyCustomEndpoint/'; @@ -131,7 +137,10 @@ class DiscoveryManagerTest extends \Test\TestCase { $this->client ->expects($this->once()) ->method('get') - ->with('https://myhost.com/ocs-provider/', []) + ->with('https://myhost.com/ocs-provider/', [ + 'timeout' => 10, + 'connect_timeout' => 10, + ]) ->willReturn($response); $expectedResult = '/public.php/webdav'; @@ -151,7 +160,10 @@ class DiscoveryManagerTest extends \Test\TestCase { $this->client ->expects($this->once()) ->method('get') - ->with('https://myhost.com/ocs-provider/', []) + ->with('https://myhost.com/ocs-provider/', [ + 'timeout' => 10, + 'connect_timeout' => 10, + ]) ->willReturn($response); $expectedResult = '/ocs/v2.php/cloud/MyCustomShareEndpoint'; @@ -171,7 +183,10 @@ class DiscoveryManagerTest extends \Test\TestCase { $this->client ->expects($this->once()) ->method('get') - ->with('https://myhost.com/ocs-provider/', []) + ->with('https://myhost.com/ocs-provider/', [ + 'timeout' => 10, + 'connect_timeout' => 10, + ]) ->willReturn($response); $this->cache ->expects($this->at(0)) diff --git a/apps/files/l10n/ast.js b/apps/files/l10n/ast.js index 6fe07fed765..092610b7140 100644 --- a/apps/files/l10n/ast.js +++ b/apps/files/l10n/ast.js @@ -21,6 +21,7 @@ OC.L10N.register( "Invalid directory." : "Direutoriu non válidu.", "Files" : "Ficheros", "All files" : "Tolos ficheros", + "File could not be found" : "Nun s'atopó el ficheru", "Home" : "Casa", "Close" : "Zarrar", "Favorites" : "Favoritos", @@ -28,8 +29,19 @@ OC.L10N.register( "Unable to upload {filename} as it is a directory or has 0 bytes" : "Nun pudo xubise {filename}, paez que ye un directoriu o tien 0 bytes", "Total file size {size1} exceeds upload limit {size2}" : "El tamañu de ficheru total {size1} perpasa la llende de xuba {size2}", "Not enough free space, you are uploading {size1} but only {size2} is left" : "Nun hai abondu espaciu llibre, tas xubiendo {size1} pero namái falta {size2}", + "Error uploading file \"{fileName}\": {message}" : "Fallu xubiendo'l ficheru \"{fileName}\": {message}", "Could not get result from server." : "Nun pudo obtenese'l resultáu del sirvidor.", "Uploading..." : "Xubiendo...", + "..." : "...", + "{hours}:{minutes}:{seconds} hour{plural_s} left" : "Falten {hours}:{minutes}:{seconds} hour{plural_s}", + "{hours}:{minutes}h" : "{hours}:{minutes}h", + "{minutes}:{seconds} minute{plural_s} left" : "Falten {minutes}:{seconds} minute{plural_s} ", + "{minutes}:{seconds}m" : "{minutes}:{seconds}m", + "{seconds} second{plural_s} left" : "Falten {seconds} second{plural_s}", + "{seconds}s" : "{seconds}s", + "Any moment now..." : "En cualquier momentu...", + "Soon..." : "Pronto...", + "{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} de {totalSize} ({bitrate})", "File upload is in progress. Leaving the page now will cancel the upload." : "La xuba del ficheru ta en progresu. Si dexes agora la páxina, va encaboxase la xuba.", "Actions" : "Aiciones", "Download" : "Descargar", @@ -43,6 +55,17 @@ OC.L10N.register( "Unable to determine date" : "Imposible determinar la fecha", "This operation is forbidden" : "La operación ta prohibida", "This directory is unavailable, please check the logs or contact the administrator" : "Esti direutoriu nun ta disponible, por favor verifica'l rexistru o contacta l'alministrador", + "Could not move \"{file}\", target exists" : "Nun pudo movese \"{file}\", destín yá esiste", + "Could not move \"{file}\"" : "Nun pudo movese \"{file}\"", + "{newName} already exists" : "{newName} yá esiste", + "Could not rename \"{fileName}\", it does not exist any more" : "Nun pudo renomase \"{fileName}\", yá nun esiste", + "The name \"{targetName}\" is already used in the folder \"{dir}\". Please choose a different name." : "El nome \"{targetName}\" yá ta n'usu na carpeta \"{dir}\". Por favor, escueyi un nome diferente.", + "Could not rename \"{fileName}\"" : "Nun pudo renomase \"{fileName}\"", + "Could not create file \"{file}\"" : "Nun pudo crease'l ficheru \"{file}\"", + "Could not create file \"{file}\" because it already exists" : "Nun pudo crease'l ficheru \"{file}\" porque yá esiste", + "Could not create folder \"{dir}\"" : "Nun pudo crease la carpeta \"{dir}\"", + "Could not create folder \"{dir}\" because it already exists" : "Nun pudo crease la carpeta \"{dir}\" porque yá esiste", + "Error deleting file \"{fileName}\"." : "Fallu borrando'l ficheru \"{fileName}\".", "No entries in this folder match '{filter}'" : "Nun concasa nenguna entrada nesta carpeta '{filter}'", "Name" : "Nome", "Size" : "Tamañu", @@ -64,6 +87,7 @@ OC.L10N.register( "_%n byte_::_%n bytes_" : ["%n bytes","%n bytes"], "Favorited" : "Favoritos", "Favorite" : "Favoritu", + "Local link" : "Enllaz llocal", "Folder" : "Carpeta", "New folder" : "Nueva carpeta", "{newname} already exists" : "{newname} yá existe", @@ -91,8 +115,12 @@ OC.L10N.register( "Maximum upload size" : "Tamañu máximu de xubida", "max. possible: " : "máx. posible:", "Save" : "Guardar", + "With PHP-FPM it might take 5 minutes for changes to be applied." : "Con PHP-FPM pue retrasase 5 minutos pa que los cambeos s'apliquen.", + "Missing permissions to edit from here." : "Falten permisos pa editar dende equí.", "Settings" : "Axustes", + "Show hidden files" : "Amosar ficheros ocultos", "WebDAV" : "WebDAV", + "Use this address to <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">access your Files via WebDAV</a>" : "Usa esta direición <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">p'acceder a los dos Ficheros via WebDAV</a>", "No files in here" : "Nun hai nengún ficheru equí", "Upload some content or sync with your devices!" : "¡Xuba algún conteníu o sincroniza colos sos preseos!", "No entries found in this folder" : "Nenguna entrada en esta carpeta", diff --git a/apps/files/l10n/ast.json b/apps/files/l10n/ast.json index 5b554ab8f93..7631a9149f2 100644 --- a/apps/files/l10n/ast.json +++ b/apps/files/l10n/ast.json @@ -19,6 +19,7 @@ "Invalid directory." : "Direutoriu non válidu.", "Files" : "Ficheros", "All files" : "Tolos ficheros", + "File could not be found" : "Nun s'atopó el ficheru", "Home" : "Casa", "Close" : "Zarrar", "Favorites" : "Favoritos", @@ -26,8 +27,19 @@ "Unable to upload {filename} as it is a directory or has 0 bytes" : "Nun pudo xubise {filename}, paez que ye un directoriu o tien 0 bytes", "Total file size {size1} exceeds upload limit {size2}" : "El tamañu de ficheru total {size1} perpasa la llende de xuba {size2}", "Not enough free space, you are uploading {size1} but only {size2} is left" : "Nun hai abondu espaciu llibre, tas xubiendo {size1} pero namái falta {size2}", + "Error uploading file \"{fileName}\": {message}" : "Fallu xubiendo'l ficheru \"{fileName}\": {message}", "Could not get result from server." : "Nun pudo obtenese'l resultáu del sirvidor.", "Uploading..." : "Xubiendo...", + "..." : "...", + "{hours}:{minutes}:{seconds} hour{plural_s} left" : "Falten {hours}:{minutes}:{seconds} hour{plural_s}", + "{hours}:{minutes}h" : "{hours}:{minutes}h", + "{minutes}:{seconds} minute{plural_s} left" : "Falten {minutes}:{seconds} minute{plural_s} ", + "{minutes}:{seconds}m" : "{minutes}:{seconds}m", + "{seconds} second{plural_s} left" : "Falten {seconds} second{plural_s}", + "{seconds}s" : "{seconds}s", + "Any moment now..." : "En cualquier momentu...", + "Soon..." : "Pronto...", + "{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} de {totalSize} ({bitrate})", "File upload is in progress. Leaving the page now will cancel the upload." : "La xuba del ficheru ta en progresu. Si dexes agora la páxina, va encaboxase la xuba.", "Actions" : "Aiciones", "Download" : "Descargar", @@ -41,6 +53,17 @@ "Unable to determine date" : "Imposible determinar la fecha", "This operation is forbidden" : "La operación ta prohibida", "This directory is unavailable, please check the logs or contact the administrator" : "Esti direutoriu nun ta disponible, por favor verifica'l rexistru o contacta l'alministrador", + "Could not move \"{file}\", target exists" : "Nun pudo movese \"{file}\", destín yá esiste", + "Could not move \"{file}\"" : "Nun pudo movese \"{file}\"", + "{newName} already exists" : "{newName} yá esiste", + "Could not rename \"{fileName}\", it does not exist any more" : "Nun pudo renomase \"{fileName}\", yá nun esiste", + "The name \"{targetName}\" is already used in the folder \"{dir}\". Please choose a different name." : "El nome \"{targetName}\" yá ta n'usu na carpeta \"{dir}\". Por favor, escueyi un nome diferente.", + "Could not rename \"{fileName}\"" : "Nun pudo renomase \"{fileName}\"", + "Could not create file \"{file}\"" : "Nun pudo crease'l ficheru \"{file}\"", + "Could not create file \"{file}\" because it already exists" : "Nun pudo crease'l ficheru \"{file}\" porque yá esiste", + "Could not create folder \"{dir}\"" : "Nun pudo crease la carpeta \"{dir}\"", + "Could not create folder \"{dir}\" because it already exists" : "Nun pudo crease la carpeta \"{dir}\" porque yá esiste", + "Error deleting file \"{fileName}\"." : "Fallu borrando'l ficheru \"{fileName}\".", "No entries in this folder match '{filter}'" : "Nun concasa nenguna entrada nesta carpeta '{filter}'", "Name" : "Nome", "Size" : "Tamañu", @@ -62,6 +85,7 @@ "_%n byte_::_%n bytes_" : ["%n bytes","%n bytes"], "Favorited" : "Favoritos", "Favorite" : "Favoritu", + "Local link" : "Enllaz llocal", "Folder" : "Carpeta", "New folder" : "Nueva carpeta", "{newname} already exists" : "{newname} yá existe", @@ -89,8 +113,12 @@ "Maximum upload size" : "Tamañu máximu de xubida", "max. possible: " : "máx. posible:", "Save" : "Guardar", + "With PHP-FPM it might take 5 minutes for changes to be applied." : "Con PHP-FPM pue retrasase 5 minutos pa que los cambeos s'apliquen.", + "Missing permissions to edit from here." : "Falten permisos pa editar dende equí.", "Settings" : "Axustes", + "Show hidden files" : "Amosar ficheros ocultos", "WebDAV" : "WebDAV", + "Use this address to <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">access your Files via WebDAV</a>" : "Usa esta direición <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">p'acceder a los dos Ficheros via WebDAV</a>", "No files in here" : "Nun hai nengún ficheru equí", "Upload some content or sync with your devices!" : "¡Xuba algún conteníu o sincroniza colos sos preseos!", "No entries found in this folder" : "Nenguna entrada en esta carpeta", diff --git a/apps/files/l10n/bg_BG.js b/apps/files/l10n/bg_BG.js index 3a00853fa18..d080e4b7c69 100644 --- a/apps/files/l10n/bg_BG.js +++ b/apps/files/l10n/bg_BG.js @@ -90,6 +90,7 @@ OC.L10N.register( "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Файловете, които се опитваш да качиш са по-големи от позволеното на този сървър.", "No favorites" : "Няма любими", "Files and folders you mark as favorite will show up here" : "Файловете и папките които отбелязваш като любими ще се показват тук", - "Text file" : "Текстов файл" + "Text file" : "Текстов файл", + "New text file.txt" : "Нов текст file.txt" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files/l10n/bg_BG.json b/apps/files/l10n/bg_BG.json index 4d60be20692..080390bd8a6 100644 --- a/apps/files/l10n/bg_BG.json +++ b/apps/files/l10n/bg_BG.json @@ -88,6 +88,7 @@ "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Файловете, които се опитваш да качиш са по-големи от позволеното на този сървър.", "No favorites" : "Няма любими", "Files and folders you mark as favorite will show up here" : "Файловете и папките които отбелязваш като любими ще се показват тук", - "Text file" : "Текстов файл" + "Text file" : "Текстов файл", + "New text file.txt" : "Нов текст file.txt" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/files/l10n/lb.js b/apps/files/l10n/lb.js index 30a86b000bb..d7888f9f197 100644 --- a/apps/files/l10n/lb.js +++ b/apps/files/l10n/lb.js @@ -9,11 +9,13 @@ OC.L10N.register( "Missing a temporary folder" : "Et feelt en temporären Dossier", "Failed to write to disk" : "Konnt net op den Disk schreiwen", "Files" : "Dateien", + "All files" : "All d'Fichieren", "Home" : "Doheem", "Close" : "Zoumaachen", "Favorites" : "Favoriten", "Upload cancelled." : "Upload ofgebrach.", "Uploading..." : "Lueden erop...", + "..." : "...", "File upload is in progress. Leaving the page now will cancel the upload." : "File Upload am gaang. Wann's de des Säit verléiss gëtt den Upload ofgebrach.", "Download" : "Download", "Rename" : "Ëmbenennen", diff --git a/apps/files/l10n/lb.json b/apps/files/l10n/lb.json index 99a6b4845da..a736e06570b 100644 --- a/apps/files/l10n/lb.json +++ b/apps/files/l10n/lb.json @@ -7,11 +7,13 @@ "Missing a temporary folder" : "Et feelt en temporären Dossier", "Failed to write to disk" : "Konnt net op den Disk schreiwen", "Files" : "Dateien", + "All files" : "All d'Fichieren", "Home" : "Doheem", "Close" : "Zoumaachen", "Favorites" : "Favoriten", "Upload cancelled." : "Upload ofgebrach.", "Uploading..." : "Lueden erop...", + "..." : "...", "File upload is in progress. Leaving the page now will cancel the upload." : "File Upload am gaang. Wann's de des Säit verléiss gëtt den Upload ofgebrach.", "Download" : "Download", "Rename" : "Ëmbenennen", diff --git a/apps/files/l10n/sv.js b/apps/files/l10n/sv.js index d2f7df4a3a4..b07bdf8b59b 100644 --- a/apps/files/l10n/sv.js +++ b/apps/files/l10n/sv.js @@ -21,6 +21,7 @@ OC.L10N.register( "Invalid directory." : "Felaktig mapp.", "Files" : "Filer", "All files" : "Alla filer", + "File could not be found" : "Fil kunde inte hittas", "Home" : "Hem", "Close" : "Stäng", "Favorites" : "Favoriter", @@ -32,6 +33,15 @@ OC.L10N.register( "Could not get result from server." : "Gick inte att hämta resultat från server.", "Uploading..." : "Laddar upp...", "..." : "...", + "{hours}:{minutes}:{seconds} hour{plural_s} left" : "{hours}:{minutes}:{seconds} timme/ar kvar", + "{hours}:{minutes}h" : "{hours}:{minutes}", + "{minutes}:{seconds} minute{plural_s} left" : "{minutes}:{seconds} minut(er) kvar", + "{minutes}:{seconds}m" : "{minutes}:{seconds}", + "{seconds} second{plural_s} left" : "{seconds} sekund(er) kvar", + "{seconds}s" : "{seconds}s", + "Any moment now..." : "Alldeles strax...", + "Soon..." : "Snart...", + "{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} av {totalSize} ({bitrate})", "File upload is in progress. Leaving the page now will cancel the upload." : "Filuppladdning pågår. Lämnar du sidan så avbryts uppladdningen.", "Actions" : "Åtgärder", "Download" : "Ladda ner", @@ -77,6 +87,7 @@ OC.L10N.register( "_%n byte_::_%n bytes_" : ["%n bytes","%n bytes"], "Favorited" : "Favoriserad", "Favorite" : "Favorit", + "Local link" : "Lokal länk", "Folder" : "Mapp", "New folder" : "Ny mapp", "{newname} already exists" : "{newname} existerar redan", diff --git a/apps/files/l10n/sv.json b/apps/files/l10n/sv.json index c2d1d464bc9..957088d80fc 100644 --- a/apps/files/l10n/sv.json +++ b/apps/files/l10n/sv.json @@ -19,6 +19,7 @@ "Invalid directory." : "Felaktig mapp.", "Files" : "Filer", "All files" : "Alla filer", + "File could not be found" : "Fil kunde inte hittas", "Home" : "Hem", "Close" : "Stäng", "Favorites" : "Favoriter", @@ -30,6 +31,15 @@ "Could not get result from server." : "Gick inte att hämta resultat från server.", "Uploading..." : "Laddar upp...", "..." : "...", + "{hours}:{minutes}:{seconds} hour{plural_s} left" : "{hours}:{minutes}:{seconds} timme/ar kvar", + "{hours}:{minutes}h" : "{hours}:{minutes}", + "{minutes}:{seconds} minute{plural_s} left" : "{minutes}:{seconds} minut(er) kvar", + "{minutes}:{seconds}m" : "{minutes}:{seconds}", + "{seconds} second{plural_s} left" : "{seconds} sekund(er) kvar", + "{seconds}s" : "{seconds}s", + "Any moment now..." : "Alldeles strax...", + "Soon..." : "Snart...", + "{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} av {totalSize} ({bitrate})", "File upload is in progress. Leaving the page now will cancel the upload." : "Filuppladdning pågår. Lämnar du sidan så avbryts uppladdningen.", "Actions" : "Åtgärder", "Download" : "Ladda ner", @@ -75,6 +85,7 @@ "_%n byte_::_%n bytes_" : ["%n bytes","%n bytes"], "Favorited" : "Favoriserad", "Favorite" : "Favorit", + "Local link" : "Lokal länk", "Folder" : "Mapp", "New folder" : "Ny mapp", "{newname} already exists" : "{newname} existerar redan", diff --git a/apps/files_external/l10n/lb.js b/apps/files_external/l10n/lb.js index 598458c731f..50bb06ff7f9 100644 --- a/apps/files_external/l10n/lb.js +++ b/apps/files_external/l10n/lb.js @@ -6,6 +6,7 @@ OC.L10N.register( "Username" : "Benotzernumm", "Password" : "Passwuert", "Save" : "Späicheren", + "None" : "Keng", "Port" : "Port", "Region" : "Regioun", "URL" : "URL", diff --git a/apps/files_external/l10n/lb.json b/apps/files_external/l10n/lb.json index 265d8ffda96..9f7aa84bb1a 100644 --- a/apps/files_external/l10n/lb.json +++ b/apps/files_external/l10n/lb.json @@ -4,6 +4,7 @@ "Username" : "Benotzernumm", "Password" : "Passwuert", "Save" : "Späicheren", + "None" : "Keng", "Port" : "Port", "Region" : "Regioun", "URL" : "URL", diff --git a/apps/files_external/l10n/sv.js b/apps/files_external/l10n/sv.js index dfa978f202a..3df7763a5fe 100644 --- a/apps/files_external/l10n/sv.js +++ b/apps/files_external/l10n/sv.js @@ -1,6 +1,7 @@ OC.L10N.register( "files_external", { + "Fetching request tokens failed. Verify that your app key and secret are correct." : "Fel vid hämtning av åtkomst-token. Verifiera att din app-nyckel och hemlighet stämmer.", "Step 1 failed. Exception: %s" : "Steg 1 flaerade. Undantag: %s", "Step 2 failed. Exception: %s" : "Steg 2 falerade. Undantag: %s", "External storage" : "Extern lagring", diff --git a/apps/files_external/l10n/sv.json b/apps/files_external/l10n/sv.json index 528588bd702..1070a322e92 100644 --- a/apps/files_external/l10n/sv.json +++ b/apps/files_external/l10n/sv.json @@ -1,4 +1,5 @@ { "translations": { + "Fetching request tokens failed. Verify that your app key and secret are correct." : "Fel vid hämtning av åtkomst-token. Verifiera att din app-nyckel och hemlighet stämmer.", "Step 1 failed. Exception: %s" : "Steg 1 flaerade. Undantag: %s", "Step 2 failed. Exception: %s" : "Steg 2 falerade. Undantag: %s", "External storage" : "Extern lagring", diff --git a/apps/files_external/lib/Command/ListCommand.php b/apps/files_external/lib/Command/ListCommand.php index 26133ea5ed5..bb43db17a8a 100644 --- a/apps/files_external/lib/Command/ListCommand.php +++ b/apps/files_external/lib/Command/ListCommand.php @@ -167,7 +167,9 @@ class ListCommand extends Base { $defaultMountOptions = [ 'encrypt' => true, 'previews' => true, - 'filesystem_check_changes' => 1 + 'filesystem_check_changes' => 1, + 'enable_sharing' => false, + 'encoding_compatibility' => false ]; $rows = array_map(function (StorageConfig $config) use ($userId, $defaultMountOptions, $full) { $storageConfig = $config->getBackendOptions(); diff --git a/apps/files_external/tests/env/start-swift-ceph.sh b/apps/files_external/tests/env/start-swift-ceph.sh index ba17b8f42dd..b73fa899a6d 100755 --- a/apps/files_external/tests/env/start-swift-ceph.sh +++ b/apps/files_external/tests/env/start-swift-ceph.sh @@ -74,6 +74,11 @@ if [[ $ready != 'READY=1' ]]; then docker logs $container exit 1 fi +if ! "$thisFolder"/env/wait-for-connection ${host} 80 600; then + echo "[ERROR] Waited 600 seconds, no response" >&2 + docker logs $container + exit 1 +fi echo "Waiting another 15 seconds" sleep 15 diff --git a/apps/files_sharing/ajax/external.php b/apps/files_sharing/ajax/external.php index 5cf86087f94..4a7a6096c91 100644 --- a/apps/files_sharing/ajax/external.php +++ b/apps/files_sharing/ajax/external.php @@ -77,7 +77,10 @@ $externalManager = new \OCA\Files_Sharing\External\Manager( // check for ssl cert if (substr($remote, 0, 5) === 'https') { try { - \OC::$server->getHTTPClientService()->newClient()->get($remote)->getBody(); + \OC::$server->getHTTPClientService()->newClient()->get($remote, [ + 'timeout' => 10, + 'connect_timeout' => 10, + ])->getBody(); } catch (\Exception $e) { \OCP\JSON::error(array('data' => array('message' => $l->t('Invalid or untrusted SSL certificate')))); exit; diff --git a/apps/files_sharing/l10n/lb.js b/apps/files_sharing/l10n/lb.js index fcbfd04c64f..0679858d818 100644 --- a/apps/files_sharing/l10n/lb.js +++ b/apps/files_sharing/l10n/lb.js @@ -5,6 +5,7 @@ OC.L10N.register( "No shared links" : "Keng gedeelte Linken", "Cancel" : "Ofbriechen", "Shared by" : "Gedeelt vun", + "Sharing" : "Gedeelt", "The password is wrong. Try again." : "Den Passwuert ass incorrect. Probeier ed nach eng keier.", "Password" : "Passwuert", "No entries found in this folder" : "Keng Elementer an dësem Dossier fonnt", diff --git a/apps/files_sharing/l10n/lb.json b/apps/files_sharing/l10n/lb.json index 5a466e560c6..9355d70a6fb 100644 --- a/apps/files_sharing/l10n/lb.json +++ b/apps/files_sharing/l10n/lb.json @@ -3,6 +3,7 @@ "No shared links" : "Keng gedeelte Linken", "Cancel" : "Ofbriechen", "Shared by" : "Gedeelt vun", + "Sharing" : "Gedeelt", "The password is wrong. Try again." : "Den Passwuert ass incorrect. Probeier ed nach eng keier.", "Password" : "Passwuert", "No entries found in this folder" : "Keng Elementer an dësem Dossier fonnt", diff --git a/apps/files_sharing/lib/External/Storage.php b/apps/files_sharing/lib/External/Storage.php index ca99393a1e0..29b9c7b563c 100644 --- a/apps/files_sharing/lib/External/Storage.php +++ b/apps/files_sharing/lib/External/Storage.php @@ -254,7 +254,10 @@ class Storage extends DAV implements ISharedStorage { $client = $this->httpClient->newClient(); try { - $result = $client->get($url)->getBody(); + $result = $client->get($url, [ + 'timeout' => 10, + 'connect_timeout' => 10, + ])->getBody(); $data = json_decode($result); $returnValue = (is_object($data) && !empty($data->version)); } catch (ConnectException $e) { @@ -301,7 +304,11 @@ class Storage extends DAV implements ISharedStorage { // TODO: DI $client = \OC::$server->getHTTPClientService()->newClient(); try { - $response = $client->post($url, ['body' => ['password' => $password]]); + $response = $client->post($url, [ + 'body' => ['password' => $password], + 'timeout' => 10, + 'connect_timeout' => 10, + ]); } catch (\GuzzleHttp\Exception\RequestException $e) { if ($e->getCode() === 401 || $e->getCode() === 403) { throw new ForbiddenException(); diff --git a/apps/files_sharing/tests/MountProviderTest.php b/apps/files_sharing/tests/MountProviderTest.php index 993d3654891..f69098cde7b 100644 --- a/apps/files_sharing/tests/MountProviderTest.php +++ b/apps/files_sharing/tests/MountProviderTest.php @@ -24,6 +24,7 @@ namespace OCA\Files_Sharing\Tests; use OCA\Files_Sharing\MountProvider; use OCP\Files\Storage\IStorageFactory; use OCP\IConfig; +use OCP\ILogger; use OCP\IUser; use OCP\Share\IShare; use OCP\Share\IManager; @@ -46,6 +47,9 @@ class MountProviderTest extends \Test\TestCase { /** @var IManager|\PHPUnit_Framework_MockObject_MockObject */ private $shareManager; + /** @var ILogger | \PHPUnit_Framework_MockObject_MockObject */ + private $logger; + public function setUp() { parent::setUp(); @@ -53,11 +57,13 @@ class MountProviderTest extends \Test\TestCase { $this->user = $this->getMock('OCP\IUser'); $this->loader = $this->getMock('OCP\Files\Storage\IStorageFactory'); $this->shareManager = $this->getMock('\OCP\Share\IManager'); + $this->logger = $this->getMock('\OCP\ILogger'); - $this->provider = new MountProvider($this->config, $this->shareManager); + $this->provider = new MountProvider($this->config, $this->shareManager, $this->logger); } public function testExcludeShares() { + /** @var IShare | \PHPUnit_Framework_MockObject_MockObject $share1 */ $share1 = $this->getMock('\OCP\Share\IShare'); $share1->expects($this->once()) ->method('getPermissions') @@ -79,6 +85,7 @@ class MountProviderTest extends \Test\TestCase { ->method('getPermissions') ->will($this->returnValue(0)); + /** @var IShare | \PHPUnit_Framework_MockObject_MockObject $share4 */ $share4 = $this->getMock('\OCP\Share\IShare'); $share4->expects($this->once()) ->method('getPermissions') diff --git a/apps/files_trashbin/js/filelist.js b/apps/files_trashbin/js/filelist.js index feed28d8fc7..510ab2c21bc 100644 --- a/apps/files_trashbin/js/filelist.js +++ b/apps/files_trashbin/js/filelist.js @@ -93,6 +93,8 @@ _renderRow: function(fileData, options) { options = options || {}; + // make a copy to avoid changing original object + fileData = _.extend({}, fileData); var dir = this.getCurrentDirectory(); var dirListing = dir !== '' && dir !== '/'; // show deleted time as mtime diff --git a/apps/files_trashbin/tests/js/filelistSpec.js b/apps/files_trashbin/tests/js/filelistSpec.js index 05caaf27865..5e9a4cf27d1 100644 --- a/apps/files_trashbin/tests/js/filelistSpec.js +++ b/apps/files_trashbin/tests/js/filelistSpec.js @@ -163,6 +163,28 @@ describe('OCA.Trashbin.FileList tests', function() { expect(fileList.findFileEl('One.txt.d11111')[0]).toEqual($tr[0]); }); + it('renders rows with the correct data when in root after calling setFiles with the same data set', function() { + // dir listing is false when in root + $('#dir').val('/'); + fileList.setFiles(testFiles); + fileList.setFiles(fileList.files); + var $rows = fileList.$el.find('tbody tr'); + var $tr = $rows.eq(0); + expect($rows.length).toEqual(4); + expect($tr.attr('data-id')).toEqual('1'); + expect($tr.attr('data-type')).toEqual('file'); + expect($tr.attr('data-file')).toEqual('One.txt.d11111'); + expect($tr.attr('data-size')).not.toBeDefined(); + expect($tr.attr('data-etag')).toEqual('abc'); + expect($tr.attr('data-permissions')).toEqual('9'); // read and delete + expect($tr.attr('data-mime')).toEqual('text/plain'); + expect($tr.attr('data-mtime')).toEqual('11111000'); + expect($tr.find('a.name').attr('href')).toEqual('#'); + + expect($tr.find('.nametext').text().trim()).toEqual('One.txt'); + + expect(fileList.findFileEl('One.txt.d11111')[0]).toEqual($tr[0]); + }); it('renders rows with the correct data when in subdirectory', function() { // dir listing is true when in a subdir $('#dir').val('/subdir'); diff --git a/apps/files_versions/lib/Storage.php b/apps/files_versions/lib/Storage.php index 638a1916f6a..93f8b848ce8 100644 --- a/apps/files_versions/lib/Storage.php +++ b/apps/files_versions/lib/Storage.php @@ -336,9 +336,16 @@ class Storage { // Restore encrypted version of the old file for the newly restored file // This has to happen manually here since the file is manually copied below $oldVersion = $users_view->getFileInfo($fileToRestore)->getEncryptedVersion(); + $oldFileInfo = $users_view->getFileInfo($fileToRestore); $newFileInfo = $files_view->getFileInfo($filename); $cache = $newFileInfo->getStorage()->getCache(); - $cache->update($newFileInfo->getId(), ['encrypted' => $oldVersion, 'encryptedVersion' => $oldVersion]); + $cache->update( + $newFileInfo->getId(), [ + 'encrypted' => $oldVersion, + 'encryptedVersion' => $oldVersion, + 'size' => $oldFileInfo->getSize() + ] + ); // rollback if (self::copyFileContents($users_view, $fileToRestore, 'files' . $filename)) { diff --git a/apps/updatenotification/l10n/lb.js b/apps/updatenotification/l10n/lb.js new file mode 100644 index 00000000000..e877f169fc4 --- /dev/null +++ b/apps/updatenotification/l10n/lb.js @@ -0,0 +1,15 @@ +OC.L10N.register( + "updatenotification", + { + "Update notifications" : "Notifikatiounen aktualiséieren", + "{version} is available. Get more information on how to update." : "{Versioun} ass verfügbar. Kréi méi Informatiounen doriwwer wéi d'Aktualiséierung ofleeft.", + "Updated channel" : "Aktualiséierte Kanal", + "ownCloud core" : "ownCloud Kär", + "Update for %1$s to version %2$s is available." : "D'Aktualiséierung fir %1$s op d'Versioun %2$s ass verfügbar.", + "A new version is available: %s" : "Eng nei Versioun ass verfügbar: %s", + "Open updater" : "Den Aktualiséierungsprogramm opmaachen", + "Your version is up to date." : "Déng Versioun ass aktualiséiert.", + "Checked on %s" : "Gepréift um %s", + "Update channel:" : "Kanal updaten:" +}, +"nplurals=2; plural=(n != 1);"); diff --git a/apps/updatenotification/l10n/lb.json b/apps/updatenotification/l10n/lb.json new file mode 100644 index 00000000000..a43883f6c3e --- /dev/null +++ b/apps/updatenotification/l10n/lb.json @@ -0,0 +1,13 @@ +{ "translations": { + "Update notifications" : "Notifikatiounen aktualiséieren", + "{version} is available. Get more information on how to update." : "{Versioun} ass verfügbar. Kréi méi Informatiounen doriwwer wéi d'Aktualiséierung ofleeft.", + "Updated channel" : "Aktualiséierte Kanal", + "ownCloud core" : "ownCloud Kär", + "Update for %1$s to version %2$s is available." : "D'Aktualiséierung fir %1$s op d'Versioun %2$s ass verfügbar.", + "A new version is available: %s" : "Eng nei Versioun ass verfügbar: %s", + "Open updater" : "Den Aktualiséierungsprogramm opmaachen", + "Your version is up to date." : "Déng Versioun ass aktualiséiert.", + "Checked on %s" : "Gepréift um %s", + "Update channel:" : "Kanal updaten:" +},"pluralForm" :"nplurals=2; plural=(n != 1);" +}
\ No newline at end of file diff --git a/apps/user_ldap/l10n/lb.js b/apps/user_ldap/l10n/lb.js index b340887548e..f62d2924488 100644 --- a/apps/user_ldap/l10n/lb.js +++ b/apps/user_ldap/l10n/lb.js @@ -1,14 +1,51 @@ OC.L10N.register( "user_ldap", { + "Failed to delete the server configuration" : "D'Server-Konfiguratioun konnt net geläscht ginn", + "The configuration is invalid: anonymous bind is not allowed." : "Dës Konfiguratioun ass ongëlteg: eng anonym Bindung ass net erlaabt.", + "Action does not exist" : "Dës Aktioun gëtt et net", + "Testing configuration…" : "D'Konfiguratioun gëtt getest...", + "Configuration incorrect" : "D'Konfiguratioun ass net korrekt", + "Configuration incomplete" : "D'Konfiguratioun ass net komplett", + "Configuration OK" : "Konfiguratioun OK", + "Select groups" : "Wiel Gruppen äus", + "Saving failed. Please make sure the database is in Operation. Reload before continuing." : "D'Späicheren huet net geklappt. W.e.g. géi sécher dass Datebank an der Operatioun ass. Lued nach emol éiers de weider fiers.", + "Select attributes" : "Wiel Attributer aus", + "User not found. Please check your login attributes and username. Effective filter (to copy-and-paste for command line validation): <br/>" : "De Benotzer konnt net fonnt ginn. W.e.g. kuck deng Login Attributer a Benotzernumm no. \n ", + "_%s group found_::_%s groups found_" : ["%s Grupp fonnt","%s Gruppe fonnt"], + "_%s user found_::_%s users found_" : ["%s Benotzer fonnt","%s Benotzere fonnt"], + "Could not find the desired feature" : "Déi gewënschte Funktioun konnt net fonnt ginn", + "Server" : "Server", "Users" : "Benotzer", "Groups" : "Gruppen", + "Test Configuration" : "Konfiguratiounstest", "Help" : "Hëllef", + "Groups meeting these criteria are available in %s:" : "D'Gruppen, déi dës Critèren erfëllen sinn am %s:", + "Only these object classes:" : "Nëmmen des Klass vun Objeten:", + "Only from these groups:" : "Nëmme vun dëse Gruppen:", + "Search groups" : "Sich Gruppen", + "Available groups" : "Disponibel Gruppen", + "Selected groups" : "Ausgewielte Gruppen", + "Test Loginname" : "Test Benotzernumm", + "Verify settings" : "Astellungen iwwerpréiwen", + "1. Server" : "1. Server", + "%s. Server:" : "%s. Server", + "Delete the current configuration" : "Läsch déi aktuell Konfiguratioun", "Host" : "Host", "Port" : "Port", + "User DN" : "Benotzer DN", "Password" : "Passwuert", + "Saving" : "Speicheren...", "Back" : "Zeréck", "Continue" : "Weider", - "Advanced" : "Avancéiert" + "Advanced" : "Erweidert", + "Connection Settings" : "D'Astellunge vun der Verbindung", + "Configuration Active" : "D'Konfiguratioun ass aktiv", + "When unchecked, this configuration will be skipped." : "Ouni Iwwerpréiwung wäert dës Konfiguratioun iwwergaange ginn.", + "Directory Settings" : "Dossier's Astellungen", + "in bytes" : "A Bytes", + "Email Field" : "Email Feld", + "Internal Username" : "Interne Benotzernumm", + "Internal Username Attribute:" : "Interne Benotzernumm Attribut:" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/lb.json b/apps/user_ldap/l10n/lb.json index 4b4d46427b8..e869a5821b1 100644 --- a/apps/user_ldap/l10n/lb.json +++ b/apps/user_ldap/l10n/lb.json @@ -1,12 +1,49 @@ { "translations": { + "Failed to delete the server configuration" : "D'Server-Konfiguratioun konnt net geläscht ginn", + "The configuration is invalid: anonymous bind is not allowed." : "Dës Konfiguratioun ass ongëlteg: eng anonym Bindung ass net erlaabt.", + "Action does not exist" : "Dës Aktioun gëtt et net", + "Testing configuration…" : "D'Konfiguratioun gëtt getest...", + "Configuration incorrect" : "D'Konfiguratioun ass net korrekt", + "Configuration incomplete" : "D'Konfiguratioun ass net komplett", + "Configuration OK" : "Konfiguratioun OK", + "Select groups" : "Wiel Gruppen äus", + "Saving failed. Please make sure the database is in Operation. Reload before continuing." : "D'Späicheren huet net geklappt. W.e.g. géi sécher dass Datebank an der Operatioun ass. Lued nach emol éiers de weider fiers.", + "Select attributes" : "Wiel Attributer aus", + "User not found. Please check your login attributes and username. Effective filter (to copy-and-paste for command line validation): <br/>" : "De Benotzer konnt net fonnt ginn. W.e.g. kuck deng Login Attributer a Benotzernumm no. \n ", + "_%s group found_::_%s groups found_" : ["%s Grupp fonnt","%s Gruppe fonnt"], + "_%s user found_::_%s users found_" : ["%s Benotzer fonnt","%s Benotzere fonnt"], + "Could not find the desired feature" : "Déi gewënschte Funktioun konnt net fonnt ginn", + "Server" : "Server", "Users" : "Benotzer", "Groups" : "Gruppen", + "Test Configuration" : "Konfiguratiounstest", "Help" : "Hëllef", + "Groups meeting these criteria are available in %s:" : "D'Gruppen, déi dës Critèren erfëllen sinn am %s:", + "Only these object classes:" : "Nëmmen des Klass vun Objeten:", + "Only from these groups:" : "Nëmme vun dëse Gruppen:", + "Search groups" : "Sich Gruppen", + "Available groups" : "Disponibel Gruppen", + "Selected groups" : "Ausgewielte Gruppen", + "Test Loginname" : "Test Benotzernumm", + "Verify settings" : "Astellungen iwwerpréiwen", + "1. Server" : "1. Server", + "%s. Server:" : "%s. Server", + "Delete the current configuration" : "Läsch déi aktuell Konfiguratioun", "Host" : "Host", "Port" : "Port", + "User DN" : "Benotzer DN", "Password" : "Passwuert", + "Saving" : "Speicheren...", "Back" : "Zeréck", "Continue" : "Weider", - "Advanced" : "Avancéiert" + "Advanced" : "Erweidert", + "Connection Settings" : "D'Astellunge vun der Verbindung", + "Configuration Active" : "D'Konfiguratioun ass aktiv", + "When unchecked, this configuration will be skipped." : "Ouni Iwwerpréiwung wäert dës Konfiguratioun iwwergaange ginn.", + "Directory Settings" : "Dossier's Astellungen", + "in bytes" : "A Bytes", + "Email Field" : "Email Feld", + "Internal Username" : "Interne Benotzernumm", + "Internal Username Attribute:" : "Interne Benotzernumm Attribut:" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/user_ldap/lib/Access.php b/apps/user_ldap/lib/Access.php index daeb7d942a4..4d0753696ff 100644 --- a/apps/user_ldap/lib/Access.php +++ b/apps/user_ldap/lib/Access.php @@ -732,7 +732,14 @@ class Access extends LDAPUtility implements IUserTools { $user->unmark(); $user = $this->userManager->get($ocName); } - $user->processAttributes($userRecord); + if ($user !== null) { + $user->processAttributes($userRecord); + } else { + \OC::$server->getLogger()->debug( + "The ldap user manager returned null for $ocName", + ['app'=>'user_ldap'] + ); + } } } |