diff options
108 files changed, 1712 insertions, 578 deletions
diff --git a/apps/dav/lib/carddav/addressbookimpl.php b/apps/dav/lib/carddav/addressbookimpl.php index 240e40c9688..1d7b55c1a5d 100644 --- a/apps/dav/lib/carddav/addressbookimpl.php +++ b/apps/dav/lib/carddav/addressbookimpl.php @@ -178,7 +178,8 @@ class AddressBookImpl implements IAddressBook { protected function createUid() { do { $uid = $this->getUid(); - } while (!empty($this->backend->getContact($uid . '.vcf'))); + $contact = $this->backend->getContact($uid . '.vcf'); + } while (!empty($contact)); return $uid; } @@ -213,6 +214,10 @@ class AddressBookImpl implements IAddressBook { foreach ($vCard->children as $property) { $result[$property->name] = $property->getValue(); } + if ($this->addressBookInfo['principaluri'] === 'principals/system/system' && + $this->addressBookInfo['uri'] === 'system') { + $result['isLocalSystemBook'] = true; + } return $result; } } diff --git a/apps/dav/lib/carddav/contactsmanager.php b/apps/dav/lib/carddav/contactsmanager.php index 3fe4de4a15e..7900c6ccae0 100644 --- a/apps/dav/lib/carddav/contactsmanager.php +++ b/apps/dav/lib/carddav/contactsmanager.php @@ -39,8 +39,18 @@ class ContactsManager { * @param string $userId */ public function setupContactsProvider(IManager $cm, $userId) { - $addressBooks = $this->backend->getAddressBooksForUser("principals/$userId"); - foreach ($addressBooks as $addressBookInfo) { + $addressBooks = $this->backend->getAddressBooksForUser("principals/users/$userId"); + $this->register($cm, $addressBooks); + $addressBooks = $this->backend->getAddressBooksForUser("principals/system/system"); + $this->register($cm, $addressBooks); + } + + /** + * @param IManager $cm + * @param $addressBooks + */ + private function register(IManager $cm, $addressBooks) { + foreach ($addressBooks as $addressBookInfo) { $addressBook = new \OCA\DAV\CardDAV\AddressBook($this->backend, $addressBookInfo); $cm->registerAddressBook( new AddressBookImpl( diff --git a/apps/dav/lib/rootcollection.php b/apps/dav/lib/rootcollection.php index b7c2995dbad..5be469e7b0c 100644 --- a/apps/dav/lib/rootcollection.php +++ b/apps/dav/lib/rootcollection.php @@ -68,7 +68,8 @@ class RootCollection extends SimpleCollection { \OC::$server->getSystemTagManager(), \OC::$server->getSystemTagObjectMapper(), \OC::$server->getUserSession(), - \OC::$server->getGroupManager() + \OC::$server->getGroupManager(), + \OC::$server->getRootFolder() ); $commentsCollection = new Comments\RootCollection( \OC::$server->getCommentsManager(), diff --git a/apps/dav/lib/systemtag/systemtagplugin.php b/apps/dav/lib/systemtag/systemtagplugin.php index 4636ed428b1..3348b431c47 100644 --- a/apps/dav/lib/systemtag/systemtagplugin.php +++ b/apps/dav/lib/systemtag/systemtagplugin.php @@ -104,12 +104,7 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { $path = $request->getPath(); // Making sure the node exists - try { - $node = $this->server->tree->getNodeForPath($path); - } catch (NotFound $e) { - return null; - } - + $node = $this->server->tree->getNodeForPath($path); if ($node instanceof SystemTagsByIdCollection || $node instanceof SystemTagsObjectMappingCollection) { $data = $request->getBodyAsString(); diff --git a/apps/dav/lib/systemtag/systemtagsobjecttypecollection.php b/apps/dav/lib/systemtag/systemtagsobjecttypecollection.php index 166e3219bc1..93cc7561928 100644 --- a/apps/dav/lib/systemtag/systemtagsobjecttypecollection.php +++ b/apps/dav/lib/systemtag/systemtagsobjecttypecollection.php @@ -25,12 +25,14 @@ namespace OCA\DAV\SystemTag; use Sabre\DAV\Exception\Forbidden; use Sabre\DAV\Exception\MethodNotAllowed; +use Sabre\DAV\Exception\NotFound; use Sabre\DAV\ICollection; use OCP\SystemTag\ISystemTagManager; use OCP\SystemTag\ISystemTagObjectMapper; use OCP\IUserSession; use OCP\IGroupManager; +use OCP\Files\IRootFolder; /** * Collection containing object ids by object type @@ -63,6 +65,11 @@ class SystemTagsObjectTypeCollection implements ICollection { private $userSession; /** + * @var IRootFolder + **/ + protected $fileRoot; + + /** * Constructor * * @param string $objectType object type @@ -70,19 +77,22 @@ class SystemTagsObjectTypeCollection implements ICollection { * @param ISystemTagObjectMapper $tagMapper * @param IUserSession $userSession * @param IGroupManager $groupManager + * @param IRootFolder $fileRoot */ public function __construct( $objectType, ISystemTagManager $tagManager, ISystemTagObjectMapper $tagMapper, IUserSession $userSession, - IGroupManager $groupManager + IGroupManager $groupManager, + IRootFolder $fileRoot ) { $this->tagManager = $tagManager; $this->tagMapper = $tagMapper; $this->objectType = $objectType; $this->userSession = $userSession; $this->groupManager = $groupManager; + $this->fileRoot = $fileRoot; } /** @@ -116,6 +126,10 @@ class SystemTagsObjectTypeCollection implements ICollection { * @param string $objectId */ function getChild($objectId) { + // make sure the object exists and is reachable + if(!$this->childExists($objectId)) { + throw new NotFound('Entity does not exist or is not available'); + } return new SystemTagsObjectMappingCollection( $objectId, $this->objectType, @@ -134,6 +148,13 @@ class SystemTagsObjectTypeCollection implements ICollection { * @param string $name */ function childExists($name) { + // TODO: make this more abstract + if ($this->objectType === 'files') { + // make sure the object is reachable for the current user + $userId = $this->userSession->getUser()->getUID(); + $nodes = $this->fileRoot->getUserFolder($userId)->getById(intval($name)); + return !empty($nodes); + } return true; } diff --git a/apps/dav/lib/systemtag/systemtagsrelationscollection.php b/apps/dav/lib/systemtag/systemtagsrelationscollection.php index 223aaac93d6..6af4edfc1ab 100644 --- a/apps/dav/lib/systemtag/systemtagsrelationscollection.php +++ b/apps/dav/lib/systemtag/systemtagsrelationscollection.php @@ -28,6 +28,7 @@ use Sabre\DAV\Exception\Forbidden; use Sabre\DAV\SimpleCollection; use OCP\IUserSession; use OCP\IGroupManager; +use OCP\Files\IRootFolder; class SystemTagsRelationsCollection extends SimpleCollection { @@ -38,12 +39,14 @@ class SystemTagsRelationsCollection extends SimpleCollection { * @param ISystemTagObjectMapper $tagMapper * @param IUserSession $userSession * @param IGroupManager $groupManager + * @param IRootFolder $fileRoot */ public function __construct( ISystemTagManager $tagManager, ISystemTagObjectMapper $tagMapper, IUserSession $userSession, - IGroupManager $groupManager + IGroupManager $groupManager, + IRootFolder $fileRoot ) { $children = [ new SystemTagsObjectTypeCollection( @@ -51,7 +54,8 @@ class SystemTagsRelationsCollection extends SimpleCollection { $tagManager, $tagMapper, $userSession, - $groupManager + $groupManager, + $fileRoot ), ]; diff --git a/apps/dav/tests/unit/appinfo/applicationtest.php b/apps/dav/tests/unit/appinfo/applicationtest.php index 36a75212ff5..7f533a185df 100644 --- a/apps/dav/tests/unit/appinfo/applicationtest.php +++ b/apps/dav/tests/unit/appinfo/applicationtest.php @@ -35,17 +35,28 @@ use Test\TestCase; class ApplicationTest extends TestCase { public function test() { $app = new Application(); + $c = $app->getContainer(); // assert service instances in the container are properly setup - $s = $app->getContainer()->query('ContactsManager'); + $s = $c->query('ContactsManager'); $this->assertInstanceOf('OCA\DAV\CardDAV\ContactsManager', $s); - $s = $app->getContainer()->query('CardDavBackend'); + $s = $c->query('CardDavBackend'); $this->assertInstanceOf('OCA\DAV\CardDAV\CardDavBackend', $s); + } + + public function testContactsManagerSetup() { + $app = new Application(); + $c = $app->getContainer(); + $c->registerService('CardDavBackend', function($c) { + $service = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')->disableOriginalConstructor()->getMock(); + $service->method('getAddressBooksForUser')->willReturn([]); + return $service; + }); // assert setupContactsProvider() is proper /** @var IManager | \PHPUnit_Framework_MockObject_MockObject $cm */ $cm = $this->getMockBuilder('OCP\Contacts\IManager')->disableOriginalConstructor()->getMock(); - $app->setupContactsProvider($cm, 'user01'); + $app->setupContactsProvider($cm, 'xxx'); $this->assertTrue(true); } } diff --git a/apps/dav/tests/unit/carddav/contactsmanagertest.php b/apps/dav/tests/unit/carddav/contactsmanagertest.php index c4ec4c29e39..5a384550df5 100644 --- a/apps/dav/tests/unit/carddav/contactsmanagertest.php +++ b/apps/dav/tests/unit/carddav/contactsmanagertest.php @@ -30,7 +30,7 @@ class ContactsManagerTest extends TestCase { public function test() { /** @var IManager | \PHPUnit_Framework_MockObject_MockObject $cm */ $cm = $this->getMockBuilder('OCP\Contacts\IManager')->disableOriginalConstructor()->getMock(); - $cm->expects($this->once())->method('registerAddressBook'); + $cm->expects($this->exactly(2))->method('registerAddressBook'); /** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject $backEnd */ $backEnd = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')->disableOriginalConstructor()->getMock(); $backEnd->method('getAddressBooksForUser')->willReturn([ diff --git a/apps/dav/tests/unit/systemtag/systemtagplugin.php b/apps/dav/tests/unit/systemtag/systemtagplugin.php index 873dd7088a8..b026451701f 100644 --- a/apps/dav/tests/unit/systemtag/systemtagplugin.php +++ b/apps/dav/tests/unit/systemtag/systemtagplugin.php @@ -272,6 +272,40 @@ class SystemTagPlugin extends \Test\TestCase { } /** + * @expectedException \Sabre\DAV\Exception\NotFound + */ + public function testCreateTagToUnknownNode() { + $systemTag = new SystemTag(1, 'Test', true, false); + + $node = $this->getMockBuilder('\OCA\DAV\SystemTag\SystemTagsObjectMappingCollection') + ->disableOriginalConstructor() + ->getMock(); + + $this->tree->expects($this->any()) + ->method('getNodeForPath') + ->will($this->throwException(new \Sabre\DAV\Exception\NotFound())); + + $this->tagManager->expects($this->never()) + ->method('createTag'); + + $node->expects($this->never()) + ->method('createFile'); + + $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('/systemtags-relations/files/12')); + + $this->plugin->httpPost($request, $response); + } + + /** * @dataProvider nodeClassProvider * @expectedException Sabre\DAV\Exception\Conflict */ diff --git a/apps/dav/tests/unit/systemtag/systemtagsobjecttypecollection.php b/apps/dav/tests/unit/systemtag/systemtagsobjecttypecollection.php index e6d94803cc0..1d4264f94f9 100644 --- a/apps/dav/tests/unit/systemtag/systemtagsobjecttypecollection.php +++ b/apps/dav/tests/unit/systemtag/systemtagsobjecttypecollection.php @@ -38,6 +38,11 @@ class SystemTagsObjectTypeCollection extends \Test\TestCase { */ private $tagMapper; + /** + * @var \OCP\Files\Folder + */ + private $userFolder; + protected function setUp() { parent::setUp(); @@ -58,12 +63,21 @@ class SystemTagsObjectTypeCollection extends \Test\TestCase { ->with('testuser') ->will($this->returnValue(true)); + $this->userFolder = $this->getMock('\OCP\Files\Folder'); + + $fileRoot = $this->getMock('\OCP\Files\IRootFolder'); + $fileRoot->expects($this->any()) + ->method('getUserfolder') + ->with('testuser') + ->will($this->returnValue($this->userFolder)); + $this->node = new \OCA\DAV\SystemTag\SystemTagsObjectTypeCollection( 'files', $this->tagManager, $this->tagMapper, $userSession, - $groupManager + $groupManager, + $fileRoot ); } @@ -82,10 +96,25 @@ class SystemTagsObjectTypeCollection extends \Test\TestCase { } public function testGetChild() { - $childNode = $this->node->getChild('files'); + $this->userFolder->expects($this->once()) + ->method('getById') + ->with('555') + ->will($this->returnValue([true])); + $childNode = $this->node->getChild('555'); $this->assertInstanceOf('\OCA\DAV\SystemTag\SystemTagsObjectMappingCollection', $childNode); - $this->assertEquals('files', $childNode->getName()); + $this->assertEquals('555', $childNode->getName()); + } + + /** + * @expectedException Sabre\DAV\Exception\NotFound + */ + public function testGetChildWithoutAccess() { + $this->userFolder->expects($this->once()) + ->method('getById') + ->with('555') + ->will($this->returnValue([])); + $this->node->getChild('555'); } /** @@ -96,9 +125,21 @@ class SystemTagsObjectTypeCollection extends \Test\TestCase { } public function testChildExists() { + $this->userFolder->expects($this->once()) + ->method('getById') + ->with('123') + ->will($this->returnValue([true])); $this->assertTrue($this->node->childExists('123')); } + public function testChildExistsWithoutAccess() { + $this->userFolder->expects($this->once()) + ->method('getById') + ->with('555') + ->will($this->returnValue([])); + $this->assertFalse($this->node->childExists('555')); + } + /** * @expectedException Sabre\DAV\Exception\Forbidden */ diff --git a/apps/federation/lib/syncfederationaddressbooks.php b/apps/federation/lib/syncfederationaddressbooks.php index 86fc4179dc4..6419fdddf8e 100644 --- a/apps/federation/lib/syncfederationaddressbooks.php +++ b/apps/federation/lib/syncfederationaddressbooks.php @@ -46,7 +46,7 @@ class SyncFederationAddressBooks { '{DAV:}displayname' => $url ]; try { - $newToken = $this->syncService->syncRemoteAddressBook($url, 'system', $sharedSecret, $syncToken, $targetPrincipal, $targetBookId, $targetBookProperties); + $newToken = $this->syncService->syncRemoteAddressBook($url, 'system', $sharedSecret, $syncToken, $targetBookId, $targetPrincipal, $targetBookProperties); if ($newToken !== $syncToken) { $this->dbHandler->setServerStatus($url, TrustedServers::STATUS_OK, $newToken); } diff --git a/apps/files/command/scan.php b/apps/files/command/scan.php index 4a68429897a..3251682445c 100644 --- a/apps/files/command/scan.php +++ b/apps/files/command/scan.php @@ -26,20 +26,19 @@ namespace OCA\Files\Command; +use OC\Core\Command\Base; use OC\ForbiddenException; use OCP\Files\StorageNotAvailableException; -use Symfony\Component\Console\Command\Command; +use OCP\IUserManager; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Helper\Table; -class Scan extends Command { +class Scan extends Base { - /** - * @var \OC\User\Manager $userManager - */ + /** @var IUserManager $userManager */ private $userManager; /** @var float */ protected $execTime = 0; @@ -47,19 +46,15 @@ class Scan extends Command { protected $foldersCounter = 0; /** @var int */ protected $filesCounter = 0; - /** @var bool */ - protected $interrupted = false; - /** @var bool */ - protected $php_pcntl_signal = true; - - - public function __construct(\OC\User\Manager $userManager) { + public function __construct(IUserManager $userManager) { $this->userManager = $userManager; parent::__construct(); } protected function configure() { + parent::configure(); + $this ->setName('files:scan') ->setDescription('rescan filesystem') @@ -96,7 +91,7 @@ class Scan extends Command { protected function scanFiles($user, $path, $verbose, OutputInterface $output) { $scanner = new \OC\Files\Utils\Scanner($user, \OC::$server->getDatabaseConnection(), \OC::$server->getLogger()); - # check on each file/folder if there was a user interrupt (ctrl-c) and throw an exeption + # check on each file/folder if there was a user interrupt (ctrl-c) and throw an exception # printout and count if ($verbose) { $scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', function ($path) use ($output) { @@ -118,13 +113,13 @@ class Scan extends Command { }); # count only } else { - $scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', function ($path) use ($output) { + $scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', function () use ($output) { $this->filesCounter += 1; if ($this->hasBeenInterrupted()) { throw new \Exception('ctrl-c'); } }); - $scanner->listen('\OC\Files\Utils\Scanner', 'scanFolder', function ($path) use ($output) { + $scanner->listen('\OC\Files\Utils\Scanner', 'scanFolder', function () use ($output) { $this->foldersCounter += 1; if ($this->hasBeenInterrupted()) { throw new \Exception('ctrl-c'); @@ -194,7 +189,7 @@ class Scan extends Command { $path = $inputPath ? $inputPath : '/' . $user; $user_count += 1; if ($this->userManager->userExists($user)) { - # add an extra line when verbose is set to optical seperate users + # add an extra line when verbose is set to optical separate users if ($verbose) {$output->writeln(""); } $output->writeln("Starting scan for user $user_count out of $users_total ($user)"); # full: printout data if $verbose was set @@ -212,10 +207,8 @@ class Scan extends Command { if (!$quiet) { $this->presentStats($output); } - } - /** * Initialises some useful tools for the Command */ @@ -224,46 +217,8 @@ class Scan extends Command { $this->execTime = -microtime(true); // Convert PHP errors to exceptions set_error_handler([$this, 'exceptionErrorHandler'], E_ALL); - - // check if the php pcntl_signal functions are accessible - if (function_exists('pcntl_signal')) { - // Collect interrupts and notify the running command - pcntl_signal(SIGTERM, [$this, 'cancelOperation']); - pcntl_signal(SIGINT, [$this, 'cancelOperation']); - } else { - $this->php_pcntl_signal = false; - } - } - - - /** - * Changes the status of the command to "interrupted" if ctrl-c has been pressed - * - * Gives a chance to the command to properly terminate what it's doing - */ - private function cancelOperation() { - $this->interrupted = true; } - - /** - * @return bool - */ - protected function hasBeenInterrupted() { - // return always false if pcntl_signal functions are not accessible - if ($this->php_pcntl_signal) { - pcntl_signal_dispatch(); - if ($this->interrupted) { - return true; - } else { - return false; - } - } else { - return false; - } - } - - /** * Processes PHP errors as exceptions in order to be able to keep track of problems * @@ -284,7 +239,6 @@ class Scan extends Command { throw new \ErrorException($message, 0, $severity, $file, $line); } - /** * @param OutputInterface $output */ @@ -300,7 +254,6 @@ class Scan extends Command { $this->showSummary($headers, null, $output); } - /** * Shows a summary of operations * @@ -332,10 +285,9 @@ class Scan extends Command { */ protected function formatExecTime() { list($secs, $tens) = explode('.', sprintf("%.1f", ($this->execTime))); - # add the following to $niceDate if you want to have microsecons added: . '.' . $tens; - $niceDate = date('H:i:s', $secs); - return $niceDate; + # if you want to have microseconds add this: . '.' . $tens; + return date('H:i:s', $secs); } } diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js index ccb1e858fa0..26df203091e 100644 --- a/apps/files_external/js/settings.js +++ b/apps/files_external/js/settings.js @@ -23,6 +23,10 @@ var MOUNT_OPTIONS_DROPDOWN_TEMPLATE = ' <label for="mountOptionsPreviews">{{t "files_external" "Enable previews"}}</label>' + ' </div>' + ' <div class="optionRow">' + + ' <input id="mountOptionsSharing" name="enable_sharing" type="checkbox" value="true" checked="checked"/>' + + ' <label for="mountOptionsSharing">{{t "files_external" "Enable sharing"}}</label>' + + ' </div>' + + ' <div class="optionRow">' + ' <label for="mountOptionsFilesystemCheck">{{t "files_external" "Check for changes"}}</label>' + ' <select id="mountOptionsFilesystemCheck" name="filesystem_check_changes" data-type="int">' + ' <option value="0">{{t "files_external" "Never"}}</option>' + @@ -35,6 +39,7 @@ var MOUNT_OPTIONS_DROPDOWN_TEMPLATE = templates therefore they are duplicated here t("files_external", "Enable encryption") t("files_external", "Enable previews") + t("files_external", "Enable sharing") t("files_external", "Check for changes") t("files_external", "Never") t("files_external", "Once every direct access") @@ -582,6 +587,19 @@ MountOptionsDropdown.prototype = { var MountConfigListView = function($el, options) { this.initialize($el, options); }; + +MountConfigListView.ParameterFlags = { + OPTIONAL: 1, + USER_PROVIDED: 2 +}; + +MountConfigListView.ParameterTypes = { + TEXT: 0, + BOOLEAN: 1, + PASSWORD: 2, + HIDDEN: 3 +}; + /** * @memberOf OCA.External.Settings */ @@ -870,6 +888,7 @@ MountConfigListView.prototype = _.extend({ $tr.find('input.mountOptions').val(JSON.stringify({ 'encrypt': true, 'previews': true, + 'enable_sharing': true, 'filesystem_check_changes': 1 })); } @@ -955,16 +974,15 @@ MountConfigListView.prototype = _.extend({ */ writeParameterInput: function($td, parameter, placeholder, classes) { var hasFlag = function(flag) { - return placeholder.indexOf(flag) !== -1; + return (placeholder.flags & flag) === flag; }; classes = $.isArray(classes) ? classes : []; classes.push('added'); - if (placeholder.indexOf('&') === 0) { + if (hasFlag(MountConfigListView.ParameterFlags.OPTIONAL)) { classes.push('optional'); - placeholder = placeholder.substring(1); } - if (hasFlag('@')) { + if (hasFlag(MountConfigListView.ParameterFlags.USER_PROVIDED)) { if (this._isPersonal) { classes.push('user_provided'); } else { @@ -974,17 +992,13 @@ MountConfigListView.prototype = _.extend({ var newElement; - var trimmedPlaceholder = placeholder; - var flags = ['@', '*', '!', '#', '&']; // used to determine what kind of parameter - while(flags.indexOf(trimmedPlaceholder[0]) !== -1) { - trimmedPlaceholder = trimmedPlaceholder.substr(1); - } - if (hasFlag('*')) { + var trimmedPlaceholder = placeholder.value; + if (placeholder.type === MountConfigListView.ParameterTypes.PASSWORD) { newElement = $('<input type="password" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" placeholder="'+ trimmedPlaceholder+'" />'); - } else if (hasFlag('!')) { + } else if (placeholder.type === MountConfigListView.ParameterTypes.BOOLEAN) { var checkboxId = _.uniqueId('checkbox_'); newElement = $('<input type="checkbox" id="'+checkboxId+'" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" /><label for="'+checkboxId+'">'+ trimmedPlaceholder+'</label>'); - } else if (hasFlag('#')) { + } else if (placeholder.type === MountConfigListView.ParameterTypes.HIDDEN) { newElement = $('<input type="hidden" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" />'); } else { newElement = $('<input type="text" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" placeholder="'+ trimmedPlaceholder+'" />'); @@ -1245,7 +1259,7 @@ MountConfigListView.prototype = _.extend({ var storage = this.getStorageConfig($tr); var $toggle = $tr.find('.mountOptionsToggle'); var dropDown = new MountOptionsDropdown(); - var enabledOptions = ['previews', 'filesystem_check_changes']; + var enabledOptions = ['previews', 'filesystem_check_changes', 'enable_sharing']; if (this._encryptionEnabled) { enabledOptions.push('encrypt'); } diff --git a/apps/files_external/l10n/cs_CZ.js b/apps/files_external/l10n/cs_CZ.js index 5ac3b82d67f..56a8147fd99 100644 --- a/apps/files_external/l10n/cs_CZ.js +++ b/apps/files_external/l10n/cs_CZ.js @@ -61,10 +61,7 @@ OC.L10N.register( "Identity endpoint URL" : "Identifikační koncový bod URL", "Rackspace" : "Rackspace", "API key" : "Klíč API", - "Login credentials" : "Přihlašovací údaje", "Username and password" : "Uživatelské jméno a heslo", - "Session credentials" : "Přihlašovací údaje sezení", - "User provided" : "Poskytnuto uživatelem", "RSA public key" : "RSA veřejný klíč", "Public key" : "Veřejný klíč", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/cs_CZ.json b/apps/files_external/l10n/cs_CZ.json index a21b78f02c7..f22bbc25e35 100644 --- a/apps/files_external/l10n/cs_CZ.json +++ b/apps/files_external/l10n/cs_CZ.json @@ -59,10 +59,7 @@ "Identity endpoint URL" : "Identifikační koncový bod URL", "Rackspace" : "Rackspace", "API key" : "Klíč API", - "Login credentials" : "Přihlašovací údaje", "Username and password" : "Uživatelské jméno a heslo", - "Session credentials" : "Přihlašovací údaje sezení", - "User provided" : "Poskytnuto uživatelem", "RSA public key" : "RSA veřejný klíč", "Public key" : "Veřejný klíč", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/da.js b/apps/files_external/l10n/da.js index 6b6db06d817..70f43819496 100644 --- a/apps/files_external/l10n/da.js +++ b/apps/files_external/l10n/da.js @@ -50,7 +50,6 @@ OC.L10N.register( "Rackspace" : "Hyldeplads", "API key" : "API nøgle", "Username and password" : "Brugernavn og kodeord", - "Session credentials" : "Brugeroplysninger for session", "RSA public key" : "RSA offentlig nøgle", "Public key" : "Offentlig nøgle", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/da.json b/apps/files_external/l10n/da.json index 61b1bab2d55..aaeaaa58ae0 100644 --- a/apps/files_external/l10n/da.json +++ b/apps/files_external/l10n/da.json @@ -48,7 +48,6 @@ "Rackspace" : "Hyldeplads", "API key" : "API nøgle", "Username and password" : "Brugernavn og kodeord", - "Session credentials" : "Brugeroplysninger for session", "RSA public key" : "RSA offentlig nøgle", "Public key" : "Offentlig nøgle", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/el.js b/apps/files_external/l10n/el.js index bae61dee741..c04d3d015d3 100644 --- a/apps/files_external/l10n/el.js +++ b/apps/files_external/l10n/el.js @@ -52,7 +52,6 @@ OC.L10N.register( "Rackspace" : "Rackspace", "API key" : "Κλειδί Google API", "Username and password" : "Όνομα χρήστη και κωδικός πρόσβασης", - "Session credentials" : "Διαπιστευτήρια συνεδρίας", "RSA public key" : "Δημόσιο κλειδί RSA", "Public key" : "Δημόσιο κλειδί", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/el.json b/apps/files_external/l10n/el.json index e85059d88ba..98a6d18bfc3 100644 --- a/apps/files_external/l10n/el.json +++ b/apps/files_external/l10n/el.json @@ -50,7 +50,6 @@ "Rackspace" : "Rackspace", "API key" : "Κλειδί Google API", "Username and password" : "Όνομα χρήστη και κωδικός πρόσβασης", - "Session credentials" : "Διαπιστευτήρια συνεδρίας", "RSA public key" : "Δημόσιο κλειδί RSA", "Public key" : "Δημόσιο κλειδί", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/es.js b/apps/files_external/l10n/es.js index 6db3afd6441..8a49dd4ec05 100644 --- a/apps/files_external/l10n/es.js +++ b/apps/files_external/l10n/es.js @@ -61,7 +61,6 @@ OC.L10N.register( "Rackspace" : "Espacio de Rack", "API key" : "Clave API", "Username and password" : "Nombre de usuario y contraseña", - "Session credentials" : "Credenciales de la sesión", "RSA public key" : "Clave pública RSA", "Public key" : "Clave pública", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/es.json b/apps/files_external/l10n/es.json index e9a3e317679..c3b81338776 100644 --- a/apps/files_external/l10n/es.json +++ b/apps/files_external/l10n/es.json @@ -59,7 +59,6 @@ "Rackspace" : "Espacio de Rack", "API key" : "Clave API", "Username and password" : "Nombre de usuario y contraseña", - "Session credentials" : "Credenciales de la sesión", "RSA public key" : "Clave pública RSA", "Public key" : "Clave pública", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/fi_FI.js b/apps/files_external/l10n/fi_FI.js index 23b9227348c..ec969586d6d 100644 --- a/apps/files_external/l10n/fi_FI.js +++ b/apps/files_external/l10n/fi_FI.js @@ -45,9 +45,10 @@ OC.L10N.register( "Password" : "Salasana", "Rackspace" : "Rackspace", "API key" : "API-avain", - "Login credentials" : "Kirjautumistiedot", + "Log-in credentials, save in database" : "Kirjautumistiedot, tallenna tietokantaan", "Username and password" : "Käyttäjätunnus ja salasana", - "Session credentials" : "Istunnon tunnistetiedot", + "Log-in credentials, save in session" : "Kirjautumistiedot, tallenna istuntoon", + "User entered, store in database" : "Käyttäjän määrittämä, tallenna tietokantaan", "RSA public key" : "Julkinen RSA-avain", "Public key" : "Julkinen avain", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/fi_FI.json b/apps/files_external/l10n/fi_FI.json index 2c778205e10..8c39acff034 100644 --- a/apps/files_external/l10n/fi_FI.json +++ b/apps/files_external/l10n/fi_FI.json @@ -43,9 +43,10 @@ "Password" : "Salasana", "Rackspace" : "Rackspace", "API key" : "API-avain", - "Login credentials" : "Kirjautumistiedot", + "Log-in credentials, save in database" : "Kirjautumistiedot, tallenna tietokantaan", "Username and password" : "Käyttäjätunnus ja salasana", - "Session credentials" : "Istunnon tunnistetiedot", + "Log-in credentials, save in session" : "Kirjautumistiedot, tallenna istuntoon", + "User entered, store in database" : "Käyttäjän määrittämä, tallenna tietokantaan", "RSA public key" : "Julkinen RSA-avain", "Public key" : "Julkinen avain", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/fr.js b/apps/files_external/l10n/fr.js index 0c2bb063b29..cc1c1bc693c 100644 --- a/apps/files_external/l10n/fr.js +++ b/apps/files_external/l10n/fr.js @@ -18,6 +18,7 @@ OC.L10N.register( "Unsatisfied authentication mechanism parameters" : "Paramètres manquants pour la méthode d'authentification", "Insufficient data: %s" : "Données insuffisantes : %s", "%s" : "%s", + "Storage with id \"%i\" is not user editable" : "Le support de stockage d'id \"%i\" n'est pas modifiable par les utilisateurs", "Personal" : "Personnel", "System" : "Système", "Grant access" : "Autoriser l'accès", @@ -60,9 +61,7 @@ OC.L10N.register( "Identity endpoint URL" : "Identity endpoint URL", "Rackspace" : "Rackspace", "API key" : "Clé API", - "Login credentials" : "Informations d'identification", "Username and password" : "Nom d'utilisateur et mot de passe", - "Session credentials" : "Informations d'identification de session", "RSA public key" : "Clé publique RSA", "Public key" : "Clef publique", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/fr.json b/apps/files_external/l10n/fr.json index 6f2fb0615bd..47a70fcd12a 100644 --- a/apps/files_external/l10n/fr.json +++ b/apps/files_external/l10n/fr.json @@ -16,6 +16,7 @@ "Unsatisfied authentication mechanism parameters" : "Paramètres manquants pour la méthode d'authentification", "Insufficient data: %s" : "Données insuffisantes : %s", "%s" : "%s", + "Storage with id \"%i\" is not user editable" : "Le support de stockage d'id \"%i\" n'est pas modifiable par les utilisateurs", "Personal" : "Personnel", "System" : "Système", "Grant access" : "Autoriser l'accès", @@ -58,9 +59,7 @@ "Identity endpoint URL" : "Identity endpoint URL", "Rackspace" : "Rackspace", "API key" : "Clé API", - "Login credentials" : "Informations d'identification", "Username and password" : "Nom d'utilisateur et mot de passe", - "Session credentials" : "Informations d'identification de session", "RSA public key" : "Clé publique RSA", "Public key" : "Clef publique", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/he.js b/apps/files_external/l10n/he.js index 83ff5a524d0..d963d796428 100644 --- a/apps/files_external/l10n/he.js +++ b/apps/files_external/l10n/he.js @@ -61,10 +61,10 @@ OC.L10N.register( "Identity endpoint URL" : "זהות נתיב נקודת קצה", "Rackspace" : "חץ אחורה", "API key" : "מפתח API", - "Login credentials" : "פרטי הכניסה", + "Log-in credentials, save in database" : "אישורי התחברות, נשמרים במסד הנתונים", "Username and password" : "שם משתמש וסיסמא", - "Session credentials" : "אישורי סשן", - "User provided" : "סופק על ידי משתמש", + "Log-in credentials, save in session" : "אישורי התחברות, נשמרים במידע שיחה - סשן", + "User entered, store in database" : "משתמש התחבר, נשמר במסד הנתונים", "RSA public key" : "מפתח ציבורי RSA", "Public key" : "מפתח ציבורי", "Amazon S3" : "אמזון S3", diff --git a/apps/files_external/l10n/he.json b/apps/files_external/l10n/he.json index 71e07d5f6af..fbdcc287495 100644 --- a/apps/files_external/l10n/he.json +++ b/apps/files_external/l10n/he.json @@ -59,10 +59,10 @@ "Identity endpoint URL" : "זהות נתיב נקודת קצה", "Rackspace" : "חץ אחורה", "API key" : "מפתח API", - "Login credentials" : "פרטי הכניסה", + "Log-in credentials, save in database" : "אישורי התחברות, נשמרים במסד הנתונים", "Username and password" : "שם משתמש וסיסמא", - "Session credentials" : "אישורי סשן", - "User provided" : "סופק על ידי משתמש", + "Log-in credentials, save in session" : "אישורי התחברות, נשמרים במידע שיחה - סשן", + "User entered, store in database" : "משתמש התחבר, נשמר במסד הנתונים", "RSA public key" : "מפתח ציבורי RSA", "Public key" : "מפתח ציבורי", "Amazon S3" : "אמזון S3", diff --git a/apps/files_external/l10n/id.js b/apps/files_external/l10n/id.js index d782e285cc8..15f33571ee6 100644 --- a/apps/files_external/l10n/id.js +++ b/apps/files_external/l10n/id.js @@ -50,7 +50,6 @@ OC.L10N.register( "Rackspace" : "Rackspace", "API key" : "Kunci API", "Username and password" : "Nama pengguna dan sandi", - "Session credentials" : "Kredensial sesi", "RSA public key" : "Kunci publik RSA", "Public key" : "Kunci Public", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/id.json b/apps/files_external/l10n/id.json index ae39765674b..00f78599006 100644 --- a/apps/files_external/l10n/id.json +++ b/apps/files_external/l10n/id.json @@ -48,7 +48,6 @@ "Rackspace" : "Rackspace", "API key" : "Kunci API", "Username and password" : "Nama pengguna dan sandi", - "Session credentials" : "Kredensial sesi", "RSA public key" : "Kunci publik RSA", "Public key" : "Kunci Public", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/it.js b/apps/files_external/l10n/it.js index c27a92d76f4..d9adaad833b 100644 --- a/apps/files_external/l10n/it.js +++ b/apps/files_external/l10n/it.js @@ -61,10 +61,10 @@ OC.L10N.register( "Identity endpoint URL" : "URL endpoint delle identità", "Rackspace" : "Rackspace", "API key" : "Chiave API", - "Login credentials" : "Credenziali di accesso", + "Log-in credentials, save in database" : "Credenziali di accesso, salva nel database", "Username and password" : "Nome utente e password", - "Session credentials" : "Credenziali di sessione", - "User provided" : "Fornita dall'utente", + "Log-in credentials, save in session" : "Credenziali di accesso, salva nella sessione", + "User entered, store in database" : "Digitate dall'utente, memorizza nel database", "RSA public key" : "Chiave pubblica RSA", "Public key" : "Chiave pubblica", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/it.json b/apps/files_external/l10n/it.json index cf7775f1d0e..b228cd76604 100644 --- a/apps/files_external/l10n/it.json +++ b/apps/files_external/l10n/it.json @@ -59,10 +59,10 @@ "Identity endpoint URL" : "URL endpoint delle identità", "Rackspace" : "Rackspace", "API key" : "Chiave API", - "Login credentials" : "Credenziali di accesso", + "Log-in credentials, save in database" : "Credenziali di accesso, salva nel database", "Username and password" : "Nome utente e password", - "Session credentials" : "Credenziali di sessione", - "User provided" : "Fornita dall'utente", + "Log-in credentials, save in session" : "Credenziali di accesso, salva nella sessione", + "User entered, store in database" : "Digitate dall'utente, memorizza nel database", "RSA public key" : "Chiave pubblica RSA", "Public key" : "Chiave pubblica", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/ja.js b/apps/files_external/l10n/ja.js index fafe03c4fa0..f14c07808ca 100644 --- a/apps/files_external/l10n/ja.js +++ b/apps/files_external/l10n/ja.js @@ -61,9 +61,7 @@ OC.L10N.register( "Identity endpoint URL" : "認証エンドポイントURL", "Rackspace" : "Rackspace", "API key" : "APIキー", - "Login credentials" : "ログイン資格情報", "Username and password" : "ユーザー名とパスワード", - "Session credentials" : "セッション資格情報", "RSA public key" : "RSA公開鍵", "Public key" : "公開鍵", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/ja.json b/apps/files_external/l10n/ja.json index 0d1f1729dae..df6f7f44618 100644 --- a/apps/files_external/l10n/ja.json +++ b/apps/files_external/l10n/ja.json @@ -59,9 +59,7 @@ "Identity endpoint URL" : "認証エンドポイントURL", "Rackspace" : "Rackspace", "API key" : "APIキー", - "Login credentials" : "ログイン資格情報", "Username and password" : "ユーザー名とパスワード", - "Session credentials" : "セッション資格情報", "RSA public key" : "RSA公開鍵", "Public key" : "公開鍵", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/ko.js b/apps/files_external/l10n/ko.js index 6c569639cab..df30d86ca13 100644 --- a/apps/files_external/l10n/ko.js +++ b/apps/files_external/l10n/ko.js @@ -51,7 +51,6 @@ OC.L10N.register( "Rackspace" : "Rackspace", "API key" : "API 키", "Username and password" : "사용자 이름과 암호", - "Session credentials" : "세션 접근 정보", "RSA public key" : "RSA 공개 키", "Public key" : "공개 키", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/ko.json b/apps/files_external/l10n/ko.json index 4b64b7433ac..a5f4b4946ca 100644 --- a/apps/files_external/l10n/ko.json +++ b/apps/files_external/l10n/ko.json @@ -49,7 +49,6 @@ "Rackspace" : "Rackspace", "API key" : "API 키", "Username and password" : "사용자 이름과 암호", - "Session credentials" : "세션 접근 정보", "RSA public key" : "RSA 공개 키", "Public key" : "공개 키", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/nb_NO.js b/apps/files_external/l10n/nb_NO.js index cf8e7813d20..fc791fe60ab 100644 --- a/apps/files_external/l10n/nb_NO.js +++ b/apps/files_external/l10n/nb_NO.js @@ -61,7 +61,6 @@ OC.L10N.register( "Rackspace" : "Rackspace", "API key" : "API-nøkkel", "Username and password" : "Brukernavn og passord", - "Session credentials" : "Påloggingsdetaljer for økt", "RSA public key" : "RSA offentlig nøkkel", "Public key" : "Offentlig nøkkel", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/nb_NO.json b/apps/files_external/l10n/nb_NO.json index eaad9c7461d..0e956952948 100644 --- a/apps/files_external/l10n/nb_NO.json +++ b/apps/files_external/l10n/nb_NO.json @@ -59,7 +59,6 @@ "Rackspace" : "Rackspace", "API key" : "API-nøkkel", "Username and password" : "Brukernavn og passord", - "Session credentials" : "Påloggingsdetaljer for økt", "RSA public key" : "RSA offentlig nøkkel", "Public key" : "Offentlig nøkkel", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/nds.js b/apps/files_external/l10n/nds.js index 73df3c8483d..b4649fe681a 100644 --- a/apps/files_external/l10n/nds.js +++ b/apps/files_external/l10n/nds.js @@ -47,7 +47,6 @@ OC.L10N.register( "Password" : "Passwort", "API key" : "API Schlüssel", "Username and password" : "Benutzername und Passwort", - "Session credentials" : "Anmeldedaten der Sitzung", "RSA public key" : "Öffentlicher RSA Schlüssel", "Public key" : "Öffentlicher Schlüssel", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/nds.json b/apps/files_external/l10n/nds.json index 57cbefff91b..75e36016384 100644 --- a/apps/files_external/l10n/nds.json +++ b/apps/files_external/l10n/nds.json @@ -45,7 +45,6 @@ "Password" : "Passwort", "API key" : "API Schlüssel", "Username and password" : "Benutzername und Passwort", - "Session credentials" : "Anmeldedaten der Sitzung", "RSA public key" : "Öffentlicher RSA Schlüssel", "Public key" : "Öffentlicher Schlüssel", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/nl.js b/apps/files_external/l10n/nl.js index a6dd5164992..a3f3ca9a566 100644 --- a/apps/files_external/l10n/nl.js +++ b/apps/files_external/l10n/nl.js @@ -61,10 +61,7 @@ OC.L10N.register( "Identity endpoint URL" : "Identiteiten endpoint URL", "Rackspace" : "Rackspace", "API key" : "API sleutel", - "Login credentials" : "Inloggegevens", "Username and password" : "Gebruikersnaam en wachtwoord", - "Session credentials" : "Sessie inloggegevens", - "User provided" : "Gebruiker gaf op", "RSA public key" : "RSA publieke sleutel", "Public key" : "Publieke sleutel", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/nl.json b/apps/files_external/l10n/nl.json index 03b8953a62b..8654cdc662d 100644 --- a/apps/files_external/l10n/nl.json +++ b/apps/files_external/l10n/nl.json @@ -59,10 +59,7 @@ "Identity endpoint URL" : "Identiteiten endpoint URL", "Rackspace" : "Rackspace", "API key" : "API sleutel", - "Login credentials" : "Inloggegevens", "Username and password" : "Gebruikersnaam en wachtwoord", - "Session credentials" : "Sessie inloggegevens", - "User provided" : "Gebruiker gaf op", "RSA public key" : "RSA publieke sleutel", "Public key" : "Publieke sleutel", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/oc.js b/apps/files_external/l10n/oc.js index 71b174f2e61..716326f1cae 100644 --- a/apps/files_external/l10n/oc.js +++ b/apps/files_external/l10n/oc.js @@ -51,7 +51,6 @@ OC.L10N.register( "Rackspace" : "Rackspace", "API key" : "Clau API", "Username and password" : "Nom d'utilizaire e senhal", - "Session credentials" : "Informacions d'identificacion de session", "RSA public key" : "Clau publica RSA", "Public key" : "Clau publica", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/oc.json b/apps/files_external/l10n/oc.json index edfd9d0a21b..bc882de1456 100644 --- a/apps/files_external/l10n/oc.json +++ b/apps/files_external/l10n/oc.json @@ -49,7 +49,6 @@ "Rackspace" : "Rackspace", "API key" : "Clau API", "Username and password" : "Nom d'utilizaire e senhal", - "Session credentials" : "Informacions d'identificacion de session", "RSA public key" : "Clau publica RSA", "Public key" : "Clau publica", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/pt_BR.js b/apps/files_external/l10n/pt_BR.js index 4a301a306ab..283b9478577 100644 --- a/apps/files_external/l10n/pt_BR.js +++ b/apps/files_external/l10n/pt_BR.js @@ -61,9 +61,7 @@ OC.L10N.register( "Identity endpoint URL" : "Identidade pontofinal URL", "Rackspace" : "Espaço em rack", "API key" : "Chave API", - "Login credentials" : "Credenciais de login", "Username and password" : "Nome de Usuário e senha", - "Session credentials" : "Credenciais de Sessão", "RSA public key" : "Chave pública RSA", "Public key" : "Chave pública", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/pt_BR.json b/apps/files_external/l10n/pt_BR.json index 26c20fcb3c1..f1d97e6cf4a 100644 --- a/apps/files_external/l10n/pt_BR.json +++ b/apps/files_external/l10n/pt_BR.json @@ -59,9 +59,7 @@ "Identity endpoint URL" : "Identidade pontofinal URL", "Rackspace" : "Espaço em rack", "API key" : "Chave API", - "Login credentials" : "Credenciais de login", "Username and password" : "Nome de Usuário e senha", - "Session credentials" : "Credenciais de Sessão", "RSA public key" : "Chave pública RSA", "Public key" : "Chave pública", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/pt_PT.js b/apps/files_external/l10n/pt_PT.js index 3065f6780af..b84c399e34d 100644 --- a/apps/files_external/l10n/pt_PT.js +++ b/apps/files_external/l10n/pt_PT.js @@ -61,10 +61,10 @@ OC.L10N.register( "Identity endpoint URL" : "Identidade URL endpoint", "Rackspace" : "Rackspace", "API key" : "Chave API", - "Login credentials" : "Credenciais de login", + "Log-in credentials, save in database" : "Credenciais de login, guardar na base de dados", "Username and password" : "Nome de utilizador e palavra-passe", - "Session credentials" : "Credenciais da sessão", - "User provided" : "Utilizador fornecido", + "Log-in credentials, save in session" : "Credenciais de login, guardar na sessão", + "User entered, store in database" : "Utilizador introduzido, guardar na base de dados", "RSA public key" : "Chave pública RSA", "Public key" : "Chave pública", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/pt_PT.json b/apps/files_external/l10n/pt_PT.json index 2525f001dea..ac65ca7744f 100644 --- a/apps/files_external/l10n/pt_PT.json +++ b/apps/files_external/l10n/pt_PT.json @@ -59,10 +59,10 @@ "Identity endpoint URL" : "Identidade URL endpoint", "Rackspace" : "Rackspace", "API key" : "Chave API", - "Login credentials" : "Credenciais de login", + "Log-in credentials, save in database" : "Credenciais de login, guardar na base de dados", "Username and password" : "Nome de utilizador e palavra-passe", - "Session credentials" : "Credenciais da sessão", - "User provided" : "Utilizador fornecido", + "Log-in credentials, save in session" : "Credenciais de login, guardar na sessão", + "User entered, store in database" : "Utilizador introduzido, guardar na base de dados", "RSA public key" : "Chave pública RSA", "Public key" : "Chave pública", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/ru.js b/apps/files_external/l10n/ru.js index 113cebcc9ef..ceae42c7942 100644 --- a/apps/files_external/l10n/ru.js +++ b/apps/files_external/l10n/ru.js @@ -18,6 +18,7 @@ OC.L10N.register( "Unsatisfied authentication mechanism parameters" : "Недопустимые настройки механизма авторизации", "Insufficient data: %s" : "Недостаточно данных: %s", "%s" : "%s", + "Storage with id \"%i\" is not user editable" : "Пользователь не может редактировать хранилище \"%i\"", "Personal" : "Личное", "System" : "Система", "Grant access" : "Предоставить доступ", @@ -60,8 +61,10 @@ OC.L10N.register( "Identity endpoint URL" : "Удостоверение конечной точки URL", "Rackspace" : "Rackspace", "API key" : "Ключ API", + "Log-in credentials, save in database" : "Учетные данные, хранить в базе данных", "Username and password" : "Имя пользователя и пароль", - "Session credentials" : "Учетные данные сессии", + "Log-in credentials, save in session" : "Учетные данные, хранить в сессии", + "User entered, store in database" : "Введенные пользователем, хранить в базе данных", "RSA public key" : "Открытый ключ RSA", "Public key" : "Открытый ключ", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/ru.json b/apps/files_external/l10n/ru.json index 81df3078c59..d0dab706ea9 100644 --- a/apps/files_external/l10n/ru.json +++ b/apps/files_external/l10n/ru.json @@ -16,6 +16,7 @@ "Unsatisfied authentication mechanism parameters" : "Недопустимые настройки механизма авторизации", "Insufficient data: %s" : "Недостаточно данных: %s", "%s" : "%s", + "Storage with id \"%i\" is not user editable" : "Пользователь не может редактировать хранилище \"%i\"", "Personal" : "Личное", "System" : "Система", "Grant access" : "Предоставить доступ", @@ -58,8 +59,10 @@ "Identity endpoint URL" : "Удостоверение конечной точки URL", "Rackspace" : "Rackspace", "API key" : "Ключ API", + "Log-in credentials, save in database" : "Учетные данные, хранить в базе данных", "Username and password" : "Имя пользователя и пароль", - "Session credentials" : "Учетные данные сессии", + "Log-in credentials, save in session" : "Учетные данные, хранить в сессии", + "User entered, store in database" : "Введенные пользователем, хранить в базе данных", "RSA public key" : "Открытый ключ RSA", "Public key" : "Открытый ключ", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/sk_SK.js b/apps/files_external/l10n/sk_SK.js index 2c81272ff1f..72fb57a1e0b 100644 --- a/apps/files_external/l10n/sk_SK.js +++ b/apps/files_external/l10n/sk_SK.js @@ -50,7 +50,6 @@ OC.L10N.register( "Rackspace" : "Rackspace", "API key" : "API kľúč", "Username and password" : "Meno a heslo", - "Session credentials" : "Pihlasovacie údaje sezóny", "RSA public key" : "RSA verejný kľúč", "Public key" : "Verejný kľúč", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/sk_SK.json b/apps/files_external/l10n/sk_SK.json index 85532f676bc..267eb5b48b9 100644 --- a/apps/files_external/l10n/sk_SK.json +++ b/apps/files_external/l10n/sk_SK.json @@ -48,7 +48,6 @@ "Rackspace" : "Rackspace", "API key" : "API kľúč", "Username and password" : "Meno a heslo", - "Session credentials" : "Pihlasovacie údaje sezóny", "RSA public key" : "RSA verejný kľúč", "Public key" : "Verejný kľúč", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/sl.js b/apps/files_external/l10n/sl.js index 362e2cf84e1..62b35ffab5e 100644 --- a/apps/files_external/l10n/sl.js +++ b/apps/files_external/l10n/sl.js @@ -41,9 +41,7 @@ OC.L10N.register( "Password" : "Geslo", "Tenant name" : "Ime uporabnika", "API key" : "Ključ API", - "Login credentials" : "Poverila prijave", "Username and password" : "Uporabniško ime in geslo", - "Session credentials" : "Poverila seje", "RSA public key" : "Javni ključ RSA", "Public key" : "Javni ključ", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/sl.json b/apps/files_external/l10n/sl.json index 2496a4d7199..3a806fbd25b 100644 --- a/apps/files_external/l10n/sl.json +++ b/apps/files_external/l10n/sl.json @@ -39,9 +39,7 @@ "Password" : "Geslo", "Tenant name" : "Ime uporabnika", "API key" : "Ključ API", - "Login credentials" : "Poverila prijave", "Username and password" : "Uporabniško ime in geslo", - "Session credentials" : "Poverila seje", "RSA public key" : "Javni ključ RSA", "Public key" : "Javni ključ", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/sq.js b/apps/files_external/l10n/sq.js index 96438f293bd..5549657c448 100644 --- a/apps/files_external/l10n/sq.js +++ b/apps/files_external/l10n/sq.js @@ -60,10 +60,7 @@ OC.L10N.register( "Tenant name" : "Emër qiraxhiu", "Rackspace" : "Rackspace", "API key" : "Kyç API", - "Login credentials" : "Kredenciale hyrjesh", "Username and password" : "Emër përdoruesi dhe fjalëkalim", - "Session credentials" : "Kredenciale sesioni", - "User provided" : "Dhënë nga përdoruesi", "RSA public key" : "Kyç publik RSA ", "Public key" : "Kyç publik", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/sq.json b/apps/files_external/l10n/sq.json index e3e21598d7a..5176c5ded27 100644 --- a/apps/files_external/l10n/sq.json +++ b/apps/files_external/l10n/sq.json @@ -58,10 +58,7 @@ "Tenant name" : "Emër qiraxhiu", "Rackspace" : "Rackspace", "API key" : "Kyç API", - "Login credentials" : "Kredenciale hyrjesh", "Username and password" : "Emër përdoruesi dhe fjalëkalim", - "Session credentials" : "Kredenciale sesioni", - "User provided" : "Dhënë nga përdoruesi", "RSA public key" : "Kyç publik RSA ", "Public key" : "Kyç publik", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/th_TH.js b/apps/files_external/l10n/th_TH.js index 90db47a31d7..31993619cae 100644 --- a/apps/files_external/l10n/th_TH.js +++ b/apps/files_external/l10n/th_TH.js @@ -60,9 +60,7 @@ OC.L10N.register( "Identity endpoint URL" : "ตัวตนของ URL ปลายทาง", "Rackspace" : "Rackspace", "API key" : "รหัส API", - "Login credentials" : "เข้าสู่ระบบด้วยข้อมูลประจำตัว", "Username and password" : "ชื่อผู้ใช้และรหัสผ่าน", - "Session credentials" : "ข้อมูลของเซสชั่น", "RSA public key" : "RSA คีย์สาธารณะ", "Public key" : "คีย์สาธารณะ", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/th_TH.json b/apps/files_external/l10n/th_TH.json index 4f327592ab8..07424cc1d23 100644 --- a/apps/files_external/l10n/th_TH.json +++ b/apps/files_external/l10n/th_TH.json @@ -58,9 +58,7 @@ "Identity endpoint URL" : "ตัวตนของ URL ปลายทาง", "Rackspace" : "Rackspace", "API key" : "รหัส API", - "Login credentials" : "เข้าสู่ระบบด้วยข้อมูลประจำตัว", "Username and password" : "ชื่อผู้ใช้และรหัสผ่าน", - "Session credentials" : "ข้อมูลของเซสชั่น", "RSA public key" : "RSA คีย์สาธารณะ", "Public key" : "คีย์สาธารณะ", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/tr.js b/apps/files_external/l10n/tr.js index 8f75ae2a274..cb506b24c1f 100644 --- a/apps/files_external/l10n/tr.js +++ b/apps/files_external/l10n/tr.js @@ -51,7 +51,6 @@ OC.L10N.register( "Rackspace" : "Rackspace", "API key" : "API anahtarı", "Username and password" : "Kullanıcı adı ve parola", - "Session credentials" : "Oturum bilgileri", "RSA public key" : "RSA ortak anahtarı", "Public key" : "Ortak anahtar", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/l10n/tr.json b/apps/files_external/l10n/tr.json index fdae4642acc..1eeaafa433c 100644 --- a/apps/files_external/l10n/tr.json +++ b/apps/files_external/l10n/tr.json @@ -49,7 +49,6 @@ "Rackspace" : "Rackspace", "API key" : "API anahtarı", "Username and password" : "Kullanıcı adı ve parola", - "Session credentials" : "Oturum bilgileri", "RSA public key" : "RSA ortak anahtarı", "Public key" : "Ortak anahtar", "Amazon S3" : "Amazon S3", diff --git a/apps/files_external/lib/definitionparameter.php b/apps/files_external/lib/definitionparameter.php index dc7985837f5..27c6af0fcda 100644 --- a/apps/files_external/lib/definitionparameter.php +++ b/apps/files_external/lib/definitionparameter.php @@ -131,27 +131,11 @@ class DefinitionParameter implements \JsonSerializable { * @return string */ public function jsonSerialize() { - $prefix = ''; - switch ($this->getType()) { - case self::VALUE_BOOLEAN: - $prefix = '!'; - break; - case self::VALUE_PASSWORD: - $prefix = '*'; - break; - case self::VALUE_HIDDEN: - $prefix = '#'; - break; - } - - if ($this->isFlagSet(self::FLAG_OPTIONAL)) { - $prefix = '&' . $prefix; - } - if ($this->isFlagSet(self::FLAG_USER_PROVIDED)) { - $prefix = '@' . $prefix; - } - - return $prefix . $this->getText(); + return [ + 'value' => $this->getText(), + 'flags' => $this->getFlags(), + 'type' => $this->getType() + ]; } public function isOptional() { diff --git a/apps/files_external/tests/definitionparameterttest.php b/apps/files_external/tests/definitionparameterttest.php index dc7c150ec96..e89058d5c78 100644 --- a/apps/files_external/tests/definitionparameterttest.php +++ b/apps/files_external/tests/definitionparameterttest.php @@ -27,18 +27,34 @@ class DefinitionParameterTest extends \Test\TestCase { public function testJsonSerialization() { $param = new Param('foo', 'bar'); - $this->assertEquals('bar', $param->jsonSerialize()); + $this->assertEquals([ + 'value' => 'bar', + 'flags' => 0, + 'type' => 0 + ], $param->jsonSerialize()); $param->setType(Param::VALUE_BOOLEAN); - $this->assertEquals('!bar', $param->jsonSerialize()); + $this->assertEquals([ + 'value' => 'bar', + 'flags' => 0, + 'type' => Param::VALUE_BOOLEAN + ], $param->jsonSerialize()); $param->setType(Param::VALUE_PASSWORD); $param->setFlag(Param::FLAG_OPTIONAL); - $this->assertEquals('&*bar', $param->jsonSerialize()); + $this->assertEquals([ + 'value' => 'bar', + 'flags' => Param::FLAG_OPTIONAL, + 'type' => Param::VALUE_PASSWORD + ], $param->jsonSerialize()); $param->setType(Param::VALUE_HIDDEN); $param->setFlags(Param::FLAG_NONE); - $this->assertEquals('#bar', $param->jsonSerialize()); + $this->assertEquals([ + 'value' => 'bar', + 'flags' => Param::FLAG_NONE, + 'type' => Param::VALUE_HIDDEN + ], $param->jsonSerialize()); } public function validateValueProvider() { diff --git a/apps/files_external/tests/js/settingsSpec.js b/apps/files_external/tests/js/settingsSpec.js index b2b5e1f57ec..6f5bb2a8e3e 100644 --- a/apps/files_external/tests/js/settingsSpec.js +++ b/apps/files_external/tests/js/settingsSpec.js @@ -58,8 +58,13 @@ describe('OCA.External.Settings tests', function() { 'identifier': '\\OC\\TestBackend', 'name': 'Test Backend', 'configuration': { - 'field1': 'Display Name 1', - 'field2': '&Display Name 2' + 'field1': { + 'value': 'Display Name 1' + }, + 'field2': { + 'value': 'Display Name 2', + 'flags': 1 + } }, 'authSchemes': { 'builtin': true, @@ -70,8 +75,13 @@ describe('OCA.External.Settings tests', function() { 'identifier': '\\OC\\AnotherTestBackend', 'name': 'Another Test Backend', 'configuration': { - 'field1': 'Display Name 1', - 'field2': '&Display Name 2' + 'field1': { + 'value': 'Display Name 1' + }, + 'field2': { + 'value': 'Display Name 2', + 'flags': 1 + } }, 'authSchemes': { 'builtin': true, @@ -82,12 +92,30 @@ describe('OCA.External.Settings tests', function() { 'identifier': '\\OC\\InputsTestBackend', 'name': 'Inputs test backend', 'configuration': { - 'field_text': 'Text field', - 'field_password': '*Password field', - 'field_bool': '!Boolean field', - 'field_hidden': '#Hidden field', - 'field_text_optional': '&Text field optional', - 'field_password_optional': '&*Password field optional' + 'field_text': { + 'value': 'Text field' + }, + 'field_password': { + 'value': ',Password field', + 'type': 2 + }, + 'field_bool': { + 'value': 'Boolean field', + 'type': 1 + }, + 'field_hidden': { + 'value': 'Hidden field', + 'type': 3 + }, + 'field_text_optional': { + 'value': 'Text field optional', + 'flags': 1 + }, + 'field_password_optional': { + 'value': 'Password field optional', + 'flags': 1, + 'type': 2 + } }, 'authSchemes': { 'builtin': true, @@ -335,6 +363,7 @@ describe('OCA.External.Settings tests', function() { expect(JSON.parse($tr.find('input.mountOptions').val())).toEqual({ encrypt: true, previews: true, + enable_sharing: true, filesystem_check_changes: 0 }); }); diff --git a/apps/files_sharing/api/sharees.php b/apps/files_sharing/api/sharees.php index d23a6f56501..85cea2e4238 100644 --- a/apps/files_sharing/api/sharees.php +++ b/apps/files_sharing/api/sharees.php @@ -270,8 +270,15 @@ class Sharees { $addressBookContacts = $this->contactsManager->search($search, ['CLOUD', 'FN']); $foundRemoteById = false; foreach ($addressBookContacts as $contact) { + if (isset($contact['isLocalSystemBook'])) { + continue; + } if (isset($contact['CLOUD'])) { - foreach ($contact['CLOUD'] as $cloudId) { + $cloudIds = $contact['CLOUD']; + if (!is_array($cloudIds)) { + $cloudIds = [$cloudIds]; + } + foreach ($cloudIds as $cloudId) { if (strtolower($contact['FN']) === $search || strtolower($cloudId) === $search) { if (strtolower($cloudId) === $search) { $foundRemoteById = true; diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 3ae5749ea87..101503a03fb 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -32,6 +32,7 @@ namespace OC\Files\Storage; use OC\Files\Filesystem; use OCA\Files_Sharing\ISharedStorage; +use OCP\Constants; use OCP\Files\Cache\ICacheEntry; use OCP\Files\Storage\IStorage; use OCP\Lock\ILockingProvider; @@ -83,6 +84,10 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage { $this->sourceRootInfo = $this->sourceStorage->getCache()->get($sourceInternalPath); } + private function isValid() { + return ($this->sourceRootInfo->getPermissions() & Constants::PERMISSION_SHARE) === Constants::PERMISSION_SHARE; + } + /** * get id of the mount point * @@ -133,6 +138,9 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage { * @return string|false source file path or false if not found */ public function getSourcePath($target) { + if (!$this->isValid()){ + return false; + } $source = $this->getFile($target); if ($source) { if (!isset($source['fullPath'])) { @@ -157,6 +165,9 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage { * @return int CRUDS permissions granted */ public function getPermissions($target = '') { + if (!$this->isValid()) { + return 0; + } $permissions = $this->share['permissions']; // part files and the mount point always have delete permissions if ($target === '' || pathinfo($target, PATHINFO_EXTENSION) === 'part') { @@ -253,13 +264,14 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage { } public function isReadable($path) { - $isReadable = false; - if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); - $isReadable = $storage->isReadable($internalPath); + if (!$this->isValid()) { + return false; } - - return $isReadable && $this->file_exists($path); + if (!$this->file_exists($path)) { + return false; + } + list($storage, $internalPath) = $this->resolvePath($path); + return $storage->isReadable($internalPath); } public function isUpdatable($path) { diff --git a/apps/systemtags/activity/extension.php b/apps/systemtags/activity/extension.php new file mode 100644 index 00000000000..4a974611509 --- /dev/null +++ b/apps/systemtags/activity/extension.php @@ -0,0 +1,300 @@ +<?php +/** + * @author Joas Schilling <nickvergessen@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 OCA\SystemTags\Activity; + +use OCP\Activity\IExtension; +use OCP\Activity\IManager; +use OCP\IL10N; +use OCP\L10N\IFactory; + +/** + * Class Extension + * + * @package OCA\SystemTags\Activity + */ +class Extension implements IExtension { + const APP_NAME = 'systemtags'; + + const CREATE_TAG = 'create_tag'; + const UPDATE_TAG = 'update_tag'; + const DELETE_TAG = 'delete_tag'; + + const ASSIGN_TAG = 'assign_tag'; + const UNASSIGN_TAG = 'unassign_tag'; + + /** @var IFactory */ + protected $languageFactory; + + /** @var IManager */ + protected $activityManager; + + /** + * @param IFactory $languageFactory + * @param IManager $activityManager + */ + public function __construct(IFactory $languageFactory, IManager $activityManager) { + $this->languageFactory = $languageFactory; + $this->activityManager = $activityManager; + } + + protected function getL10N($languageCode = null) { + return $this->languageFactory->get(self::APP_NAME, $languageCode); + } + + /** + * The extension can return an array of additional notification types. + * If no additional types are to be added false is to be returned + * + * @param string $languageCode + * @return array|false + */ + public function getNotificationTypes($languageCode) { + $l = $this->getL10N($languageCode); + + return array( + self::APP_NAME => (string) $l->t('<strong>System tags</strong> for a file have been modified'), + ); + } + + /** + * For a given method additional types to be displayed in the settings can be returned. + * In case no additional types are to be added false is to be returned. + * + * @param string $method + * @return array|false + */ + public function getDefaultTypes($method) { + return $method === self::METHOD_STREAM ? [self::APP_NAME] : false; + } + + /** + * A string naming the css class for the icon to be used can be returned. + * If no icon is known for the given type false is to be returned. + * + * @param string $type + * @return string|false + */ + public function getTypeIcon($type) { + switch ($type) { + case self::APP_NAME: + return false; + } + + return false; + } + + /** + * The extension can translate a given message to the requested languages. + * If no translation is available false is to be returned. + * + * @param string $app + * @param string $text + * @param array $params + * @param boolean $stripPath + * @param boolean $highlightParams + * @param string $languageCode + * @return string|false + */ + public function translate($app, $text, $params, $stripPath, $highlightParams, $languageCode) { + if ($app !== self::APP_NAME) { + return false; + } + + $l = $this->getL10N($languageCode); + + if ($this->activityManager->isFormattingFilteredObject()) { + $translation = $this->translateShort($text, $l, $params); + if ($translation !== false) { + return $translation; + } + } + + return $this->translateLong($text, $l, $params); + } + + /** + * @param string $text + * @param IL10N $l + * @param array $params + * @return bool|string + */ + protected function translateShort($text, IL10N $l, array $params) { + + switch ($text) { + case self::ASSIGN_TAG: + $params[2] = $this->convertParameterToTag($params[2], $l); + return (string) $l->t('%1$s assigned system tag %3$s', $params); + case self::UNASSIGN_TAG: + $params[2] = $this->convertParameterToTag($params[2], $l); + return (string) $l->t('%1$s unassigned system tag %3$s', $params); + } + + return false; + } + + /** + * @param string $text + * @param IL10N $l + * @param array $params + * @return bool|string + */ + protected function translateLong($text, IL10N $l, array $params) { + + switch ($text) { + case self::CREATE_TAG: + $params[1] = $this->convertParameterToTag($params[1], $l); + return (string) $l->t('%1$s created system tag %2$s', $params); + case self::DELETE_TAG: + $params[1] = $this->convertParameterToTag($params[1], $l); + return (string) $l->t('%1$s deleted system tag %2$s', $params); + case self::UPDATE_TAG: + $params[1] = $this->convertParameterToTag($params[1], $l); + $params[2] = $this->convertParameterToTag($params[2], $l); + return (string) $l->t('%1$s updated system tag %3$s to %2$s', $params); + case self::ASSIGN_TAG: + $params[2] = $this->convertParameterToTag($params[2], $l); + return (string) $l->t('%1$s assigned system tag %3$s to %2$s', $params); + case self::UNASSIGN_TAG: + $params[2] = $this->convertParameterToTag($params[2], $l); + return (string) $l->t('%1$s unassigned system tag %3$s from %2$s', $params); + } + + return false; + } + + /** + * The extension can define the type of parameters for translation + * + * Currently known types are: + * * file => will strip away the path of the file and add a tooltip with it + * * username => will add the avatar of the user + * + * @param string $app + * @param string $text + * @return array|false + */ + public function getSpecialParameterList($app, $text) { + if ($app === self::APP_NAME) { + switch ($text) { + case self::CREATE_TAG: + case self::DELETE_TAG: + return array( + 0 => 'username', + //1 => 'systemtag description', + ); + case self::UPDATE_TAG: + return array( + 0 => 'username', + //1 => 'systemtag description', + //2 => 'systemtag description', + ); + + case self::ASSIGN_TAG: + case self::UNASSIGN_TAG: + return array( + 0 => 'username', + 1 => 'file', + //2 => 'systemtag description', + ); + } + } + + return false; + } + + /** + * The extension can define the parameter grouping by returning the index as integer. + * In case no grouping is required false is to be returned. + * + * @param array $activity + * @return integer|false + */ + public function getGroupParameter($activity) { + return false; + } + + /** + * The extension can define additional navigation entries. The array returned has to contain two keys 'top' + * and 'apps' which hold arrays with the relevant entries. + * If no further entries are to be added false is no be returned. + * + * @return array|false + */ + public function getNavigation() { + return false; + } + + /** + * The extension can check if a custom filter (given by a query string like filter=abc) is valid or not. + * + * @param string $filterValue + * @return boolean + */ + public function isFilterValid($filterValue) { + return false; + } + + /** + * The extension can filter the types based on the filter if required. + * In case no filter is to be applied false is to be returned unchanged. + * + * @param array $types + * @param string $filter + * @return array|false + */ + public function filterNotificationTypes($types, $filter) { + return false; + } + + /** + * For a given filter the extension can specify the sql query conditions including parameters for that query. + * In case the extension does not know the filter false is to be returned. + * The query condition and the parameters are to be returned as array with two elements. + * E.g. return array('`app` = ? and `message` like ?', array('mail', 'ownCloud%')); + * + * @param string $filter + * @return array|false + */ + public function getQueryForFilter($filter) { + return false; + } + + /** + * @param string $parameter + * @param IL10N $l + * @return string + */ + protected function convertParameterToTag($parameter, IL10N $l) { + if (preg_match('/^\<parameter\>\{\{\{(.*)\|\|\|(.*)\}\}\}\<\/parameter\>$/', $parameter, $matches)) { + switch ($matches[2]) { + case 'assignable': + return '<parameter>' . $matches[1] . '</parameter>'; + case 'not-assignable': + return '<parameter>' . $l->t('%s (not-assignable)', $matches[1]) . '</parameter>'; + case 'invisible': + return '<parameter>' . $l->t('%s (invisible)', $matches[1]) . '</parameter>'; + } + } + + return $parameter; + } +} diff --git a/apps/systemtags/activity/listener.php b/apps/systemtags/activity/listener.php new file mode 100644 index 00000000000..9b6597119c6 --- /dev/null +++ b/apps/systemtags/activity/listener.php @@ -0,0 +1,223 @@ +<?php +/** + * @author Joas Schilling <nickvergessen@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 OCA\SystemTags\Activity; + +use OCP\Activity\IManager; +use OCP\App\IAppManager; +use OCP\Files\Config\IMountProviderCollection; +use OCP\Files\IRootFolder; +use OCP\Files\Node; +use OCP\IGroup; +use OCP\IGroupManager; +use OCP\IUser; +use OCP\IUserSession; +use OCP\Share; +use OCP\SystemTag\ISystemTag; +use OCP\SystemTag\ISystemTagManager; +use OCP\SystemTag\ManagerEvent; +use OCP\SystemTag\MapperEvent; +use OCP\SystemTag\TagNotFoundException; + +class Listener { + /** @var IGroupManager */ + protected $groupManager; + /** @var IManager */ + protected $activityManager; + /** @var IUserSession */ + protected $session; + /** @var \OCP\SystemTag\ISystemTagManager */ + protected $tagManager; + /** @var \OCP\App\IAppManager */ + protected $appManager; + /** @var \OCP\Files\Config\IMountProviderCollection */ + protected $mountCollection; + /** @var \OCP\Files\IRootFolder */ + protected $rootFolder; + + /** + * Listener constructor. + * + * @param IGroupManager $groupManager + * @param IManager $activityManager + * @param IUserSession $session + * @param ISystemTagManager $tagManager + * @param IAppManager $appManager + * @param IMountProviderCollection $mountCollection + * @param IRootFolder $rootFolder + */ + public function __construct(IGroupManager $groupManager, + IManager $activityManager, + IUserSession $session, + ISystemTagManager $tagManager, + IAppManager $appManager, + IMountProviderCollection $mountCollection, + IRootFolder $rootFolder) { + $this->groupManager = $groupManager; + $this->activityManager = $activityManager; + $this->session = $session; + $this->tagManager = $tagManager; + $this->appManager = $appManager; + $this->mountCollection = $mountCollection; + $this->rootFolder = $rootFolder; + } + + /** + * @param ManagerEvent $event + */ + public function event(ManagerEvent $event) { + $actor = $this->session->getUser(); + if ($actor instanceof IUser) { + $actor = $actor->getUID(); + } else { + $actor = ''; + } + + $activity = $this->activityManager->generateEvent(); + $activity->setApp(Extension::APP_NAME) + ->setType(Extension::APP_NAME) + ->setAuthor($actor); + if ($event->getEvent() === ManagerEvent::EVENT_CREATE) { + $activity->setSubject(Extension::CREATE_TAG, [ + $actor, + $this->prepareTagAsParameter($event->getTag()), + ]); + } else if ($event->getEvent() === ManagerEvent::EVENT_UPDATE) { + $activity->setSubject(Extension::UPDATE_TAG, [ + $actor, + $this->prepareTagAsParameter($event->getTag()), + $this->prepareTagAsParameter($event->getTagBefore()), + ]); + } else if ($event->getEvent() === ManagerEvent::EVENT_DELETE) { + $activity->setSubject(Extension::DELETE_TAG, [ + $actor, + $this->prepareTagAsParameter($event->getTag()), + ]); + } else { + return; + } + + $group = $this->groupManager->get('admin'); + if ($group instanceof IGroup) { + foreach ($group->getUsers() as $user) { + $activity->setAffectedUser($user->getUID()); + $this->activityManager->publish($activity); + } + } + } + + /** + * @param MapperEvent $event + */ + public function mapperEvent(MapperEvent $event) { + $tagIds = $event->getTags(); + if ($event->getObjectType() !== 'files' ||empty($tagIds) + || !in_array($event->getEvent(), [MapperEvent::EVENT_ASSIGN, MapperEvent::EVENT_UNASSIGN]) + || !$this->appManager->isInstalled('activity')) { + // System tags not for files, no tags, not (un-)assigning or no activity-app enabled (save the energy) + return; + } + + try { + $tags = $this->tagManager->getTagsByIds($tagIds); + } catch (TagNotFoundException $e) { + // User assigned/unassigned a non-existing tag, ignore... + return; + } + + if (empty($tags)) { + return; + } + + // Get all mount point owners + $cache = $this->mountCollection->getMountCache(); + $mounts = $cache->getMountsForFileId($event->getObjectId()); + if (empty($mounts)) { + return; + } + + $users = []; + foreach ($mounts as $mount) { + $owner = $mount->getUser()->getUID(); + $ownerFolder = $this->rootFolder->getUserFolder($owner); + $nodes = $ownerFolder->getById($event->getObjectId()); + if (!empty($nodes)) { + /** @var Node $node */ + $node = array_shift($nodes); + $path = $node->getPath(); + if (strpos($path, '/' . $owner . '/files/') === 0) { + $path = substr($path, strlen('/' . $owner . '/files')); + } + // Get all users that have access to the mount point + $users = array_merge($users, Share::getUsersSharingFile($path, $owner, true, true)); + } + } + + $actor = $this->session->getUser(); + if ($actor instanceof IUser) { + $actor = $actor->getUID(); + } else { + $actor = ''; + } + + $activity = $this->activityManager->generateEvent(); + $activity->setApp(Extension::APP_NAME) + ->setType(Extension::APP_NAME) + ->setAuthor($actor) + ->setObject($event->getObjectType(), $event->getObjectId()); + + foreach ($users as $user => $path) { + $activity->setAffectedUser($user); + + foreach ($tags as $tag) { + if ($event->getEvent() === MapperEvent::EVENT_ASSIGN) { + $activity->setSubject(Extension::ASSIGN_TAG, [ + $actor, + $path, + $this->prepareTagAsParameter($tag), + ]); + } else if ($event->getEvent() === MapperEvent::EVENT_UNASSIGN) { + $activity->setSubject(Extension::UNASSIGN_TAG, [ + $actor, + $path, + $this->prepareTagAsParameter($tag), + ]); + } + + $this->activityManager->publish($activity); + } + } + } + + /** + * @param ISystemTag $tag + * @return string + */ + protected function prepareTagAsParameter(ISystemTag $tag) { + if (!$tag->isUserVisible()) { + return '{{{' . $tag->getName() . '|||invisible}}}'; + } else if (!$tag->isUserAssignable()) { + return '{{{' . $tag->getName() . '|||not-assignable}}}'; + } else { + return '{{{' . $tag->getName() . '|||assignable}}}'; + } + } +} diff --git a/apps/systemtags/appinfo/app.php b/apps/systemtags/appinfo/app.php index d3886993f8f..0bb57e1227b 100644 --- a/apps/systemtags/appinfo/app.php +++ b/apps/systemtags/appinfo/app.php @@ -19,6 +19,11 @@ * */ +use OCA\SystemTags\Activity\Extension; +use OCA\SystemTags\Activity\Listener; +use OCP\SystemTag\ManagerEvent; +use OCP\SystemTag\MapperEvent; + $eventDispatcher = \OC::$server->getEventDispatcher(); $eventDispatcher->addListener( 'OCA\Files::loadAdditionalScripts', @@ -39,3 +44,32 @@ $eventDispatcher->addListener( \OCP\Util::addStyle('systemtags'); } ); + +$activityManager = \OC::$server->getActivityManager(); +$activityManager->registerExtension(function() { + $application = new \OCP\AppFramework\App('systemtags'); + /** @var \OCA\SystemTags\Activity\Extension $extension */ + $extension = $application->getContainer()->query('OCA\SystemTags\Activity\Extension'); + return $extension; +}); + +$managerListener = function(ManagerEvent $event) use ($activityManager) { + $application = new \OCP\AppFramework\App('systemtags'); + /** @var \OCA\SystemTags\Activity\Listener $listener */ + $listener = $application->getContainer()->query('OCA\SystemTags\Activity\Listener'); + $listener->event($event); +}; + +$eventDispatcher->addListener(ManagerEvent::EVENT_CREATE, $managerListener); +$eventDispatcher->addListener(ManagerEvent::EVENT_DELETE, $managerListener); +$eventDispatcher->addListener(ManagerEvent::EVENT_UPDATE, $managerListener); + +$mapperListener = function(MapperEvent $event) use ($activityManager) { + $application = new \OCP\AppFramework\App('systemtags'); + /** @var \OCA\SystemTags\Activity\Listener $listener */ + $listener = $application->getContainer()->query('OCA\SystemTags\Activity\Listener'); + $listener->mapperEvent($event); +}; + +$eventDispatcher->addListener(MapperEvent::EVENT_ASSIGN, $mapperListener); +$eventDispatcher->addListener(MapperEvent::EVENT_UNASSIGN, $mapperListener); diff --git a/apps/systemtags/appinfo/info.xml b/apps/systemtags/appinfo/info.xml index d2f30e2c040..5da945db703 100644 --- a/apps/systemtags/appinfo/info.xml +++ b/apps/systemtags/appinfo/info.xml @@ -6,11 +6,14 @@ <licence>AGPL</licence> <author>Vincent Petry</author> <default_enable/> - <version>0.1</version> + <version>0.2</version> <dependencies> <owncloud min-version="9.0" max-version="9.0" /> </dependencies> <documentation> <user>user-systemtags</user> </documentation> + <types> + <logging/> + </types> </info> diff --git a/apps/user_ldap/l10n/he.js b/apps/user_ldap/l10n/he.js index 9d2fae8295a..56be7447e72 100644 --- a/apps/user_ldap/l10n/he.js +++ b/apps/user_ldap/l10n/he.js @@ -90,8 +90,12 @@ OC.L10N.register( "Password" : "סיסמא", "For anonymous access, leave DN and Password empty." : "לגישה אנונימית, השאר את הDM והסיסמא ריקים.", "One Base DN per line" : "DN בסיסי אחד לשורה", + "You can specify Base DN for users and groups in the Advanced tab" : "ניתן לציין DN בסיסי למשתמשים ולקבוצות בלשונית מתקדם", "Detect Base DN" : "גילוי DN בסיסי", "Test Base DN" : "בדיקת DN בסיסי", + "Avoids automatic LDAP requests. Better for bigger setups, but requires some LDAP knowledge." : "נמנע מבקשות אוטומטיות של LDAP. מועדף עבור התקנות גדולות, אבל מחייב ידע מסויים של LDAP.", + "Manually enter LDAP filters (recommended for large directories)" : "הכנסת מסנני LDAP ידנית (מומלץ עבוק תיקיות גדולות)", + "Limit %s access to users meeting these criteria:" : "מגביל כניסות %s למשתמשים אשר עומדים בתנאים אלו:", "Verify settings and count users" : "מאמת הגדרות וסופר משתמשים", "Saving" : "שמירה", "Back" : "אחורה", @@ -102,9 +106,14 @@ OC.L10N.register( "Connection Settings" : "הגדרות התחברות", "Configuration Active" : "תצורה פעילה", "When unchecked, this configuration will be skipped." : "כאשר לא מסומן, נדלג על תצורה זו.", + "Backup (Replica) Host" : "גיבוי (העתק) שרת", + "Backup (Replica) Port" : "גיבוי (העתק) שער - פורט", "Disable Main Server" : "ניטרול שרת עיקרי", + "Only connect to the replica server." : "חיבור רק להעתק שרת.", + "Turn off SSL certificate validation." : "כיבוי אימות אישורי אבטחה SSL.", "in seconds. A change empties the cache." : "בשניות. שינוי מרוקן את המטמון.", "Directory Settings" : "הגדרות תיקייה", + "Base User Tree" : "עץ משתמש בסיסי", "in bytes" : "בבתים" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/user_ldap/l10n/he.json b/apps/user_ldap/l10n/he.json index c325d8f4405..ca2ba2f91a6 100644 --- a/apps/user_ldap/l10n/he.json +++ b/apps/user_ldap/l10n/he.json @@ -88,8 +88,12 @@ "Password" : "סיסמא", "For anonymous access, leave DN and Password empty." : "לגישה אנונימית, השאר את הDM והסיסמא ריקים.", "One Base DN per line" : "DN בסיסי אחד לשורה", + "You can specify Base DN for users and groups in the Advanced tab" : "ניתן לציין DN בסיסי למשתמשים ולקבוצות בלשונית מתקדם", "Detect Base DN" : "גילוי DN בסיסי", "Test Base DN" : "בדיקת DN בסיסי", + "Avoids automatic LDAP requests. Better for bigger setups, but requires some LDAP knowledge." : "נמנע מבקשות אוטומטיות של LDAP. מועדף עבור התקנות גדולות, אבל מחייב ידע מסויים של LDAP.", + "Manually enter LDAP filters (recommended for large directories)" : "הכנסת מסנני LDAP ידנית (מומלץ עבוק תיקיות גדולות)", + "Limit %s access to users meeting these criteria:" : "מגביל כניסות %s למשתמשים אשר עומדים בתנאים אלו:", "Verify settings and count users" : "מאמת הגדרות וסופר משתמשים", "Saving" : "שמירה", "Back" : "אחורה", @@ -100,9 +104,14 @@ "Connection Settings" : "הגדרות התחברות", "Configuration Active" : "תצורה פעילה", "When unchecked, this configuration will be skipped." : "כאשר לא מסומן, נדלג על תצורה זו.", + "Backup (Replica) Host" : "גיבוי (העתק) שרת", + "Backup (Replica) Port" : "גיבוי (העתק) שער - פורט", "Disable Main Server" : "ניטרול שרת עיקרי", + "Only connect to the replica server." : "חיבור רק להעתק שרת.", + "Turn off SSL certificate validation." : "כיבוי אימות אישורי אבטחה SSL.", "in seconds. A change empties the cache." : "בשניות. שינוי מרוקן את המטמון.", "Directory Settings" : "הגדרות תיקייה", + "Base User Tree" : "עץ משתמש בסיסי", "in bytes" : "בבתים" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/console.php b/console.php index 23f40a15437..2073654fa8d 100644 --- a/console.php +++ b/console.php @@ -76,6 +76,10 @@ try { exit(1); } + if (!function_exists('pcntl_signal')) { + echo "The process control (PCNTL) extensions are required in case you want to interrupt long running commands - see http://php.net/manual/en/book.pcntl.php" . PHP_EOL; + } + $application = new Application(\OC::$server->getConfig()); $application->loadCommands(new ConsoleOutput()); $application->run(); diff --git a/core/command/base.php b/core/command/base.php index bc5ae2e429b..a34d7ec1c9a 100644 --- a/core/command/base.php +++ b/core/command/base.php @@ -33,6 +33,12 @@ class Base extends Command { protected $defaultOutputFormat = self::OUTPUT_FORMAT_PLAIN; + /** @var boolean */ + private $php_pcntl_signal = false; + + /** @var boolean */ + private $interrupted = false; + protected function configure() { $this ->addOption( @@ -43,6 +49,15 @@ class Base extends Command { $this->defaultOutputFormat ) ; + + // check if the php pcntl_signal functions are accessible + $this->php_pcntl_signal = function_exists('pcntl_signal'); + if ($this->php_pcntl_signal) { + // Collect interrupts and notify the running command + pcntl_signal(SIGTERM, [$this, 'cancelOperation']); + pcntl_signal(SIGINT, [$this, 'cancelOperation']); + } + } /** @@ -116,4 +131,27 @@ class Base extends Command { return $value; } } + + /** + * @return bool + */ + protected function hasBeenInterrupted() { + // return always false if pcntl_signal functions are not accessible + if ($this->php_pcntl_signal) { + pcntl_signal_dispatch(); + return $this->interrupted; + } else { + return false; + } + } + + /** + * Changes the status of the command to "interrupted" if ctrl-c has been pressed + * + * Gives a chance to the command to properly terminate what it's doing + */ + private function cancelOperation() { + $this->interrupted = true; + } + } diff --git a/core/js/config.php b/core/js/config.php index 9ea8f3864d1..aac7630a1d8 100644 --- a/core/js/config.php +++ b/core/js/config.php @@ -62,9 +62,17 @@ if ($defaultExpireDateEnabled) { } $outgoingServer2serverShareEnabled = $config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes'; +$countOfDataLocation = 0; + +$dataLocation = str_replace(OC::$SERVERROOT .'/', '', $config->getSystemValue('datadirectory', ''), $countOfDataLocation); +if($countOfDataLocation !== 1 || !OC_User::isAdminUser(OC_User::getUser())){ + $dataLocation = false; +} + $array = array( "oc_debug" => $config->getSystemValue('debug', false) ? 'true' : 'false', "oc_isadmin" => OC_User::isAdminUser(OC_User::getUser()) ? 'true' : 'false', + "oc_dataURL" => is_string($dataLocation) ? "\"".$dataLocation."\"" : 'false', "oc_webroot" => "\"".OC::$WEBROOT."\"", "oc_appswebroots" => str_replace('\\/', '/', json_encode($apps_paths)), // Ugly unescape slashes waiting for better solution "datepickerFormatDate" => json_encode($l->l('jsdate', null)), diff --git a/core/js/setupchecks.js b/core/js/setupchecks.js index 2fa119334db..bc49c61a5aa 100644 --- a/core/js/setupchecks.js +++ b/core/js/setupchecks.js @@ -15,7 +15,6 @@ MESSAGE_TYPE_INFO:0, MESSAGE_TYPE_WARNING:1, MESSAGE_TYPE_ERROR:2, - /** * Check whether the WebDAV connection works. * @@ -97,12 +96,6 @@ type: OC.SetupChecks.MESSAGE_TYPE_WARNING }); } - if(!data.dataDirectoryProtected) { - messages.push({ - msg: t('core', 'Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root.'), - type: OC.SetupChecks.MESSAGE_TYPE_ERROR - }); - } if(!data.isMemcacheConfigured) { messages.push({ msg: t('core', 'No memory cache has been configured. To enhance your performance please configure a memcache if available. Further information can be found in our <a target="_blank" href="{docLink}">documentation</a>.', {docLink: data.memcacheDocs}), @@ -194,6 +187,30 @@ return deferred.promise(); }, + checkDataProtected: function() { + var deferred = $.Deferred(); + if(oc_dataURL === false){ + return deferred.resolve([]); + } + var afterCall = function(xhr) { + var messages = []; + if (xhr.status !== 403 && xhr.status !== 307 && xhr.status !== 301) { + messages.push({ + msg: t('core', 'Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root.'), + type: OC.SetupChecks.MESSAGE_TYPE_ERROR + }); + } + deferred.resolve(messages); + }; + + $.ajax({ + type: 'GET', + url: OC.linkTo('', oc_dataURL+'/.ocdata'), + complete: afterCall + }); + return deferred.promise(); + }, + /** * Runs check for some generic security headers on the server side * diff --git a/core/js/tests/specs/setupchecksSpec.js b/core/js/tests/specs/setupchecksSpec.js index fff169ec098..59df3a58746 100644 --- a/core/js/tests/specs/setupchecksSpec.js +++ b/core/js/tests/specs/setupchecksSpec.js @@ -96,6 +96,49 @@ describe('OC.SetupChecks tests', function() { }); }); + describe('checkDataProtected', function() { + + oc_dataURL = "data"; + + it('should return an error if data directory is not protected', function(done) { + var async = OC.SetupChecks.checkDataProtected(); + + suite.server.requests[0].respond(200); + + async.done(function( data, s, x ){ + expect(data).toEqual([ + { + msg: 'Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root.', + type: OC.SetupChecks.MESSAGE_TYPE_ERROR + }]); + done(); + }); + }); + + it('should not return an error if data directory is protected', function(done) { + var async = OC.SetupChecks.checkDataProtected(); + + suite.server.requests[0].respond(403); + + async.done(function( data, s, x ){ + expect(data).toEqual([]); + done(); + }); + }); + + it('should return an error if data directory is a boolean', function(done) { + + oc_dataURL = false; + + var async = OC.SetupChecks.checkDataProtected(); + + async.done(function( data, s, x ){ + expect(data).toEqual([]); + done(); + }); + }); + }); + describe('checkSetup', function() { it('should return an error if server has no internet connection', function(done) { var async = OC.SetupChecks.checkSetup(); @@ -121,9 +164,6 @@ describe('OC.SetupChecks tests', function() { msg: 'This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features.', type: OC.SetupChecks.MESSAGE_TYPE_WARNING }, { - msg: 'Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root.', - type: OC.SetupChecks.MESSAGE_TYPE_ERROR - }, { msg: 'No memory cache has been configured. To enhance your performance please configure a memcache if available. Further information can be found in our <a target="_blank" href="https://doc.owncloud.org/server/go.php?to=admin-performance">documentation</a>.', type: OC.SetupChecks.MESSAGE_TYPE_INFO }]); @@ -142,7 +182,6 @@ describe('OC.SetupChecks tests', function() { JSON.stringify({ isUrandomAvailable: true, serverHasInternetConnection: false, - dataDirectoryProtected: false, memcacheDocs: 'https://doc.owncloud.org/server/go.php?to=admin-performance', forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, @@ -157,10 +196,6 @@ describe('OC.SetupChecks tests', function() { type: OC.SetupChecks.MESSAGE_TYPE_WARNING }, { - msg: 'Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root.', - type: OC.SetupChecks.MESSAGE_TYPE_ERROR - }, - { msg: 'No memory cache has been configured. To enhance your performance please configure a memcache if available. Further information can be found in our <a target="_blank" href="https://doc.owncloud.org/server/go.php?to=admin-performance">documentation</a>.', type: OC.SetupChecks.MESSAGE_TYPE_INFO }]); @@ -179,7 +214,6 @@ describe('OC.SetupChecks tests', function() { JSON.stringify({ isUrandomAvailable: true, serverHasInternetConnection: false, - dataDirectoryProtected: false, isMemcacheConfigured: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, @@ -192,11 +226,8 @@ describe('OC.SetupChecks tests', function() { { msg: 'This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features.', type: OC.SetupChecks.MESSAGE_TYPE_WARNING - }, - { - msg: 'Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root.', - type: OC.SetupChecks.MESSAGE_TYPE_ERROR - }]); + } + ]); done(); }); }); @@ -213,7 +244,6 @@ describe('OC.SetupChecks tests', function() { isUrandomAvailable: false, securityDocs: 'https://docs.owncloud.org/myDocs.html', serverHasInternetConnection: true, - dataDirectoryProtected: true, isMemcacheConfigured: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, @@ -242,7 +272,6 @@ describe('OC.SetupChecks tests', function() { isUrandomAvailable: true, securityDocs: 'https://docs.owncloud.org/myDocs.html', serverHasInternetConnection: true, - dataDirectoryProtected: true, isMemcacheConfigured: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: false, @@ -270,7 +299,6 @@ describe('OC.SetupChecks tests', function() { JSON.stringify({ isUrandomAvailable: true, serverHasInternetConnection: true, - dataDirectoryProtected: true, isMemcacheConfigured: true, forwardedForHeadersWorking: false, reverseProxyDocs: 'https://docs.owncloud.org/foo/bar.html', @@ -296,7 +324,7 @@ describe('OC.SetupChecks tests', function() { { 'Content-Type': 'application/json' }, - JSON.stringify({data: {serverHasInternetConnection: false, dataDirectoryProtected: false}}) + JSON.stringify({data: {serverHasInternetConnection: false}}) ); async.done(function( data, s, x ){ @@ -320,7 +348,6 @@ describe('OC.SetupChecks tests', function() { isUrandomAvailable: true, securityDocs: 'https://docs.owncloud.org/myDocs.html', serverHasInternetConnection: true, - dataDirectoryProtected: true, isMemcacheConfigured: true, forwardedForHeadersWorking: true, phpSupported: {eol: true, version: '5.4.0'}, @@ -484,7 +511,7 @@ describe('OC.SetupChecks tests', function() { { 'Content-Type': 'application/json' }, - JSON.stringify({data: {serverHasInternetConnection: false, dataDirectoryProtected: false}}) + JSON.stringify({data: {serverHasInternetConnection: false}}) ); async.done(function( data, s, x ){ expect(data).toEqual([{ diff --git a/core/l10n/fr.js b/core/l10n/fr.js index 5e312662719..2f1ebc3a9cb 100644 --- a/core/l10n/fr.js +++ b/core/l10n/fr.js @@ -86,7 +86,7 @@ OC.L10N.register( "Oct." : "Oct.", "Nov." : "Nov.", "Dec." : "Déc.", - "<a href=\"{docUrl}\">There were problems with the code integrity check. More information…</a>" : "<a href=\"{docUrl}\">Il y a eu des problèmes avec la vérification d’intégrité du code. Plus d'infos...</a>", + "<a href=\"{docUrl}\">There were problems with the code integrity check. More information…</a>" : "<a href=\"{docUrl}\">Il y a eu des problèmes à la vérification d’intégrité du code. Plus d'infos...</a>", "Settings" : "Paramètres", "Saving..." : "Enregistrement…", "seconds ago" : "à l'instant", @@ -120,7 +120,6 @@ OC.L10N.register( "Your web server is not yet set up properly to allow file synchronization because the WebDAV interface seems to be broken." : "Votre serveur web n'est pas correctement configuré pour la synchronisation de fichiers : l'interface WebDAV semble ne pas fonctionner.", "Your web server is not set up properly to resolve \"{url}\". Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "La configuration du serveur web ne permet pas d'atteindre \"{url}\". Consultez la <a target=\"_blank\" href=\"{docLink}\">documentation</a> pour avoir plus d'informations à ce sujet.", "This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features." : "Ce serveur ne peut se connecter à internet. Cela signifie que certaines fonctionnalités, telles que le montage de supports de stockage distants, les notifications de mises à jour ou l'installation d'applications tierces ne fonctionneront pas. L'accès aux fichiers à distance, ainsi que les notifications par mail peuvent aussi être indisponibles. Il est recommandé d'activer la connexion internet pour ce serveur si vous souhaitez disposer de l'ensemble des fonctionnalités offertes.", - "Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root." : "Votre dossier de données et vos fichiers sont probablement accessibles depuis internet. Le fichier .htaccess ne fonctionne pas. Nous vous recommandons vivement de configurer votre serveur web de façon à ce que ce dossier de données ne soit plus accessible, ou de le déplacer hors de la racine du serveur web.", "No memory cache has been configured. To enhance your performance please configure a memcache if available. Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "Aucun cache mémoire n'est configuré. Si possible, configurez un cache pour augmenter les performances. Consultez la <a target=\"_blank\" href=\"{docLink}\">documentation</a> pour avoir plus d'informations à ce sujet.", "/dev/urandom is not readable by PHP which is highly discouraged for security reasons. Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "/dev/urandom n'est pas lisible par PHP, ce qui est fortement déconseillé pour des raisons de sécurité. Consultez la <a target=\"_blank\" href=\"{docLink}\">documentation</a> pour avoir plus d'informations à ce sujet.", "Your PHP version ({version}) is no longer <a target=\"_blank\" href=\"{phpLink}\">supported by PHP</a>. We encourage you to upgrade your PHP version to take advantage of performance and security updates provided by PHP." : "Votre version de PHP ({version}) <a target=\"_blank\" href=\"{phpLink}\">n'est plus prise en charge par les créateurs de PHP</a>. Nous vous recommandons de mettre à niveau votre installation de PHP pour bénéficier de meilleures performances et des mises à jour de sécurité fournies par PHP.", @@ -128,6 +127,7 @@ OC.L10N.register( "Memcached is configured as distributed cache, but the wrong PHP module \"memcache\" is installed. \\OC\\Memcache\\Memcached only supports \"memcached\" and not \"memcache\". See the <a target=\"_blank\" href=\"{wikiLink}\">memcached wiki about both modules</a>." : "\"memcached\" est configuré comme cache distribué, mais le module installé est \"memcache\". \\OC\\Memcache\\Memcached ne prend en charge que \"memcached\" et non \"memcache\". <a target=\"_blank\" href=\"{wikiLink}\">Consulter le wiki de memcached à propos de ces deux modules.</a>", "Some files have not passed the integrity check. Further information on how to resolve this issue can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>. (<a href=\"{codeIntegrityDownloadEndpoint}\">List of invalid files…</a> / <a href=\"{rescanEndpoint}\">Rescan…</a>)" : "Des fichiers n'ont pas passé la vérification d’intégrité. \nConsultez la <a target=\"_blank\" href=\"{docLink}\">documentation</a> pour avoir plus d'informations sur comment résoudre ce problème.\n(<a target=\"_blank\" href=\"{codeIntegrityDownloadEndpoint}\">Liste des fichiers non valides…</a> / <a href=\"{rescanEndpoint}\">Relancer…</a>)", "Error occurred while checking server setup" : "Une erreur s'est produite lors de la vérification de la configuration du serveur", + "Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root." : "Votre dossier de données et vos fichiers sont probablement accessibles depuis internet. Le fichier .htaccess ne fonctionne pas. Nous vous recommandons vivement de configurer votre serveur web de façon à ce que ce dossier de données ne soit plus accessible, ou de le déplacer hors de la racine du serveur web.", "The \"{header}\" HTTP header is not configured to equal to \"{expected}\". This is a potential security or privacy risk and we recommend adjusting this setting." : "L'en-tête HTTP \"{header}\" n'est pas configurée pour être égale à \"{expected}\" créant potentiellement un risque relié à la sécurité et à la vie privée. Il est donc recommandé d'ajuster ce paramètre.", "The \"Strict-Transport-Security\" HTTP header is not configured to least \"{seconds}\" seconds. For enhanced security we recommend enabling HSTS as described in our <a href=\"{docUrl}\">security tips</a>." : "L'en-tête HTTP \"Strict-Transport-Security\" n'est pas configurée à \"{seconds}\" secondes. Pour renforcer la sécurité nous recommandons d'activer HSTS comme décrit dans notre <a href=\"{docUrl}\">Guide pour le renforcement et la sécurité</a>.", "You are accessing this site via HTTP. We strongly suggest you configure your server to require using HTTPS instead as described in our <a href=\"{docUrl}\">security tips</a>." : "Vous accédez à ce site via HTTP. Nous vous recommandons fortement de configurer votre serveur pour forcer l'utilisation de HTTPS, comme expliqué dans notre <a href=\"{docUrl}\">Guide pour le renforcement et la sécurité</a>.", @@ -164,17 +164,20 @@ OC.L10N.register( "change" : "modification", "delete" : "suppression", "access control" : "contrôle d'accès", + "Could not unshare" : "Impossible d'arrêter de partager", "Share details could not be loaded for this item." : "Les informations de partage n'ont pu être chargées pour cet élément.", "An error occured. Please try again" : "Une erreur est survenue. Merci de réessayer", "Share" : "Partager", "Share with people on other ownClouds using the syntax username@example.com/owncloud" : "Partagez avec des personnes sur d'autres ownClouds en utilisant la syntaxe utilisateur@exemple.com/owncloud", "Share with users or groups …" : "Partager avec des utilisateurs ou groupes...", "Share with users, groups or remote users …" : "Partager avec des utilisateurs, groupes, ou utilisateurs distants", + "Error removing share" : "Erreur lors de l'arrêt du partage", "Warning" : "Attention", "Error while sending notification" : "Erreur lors de l'envoi de la notification", "Non-existing tag #{tag}" : "Étiquette #{tag} inexistante", "not assignable" : "inassignable", "invisible" : "invisible", + "({scope})" : "({scope})", "Delete" : "Supprimer", "Rename" : "Renommer", "Global tags" : "Étiquettes globales", diff --git a/core/l10n/fr.json b/core/l10n/fr.json index 4b0196e5ee4..df7cd0cf3c5 100644 --- a/core/l10n/fr.json +++ b/core/l10n/fr.json @@ -84,7 +84,7 @@ "Oct." : "Oct.", "Nov." : "Nov.", "Dec." : "Déc.", - "<a href=\"{docUrl}\">There were problems with the code integrity check. More information…</a>" : "<a href=\"{docUrl}\">Il y a eu des problèmes avec la vérification d’intégrité du code. Plus d'infos...</a>", + "<a href=\"{docUrl}\">There were problems with the code integrity check. More information…</a>" : "<a href=\"{docUrl}\">Il y a eu des problèmes à la vérification d’intégrité du code. Plus d'infos...</a>", "Settings" : "Paramètres", "Saving..." : "Enregistrement…", "seconds ago" : "à l'instant", @@ -118,7 +118,6 @@ "Your web server is not yet set up properly to allow file synchronization because the WebDAV interface seems to be broken." : "Votre serveur web n'est pas correctement configuré pour la synchronisation de fichiers : l'interface WebDAV semble ne pas fonctionner.", "Your web server is not set up properly to resolve \"{url}\". Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "La configuration du serveur web ne permet pas d'atteindre \"{url}\". Consultez la <a target=\"_blank\" href=\"{docLink}\">documentation</a> pour avoir plus d'informations à ce sujet.", "This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features." : "Ce serveur ne peut se connecter à internet. Cela signifie que certaines fonctionnalités, telles que le montage de supports de stockage distants, les notifications de mises à jour ou l'installation d'applications tierces ne fonctionneront pas. L'accès aux fichiers à distance, ainsi que les notifications par mail peuvent aussi être indisponibles. Il est recommandé d'activer la connexion internet pour ce serveur si vous souhaitez disposer de l'ensemble des fonctionnalités offertes.", - "Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root." : "Votre dossier de données et vos fichiers sont probablement accessibles depuis internet. Le fichier .htaccess ne fonctionne pas. Nous vous recommandons vivement de configurer votre serveur web de façon à ce que ce dossier de données ne soit plus accessible, ou de le déplacer hors de la racine du serveur web.", "No memory cache has been configured. To enhance your performance please configure a memcache if available. Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "Aucun cache mémoire n'est configuré. Si possible, configurez un cache pour augmenter les performances. Consultez la <a target=\"_blank\" href=\"{docLink}\">documentation</a> pour avoir plus d'informations à ce sujet.", "/dev/urandom is not readable by PHP which is highly discouraged for security reasons. Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "/dev/urandom n'est pas lisible par PHP, ce qui est fortement déconseillé pour des raisons de sécurité. Consultez la <a target=\"_blank\" href=\"{docLink}\">documentation</a> pour avoir plus d'informations à ce sujet.", "Your PHP version ({version}) is no longer <a target=\"_blank\" href=\"{phpLink}\">supported by PHP</a>. We encourage you to upgrade your PHP version to take advantage of performance and security updates provided by PHP." : "Votre version de PHP ({version}) <a target=\"_blank\" href=\"{phpLink}\">n'est plus prise en charge par les créateurs de PHP</a>. Nous vous recommandons de mettre à niveau votre installation de PHP pour bénéficier de meilleures performances et des mises à jour de sécurité fournies par PHP.", @@ -126,6 +125,7 @@ "Memcached is configured as distributed cache, but the wrong PHP module \"memcache\" is installed. \\OC\\Memcache\\Memcached only supports \"memcached\" and not \"memcache\". See the <a target=\"_blank\" href=\"{wikiLink}\">memcached wiki about both modules</a>." : "\"memcached\" est configuré comme cache distribué, mais le module installé est \"memcache\". \\OC\\Memcache\\Memcached ne prend en charge que \"memcached\" et non \"memcache\". <a target=\"_blank\" href=\"{wikiLink}\">Consulter le wiki de memcached à propos de ces deux modules.</a>", "Some files have not passed the integrity check. Further information on how to resolve this issue can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>. (<a href=\"{codeIntegrityDownloadEndpoint}\">List of invalid files…</a> / <a href=\"{rescanEndpoint}\">Rescan…</a>)" : "Des fichiers n'ont pas passé la vérification d’intégrité. \nConsultez la <a target=\"_blank\" href=\"{docLink}\">documentation</a> pour avoir plus d'informations sur comment résoudre ce problème.\n(<a target=\"_blank\" href=\"{codeIntegrityDownloadEndpoint}\">Liste des fichiers non valides…</a> / <a href=\"{rescanEndpoint}\">Relancer…</a>)", "Error occurred while checking server setup" : "Une erreur s'est produite lors de la vérification de la configuration du serveur", + "Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root." : "Votre dossier de données et vos fichiers sont probablement accessibles depuis internet. Le fichier .htaccess ne fonctionne pas. Nous vous recommandons vivement de configurer votre serveur web de façon à ce que ce dossier de données ne soit plus accessible, ou de le déplacer hors de la racine du serveur web.", "The \"{header}\" HTTP header is not configured to equal to \"{expected}\". This is a potential security or privacy risk and we recommend adjusting this setting." : "L'en-tête HTTP \"{header}\" n'est pas configurée pour être égale à \"{expected}\" créant potentiellement un risque relié à la sécurité et à la vie privée. Il est donc recommandé d'ajuster ce paramètre.", "The \"Strict-Transport-Security\" HTTP header is not configured to least \"{seconds}\" seconds. For enhanced security we recommend enabling HSTS as described in our <a href=\"{docUrl}\">security tips</a>." : "L'en-tête HTTP \"Strict-Transport-Security\" n'est pas configurée à \"{seconds}\" secondes. Pour renforcer la sécurité nous recommandons d'activer HSTS comme décrit dans notre <a href=\"{docUrl}\">Guide pour le renforcement et la sécurité</a>.", "You are accessing this site via HTTP. We strongly suggest you configure your server to require using HTTPS instead as described in our <a href=\"{docUrl}\">security tips</a>." : "Vous accédez à ce site via HTTP. Nous vous recommandons fortement de configurer votre serveur pour forcer l'utilisation de HTTPS, comme expliqué dans notre <a href=\"{docUrl}\">Guide pour le renforcement et la sécurité</a>.", @@ -162,17 +162,20 @@ "change" : "modification", "delete" : "suppression", "access control" : "contrôle d'accès", + "Could not unshare" : "Impossible d'arrêter de partager", "Share details could not be loaded for this item." : "Les informations de partage n'ont pu être chargées pour cet élément.", "An error occured. Please try again" : "Une erreur est survenue. Merci de réessayer", "Share" : "Partager", "Share with people on other ownClouds using the syntax username@example.com/owncloud" : "Partagez avec des personnes sur d'autres ownClouds en utilisant la syntaxe utilisateur@exemple.com/owncloud", "Share with users or groups …" : "Partager avec des utilisateurs ou groupes...", "Share with users, groups or remote users …" : "Partager avec des utilisateurs, groupes, ou utilisateurs distants", + "Error removing share" : "Erreur lors de l'arrêt du partage", "Warning" : "Attention", "Error while sending notification" : "Erreur lors de l'envoi de la notification", "Non-existing tag #{tag}" : "Étiquette #{tag} inexistante", "not assignable" : "inassignable", "invisible" : "invisible", + "({scope})" : "({scope})", "Delete" : "Supprimer", "Rename" : "Renommer", "Global tags" : "Étiquettes globales", diff --git a/core/l10n/ru.js b/core/l10n/ru.js index 93e919453a8..2b942444db1 100644 --- a/core/l10n/ru.js +++ b/core/l10n/ru.js @@ -164,16 +164,23 @@ OC.L10N.register( "change" : "изменить", "delete" : "удалить", "access control" : "контроль доступа", + "Could not unshare" : "Не удается отменить доступ", "Share details could not be loaded for this item." : "Не удалось загрузить информацию об общем доступе для этого элемента.", "An error occured. Please try again" : "Произошла ошибка. Попробуйте ещё раз", "Share" : "Поделиться", "Share with people on other ownClouds using the syntax username@example.com/owncloud" : "Поделиться с людьми на других серверах ownCloud используя формат username@example.com/owncloud", "Share with users or groups …" : "Поделиться с пользователями или группами ...", "Share with users, groups or remote users …" : "Поделиться с пользователями, группами или удаленными пользователями ...", + "Error removing share" : "Ошибка удаления общего доступа", "Warning" : "Предупреждение", "Error while sending notification" : "Ошибка при отправке уведомления", + "Non-existing tag #{tag}" : "Несуществующий тег #{tag}", + "not assignable" : "не назначаемый", + "invisible" : "невидимый", + "({scope})" : "({scope})", "Delete" : "Удалить", "Rename" : "Переименовать", + "Global tags" : "Глобальные теги", "The object type is not specified." : "Тип объекта не указан", "Enter new" : "Ввести новое", "Add" : "Добавить", diff --git a/core/l10n/ru.json b/core/l10n/ru.json index f88f24d6582..d90e88b37ae 100644 --- a/core/l10n/ru.json +++ b/core/l10n/ru.json @@ -162,16 +162,23 @@ "change" : "изменить", "delete" : "удалить", "access control" : "контроль доступа", + "Could not unshare" : "Не удается отменить доступ", "Share details could not be loaded for this item." : "Не удалось загрузить информацию об общем доступе для этого элемента.", "An error occured. Please try again" : "Произошла ошибка. Попробуйте ещё раз", "Share" : "Поделиться", "Share with people on other ownClouds using the syntax username@example.com/owncloud" : "Поделиться с людьми на других серверах ownCloud используя формат username@example.com/owncloud", "Share with users or groups …" : "Поделиться с пользователями или группами ...", "Share with users, groups or remote users …" : "Поделиться с пользователями, группами или удаленными пользователями ...", + "Error removing share" : "Ошибка удаления общего доступа", "Warning" : "Предупреждение", "Error while sending notification" : "Ошибка при отправке уведомления", + "Non-existing tag #{tag}" : "Несуществующий тег #{tag}", + "not assignable" : "не назначаемый", + "invisible" : "невидимый", + "({scope})" : "({scope})", "Delete" : "Удалить", "Rename" : "Переименовать", + "Global tags" : "Глобальные теги", "The object type is not specified." : "Тип объекта не указан", "Enter new" : "Ввести новое", "Add" : "Добавить", diff --git a/lib/base.php b/lib/base.php index 56ff1cb8962..fc4a99287d0 100644 --- a/lib/base.php +++ b/lib/base.php @@ -645,7 +645,6 @@ class OC { } self::registerShareHooks(); self::registerLogRotate(); - self::registerLocalAddressBook(); self::registerEncryptionWrapper(); self::registerEncryptionHooks(); @@ -701,14 +700,6 @@ class OC { \OC::$server->getEventLogger()->end('boot'); } - private static function registerLocalAddressBook() { - self::$server->getContactsManager()->register(function() { - $userManager = \OC::$server->getUserManager(); - \OC::$server->getContactsManager()->registerAddressBook( - new \OC\Contacts\LocalAddressBook($userManager)); - }); - } - /** * register hooks for the cache */ diff --git a/lib/l10n/ru.js b/lib/l10n/ru.js index 034f9e7f355..14a2b11dc01 100644 --- a/lib/l10n/ru.js +++ b/lib/l10n/ru.js @@ -118,6 +118,7 @@ OC.L10N.register( "Cannot set expiration date more than %s days in the future" : "Невозможно установить дату окончания срока действия более %s дней", "Could not find category \"%s\"" : "Категория \"%s\" не найдена", "Apps" : "Приложения", + "Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-'\"" : "В качестве имени пользователя допускаются следующие символы: \"a-z\", \"A-Z\", \"0-9\" и \"_.@-'\"", "A valid username must be provided" : "Укажите правильное имя пользователя", "A valid password must be provided" : "Укажите правильный пароль", "The username is already being used" : "Имя пользователя уже используется", diff --git a/lib/l10n/ru.json b/lib/l10n/ru.json index 90c7fb81ada..592abd22e81 100644 --- a/lib/l10n/ru.json +++ b/lib/l10n/ru.json @@ -116,6 +116,7 @@ "Cannot set expiration date more than %s days in the future" : "Невозможно установить дату окончания срока действия более %s дней", "Could not find category \"%s\"" : "Категория \"%s\" не найдена", "Apps" : "Приложения", + "Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-'\"" : "В качестве имени пользователя допускаются следующие символы: \"a-z\", \"A-Z\", \"0-9\" и \"_.@-'\"", "A valid username must be provided" : "Укажите правильное имя пользователя", "A valid password must be provided" : "Укажите правильный пароль", "The username is already being used" : "Имя пользователя уже используется", diff --git a/lib/private/activitymanager.php b/lib/private/activitymanager.php index e5235cb9bfe..68bb8c13401 100644 --- a/lib/private/activitymanager.php +++ b/lib/private/activitymanager.php @@ -310,20 +310,19 @@ class ActivityManager implements IManager { /** * @param string $type - * @param int $id + * @param string $id */ public function setFormattingObject($type, $id) { $this->formattingObjectType = $type; - $this->formattingObjectId = $id; + $this->formattingObjectId = (string) $id; } /** * @return bool */ public function isFormattingFilteredObject() { - return 'filter' === $this->request->getParam('filter') - && $this->formattingObjectType === $this->request->getParam('objecttype') - && $this->formattingObjectId === $this->request->getParam('objectid'); + return $this->formattingObjectType === $this->request->getParam('object_type') + && $this->formattingObjectId === $this->request->getParam('object_id'); } /** diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/appframework/dependencyinjection/dicontainer.php index ff9da88cd81..5fc45fdd2e8 100644 --- a/lib/private/appframework/dependencyinjection/dicontainer.php +++ b/lib/private/appframework/dependencyinjection/dicontainer.php @@ -152,6 +152,10 @@ class DIContainer extends SimpleContainer implements IAppContainer { return $this->getServer()->getL10N($c->query('AppName')); }); + $this->registerService('OCP\\L10N\\IFactory', function($c) { + return $this->getServer()->getL10NFactory(); + }); + $this->registerService('OCP\\ILogger', function($c) { return $this->getServer()->getLogger(); }); diff --git a/lib/private/contacts/localaddressbook.php b/lib/private/contacts/localaddressbook.php deleted file mode 100644 index 6fba63ae327..00000000000 --- a/lib/private/contacts/localaddressbook.php +++ /dev/null @@ -1,118 +0,0 @@ -<?php -/** - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @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 OC\Contacts; - -class LocalAddressBook implements \OCP\IAddressBook { - - /** - * @var \OCP\IUserManager - */ - private $userManager; - - /** - * @param $userManager - */ - public function __construct($userManager) { - $this->userManager = $userManager; - } - - /** - * @return string defining the technical unique key - */ - public function getKey() { - return 'local'; - } - - /** - * In comparison to getKey() this function returns a human readable (maybe translated) name - * - * @return mixed - */ - public function getDisplayName() { - return "Local users"; - } - - /** - * @param string $pattern which should match within the $searchProperties - * @param array $searchProperties defines the properties within the query pattern should match - * @param array $options - for future use. One should always have options! - * @return array an array of contacts which are arrays of key-value-pairs - */ - public function search($pattern, $searchProperties, $options) { - $users = array(); - if($pattern == '') { - // Fetch all contacts - $users = $this->userManager->search(''); - } else { - foreach($searchProperties as $property) { - $result = array(); - if($property === 'FN') { - $result = $this->userManager->searchDisplayName($pattern); - } else if ($property === 'id') { - $result = $this->userManager->search($pattern); - } - if (is_array($result)) { - $users = array_merge($users, $result); - } - } - } - - $contacts = array(); - foreach($users as $user){ - $contact = array( - "id" => $user->getUID(), - "FN" => $user->getDisplayname(), - "EMAIL" => array(), - "IMPP" => array( - "x-owncloud-handle:" . $user->getUID() - ) - ); - $contacts[] = $contact; - } - return $contacts; - } - - /** - * @param array $properties this array if key-value-pairs defines a contact - * @return array an array representing the contact just created or updated - */ - public function createOrUpdate($properties) { - return array(); - } - - /** - * @return int - */ - public function getPermissions() { - return \OCP\Constants::PERMISSION_READ; - } - - /** - * @param object $id the unique identifier to a contact - * @return bool successful or not - */ - public function delete($id) { - return false; - } -} diff --git a/lib/private/files/view.php b/lib/private/files/view.php index d4cc24ae0f5..2656e34cddf 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -46,6 +46,7 @@ use Icewind\Streams\CallbackWrapper; use OC\Files\Mount\MoveableMount; use OC\Files\Storage\Storage; use OC\User\User; +use OCP\Constants; use OCP\Files\Cache\ICacheEntry; use OCP\Files\FileNameTooLongException; use OCP\Files\InvalidCharacterInPathException; @@ -1335,7 +1336,7 @@ class View { $data = $this->getCacheEntry($storage, $internalPath, $directory); - if (!$data instanceof ICacheEntry || !isset($data['fileid'])) { + if (!$data instanceof ICacheEntry || !isset($data['fileid']) || !($data->getPermissions() && Constants::PERMISSION_READ)) { return []; } @@ -1385,7 +1386,7 @@ class View { $rootEntry = $subCache->get(''); } - if ($rootEntry) { + if ($rootEntry && ($rootEntry->getPermissions() && Constants::PERMISSION_READ)) { $relativePath = trim(substr($mountPoint, $dirLength), '/'); if ($pos = strpos($relativePath, '/')) { //mountpoint inside subfolder add size to the correct folder diff --git a/lib/private/share20/defaultshareprovider.php b/lib/private/share20/defaultshareprovider.php index 0fa1552a1e7..224dddf4019 100644 --- a/lib/private/share20/defaultshareprovider.php +++ b/lib/private/share20/defaultshareprovider.php @@ -20,6 +20,7 @@ */ namespace OC\Share20; +use OCP\Files\File; use OCP\Share\IShareProvider; use OC\Share20\Exception\InvalidShare; use OC\Share20\Exception\ProviderException; @@ -251,6 +252,7 @@ class DefaultShareProvider implements IShareProvider { /** * Get all children of this share + * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in * * @param \OCP\Share\IShare $parent * @return IShare[] @@ -265,12 +267,11 @@ class DefaultShareProvider implements IShareProvider { ->andWhere( $qb->expr()->in( 'share_type', - [ - $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), - $qb->expr()->literal(\OCP\Share::SHARE_TYPE_GROUP), - $qb->expr()->literal(\OCP\Share::SHARE_TYPE_LINK), - $qb->expr()->literal(self::SHARE_TYPE_USERGROUP), - ] + $qb->createNamedParameter([ + \OCP\Share::SHARE_TYPE_USER, + \OCP\Share::SHARE_TYPE_GROUP, + \OCP\Share::SHARE_TYPE_LINK, + ], IQueryBuilder::PARAM_INT_ARRAY) ) ) ->orderBy('id'); @@ -384,6 +385,63 @@ class DefaultShareProvider implements IShareProvider { } /** + * @inheritdoc + */ + public function move(\OCP\Share\IShare $share, IUser $recipient) { + if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) { + // Just update the target + $qb = $this->dbConn->getQueryBuilder(); + $qb->update('share') + ->set('file_target', $qb->createNamedParameter($share->getTarget())) + ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId()))) + ->execute(); + + } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { + + // Check if there is a usergroup share + $qb = $this->dbConn->getQueryBuilder(); + $stmt = $qb->select('id') + ->from('share') + ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP))) + ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient->getUID()))) + ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId()))) + ->setMaxResults(1) + ->execute(); + + $data = $stmt->fetch(); + $stmt->closeCursor(); + + if ($data === false) { + // No usergroup share yet. Create one. + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERGROUP), + 'share_with' => $qb->createNamedParameter($recipient->getUID()), + 'uid_owner' => $qb->createNamedParameter($share->getShareOwner()->getUID()), + 'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()->getUID()), + 'parent' => $qb->createNamedParameter($share->getId()), + 'item_type' => $qb->createNamedParameter($share->getNode() instanceof File ? 'file' : 'folder'), + 'item_source' => $qb->createNamedParameter($share->getNode()->getId()), + 'file_source' => $qb->createNamedParameter($share->getNode()->getId()), + 'file_target' => $qb->createNamedParameter($share->getTarget()), + 'permissions' => $qb->createNamedParameter($share->getPermissions()), + 'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()), + ])->execute(); + } else { + // Already a usergroup share. Update it. + $qb = $this->dbConn->getQueryBuilder(); + $qb->update('share') + ->set('file_target', $qb->createNamedParameter($share->getTarget())) + ->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id']))) + ->execute(); + } + } + + return $share; + } + + /** * Get all shares by the given user. Sharetype and path can be used to filter. * * @param IUser $user @@ -448,13 +506,9 @@ class DefaultShareProvider implements IShareProvider { } /** - * Get share by id - * - * @param int $id - * @return \OCP\Share\IShare - * @throws ShareNotFound + * @inheritdoc */ - public function getShareById($id) { + public function getShareById($id, $recipient = null) { $qb = $this->dbConn->getQueryBuilder(); $qb->select('*') @@ -463,12 +517,11 @@ class DefaultShareProvider implements IShareProvider { ->andWhere( $qb->expr()->in( 'share_type', - [ - $qb->expr()->literal(\OCP\Share::SHARE_TYPE_USER), - $qb->expr()->literal(\OCP\Share::SHARE_TYPE_GROUP), - $qb->expr()->literal(\OCP\Share::SHARE_TYPE_LINK), - $qb->expr()->literal(self::SHARE_TYPE_USERGROUP), - ] + $qb->createNamedParameter([ + \OCP\Share::SHARE_TYPE_USER, + \OCP\Share::SHARE_TYPE_GROUP, + \OCP\Share::SHARE_TYPE_LINK, + ], IQueryBuilder::PARAM_INT_ARRAY) ) ); @@ -486,6 +539,11 @@ class DefaultShareProvider implements IShareProvider { throw new ShareNotFound(); } + // If the recipient is set for a group share resolve to that user + if ($recipient !== null && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { + $share = $this->resolveGroupShare($share, $recipient); + } + return $share; } diff --git a/lib/private/share20/manager.php b/lib/private/share20/manager.php index e45fa4b40f9..b22b81bb404 100644 --- a/lib/private/share20/manager.php +++ b/lib/private/share20/manager.php @@ -612,6 +612,7 @@ class Manager implements IManager { /** * Delete all the children of this share + * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in * * @param \OCP\Share\IShare $share * @return \OCP\Share\IShare[] List of deleted shares @@ -714,6 +715,25 @@ class Manager implements IManager { } /** + * @inheritdoc + */ + public function moveShare(\OCP\Share\IShare $share, IUser $recipient) { + if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { + throw new \InvalidArgumentException('Can\'t change target of link share'); + } + + if (($share->getShareType() === \OCP\Share::SHARE_TYPE_USER && $share->getSharedWith() !== $recipient) || + ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP && !$share->getSharedWith()->inGroup($recipient))) { + throw new \InvalidArgumentException('Invalid recipient'); + } + + list($providerId, ) = $this->splitFullId($share->getId()); + $provider = $this->factory->getProvider($providerId); + + $provider->move($share, $recipient); + } + + /** * Get shares shared by (initiated) by the provided user. * * @param IUser $user @@ -746,14 +766,9 @@ class Manager implements IManager { } /** - * Retrieve a share by the share id - * - * @param string $id - * @return Share - * - * @throws ShareNotFound + * @inheritdoc */ - public function getShareById($id) { + public function getShareById($id, $recipient = null) { if ($id === null) { throw new ShareNotFound(); } @@ -761,7 +776,7 @@ class Manager implements IManager { list($providerId, $id) = $this->splitFullId($id); $provider = $this->factory->getProvider($providerId); - $share = $provider->getShareById($id); + $share = $provider->getShareById($id, $recipient); return $share; } @@ -819,7 +834,9 @@ class Manager implements IManager { } if (!empty($newHash)) { - //TODO update hash! + $share->setPassword($newHash); + $provider = $this->factory->getProviderForType($share->getShareType()); + $provider->update($share); } return true; diff --git a/lib/private/systemtag/managerfactory.php b/lib/private/systemtag/managerfactory.php index 7b7b9558b04..7ad4f922600 100644 --- a/lib/private/systemtag/managerfactory.php +++ b/lib/private/systemtag/managerfactory.php @@ -20,11 +20,10 @@ */ namespace OC\SystemTag; -use OCP\SystemTag\ISystemTagManagerFactory; -use OCP\SystemTag\ISystemTagManager; -use OC\SystemTag\SystemTagManager; -use OC\SystemTag\SystemTagObjectMapper; use OCP\IServerContainer; +use OCP\SystemTag\ISystemTagManager; +use OCP\SystemTag\ISystemTagManagerFactory; +use OCP\SystemTag\ISystemTagObjectMapper; /** * Default factory class for system tag managers @@ -58,7 +57,8 @@ class ManagerFactory implements ISystemTagManagerFactory { */ public function getManager() { return new SystemTagManager( - $this->serverContainer->getDatabaseConnection() + $this->serverContainer->getDatabaseConnection(), + $this->serverContainer->getEventDispatcher() ); } @@ -72,7 +72,8 @@ class ManagerFactory implements ISystemTagManagerFactory { public function getObjectMapper() { return new SystemTagObjectMapper( $this->serverContainer->getDatabaseConnection(), - $this->getManager() + $this->getManager(), + $this->serverContainer->getEventDispatcher() ); } } diff --git a/lib/private/systemtag/systemtagmanager.php b/lib/private/systemtag/systemtagmanager.php index af912a74936..76a60a91328 100644 --- a/lib/private/systemtag/systemtagmanager.php +++ b/lib/private/systemtag/systemtagmanager.php @@ -26,17 +26,20 @@ use Doctrine\DBAL\Exception\UniqueConstraintViolationException; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; use OCP\SystemTag\ISystemTagManager; +use OCP\SystemTag\ManagerEvent; use OCP\SystemTag\TagAlreadyExistsException; use OCP\SystemTag\TagNotFoundException; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; class SystemTagManager implements ISystemTagManager { const TAG_TABLE = 'systemtag'; - /** - * @var IDBConnection - */ - private $connection; + /** @var IDBConnection */ + protected $connection; + + /** @var EventDispatcherInterface */ + protected $dispatcher; /** * Prepared query for selecting tags directly @@ -46,12 +49,14 @@ class SystemTagManager implements ISystemTagManager { private $selectTagQuery; /** - * Constructor. - * - * @param IDBConnection $connection database connection - */ - public function __construct(IDBConnection $connection) { + * Constructor. + * + * @param IDBConnection $connection database connection + * @param EventDispatcherInterface $dispatcher + */ + public function __construct(IDBConnection $connection, EventDispatcherInterface $dispatcher) { $this->connection = $connection; + $this->dispatcher = $dispatcher; $query = $this->connection->getQueryBuilder(); $this->selectTagQuery = $query->select('*') @@ -190,14 +195,20 @@ class SystemTagManager implements ISystemTagManager { ); } - $tagId = $this->connection->lastInsertId('*PREFIX*' . self::TAG_TABLE); + $tagId = $query->getLastInsertId(); - return new SystemTag( + $tag = new SystemTag( (int)$tagId, $tagName, (bool)$userVisible, (bool)$userAssignable ); + + $this->dispatcher->dispatch(ManagerEvent::EVENT_CREATE, new ManagerEvent( + ManagerEvent::EVENT_CREATE, $tag + )); + + return $tag; } /** @@ -207,6 +218,22 @@ class SystemTagManager implements ISystemTagManager { $userVisible = (int)$userVisible; $userAssignable = (int)$userAssignable; + try { + $tags = $this->getTagsByIds($tagId); + } catch (TagNotFoundException $e) { + throw new TagNotFoundException( + 'Tag does not exist', 0, null, [$tagId] + ); + } + + $beforeUpdate = array_shift($tags); + $afterUpdate = new SystemTag( + (int) $tagId, + $tagName, + (bool) $userVisible, + (bool) $userAssignable + ); + $query = $this->connection->getQueryBuilder(); $query->update(self::TAG_TABLE) ->set('name', $query->createParameter('name')) @@ -231,6 +258,10 @@ class SystemTagManager implements ISystemTagManager { $e ); } + + $this->dispatcher->dispatch(ManagerEvent::EVENT_UPDATE, new ManagerEvent( + ManagerEvent::EVENT_UPDATE, $afterUpdate, $beforeUpdate + )); } /** @@ -242,10 +273,21 @@ class SystemTagManager implements ISystemTagManager { } $tagNotFoundException = null; + $tags = []; try { - $this->getTagsByIds($tagIds); + $tags = $this->getTagsByIds($tagIds); } catch (TagNotFoundException $e) { $tagNotFoundException = $e; + + // Get existing tag objects for the hooks later + $existingTags = array_diff($tagIds, $tagNotFoundException->getMissingTags()); + if (!empty($existingTags)) { + try { + $tags = $this->getTagsByIds($existingTags); + } catch (TagNotFoundException $e) { + // Ignore further errors... + } + } } // delete relationships first @@ -261,6 +303,12 @@ class SystemTagManager implements ISystemTagManager { ->setParameter('tagids', $tagIds, IQueryBuilder::PARAM_INT_ARRAY) ->execute(); + foreach ($tags as $tag) { + $this->dispatcher->dispatch(ManagerEvent::EVENT_DELETE, new ManagerEvent( + ManagerEvent::EVENT_DELETE, $tag + )); + } + if ($tagNotFoundException !== null) { throw new TagNotFoundException( 'Tag id(s) not found', 0, $tagNotFoundException, $tagNotFoundException->getMissingTags() diff --git a/lib/private/systemtag/systemtagobjectmapper.php b/lib/private/systemtag/systemtagobjectmapper.php index 458b558ad97..1efb4f0f6e0 100644 --- a/lib/private/systemtag/systemtagobjectmapper.php +++ b/lib/private/systemtag/systemtagobjectmapper.php @@ -28,31 +28,34 @@ use OCP\IDBConnection; use OCP\SystemTag\ISystemTag; use OCP\SystemTag\ISystemTagManager; use OCP\SystemTag\ISystemTagObjectMapper; +use OCP\SystemTag\MapperEvent; use OCP\SystemTag\TagNotFoundException; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; class SystemTagObjectMapper implements ISystemTagObjectMapper { const RELATION_TABLE = 'systemtag_object_mapping'; - /** - * @var ISystemTagManager - */ - private $tagManager; + /** @var ISystemTagManager */ + protected $tagManager; - /** - * @var IDBConnection - */ - private $connection; + /** @var IDBConnection */ + protected $connection; + + /** @var EventDispatcherInterface */ + protected $dispatcher; /** * Constructor. * * @param IDBConnection $connection database connection * @param ISystemTagManager $tagManager system tag manager + * @param EventDispatcherInterface $dispatcher */ - public function __construct(IDBConnection $connection, ISystemTagManager $tagManager) { + public function __construct(IDBConnection $connection, ISystemTagManager $tagManager, EventDispatcherInterface $dispatcher) { $this->connection = $connection; $this->tagManager = $tagManager; + $this->dispatcher = $dispatcher; } /** @@ -143,6 +146,13 @@ class SystemTagObjectMapper implements ISystemTagObjectMapper { // ignore existing relations } } + + $this->dispatcher->dispatch(MapperEvent::EVENT_ASSIGN, new MapperEvent( + MapperEvent::EVENT_ASSIGN, + $objectType, + $objId, + $tagIds + )); } /** @@ -164,6 +174,13 @@ class SystemTagObjectMapper implements ISystemTagObjectMapper { ->setParameter('objecttype', $objectType) ->setParameter('tagids', $tagIds, IQueryBuilder::PARAM_INT_ARRAY) ->execute(); + + $this->dispatcher->dispatch(MapperEvent::EVENT_UNASSIGN, new MapperEvent( + MapperEvent::EVENT_UNASSIGN, + $objectType, + $objId, + $tagIds + )); } /** diff --git a/lib/private/util.php b/lib/private/util.php index 64695d95a03..28541eff773 100644 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -152,6 +152,16 @@ class OC_Util { return $storage; }); + \OC\Files\Filesystem::addStorageWrapper('enable_sharing', function ($mountPoint, \OCP\Files\Storage $storage, \OCP\Files\Mount\IMountPoint $mount) { + if (!$mount->getOption('enable_sharing', true)) { + return new \OC\Files\Storage\Wrapper\PermissionsMask([ + 'storage' => $storage, + 'mask' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_SHARE + ]); + } + return $storage; + }); + // install storage availability wrapper, before most other wrappers \OC\Files\Filesystem::addStorageWrapper('oc_availability', function ($mountPoint, $storage) { if (!$storage->isLocal()) { diff --git a/lib/public/share/imanager.php b/lib/public/share/imanager.php index b2d9953e9ef..15b9f34764e 100644 --- a/lib/public/share/imanager.php +++ b/lib/public/share/imanager.php @@ -37,13 +37,15 @@ interface IManager { * Create a Share * * @param IShare $share - * @return Share The share object + * @return IShare The share object * @since 9.0.0 */ public function createShare(IShare $share); /** - * Update a share + * Update a share. + * The target of the share can't be changed this way: use moveShare + * The share can't be removed this way (permission 0): use deleteShare * * @param IShare $share * @return IShare The share object @@ -73,6 +75,18 @@ interface IManager { public function deleteFromSelf(IShare $share, IUser $recipient); /** + * Move the share as a recipient of the share. + * This is updating the share target. So where the recipient has the share mounted. + * + * @param IShare $share + * @param IUser $recipient + * @return IShare + * @throws \InvalidArgumentException If $share is a link share or the $recipient does not match + * @since 9.0.0 + */ + public function moveShare(IShare $share, IUser $recipient); + + /** * Get shares shared by (initiated) by the provided user. * * @param IUser $user @@ -101,20 +115,24 @@ interface IManager { public function getSharedWith(IUser $user, $shareType, $node = null, $limit = 50, $offset = 0); /** - * Retrieve a share by the share id + * Retrieve a share by the share id. + * If the recipient is set make sure to retrieve the file for that user. + * This makes sure that if a user has moved/deleted a group share this + * is reflected. * * @param string $id - * @return Share + * @param IUser|null $recipient + * @return IShare * @throws ShareNotFound * @since 9.0.0 */ - public function getShareById($id); + public function getShareById($id, $recipient = null); /** * Get the share by token possible with password * * @param string $token - * @return Share + * @return IShare * @throws ShareNotFound * @since 9.0.0 */ diff --git a/lib/public/share/ishareprovider.php b/lib/public/share/ishareprovider.php index 8507462cbed..42a2881718e 100644 --- a/lib/public/share/ishareprovider.php +++ b/lib/public/share/ishareprovider.php @@ -80,6 +80,19 @@ interface IShareProvider { public function deleteFromSelf(\OCP\Share\IShare $share, IUser $recipient); /** + * Move a share as a recipient. + * This is updating the share target. Thus the mount point of the recipient. + * This may require special handling. If a user moves a group share + * the target should only be changed for them. + * + * @param \OCP\Share\IShare $share + * @param IUser $recipient + * @return \OCP\Share\IShare + * @since 9.0.0 + */ + public function move(\OCP\Share\IShare $share, IUser $recipient); + + /** * Get all shares by the given user * * @param IUser $user @@ -97,11 +110,12 @@ interface IShareProvider { * Get share by id * * @param int $id + * @param IUser|null $recipient * @return \OCP\Share\IShare * @throws ShareNotFound * @since 9.0.0 */ - public function getShareById($id); + public function getShareById($id, $recipient = null); /** * Get shares for a given path diff --git a/lib/public/systemtag/managerevent.php b/lib/public/systemtag/managerevent.php new file mode 100644 index 00000000000..a0429fc9f67 --- /dev/null +++ b/lib/public/systemtag/managerevent.php @@ -0,0 +1,85 @@ +<?php +/** + * @author Joas Schilling <nickvergessen@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 OCP\SystemTag; + +use Symfony\Component\EventDispatcher\Event; + +/** + * Class ManagerEvent + * + * @package OCP\SystemTag + * @since 9.0.0 + */ +class ManagerEvent extends Event { + + const EVENT_CREATE = 'OCP\SystemTag\ISystemTagManager::createTag'; + const EVENT_UPDATE = 'OCP\SystemTag\ISystemTagManager::updateTag'; + const EVENT_DELETE = 'OCP\SystemTag\ISystemTagManager::deleteTag'; + + /** @var string */ + protected $event; + /** @var ISystemTag */ + protected $tag; + /** @var ISystemTag */ + protected $beforeTag; + + /** + * DispatcherEvent constructor. + * + * @param string $event + * @param ISystemTag $tag + * @param ISystemTag $beforeTag + * @since 9.0.0 + */ + public function __construct($event, ISystemTag $tag, ISystemTag $beforeTag = null) { + $this->event = $event; + $this->tag = $tag; + $this->beforeTag = $beforeTag; + } + + /** + * @return string + * @since 9.0.0 + */ + public function getEvent() { + return $this->event; + } + + /** + * @return ISystemTag + * @since 9.0.0 + */ + public function getTag() { + return $this->tag; + } + + /** + * @return ISystemTag + * @since 9.0.0 + */ + public function getTagBefore() { + if ($this->event !== self::EVENT_UPDATE) { + throw new \BadMethodCallException('getTagBefore is only available on the update Event'); + } + return $this->beforeTag; + } +} diff --git a/lib/public/systemtag/mapperevent.php b/lib/public/systemtag/mapperevent.php new file mode 100644 index 00000000000..e05a5ce09c8 --- /dev/null +++ b/lib/public/systemtag/mapperevent.php @@ -0,0 +1,93 @@ +<?php +/** + * @author Joas Schilling <nickvergessen@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 OCP\SystemTag; + +use Symfony\Component\EventDispatcher\Event; + +/** + * Class MapperEvent + * + * @package OCP\SystemTag + * @since 9.0.0 + */ +class MapperEvent extends Event { + + const EVENT_ASSIGN = 'OCP\SystemTag\ISystemTagObjectMapper::assignTags'; + const EVENT_UNASSIGN = 'OCP\SystemTag\ISystemTagObjectMapper::unassignTags'; + + /** @var string */ + protected $event; + /** @var string */ + protected $objectType; + /** @var string */ + protected $objectId; + /** @var int[] */ + protected $tags; + + /** + * DispatcherEvent constructor. + * + * @param string $event + * @param string $objectType + * @param string $objectId + * @param int[] $tags + * @since 9.0.0 + */ + public function __construct($event, $objectType, $objectId, array $tags) { + $this->event = $event; + $this->objectType = $objectType; + $this->objectId = $objectId; + $this->tags = $tags; + } + + /** + * @return string + * @since 9.0.0 + */ + public function getEvent() { + return $this->event; + } + + /** + * @return string + * @since 9.0.0 + */ + public function getObjectType() { + return $this->objectType; + } + + /** + * @return string + * @since 9.0.0 + */ + public function getObjectId() { + return $this->objectId; + } + + /** + * @return int[] + * @since 9.0.0 + */ + public function getTags() { + return $this->tags; + } +} diff --git a/settings/controller/checksetupcontroller.php b/settings/controller/checksetupcontroller.php index 7b995bf2c1b..26194bb1180 100644 --- a/settings/controller/checksetupcontroller.php +++ b/settings/controller/checksetupcontroller.php @@ -329,7 +329,6 @@ Raw output return new DataResponse( [ 'serverHasInternetConnection' => $this->isInternetConnectionWorking(), - 'dataDirectoryProtected' => $this->util->isHtaccessWorking($this->config), 'isMemcacheConfigured' => $this->isMemcacheConfigured(), 'memcacheDocs' => $this->urlGenerator->linkToDocs('admin-performance'), 'isUrandomAvailable' => $this->isUrandomAvailable(), diff --git a/settings/js/admin.js b/settings/js/admin.js index 6660bfe9b48..90b1de68370 100644 --- a/settings/js/admin.js +++ b/settings/js/admin.js @@ -171,9 +171,10 @@ $(document).ready(function(){ OC.SetupChecks.checkWellKnownUrl('/.well-known/caldav/', oc_defaults.docPlaceholderUrl, $('#postsetupchecks').data('check-wellknown') === 'true'), OC.SetupChecks.checkWellKnownUrl('/.well-known/carddav/', oc_defaults.docPlaceholderUrl, $('#postsetupchecks').data('check-wellknown') === 'true'), OC.SetupChecks.checkSetup(), - OC.SetupChecks.checkGeneric() - ).then(function(check1, check2, check3, check4, check5) { - var messages = [].concat(check1, check2, check3, check4, check5); + OC.SetupChecks.checkGeneric(), + OC.SetupChecks.checkDataProtected() + ).then(function(check1, check2, check3, check4, check5, check6) { + var messages = [].concat(check1, check2, check3, check4, check5, check6); var $el = $('#postsetupchecks'); $el.find('.loading').addClass('hidden'); diff --git a/settings/l10n/fr.js b/settings/l10n/fr.js index 7f0034ae940..43a6ef4358e 100644 --- a/settings/l10n/fr.js +++ b/settings/l10n/fr.js @@ -205,6 +205,7 @@ OC.L10N.register( "Experimental applications ahead" : "Attention! Applications expérimentales", "Experimental apps are not checked for security issues, new or known to be unstable and under heavy development. Installing them can cause data loss or security breaches." : "Les applications expérimentales n'ont pas fait l'objet de tests de sécurité, sont encore en développement et peuvent être instables. Les installer peut causer des pertes de données ou des failles de sécurité. ", "by %s" : "par %s", + "%s-licensed" : "Sous licence %s", "Documentation:" : "Documentation :", "User documentation" : "Documentation utilisateur", "Admin documentation" : "Documentation administrateur", diff --git a/settings/l10n/fr.json b/settings/l10n/fr.json index b690dc5d8e6..9b5fbd02401 100644 --- a/settings/l10n/fr.json +++ b/settings/l10n/fr.json @@ -203,6 +203,7 @@ "Experimental applications ahead" : "Attention! Applications expérimentales", "Experimental apps are not checked for security issues, new or known to be unstable and under heavy development. Installing them can cause data loss or security breaches." : "Les applications expérimentales n'ont pas fait l'objet de tests de sécurité, sont encore en développement et peuvent être instables. Les installer peut causer des pertes de données ou des failles de sécurité. ", "by %s" : "par %s", + "%s-licensed" : "Sous licence %s", "Documentation:" : "Documentation :", "User documentation" : "Documentation utilisateur", "Admin documentation" : "Documentation administrateur", diff --git a/settings/l10n/ru.js b/settings/l10n/ru.js index 77e57b69323..33697368a27 100644 --- a/settings/l10n/ru.js +++ b/settings/l10n/ru.js @@ -204,6 +204,8 @@ OC.L10N.register( "Developer documentation" : "Документация для разработчиков", "Experimental applications ahead" : "Экспериментальные приложения", "Experimental apps are not checked for security issues, new or known to be unstable and under heavy development. Installing them can cause data loss or security breaches." : "Экспериментальные приложения не проверялись на наличие уязвимостей безопасности, они также могут быть нестабильны, т.к. находятся в активной разработке. Их установка может повлечь потерю информации или нарушение безопасности.", + "by %s" : "от %s", + "%s-licensed" : "Лицензия %s", "Documentation:" : "Документация:", "User documentation" : "Пользовательская документация", "Admin documentation" : "Документация для администратора", diff --git a/settings/l10n/ru.json b/settings/l10n/ru.json index dc1a2101aca..959588abf57 100644 --- a/settings/l10n/ru.json +++ b/settings/l10n/ru.json @@ -202,6 +202,8 @@ "Developer documentation" : "Документация для разработчиков", "Experimental applications ahead" : "Экспериментальные приложения", "Experimental apps are not checked for security issues, new or known to be unstable and under heavy development. Installing them can cause data loss or security breaches." : "Экспериментальные приложения не проверялись на наличие уязвимостей безопасности, они также могут быть нестабильны, т.к. находятся в активной разработке. Их установка может повлечь потерю информации или нарушение безопасности.", + "by %s" : "от %s", + "%s-licensed" : "Лицензия %s", "Documentation:" : "Документация:", "User documentation" : "Пользовательская документация", "Admin documentation" : "Документация для администратора", diff --git a/tests/lib/contacts/localadressbook.php b/tests/lib/contacts/localadressbook.php deleted file mode 100644 index ad3c088e3cd..00000000000 --- a/tests/lib/contacts/localadressbook.php +++ /dev/null @@ -1,114 +0,0 @@ -<?php -use OC\Contacts\LocalAddressBook; -use OCP\IUser; - -/** - * ownCloud - * - * @author Thomas Müller - * @copyright 2014 Thomas Müller thomas.mueller@tmit.eu - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -class Test_LocalAddressBook extends \Test\TestCase -{ - - public function testSearchFN() { - $stub = $this->getMockForAbstractClass('\OCP\IUserManager', array('searchDisplayName')); - - $stub->expects($this->any())->method('searchDisplayName')->will($this->returnValue(array( - new SimpleUserForTesting('tom', 'Thomas'), - new SimpleUserForTesting('tomtom', 'Thomas T.'), - ))); - - $localAddressBook = new LocalAddressBook($stub); - - $result = $localAddressBook->search('tom', array('FN'), array()); - $this->assertEquals(2, count($result)); - } - - public function testSearchId() { - $stub = $this->getMockForAbstractClass('\OCP\IUserManager', array('searchDisplayName')); - - $stub->expects($this->any())->method('search')->will($this->returnValue(array( - new SimpleUserForTesting('tom', 'Thomas'), - new SimpleUserForTesting('tomtom', 'Thomas T.'), - ))); - - $localAddressBook = new LocalAddressBook($stub); - - $result = $localAddressBook->search('tom', array('id'), array()); - $this->assertEquals(2, count($result)); - } -} - - -class SimpleUserForTesting implements IUser { - - private $uid; - private $displayName; - - public function __construct($uid, $displayName) { - - $this->uid = $uid; - $this->displayName = $displayName; - } - - public function getUID() { - return $this->uid; - } - - public function getDisplayName() { - return $this->displayName; - } - - public function setDisplayName($displayName) { - } - - public function getLastLogin() { - } - - public function updateLastLoginTimestamp() { - } - - public function delete() { - } - - public function setPassword($password, $recoveryPassword = null) { - } - - public function getHome() { - } - - public function getBackendClassName() { - } - - public function canChangeAvatar() { - } - - public function canChangePassword() { - } - - public function canChangeDisplayName() { - } - - public function isEnabled() { - } - - public function setEnabled($enabled) { - } - - public function getEMailAddress() { - } - - public function getAvatarImage($size) { - } - - public function getCloudId() { - } - - public function setEMailAddress($mailAddress) { - } -} diff --git a/tests/lib/share20/defaultshareprovidertest.php b/tests/lib/share20/defaultshareprovidertest.php index 28b57435e1d..504bd776036 100644 --- a/tests/lib/share20/defaultshareprovidertest.php +++ b/tests/lib/share20/defaultshareprovidertest.php @@ -247,6 +247,44 @@ class DefaultShareProviderTest extends \Test\TestCase { $this->assertEquals('myTarget', $share->getTarget()); } + public function testGetShareByIdUserGroupShare() { + $id = $this->addShareToDB(\OCP\Share::SHARE_TYPE_GROUP, 'group0', 'user0', 'user0', 'file', 42, 'myTarget', 31, null, null); + $this->addShareToDB(2, 'user1', 'user0', 'user0', 'file', 42, 'userTarget', 0, null, null, $id); + + $user0 = $this->getMock('OCP\IUser'); + $user0->method('getUID')->willReturn('user0'); + $user1 = $this->getMock('OCP\IUser'); + $user1->method('getUID')->willReturn('user1'); + + $group0 = $this->getMock('OCP\IGroup'); + $group0->method('inGroup')->with($user1)->willReturn(true); + + $node = $this->getMock('\OCP\Files\Folder'); + $node->method('getId')->willReturn(42); + + $this->rootFolder->method('getUserFolder')->with('user0')->will($this->returnSelf()); + $this->rootFolder->method('getById')->willReturn([$node]); + + $this->userManager->method('get')->will($this->returnValueMap([ + ['user0', $user0], + ['user1', $user1], + ])); + $this->groupManager->method('get')->with('group0')->willReturn($group0); + + $share = $this->provider->getShareById($id, $user1); + + $this->assertEquals($id, $share->getId()); + $this->assertEquals(\OCP\Share::SHARE_TYPE_GROUP, $share->getShareType()); + $this->assertSame($group0, $share->getSharedWith()); + $this->assertSame($user0, $share->getSharedBy()); + $this->assertSame($user0, $share->getShareOwner()); + $this->assertSame($node, $share->getNode()); + $this->assertEquals(0, $share->getPermissions()); + $this->assertEquals(null, $share->getToken()); + $this->assertEquals(null, $share->getExpirationDate()); + $this->assertEquals('userTarget', $share->getTarget()); + } + public function testGetShareByIdLinkShare() { $qb = $this->dbConn->getQueryBuilder(); @@ -1854,6 +1892,75 @@ class DefaultShareProviderTest extends \Test\TestCase { $stmt->closeCursor(); + } + + public function testMoveUserShare() { + $id = $this->addShareToDB(\OCP\Share::SHARE_TYPE_USER, 'user0', 'user1', 'user1', 'file', + 42, 'mytaret', 31, null, null); + + $user0 = $this->getMock('\OCP\IUser'); + $user0->method('getUID')->willReturn('user0'); + $user1 = $this->getMock('\OCP\IUser'); + $user1->method('getUID')->willReturn('user1'); + + $this->userManager->method('get')->will($this->returnValueMap([ + ['user0', $user0], + ['user1', $user1], + ])); + + $file = $this->getMock('\OCP\Files\File'); + $file->method('getId')->willReturn(42); + + $this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf()); + $this->rootFolder->method('getById')->willReturn([$file]); + + $share = $this->provider->getShareById($id, null); + + $share->setTarget('/newTarget'); + $this->provider->move($share, $user0); + + $share = $this->provider->getShareById($id, null); + $this->assertSame('/newTarget', $share->getTarget()); + } + + public function testMoveGroupShare() { + $id = $this->addShareToDB(\OCP\Share::SHARE_TYPE_GROUP, 'group0', 'user1', 'user1', 'file', + 42, 'mytaret', 31, null, null); + + $user0 = $this->getMock('\OCP\IUser'); + $user0->method('getUID')->willReturn('user0'); + $user1 = $this->getMock('\OCP\IUser'); + $user1->method('getUID')->willReturn('user1'); + + $group0 = $this->getMock('\OCP\IGroup'); + $group0->method('getGID')->willReturn('group0'); + $group0->method('inGroup')->with($user0)->willReturn(true); + + $this->groupManager->method('get')->with('group0')->willReturn($group0); + + $this->userManager->method('get')->will($this->returnValueMap([ + ['user0', $user0], + ['user1', $user1], + ])); + + $folder = $this->getMock('\OCP\Files\Folder'); + $folder->method('getId')->willReturn(42); + + $this->rootFolder->method('getUserFolder')->with('user1')->will($this->returnSelf()); + $this->rootFolder->method('getById')->willReturn([$folder]); + + $share = $this->provider->getShareById($id, $user0); + + $share->setTarget('/newTarget'); + $this->provider->move($share, $user0); + + $share = $this->provider->getShareById($id, $user0); + $this->assertSame('/newTarget', $share->getTarget()); + + $share->setTarget('/ultraNewTarget'); + $this->provider->move($share, $user0); + $share = $this->provider->getShareById($id, $user0); + $this->assertSame('/ultraNewTarget', $share->getTarget()); } } diff --git a/tests/lib/share20/managertest.php b/tests/lib/share20/managertest.php index b5559bb5172..6043d30a0bb 100644 --- a/tests/lib/share20/managertest.php +++ b/tests/lib/share20/managertest.php @@ -1645,6 +1645,27 @@ class ManagerTest extends \Test\TestCase { $this->assertTrue($this->manager->checkPassword($share, 'password')); } + public function testCheckPasswordUpdateShare() { + $share = $this->manager->newShare(); + $share->setShareType(\OCP\Share::SHARE_TYPE_LINK) + ->setPassword('passwordHash'); + + $this->hasher->method('verify')->with('password', 'passwordHash', '') + ->will($this->returnCallback(function($pass, $hash, &$newHash) { + $newHash = 'newHash'; + + return true; + })); + + $this->defaultProvider->expects($this->once()) + ->method('update') + ->with($this->callback(function (\OCP\Share\IShare $share) { + return $share->getPassword() === 'newHash'; + })); + + $this->assertTrue($this->manager->checkPassword($share, 'password')); + } + /** * @expectedException Exception * @expectedExceptionMessage The Share API is disabled @@ -1887,6 +1908,79 @@ class ManagerTest extends \Test\TestCase { $manager->updateShare($share); } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Can't change target of link share + */ + public function testMoveShareLink() { + $share = $this->manager->newShare(); + $share->setShareType(\OCP\Share::SHARE_TYPE_LINK); + + $recipient = $this->getMock('\OCP\IUser'); + + $this->manager->moveShare($share, $recipient); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Invalid recipient + */ + public function testMoveShareUserNotRecipient() { + $share = $this->manager->newShare(); + $share->setShareType(\OCP\Share::SHARE_TYPE_USER); + + $sharedWith = $this->getMock('\OCP\IUser'); + $share->setSharedWith($sharedWith); + + $recipient = $this->getMock('\OCP\IUser'); + + $this->manager->moveShare($share, $recipient); + } + + public function testMoveShareUser() { + $share = $this->manager->newShare(); + $share->setShareType(\OCP\Share::SHARE_TYPE_USER); + + $recipient = $this->getMock('\OCP\IUser'); + $share->setSharedWith($recipient); + + $this->defaultProvider->method('move')->with($share, $recipient)->will($this->returnArgument(0)); + + $this->manager->moveShare($share, $recipient); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Invalid recipient + */ + public function testMoveShareGroupNotRecipient() { + $share = $this->manager->newShare(); + $share->setShareType(\OCP\Share::SHARE_TYPE_GROUP); + + $sharedWith = $this->getMock('\OCP\IGroup'); + $share->setSharedWith($sharedWith); + + $recipient = $this->getMock('\OCP\IUser'); + $sharedWith->method('inGroup')->with($recipient)->willReturn(false); + + $this->manager->moveShare($share, $recipient); + } + + public function testMoveShareGroup() { + $share = $this->manager->newShare(); + $share->setShareType(\OCP\Share::SHARE_TYPE_GROUP); + + $sharedWith = $this->getMock('\OCP\IGroup'); + $share->setSharedWith($sharedWith); + + $recipient = $this->getMock('\OCP\IUser'); + $sharedWith->method('inGroup')->with($recipient)->willReturn(true); + + $this->defaultProvider->method('move')->with($share, $recipient)->will($this->returnArgument(0)); + + $this->manager->moveShare($share, $recipient); + } } class DummyPassword { diff --git a/tests/lib/systemtag/systemtagmanagertest.php b/tests/lib/systemtag/systemtagmanagertest.php index 97c072f33f6..64220205ade 100644 --- a/tests/lib/systemtag/systemtagmanagertest.php +++ b/tests/lib/systemtag/systemtagmanagertest.php @@ -15,6 +15,7 @@ use OC\SystemTag\SystemTagObjectMapper; use OCP\IDBConnection; use OCP\SystemTag\ISystemTag; use OCP\SystemTag\ISystemTagManager; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Test\TestCase; /** @@ -35,11 +36,23 @@ class SystemTagManagerTest extends TestCase { */ private $connection; + /** + * @var EventDispatcherInterface + */ + private $dispatcher; + public function setUp() { parent::setUp(); $this->connection = \OC::$server->getDatabaseConnection(); - $this->tagManager = new SystemTagManager($this->connection); + + $this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface') + ->getMock(); + + $this->tagManager = new SystemTagManager( + $this->connection, + $this->dispatcher + ); $this->pruneTagsTables(); } @@ -378,7 +391,7 @@ class SystemTagManagerTest extends TestCase { $tag1 = $this->tagManager->createTag('one', true, false); $tag2 = $this->tagManager->createTag('two', true, true); - $tagMapper = new SystemTagObjectMapper($this->connection, $this->tagManager); + $tagMapper = new SystemTagObjectMapper($this->connection, $this->tagManager, $this->dispatcher); $tagMapper->assignTags(1, 'testtype', $tag1->getId()); $tagMapper->assignTags(1, 'testtype', $tag2->getId()); diff --git a/tests/lib/systemtag/systemtagobjectmappertest.php b/tests/lib/systemtag/systemtagobjectmappertest.php index 4ea80c216ed..5c8204f6a87 100644 --- a/tests/lib/systemtag/systemtagobjectmappertest.php +++ b/tests/lib/systemtag/systemtagobjectmappertest.php @@ -10,14 +10,15 @@ namespace Test\SystemTag; +use OC\SystemTag\SystemTag; use OC\SystemTag\SystemTagManager; use OC\SystemTag\SystemTagObjectMapper; -use \OCP\SystemTag\ISystemTag; -use \OCP\SystemTag\ISystemTagManager; -use \OCP\SystemTag\ISystemTagObjectMapper; -use \OCP\SystemTag\TagNotFoundException; -use \OCP\IDBConnection; -use \OC\SystemTag\SystemTag; +use OCP\IDBConnection; +use OCP\SystemTag\ISystemTag; +use OCP\SystemTag\ISystemTagManager; +use OCP\SystemTag\ISystemTagObjectMapper; +use OCP\SystemTag\TagNotFoundException; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Test\TestCase; /** @@ -44,6 +45,11 @@ class SystemTagObjectMapperTest extends TestCase { private $connection; /** + * @var EventDispatcherInterface + */ + private $dispatcher; + + /** * @var ISystemTag */ private $tag1; @@ -67,7 +73,14 @@ class SystemTagObjectMapperTest extends TestCase { $this->tagManager = $this->getMockBuilder('OCP\SystemTag\ISystemTagManager') ->getMock(); - $this->tagMapper = new SystemTagObjectMapper($this->connection, $this->tagManager); + $this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface') + ->getMock(); + + $this->tagMapper = new SystemTagObjectMapper( + $this->connection, + $this->tagManager, + $this->dispatcher + ); $this->tag1 = new SystemTag(1, 'testtag1', false, false); $this->tag2 = new SystemTag(2, 'testtag2', true, false); diff --git a/tests/settings/controller/CheckSetupControllerTest.php b/tests/settings/controller/CheckSetupControllerTest.php index 08d4135fa12..c22ddb2e120 100644 --- a/tests/settings/controller/CheckSetupControllerTest.php +++ b/tests/settings/controller/CheckSetupControllerTest.php @@ -326,10 +326,6 @@ class CheckSetupControllerTest extends TestCase { $this->clientService->expects($this->once()) ->method('newClient') ->will($this->returnValue($client)); - - $this->util->expects($this->once()) - ->method('isHtaccessWorking') - ->will($this->returnValue(true)); $this->urlGenerator->expects($this->at(0)) ->method('linkToDocs') ->with('admin-performance') @@ -347,7 +343,6 @@ class CheckSetupControllerTest extends TestCase { $expected = new DataResponse( [ 'serverHasInternetConnection' => false, - 'dataDirectoryProtected' => true, 'isMemcacheConfigured' => true, 'memcacheDocs' => 'http://doc.owncloud.org/server/go.php?to=admin-performance', 'isUrandomAvailable' => self::invokePrivate($this->checkSetupController, 'isUrandomAvailable'), |