diff options
60 files changed, 646 insertions, 63 deletions
diff --git a/apps/comments/js/commentstabview.js b/apps/comments/js/commentstabview.js index 9e501b141a7..20f1f590a28 100644 --- a/apps/comments/js/commentstabview.js +++ b/apps/comments/js/commentstabview.js @@ -240,19 +240,22 @@ if(!_.isUndefined(this._autoCompleteRequestCall)) { this._autoCompleteRequestCall.abort(); } - this._autoCompleteRequestCall = $.get( - OC.generateUrl('/autocomplete/get'), - { + this._autoCompleteRequestCall = $.ajax({ + url: OC.linkToOCS('core', 2) + 'autocomplete/get', + data: { search: query, itemType: 'files', itemId: s.model.get('id'), sorter: 'commenters|share-recipients', limit: OC.appConfig.comments.maxAutoCompleteResults }, - function (data) { - callback(data); + beforeSend: function (request) { + request.setRequestHeader('Accept', 'application/json'); + }, + success: function (result) { + callback(result.ocs.data); } - ); + }); }, 400); }, diff --git a/apps/comments/l10n/fi.js b/apps/comments/l10n/fi.js index 39fde95643a..c82bd4c934e 100644 --- a/apps/comments/l10n/fi.js +++ b/apps/comments/l10n/fi.js @@ -12,6 +12,7 @@ OC.L10N.register( "More comments …" : "Lisää kommentteja…", "Save" : "Tallenna", "Allowed characters {count} of {max}" : "Sallittujen merkkien määrä {count}/{max}", + "Error occurred while retrieving comment with ID {id}" : "Virhe haettaessa kommenttia tunnisteella {id}", "Error occurred while updating comment with id {id}" : "Virhe päivittäessä kommenttia tunnisteella {id}", "Error occurred while posting comment" : "Virhe kommenttia lähettäessä", "_%n unread comment_::_%n unread comments_" : ["%n lukematon kommentti","%n lukematonta kommenttia"], diff --git a/apps/comments/l10n/fi.json b/apps/comments/l10n/fi.json index 1a693ba76b0..cb1e7fcccbe 100644 --- a/apps/comments/l10n/fi.json +++ b/apps/comments/l10n/fi.json @@ -10,6 +10,7 @@ "More comments …" : "Lisää kommentteja…", "Save" : "Tallenna", "Allowed characters {count} of {max}" : "Sallittujen merkkien määrä {count}/{max}", + "Error occurred while retrieving comment with ID {id}" : "Virhe haettaessa kommenttia tunnisteella {id}", "Error occurred while updating comment with id {id}" : "Virhe päivittäessä kommenttia tunnisteella {id}", "Error occurred while posting comment" : "Virhe kommenttia lähettäessä", "_%n unread comment_::_%n unread comments_" : ["%n lukematon kommentti","%n lukematonta kommenttia"], diff --git a/apps/dav/l10n/fi.js b/apps/dav/l10n/fi.js index 1061a7bf80f..ce54c41f6da 100644 --- a/apps/dav/l10n/fi.js +++ b/apps/dav/l10n/fi.js @@ -48,6 +48,7 @@ OC.L10N.register( "The meeting »%s« with %s was canceled." : "Tapaaminen »%s« henkilön %s kanssa peruttiin.", "Invitation updated" : "Kutsu päivitetty", "The meeting »%s« with %s was updated." : "Tapaaminen »%s« henkilön %s kanssa päivitettiin.", + "%s invited you to »%s«" : "%s kutsui sinut »%s«", "When:" : "Milloin:", "Where:" : "Missä:", "Description:" : "Kuvaus:", diff --git a/apps/dav/l10n/fi.json b/apps/dav/l10n/fi.json index 37714056422..888818020f3 100644 --- a/apps/dav/l10n/fi.json +++ b/apps/dav/l10n/fi.json @@ -46,6 +46,7 @@ "The meeting »%s« with %s was canceled." : "Tapaaminen »%s« henkilön %s kanssa peruttiin.", "Invitation updated" : "Kutsu päivitetty", "The meeting »%s« with %s was updated." : "Tapaaminen »%s« henkilön %s kanssa päivitettiin.", + "%s invited you to »%s«" : "%s kutsui sinut »%s«", "When:" : "Milloin:", "Where:" : "Missä:", "Description:" : "Kuvaus:", diff --git a/apps/dav/lib/Files/FileSearchBackend.php b/apps/dav/lib/Files/FileSearchBackend.php index 275d3dc8a42..5b3c18c9720 100644 --- a/apps/dav/lib/Files/FileSearchBackend.php +++ b/apps/dav/lib/Files/FileSearchBackend.php @@ -113,7 +113,7 @@ class FileSearchBackend implements ISearchBackend { //todo dynamically load all propfind properties that are supported return [ // queryable properties - new SearchPropertyDefinition('{DAV:}displayname', true, false, true), + new SearchPropertyDefinition('{DAV:}displayname', true, true, true), new SearchPropertyDefinition('{DAV:}getcontenttype', true, true, true), new SearchPropertyDefinition('{DAV:}getlastmodified', true, true, true, SearchPropertyDefinition::DATATYPE_DATETIME), new SearchPropertyDefinition(FilesPlugin::SIZE_PROPERTYNAME, true, true, true, SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER), diff --git a/apps/federatedfilesharing/l10n/fi.js b/apps/federatedfilesharing/l10n/fi.js index de6ef87dda3..9e659981478 100644 --- a/apps/federatedfilesharing/l10n/fi.js +++ b/apps/federatedfilesharing/l10n/fi.js @@ -33,7 +33,7 @@ OC.L10N.register( "Sharing" : "Jakaminen", "Federated file sharing" : "Federoitu tiedostojako", "Federated Cloud Sharing" : "Federoitu pilvijakaminen", - "Open documentation" : "Avaa dokumentaatio", + "Open documentation" : "Avaa ohje", "Adjust how people can share between servers." : "Mukauta kuinka ihmiset voivat jakaa palvelinten välillä.", "Allow users on this server to send shares to other servers" : "Salli tämän palvelimen käyttäjien lähettää jakoja muille palvelimille", "Allow users on this server to receive shares from other servers" : "Salli tämän palvelimen käyttäjien vastaanottaa jakoja muilta palvelimilta", diff --git a/apps/federatedfilesharing/l10n/fi.json b/apps/federatedfilesharing/l10n/fi.json index 6291af9be96..89259e025d9 100644 --- a/apps/federatedfilesharing/l10n/fi.json +++ b/apps/federatedfilesharing/l10n/fi.json @@ -31,7 +31,7 @@ "Sharing" : "Jakaminen", "Federated file sharing" : "Federoitu tiedostojako", "Federated Cloud Sharing" : "Federoitu pilvijakaminen", - "Open documentation" : "Avaa dokumentaatio", + "Open documentation" : "Avaa ohje", "Adjust how people can share between servers." : "Mukauta kuinka ihmiset voivat jakaa palvelinten välillä.", "Allow users on this server to send shares to other servers" : "Salli tämän palvelimen käyttäjien lähettää jakoja muille palvelimille", "Allow users on this server to receive shares from other servers" : "Salli tämän palvelimen käyttäjien vastaanottaa jakoja muilta palvelimilta", diff --git a/apps/files_sharing/l10n/fi.js b/apps/files_sharing/l10n/fi.js index 36351ae613a..b139d8681f4 100644 --- a/apps/files_sharing/l10n/fi.js +++ b/apps/files_sharing/l10n/fi.js @@ -77,7 +77,7 @@ OC.L10N.register( "Public link sharing is disabled by the administrator" : "Ylläpitäjä on estänyt julkisen linkin jakamisen", "Public upload disabled by the administrator" : "Ylläpitäjä on estänyt julkisen lähetyksen", "Public upload is only possible for publicly shared folders" : "Julkinen lähettäminen on mahdollista vain julkisesti jaetuille kansioille", - "Invalid date, date format must be YYYY-MM-DD" : "Virheellinen päiväys, päivämäärän muodon tulee olla YYYY-MM-DD", + "Invalid date, date format must be YYYY-MM-DD" : "Virheellinen päiväys, päivämäärän muodon tulee olla VVVV-KK-PP", "Sharing %s failed because the back end does not allow shares from type %s" : "Kohteen %s jakaminen epäonnistui, koska tietovarasto ei salli %s tyyppisiä jakoja", "You cannot share to a Circle if the app is not enabled" : "Et voi jakaa piiriin, jos sovellusta ei ole aktivoitu", "Please specify a valid circle" : "Määritä kelvollinen piiri", diff --git a/apps/files_sharing/l10n/fi.json b/apps/files_sharing/l10n/fi.json index fa870dee1c4..0069f9f7c34 100644 --- a/apps/files_sharing/l10n/fi.json +++ b/apps/files_sharing/l10n/fi.json @@ -75,7 +75,7 @@ "Public link sharing is disabled by the administrator" : "Ylläpitäjä on estänyt julkisen linkin jakamisen", "Public upload disabled by the administrator" : "Ylläpitäjä on estänyt julkisen lähetyksen", "Public upload is only possible for publicly shared folders" : "Julkinen lähettäminen on mahdollista vain julkisesti jaetuille kansioille", - "Invalid date, date format must be YYYY-MM-DD" : "Virheellinen päiväys, päivämäärän muodon tulee olla YYYY-MM-DD", + "Invalid date, date format must be YYYY-MM-DD" : "Virheellinen päiväys, päivämäärän muodon tulee olla VVVV-KK-PP", "Sharing %s failed because the back end does not allow shares from type %s" : "Kohteen %s jakaminen epäonnistui, koska tietovarasto ei salli %s tyyppisiä jakoja", "You cannot share to a Circle if the app is not enabled" : "Et voi jakaa piiriin, jos sovellusta ei ole aktivoitu", "Please specify a valid circle" : "Määritä kelvollinen piiri", diff --git a/apps/files_sharing/l10n/pt_BR.js b/apps/files_sharing/l10n/pt_BR.js index b80bceabb6e..f4d4d728b84 100644 --- a/apps/files_sharing/l10n/pt_BR.js +++ b/apps/files_sharing/l10n/pt_BR.js @@ -4,8 +4,8 @@ OC.L10N.register( "Shared with you" : "Compartilhado com você", "Shared with others" : "Compartilhado com outros", "Shared by link" : "Compartilhado por link", - "Nothing shared with you yet" : "Nada foi compartilhado com você até agora", - "Files and folders others share with you will show up here" : "Arquivos e pastas que outros compartilham com você serão mostrados aqui", + "Nothing shared with you yet" : "Nada foi compartilhado!", + "Files and folders others share with you will show up here" : "Arquivos e pastas que outras pessoas compartilham com você, serão exibidos aqui.", "Nothing shared yet" : "Você ainda não compartilhou nada!", "Files and folders you share will show up here" : "Arquivos e pastas que você compartilhar serão exibidos aqui.", "No shared links" : "Nenhum link compartilhado", diff --git a/apps/files_sharing/l10n/pt_BR.json b/apps/files_sharing/l10n/pt_BR.json index af1c5427fb3..b512e5d3a6c 100644 --- a/apps/files_sharing/l10n/pt_BR.json +++ b/apps/files_sharing/l10n/pt_BR.json @@ -2,8 +2,8 @@ "Shared with you" : "Compartilhado com você", "Shared with others" : "Compartilhado com outros", "Shared by link" : "Compartilhado por link", - "Nothing shared with you yet" : "Nada foi compartilhado com você até agora", - "Files and folders others share with you will show up here" : "Arquivos e pastas que outros compartilham com você serão mostrados aqui", + "Nothing shared with you yet" : "Nada foi compartilhado!", + "Files and folders others share with you will show up here" : "Arquivos e pastas que outras pessoas compartilham com você, serão exibidos aqui.", "Nothing shared yet" : "Você ainda não compartilhou nada!", "Files and folders you share will show up here" : "Arquivos e pastas que você compartilhar serão exibidos aqui.", "No shared links" : "Nenhum link compartilhado", diff --git a/apps/provisioning_api/appinfo/routes.php b/apps/provisioning_api/appinfo/routes.php index 791267a97a1..c2bbd8025ee 100644 --- a/apps/provisioning_api/appinfo/routes.php +++ b/apps/provisioning_api/appinfo/routes.php @@ -34,6 +34,7 @@ return [ // Groups ['root' => '/cloud', 'name' => 'Groups#getGroups', 'url' => '/groups', 'verb' => 'GET'], + ['root' => '/cloud', 'name' => 'Groups#getGroupsDetails', 'url' => '/groups/details', 'verb' => 'GET'], ['root' => '/cloud', 'name' => 'Groups#getGroup', 'url' => '/groups/{groupId}', 'verb' => 'GET'], ['root' => '/cloud', 'name' => 'Groups#addGroup', 'url' => '/groups', 'verb' => 'POST'], ['root' => '/cloud', 'name' => 'Groups#deleteGroup', 'url' => '/groups/{groupId}', 'verb' => 'DELETE'], diff --git a/apps/provisioning_api/lib/Controller/GroupsController.php b/apps/provisioning_api/lib/Controller/GroupsController.php index 8aed50bf049..d6f2d9f3391 100644 --- a/apps/provisioning_api/lib/Controller/GroupsController.php +++ b/apps/provisioning_api/lib/Controller/GroupsController.php @@ -97,6 +97,33 @@ class GroupsController extends OCSController { } /** + * returns a list of groups details with ids and displaynames + * + * @NoAdminRequired + * + * @param string $search + * @param int $limit + * @param int $offset + * @return DataResponse + */ + public function getGroupsDetails(string $search = '', $limit = null, $offset = null): DataResponse { + if ($limit !== null) { + $limit = (int)$limit; + } + if ($offset !== null) { + $offset = (int)$offset; + } + + $groups = $this->groupManager->search($search, $limit, $offset); + $groups = array_map(function($group) { + /** @var IGroup $group */ + return ['id' => $group->getGID(), 'displayname' => $group->getDisplayName()]; + }, $groups); + + return new DataResponse(['groups' => $groups]); + } + + /** * returns an array of users in the group specified * * @NoAdminRequired diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php index cd277adb162..e3b7840cd3b 100644 --- a/apps/provisioning_api/lib/Controller/UsersController.php +++ b/apps/provisioning_api/lib/Controller/UsersController.php @@ -50,6 +50,7 @@ use OCP\IRequest; use OCP\IUserManager; use OCP\IUserSession; use OCP\L10N\IFactory; +use OCP\Security\ISecureRandom; class UsersController extends OCSController { @@ -73,6 +74,8 @@ class UsersController extends OCSController { private $newUserMailHelper; /** @var FederatedFileSharingFactory */ private $federatedFileSharingFactory; + /** @var ISecureRandom */ + private $secureRandom; /** * @param string $appName @@ -87,6 +90,7 @@ class UsersController extends OCSController { * @param IFactory $l10nFactory * @param NewUserMailHelper $newUserMailHelper * @param FederatedFileSharingFactory $federatedFileSharingFactory + * @param ISecureRandom $secureRandom */ public function __construct(string $appName, IRequest $request, @@ -99,7 +103,8 @@ class UsersController extends OCSController { ILogger $logger, IFactory $l10nFactory, NewUserMailHelper $newUserMailHelper, - FederatedFileSharingFactory $federatedFileSharingFactory) { + FederatedFileSharingFactory $federatedFileSharingFactory, + ISecureRandom $secureRandom) { parent::__construct($appName, $request); $this->userManager = $userManager; @@ -112,6 +117,7 @@ class UsersController extends OCSController { $this->l10nFactory = $l10nFactory; $this->newUserMailHelper = $newUserMailHelper; $this->federatedFileSharingFactory = $federatedFileSharingFactory; + $this->secureRandom = $secureRandom; } /** @@ -199,11 +205,12 @@ class UsersController extends OCSController { * * @param string $userid * @param string $password + * @param string $email * @param array $groups * @return DataResponse * @throws OCSException */ - public function addUser(string $userid, string $password, array $groups = []): DataResponse { + public function addUser(string $userid, string $password = '', string $email='', array $groups = []): DataResponse { $user = $this->userSession->getUser(); $isAdmin = $this->groupManager->isAdmin($user->getUID()); $subAdminManager = $this->groupManager->getSubAdmin(); @@ -228,6 +235,18 @@ class UsersController extends OCSController { } } + $generatePasswordResetToken = false; + if ($password === '') { + if ($email === '') { + throw new OCSException('To send a password link to the user an email address is required.', 108); + } + + $password = $this->secureRandom->generate(10); + // Make sure we pass the password_policy + $password .= $this->secureRandom->generate(2, '$!.,;:-~+*[]{}()'); + $generatePasswordResetToken = true; + } + try { $newUser = $this->userManager->createUser($userid, $password); $this->logger->info('Successful addUser call with userid: ' . $userid, ['app' => 'ocs_api']); @@ -237,7 +256,24 @@ class UsersController extends OCSController { $this->logger->info('Added userid ' . $userid . ' to group ' . $group, ['app' => 'ocs_api']); } + // Send new user mail only if a mail is set + if ($email !== '') { + $newUser->setEMailAddress($email); + try { + $emailTemplate = $this->newUserMailHelper->generateTemplate($newUser, $generatePasswordResetToken); + $this->newUserMailHelper->sendMail($newUser, $emailTemplate); + } catch (\Exception $e) { + $this->logger->logException($e, [ + 'message' => "Can't send new user mail to $email", + 'level' => \OCP\Util::ERROR, + 'app' => 'ocs_api', + ]); + throw new OCSException('Unable to send the invitation mail', 109); + } + } + return new DataResponse(); + } catch (HintException $e ) { $this->logger->logException($e, [ 'message' => 'Failed addUser attempt with hint exception.', diff --git a/apps/provisioning_api/tests/Controller/GroupsControllerTest.php b/apps/provisioning_api/tests/Controller/GroupsControllerTest.php index cd3dae79336..352264c7afb 100644 --- a/apps/provisioning_api/tests/Controller/GroupsControllerTest.php +++ b/apps/provisioning_api/tests/Controller/GroupsControllerTest.php @@ -85,6 +85,10 @@ class GroupsControllerTest extends \Test\TestCase { $group ->method('getGID') ->willReturn($gid); + $group + ->method('getDisplayName') + ->willReturn($gid.'-name'); + return $group; } @@ -165,6 +169,33 @@ class GroupsControllerTest extends \Test\TestCase { $result = $this->api->getGroups($search, $limit, $offset); $this->assertEquals(['groups' => ['group1', 'group2']], $result->getData()); + + } + + /** + * @dataProvider dataGetGroups + * + * @param string|null $search + * @param int|null $limit + * @param int|null $offset + */ + public function testGetGroupsDetails($search, $limit, $offset) { + $groups = [$this->createGroup('group1'), $this->createGroup('group2')]; + + $search = $search === null ? '' : $search; + + $this->groupManager + ->expects($this->once()) + ->method('search') + ->with($search, $limit, $offset) + ->willReturn($groups); + + $result = $this->api->getGroupsDetails($search, $limit, $offset); + $this->assertEquals(['groups' => [ + Array('id' => 'group1', 'displayname' => 'group1-name'), + Array('id' => 'group2', 'displayname' => 'group2-name') + ]], $result->getData()); + } public function testGetGroupAsSubadmin() { diff --git a/apps/provisioning_api/tests/Controller/UsersControllerTest.php b/apps/provisioning_api/tests/Controller/UsersControllerTest.php index 38e35988137..3f2cf3b1105 100644 --- a/apps/provisioning_api/tests/Controller/UsersControllerTest.php +++ b/apps/provisioning_api/tests/Controller/UsersControllerTest.php @@ -56,6 +56,7 @@ use OCP\IUserManager; use OCP\IUserSession; use OCP\L10N\IFactory; use OCP\Mail\IMailer; +use OCP\Security\ISecureRandom; use PHPUnit_Framework_MockObject_MockObject; use Test\TestCase; @@ -85,6 +86,8 @@ class UsersControllerTest extends TestCase { private $newUserMailHelper; /** @var FederatedFileSharingFactory|\PHPUnit_Framework_MockObject_MockObject */ private $federatedFileSharingFactory; + /** @var ISecureRandom|\PHPUnit_Framework_MockObject_MockObject */ + private $secureRandom; protected function setUp() { parent::setUp(); @@ -100,6 +103,7 @@ class UsersControllerTest extends TestCase { $this->l10nFactory = $this->createMock(IFactory::class); $this->newUserMailHelper = $this->createMock(NewUserMailHelper::class); $this->federatedFileSharingFactory = $this->createMock(FederatedFileSharingFactory::class); + $this->secureRandom = $this->createMock(ISecureRandom::class); $this->api = $this->getMockBuilder(UsersController::class) ->setConstructorArgs([ @@ -114,7 +118,8 @@ class UsersControllerTest extends TestCase { $this->logger, $this->l10nFactory, $this->newUserMailHelper, - $this->federatedFileSharingFactory + $this->federatedFileSharingFactory, + $this->secureRandom ]) ->setMethods(['fillStorageInfo']) ->getMock(); @@ -242,7 +247,7 @@ class UsersControllerTest extends TestCase { ->with('adminUser') ->willReturn(true); - $this->api->addUser('AlreadyExistingUser', 'password', []); + $this->api->addUser('AlreadyExistingUser', 'password', '', []); } /** @@ -278,7 +283,7 @@ class UsersControllerTest extends TestCase { ->with('NonExistingGroup') ->willReturn(false); - $this->api->addUser('NewUser', 'pass', ['NonExistingGroup']); + $this->api->addUser('NewUser', 'pass', '', ['NonExistingGroup']); } /** @@ -320,7 +325,7 @@ class UsersControllerTest extends TestCase { ['NonExistingGroup', false] ])); - $this->api->addUser('NewUser', 'pass', ['ExistingGroup', 'NonExistingGroup']); + $this->api->addUser('NewUser', 'pass', '', ['ExistingGroup', 'NonExistingGroup']); } public function testAddUserSuccessful() { @@ -412,7 +417,7 @@ class UsersControllerTest extends TestCase { ['Added userid NewUser to group ExistingGroup', ['app' => 'ocs_api']] ); - $this->assertEquals([], $this->api->addUser('NewUser', 'PasswordOfTheNewUser', ['ExistingGroup'])->getData()); + $this->assertEquals([], $this->api->addUser('NewUser', 'PasswordOfTheNewUser', '', ['ExistingGroup'])->getData()); } /** @@ -490,7 +495,7 @@ class UsersControllerTest extends TestCase { ->with() ->willReturn($subAdminManager); - $this->api->addUser('NewUser', 'PasswordOfTheNewUser', []); + $this->api->addUser('NewUser', 'PasswordOfTheNewUser', '', []); } /** @@ -539,7 +544,7 @@ class UsersControllerTest extends TestCase { ->with('ExistingGroup') ->willReturn(true); - $this->api->addUser('NewUser', 'PasswordOfTheNewUser', ['ExistingGroup'])->getData(); + $this->api->addUser('NewUser', 'PasswordOfTheNewUser', '', ['ExistingGroup'])->getData(); } public function testAddUserAsSubAdminExistingGroups() { @@ -630,7 +635,7 @@ class UsersControllerTest extends TestCase { ) ->willReturn(true); - $this->assertEquals([], $this->api->addUser('NewUser', 'PasswordOfTheNewUser', ['ExistingGroup1', 'ExistingGroup2'])->getData()); + $this->assertEquals([], $this->api->addUser('NewUser', 'PasswordOfTheNewUser', '', ['ExistingGroup1', 'ExistingGroup2'])->getData()); } /** @@ -2928,7 +2933,8 @@ class UsersControllerTest extends TestCase { $this->logger, $this->l10nFactory, $this->newUserMailHelper, - $this->federatedFileSharingFactory + $this->federatedFileSharingFactory, + $this->secureRandom ]) ->setMethods(['getUserData']) ->getMock(); @@ -2990,7 +2996,8 @@ class UsersControllerTest extends TestCase { $this->logger, $this->l10nFactory, $this->newUserMailHelper, - $this->federatedFileSharingFactory + $this->federatedFileSharingFactory, + $this->secureRandom ]) ->setMethods(['getUserData']) ->getMock(); diff --git a/apps/theming/l10n/es_MX.js b/apps/theming/l10n/es_MX.js index 905f3f7b301..6afea9f0940 100644 --- a/apps/theming/l10n/es_MX.js +++ b/apps/theming/l10n/es_MX.js @@ -10,11 +10,14 @@ OC.L10N.register( "The given web address is too long" : "La dirección web dada es demasiado larga", "The given slogan is too long" : "El lema dado es demasiado largo", "The given color is invalid" : "El color dado es inválido", + "The file was uploaded" : "El archivo fue cargado", "The uploaded file exceeds the upload_max_filesize directive in php.ini" : "El archivo cargado excede el valor establecido en la directiva upload_max_filesize en el archivo php.ini", "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "El archivo cargado excede el valor especificado de la directiva MAX_FILE_SIZE en la forma de HTML", "The file was only partially uploaded" : "El archivo sólo fue cargado parcialmente", "No file was uploaded" : "No se cargó el archivo", "Missing a temporary folder" : "Falta una carpeta temporal", + "Could not write file to disk" : "No fue posible escribir a disco", + "A PHP extension stopped the file upload" : "Una extensión de PHP detuvo la carga del archivo", "No file uploaded" : "No hay archivos cargados", "Unsupported image type" : "Tipo de imagen no soportado", "You are already using a custom theme" : "Ya estás usando un tema personalizado", diff --git a/apps/theming/l10n/es_MX.json b/apps/theming/l10n/es_MX.json index 8ea1dc1b51d..31f4534ebc2 100644 --- a/apps/theming/l10n/es_MX.json +++ b/apps/theming/l10n/es_MX.json @@ -8,11 +8,14 @@ "The given web address is too long" : "La dirección web dada es demasiado larga", "The given slogan is too long" : "El lema dado es demasiado largo", "The given color is invalid" : "El color dado es inválido", + "The file was uploaded" : "El archivo fue cargado", "The uploaded file exceeds the upload_max_filesize directive in php.ini" : "El archivo cargado excede el valor establecido en la directiva upload_max_filesize en el archivo php.ini", "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "El archivo cargado excede el valor especificado de la directiva MAX_FILE_SIZE en la forma de HTML", "The file was only partially uploaded" : "El archivo sólo fue cargado parcialmente", "No file was uploaded" : "No se cargó el archivo", "Missing a temporary folder" : "Falta una carpeta temporal", + "Could not write file to disk" : "No fue posible escribir a disco", + "A PHP extension stopped the file upload" : "Una extensión de PHP detuvo la carga del archivo", "No file uploaded" : "No hay archivos cargados", "Unsupported image type" : "Tipo de imagen no soportado", "You are already using a custom theme" : "Ya estás usando un tema personalizado", diff --git a/apps/theming/l10n/fr.js b/apps/theming/l10n/fr.js index 5e507382eca..a9cef2684c3 100644 --- a/apps/theming/l10n/fr.js +++ b/apps/theming/l10n/fr.js @@ -15,6 +15,7 @@ OC.L10N.register( "The file was only partially uploaded" : "Le fichier n'a été que partiellement envoyé", "No file was uploaded" : "Aucun fichier téléversé", "Missing a temporary folder" : "Absence de dossier temporaire", + "A PHP extension stopped the file upload" : "Une extension PHP a arrêté le téléversement du fichier", "No file uploaded" : "Aucun fichier téléversé", "Unsupported image type" : "Ce type d'image n'est pas pris en charge", "You are already using a custom theme" : "Vous utilisez déjà un thème personnalisé", diff --git a/apps/theming/l10n/fr.json b/apps/theming/l10n/fr.json index 0bee0b7739a..eb6fe57af79 100644 --- a/apps/theming/l10n/fr.json +++ b/apps/theming/l10n/fr.json @@ -13,6 +13,7 @@ "The file was only partially uploaded" : "Le fichier n'a été que partiellement envoyé", "No file was uploaded" : "Aucun fichier téléversé", "Missing a temporary folder" : "Absence de dossier temporaire", + "A PHP extension stopped the file upload" : "Une extension PHP a arrêté le téléversement du fichier", "No file uploaded" : "Aucun fichier téléversé", "Unsupported image type" : "Ce type d'image n'est pas pris en charge", "You are already using a custom theme" : "Vous utilisez déjà un thème personnalisé", diff --git a/apps/theming/l10n/sr.js b/apps/theming/l10n/sr.js index deff4a929f7..e1d76f99f89 100644 --- a/apps/theming/l10n/sr.js +++ b/apps/theming/l10n/sr.js @@ -10,11 +10,14 @@ OC.L10N.register( "The given web address is too long" : "Адреса је предугачка", "The given slogan is too long" : "Слоган је предугачак", "The given color is invalid" : "Задата боја није исправна", + "The file was uploaded" : "Фајл је отпремљен", "The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Отпремани фајл превазилази смерницу upload_max_filesize у фајлу php.ini", "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Отпремани фајл превазилази смерницу MAX_FILE_SIZE која је наведена у HTML обрасцу", "The file was only partially uploaded" : "Фајл је само делимично отпремљен", "No file was uploaded" : "Ниједан фајл није отпремљен", "Missing a temporary folder" : "Недостаје привремена фасцикла", + "Could not write file to disk" : "Не могу да пишем фајл на диск", + "A PHP extension stopped the file upload" : "PHP екстензија је зауставила отпремање фајла", "No file uploaded" : "Ниједан фајл није отпремљен", "Unsupported image type" : "Неподржани тип слике", "You are already using a custom theme" : "Већ користите прилагођену тему", diff --git a/apps/theming/l10n/sr.json b/apps/theming/l10n/sr.json index fe508a87cbe..e07c53c6438 100644 --- a/apps/theming/l10n/sr.json +++ b/apps/theming/l10n/sr.json @@ -8,11 +8,14 @@ "The given web address is too long" : "Адреса је предугачка", "The given slogan is too long" : "Слоган је предугачак", "The given color is invalid" : "Задата боја није исправна", + "The file was uploaded" : "Фајл је отпремљен", "The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Отпремани фајл превазилази смерницу upload_max_filesize у фајлу php.ini", "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Отпремани фајл превазилази смерницу MAX_FILE_SIZE која је наведена у HTML обрасцу", "The file was only partially uploaded" : "Фајл је само делимично отпремљен", "No file was uploaded" : "Ниједан фајл није отпремљен", "Missing a temporary folder" : "Недостаје привремена фасцикла", + "Could not write file to disk" : "Не могу да пишем фајл на диск", + "A PHP extension stopped the file upload" : "PHP екстензија је зауставила отпремање фајла", "No file uploaded" : "Ниједан фајл није отпремљен", "Unsupported image type" : "Неподржани тип слике", "You are already using a custom theme" : "Већ користите прилагођену тему", diff --git a/apps/workflowengine/l10n/sr.js b/apps/workflowengine/l10n/sr.js index c04e7e917bf..130cc0cdaea 100644 --- a/apps/workflowengine/l10n/sr.js +++ b/apps/workflowengine/l10n/sr.js @@ -1,6 +1,7 @@ OC.L10N.register( "workflowengine", { + "Unable to retrieve the group list" : "Није могуће дохватити списак група", "Saved" : "Снимљено", "Saving failed:" : "Снимање није успело:", "File MIME type" : "MIME тип фајла", diff --git a/apps/workflowengine/l10n/sr.json b/apps/workflowengine/l10n/sr.json index 99abd98a1a6..1caf1695ba4 100644 --- a/apps/workflowengine/l10n/sr.json +++ b/apps/workflowengine/l10n/sr.json @@ -1,4 +1,5 @@ { "translations": { + "Unable to retrieve the group list" : "Није могуће дохватити списак група", "Saved" : "Снимљено", "Saving failed:" : "Снимање није успело:", "File MIME type" : "MIME тип фајла", diff --git a/core/Controller/AutoCompleteController.php b/core/Controller/AutoCompleteController.php index 93ab9291322..3f3858ce1c8 100644 --- a/core/Controller/AutoCompleteController.php +++ b/core/Controller/AutoCompleteController.php @@ -23,7 +23,7 @@ namespace OC\Core\Controller; -use OCP\AppFramework\Controller; +use OCP\AppFramework\OCSController as Controller; use OCP\AppFramework\Http\DataResponse; use OCP\Collaboration\AutoComplete\IManager; use OCP\Collaboration\Collaborators\ISearch; diff --git a/core/css/apps.scss b/core/css/apps.scss index fc255aca676..6b3ab623704 100644 --- a/core/css/apps.scss +++ b/core/css/apps.scss @@ -152,7 +152,7 @@ kbd { &, > a { opacity: 1; - box-shadow: inset 2px 0 $color-primary; + box-shadow: inset 4px 0 $color-primary; } } @@ -177,7 +177,6 @@ kbd { /* Second level nesting for lists */ > ul { flex: 0 1 auto; - padding-left: 44px; width: 100%; transition: max-height 2000ms ease-in-out, opacity 250ms ease-in-out; @@ -187,6 +186,7 @@ kbd { > li { display: inline-flex; flex-wrap: wrap; + padding-left: 44px; &:focus, &:hover, &.active, @@ -197,10 +197,28 @@ kbd { } } + &.active { + box-shadow: inset 4px 0 $color-primary; + } + /* align loader */ &.icon-loading-small:after { left: 22px; /* 44px / 2 */ } + + > .app-navigation-entry-deleted { + /* margin to keep active indicator visible */ + margin-left: 4px; + padding-left: 84px; + } + + > .app-navigation-entry-edit { + /* margin to keep active indicator visible */ + margin-left: 4px; + /* align the input correctly with the link text + 44px+44px-4px-6px padding for the input */ + padding-left: 78px !important; + } } } } diff --git a/core/css/styles.scss b/core/css/styles.scss index 5a927046c03..0b15718eefd 100644 --- a/core/css/styles.scss +++ b/core/css/styles.scss @@ -183,6 +183,7 @@ body { font-size: 1.2em; padding: 3px; padding-left: 25px; + padding-right: 20px; background: transparent url('../img/actions/search-white.svg?v=1') no-repeat 6px center; color: $color-primary-text; border: 0; @@ -253,14 +254,17 @@ body { box-sizing: border-box; } -#controls { +#controls .actions { > div, & { > .button, button { box-sizing: border-box; display: inline-block; + display: flex; height: 36px; - padding: 7px 10px; + width: 36px; + align-items: center; + justify-content: center; } .button.hidden { display: none; diff --git a/core/l10n/es_MX.js b/core/l10n/es_MX.js index 1fa955d7f5f..25760d81702 100644 --- a/core/l10n/es_MX.js +++ b/core/l10n/es_MX.js @@ -175,6 +175,7 @@ OC.L10N.register( "This list is maybe truncated - please refine your search term to see more results." : "Esta lista puede estar truncada - por favor refina tus términos de búsqueda para poder ver más resultados. ", "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", + "An error occurred (\"{message}\"). Please try again" : "Se presentó un error (\"{message}\"). Por favor vuelve a intentarlo", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", "{sharee} (group)" : "{sharee} (grupo)", "{sharee} (remote)" : "{sharee} (remoto)", diff --git a/core/l10n/es_MX.json b/core/l10n/es_MX.json index 5fe2a13c93a..34398aedd40 100644 --- a/core/l10n/es_MX.json +++ b/core/l10n/es_MX.json @@ -173,6 +173,7 @@ "This list is maybe truncated - please refine your search term to see more results." : "Esta lista puede estar truncada - por favor refina tus términos de búsqueda para poder ver más resultados. ", "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", + "An error occurred (\"{message}\"). Please try again" : "Se presentó un error (\"{message}\"). Por favor vuelve a intentarlo", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", "{sharee} (group)" : "{sharee} (grupo)", "{sharee} (remote)" : "{sharee} (remoto)", diff --git a/core/l10n/fi.js b/core/l10n/fi.js index 6324c04391c..747f8ac6b6a 100644 --- a/core/l10n/fi.js +++ b/core/l10n/fi.js @@ -172,6 +172,7 @@ OC.L10N.register( "This list is maybe truncated - please refine your search term to see more results." : "Lista on ehkä vajaa - uudelleen määritä hakutermisi nähdäksesi lisää tuloksia.", "No users or groups found for {search}" : "Haulla {search} ei löytynyt käyttäjiä tai ryhmiä", "No users found for {search}" : "Haulla {search} ei löytynyt käyttäjiä", + "An error occurred (\"{message}\"). Please try again" : "Tapahtui virhe (\"{message}\"). Yritä uudestaan", "An error occurred. Please try again" : "Tapahtui virhe, yritä uudelleen", "{sharee} (group)" : "{sharee} (ryhmä)", "{sharee} (remote)" : "{sharee} (etä)", @@ -275,9 +276,10 @@ OC.L10N.register( "Forgot password?" : "Unohditko salasanasi?", "Back to login" : "Palaa kirjautumiseen", "Account access" : "Tilin käyttö", + "You are about to grant %s access to your %s account." : "Olet antamassa lupaa laitteelle %s päästä sinun %s tilille.", "Grant access" : "Myönnä pääsy", "App token" : "Sovellusvaltuutus", - "Alternative login using app token" : "Vaihtoehtoinen kirjautuminen käyttäen sovellusvaltuutusta", + "Alternative login using app token" : "Kirjaudu vaihtoehtoisella tavalla sovellusvaltuutusta käyttämällä", "Redirecting …" : "Ohjataan uudelleen…", "New password" : "Uusi salasana", "New Password" : "Uusi salasana", diff --git a/core/l10n/fi.json b/core/l10n/fi.json index cea8fb4525f..3d2a447ff6a 100644 --- a/core/l10n/fi.json +++ b/core/l10n/fi.json @@ -170,6 +170,7 @@ "This list is maybe truncated - please refine your search term to see more results." : "Lista on ehkä vajaa - uudelleen määritä hakutermisi nähdäksesi lisää tuloksia.", "No users or groups found for {search}" : "Haulla {search} ei löytynyt käyttäjiä tai ryhmiä", "No users found for {search}" : "Haulla {search} ei löytynyt käyttäjiä", + "An error occurred (\"{message}\"). Please try again" : "Tapahtui virhe (\"{message}\"). Yritä uudestaan", "An error occurred. Please try again" : "Tapahtui virhe, yritä uudelleen", "{sharee} (group)" : "{sharee} (ryhmä)", "{sharee} (remote)" : "{sharee} (etä)", @@ -273,9 +274,10 @@ "Forgot password?" : "Unohditko salasanasi?", "Back to login" : "Palaa kirjautumiseen", "Account access" : "Tilin käyttö", + "You are about to grant %s access to your %s account." : "Olet antamassa lupaa laitteelle %s päästä sinun %s tilille.", "Grant access" : "Myönnä pääsy", "App token" : "Sovellusvaltuutus", - "Alternative login using app token" : "Vaihtoehtoinen kirjautuminen käyttäen sovellusvaltuutusta", + "Alternative login using app token" : "Kirjaudu vaihtoehtoisella tavalla sovellusvaltuutusta käyttämällä", "Redirecting …" : "Ohjataan uudelleen…", "New password" : "Uusi salasana", "New Password" : "Uusi salasana", diff --git a/core/l10n/it.js b/core/l10n/it.js index c5655b42dd6..215973f8bec 100644 --- a/core/l10n/it.js +++ b/core/l10n/it.js @@ -175,6 +175,7 @@ OC.L10N.register( "This list is maybe truncated - please refine your search term to see more results." : "Questa lista potrebbe essere troncata - correggi i termini di ricerca per molti altri risultati.", "No users or groups found for {search}" : "Nessun utente o gruppo trovato per {search}", "No users found for {search}" : "Nessun utente trovato per {search}", + "An error occurred (\"{message}\"). Please try again" : "Si è verificato un errore (\"{message}\"). Prova ancora", "An error occurred. Please try again" : "Si è verificato un errore. Prova ancora", "{sharee} (group)" : "{sharee} (group)", "{sharee} (remote)" : "{sharee} (remote)", diff --git a/core/l10n/it.json b/core/l10n/it.json index 9479db9627c..ccc195c296f 100644 --- a/core/l10n/it.json +++ b/core/l10n/it.json @@ -173,6 +173,7 @@ "This list is maybe truncated - please refine your search term to see more results." : "Questa lista potrebbe essere troncata - correggi i termini di ricerca per molti altri risultati.", "No users or groups found for {search}" : "Nessun utente o gruppo trovato per {search}", "No users found for {search}" : "Nessun utente trovato per {search}", + "An error occurred (\"{message}\"). Please try again" : "Si è verificato un errore (\"{message}\"). Prova ancora", "An error occurred. Please try again" : "Si è verificato un errore. Prova ancora", "{sharee} (group)" : "{sharee} (group)", "{sharee} (remote)" : "{sharee} (remote)", diff --git a/core/l10n/pt_BR.js b/core/l10n/pt_BR.js index 39779a07ff1..2a19ba92116 100644 --- a/core/l10n/pt_BR.js +++ b/core/l10n/pt_BR.js @@ -175,6 +175,7 @@ OC.L10N.register( "This list is maybe truncated - please refine your search term to see more results." : "Esta lista pode estar truncada - por favor refina seus termos de pesquisa para ver mais resultados", "No users or groups found for {search}" : "Nenhum usuário ou grupo encontrado para {search}", "No users found for {search}" : "Nenhum usuário encontrado para {search}", + "An error occurred (\"{message}\"). Please try again" : "Ocorreu um erro (\"{message}\"). Tente novamente", "An error occurred. Please try again" : "Ocorreu um erro. Por favor tente novamente", "{sharee} (group)" : "{sharee} (grupo)", "{sharee} (remote)" : "{sharee} (remoto)", diff --git a/core/l10n/pt_BR.json b/core/l10n/pt_BR.json index 076c61c83e0..ba3b9e0d070 100644 --- a/core/l10n/pt_BR.json +++ b/core/l10n/pt_BR.json @@ -173,6 +173,7 @@ "This list is maybe truncated - please refine your search term to see more results." : "Esta lista pode estar truncada - por favor refina seus termos de pesquisa para ver mais resultados", "No users or groups found for {search}" : "Nenhum usuário ou grupo encontrado para {search}", "No users found for {search}" : "Nenhum usuário encontrado para {search}", + "An error occurred (\"{message}\"). Please try again" : "Ocorreu um erro (\"{message}\"). Tente novamente", "An error occurred. Please try again" : "Ocorreu um erro. Por favor tente novamente", "{sharee} (group)" : "{sharee} (grupo)", "{sharee} (remote)" : "{sharee} (remoto)", diff --git a/core/l10n/sr.js b/core/l10n/sr.js index b71a1d77c35..b37b7d5f9d6 100644 --- a/core/l10n/sr.js +++ b/core/l10n/sr.js @@ -175,6 +175,7 @@ OC.L10N.register( "This list is maybe truncated - please refine your search term to see more results." : "Ова листа је можда скраћена - претражите опет користећи мало специфичније изразе да бисте добили још резултата.", "No users or groups found for {search}" : "Није нађен ниједан корисник ни група за претрагу {search}", "No users found for {search}" : "Није нађен ниједан корисник за претрагу {search}", + "An error occurred (\"{message}\"). Please try again" : "Десила се грешка (\"{message}\"). Покушајте поново.", "An error occurred. Please try again" : "Дошло је до грешке. Покушајте поново", "{sharee} (group)" : "{sharee} (група)", "{sharee} (remote)" : "{sharee} (удаљено)", diff --git a/core/l10n/sr.json b/core/l10n/sr.json index 1091583d0f0..d8135de556e 100644 --- a/core/l10n/sr.json +++ b/core/l10n/sr.json @@ -173,6 +173,7 @@ "This list is maybe truncated - please refine your search term to see more results." : "Ова листа је можда скраћена - претражите опет користећи мало специфичније изразе да бисте добили још резултата.", "No users or groups found for {search}" : "Није нађен ниједан корисник ни група за претрагу {search}", "No users found for {search}" : "Није нађен ниједан корисник за претрагу {search}", + "An error occurred (\"{message}\"). Please try again" : "Десила се грешка (\"{message}\"). Покушајте поново.", "An error occurred. Please try again" : "Дошло је до грешке. Покушајте поново", "{sharee} (group)" : "{sharee} (група)", "{sharee} (remote)" : "{sharee} (удаљено)", diff --git a/core/l10n/zh_CN.js b/core/l10n/zh_CN.js index ecaac56116b..2af655a1b9b 100644 --- a/core/l10n/zh_CN.js +++ b/core/l10n/zh_CN.js @@ -116,6 +116,7 @@ OC.L10N.register( "/dev/urandom is not readable by PHP which is highly discouraged for security reasons. Further information can be found in the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation</a>." : "PHP 无法访问 /dev/urandom,出于安全原因这是强烈不推荐的。更多信息请参见<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">文档</a>。", "You are currently running PHP {version}. Upgrade your PHP version to take advantage of <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{phpLink}\">performance and security updates provided by the PHP Group</a> as soon as your distribution supports it." : "您当前正在运行 PHP 版本 {version}。我们建议您尽快在您的发行版支持新版本的时候进行升级,以获得<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{phpLink}\">来自 PHP 官方的性能和安全</a>的提升。", "You are currently running PHP 5.6. The current major version of Nextcloud is the last that is supported on PHP 5.6. It is recommended to upgrade the PHP version to 7.0+ to be able to upgrade to Nextcloud 14." : "您目前正在运行PHP 5.6。 Nextcloud的当前主要版本是最后一个支持PHP 5.6的版本。 建议将PHP版本升级到7.0以便能够升级到Nextcloud 14。", + "The reverse proxy header configuration is incorrect, or you are accessing Nextcloud from a trusted proxy. If not, this is a security issue and can allow an attacker to spoof their IP address as visible to the Nextcloud. Further information can be found in the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation</a>." : "反向代理头部配置错误,或者您正在通过可信的代理访问 Nextcloud。如果您不是通过可信代理访问 Nextcloud,这是一个安全问题,它允许攻击者通过伪装 IP 地址访问 Nextcloud。更多信息请查看<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">文档</a>。", "Error occurred while checking server setup" : "检查服务器设置时出错", "Shared" : "已共享", "Shared with" : "分享给", diff --git a/core/l10n/zh_CN.json b/core/l10n/zh_CN.json index d8da5457d81..151ecde8b8b 100644 --- a/core/l10n/zh_CN.json +++ b/core/l10n/zh_CN.json @@ -114,6 +114,7 @@ "/dev/urandom is not readable by PHP which is highly discouraged for security reasons. Further information can be found in the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation</a>." : "PHP 无法访问 /dev/urandom,出于安全原因这是强烈不推荐的。更多信息请参见<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">文档</a>。", "You are currently running PHP {version}. Upgrade your PHP version to take advantage of <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{phpLink}\">performance and security updates provided by the PHP Group</a> as soon as your distribution supports it." : "您当前正在运行 PHP 版本 {version}。我们建议您尽快在您的发行版支持新版本的时候进行升级,以获得<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{phpLink}\">来自 PHP 官方的性能和安全</a>的提升。", "You are currently running PHP 5.6. The current major version of Nextcloud is the last that is supported on PHP 5.6. It is recommended to upgrade the PHP version to 7.0+ to be able to upgrade to Nextcloud 14." : "您目前正在运行PHP 5.6。 Nextcloud的当前主要版本是最后一个支持PHP 5.6的版本。 建议将PHP版本升级到7.0以便能够升级到Nextcloud 14。", + "The reverse proxy header configuration is incorrect, or you are accessing Nextcloud from a trusted proxy. If not, this is a security issue and can allow an attacker to spoof their IP address as visible to the Nextcloud. Further information can be found in the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation</a>." : "反向代理头部配置错误,或者您正在通过可信的代理访问 Nextcloud。如果您不是通过可信代理访问 Nextcloud,这是一个安全问题,它允许攻击者通过伪装 IP 地址访问 Nextcloud。更多信息请查看<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">文档</a>。", "Error occurred while checking server setup" : "检查服务器设置时出错", "Shared" : "已共享", "Shared with" : "分享给", diff --git a/core/routes.php b/core/routes.php index 87c265d8098..1c7be78bc78 100644 --- a/core/routes.php +++ b/core/routes.php @@ -64,7 +64,6 @@ $application->registerRoutes($this, [ ['name' => 'Js#getJs', 'url' => '/js/{appName}/{fileName}', 'verb' => 'GET'], ['name' => 'contactsMenu#index', 'url' => '/contactsmenu/contacts', 'verb' => 'POST'], ['name' => 'contactsMenu#findOne', 'url' => '/contactsmenu/findOne', 'verb' => 'POST'], - ['name' => 'AutoComplete#get', 'url' => 'autocomplete/get', 'verb' => 'GET'], ['name' => 'WalledGarden#get', 'url' => '/204', 'verb' => 'GET'], ['name' => 'Search#search', 'url' => '/core/search', 'verb' => 'GET'], ], @@ -75,6 +74,7 @@ $application->registerRoutes($this, [ ['root' => '/identityproof', 'name' => 'OCS#getIdentityProof', 'url' => '/key/{cloudId}', 'verb' => 'GET'], ['root' => '/core', 'name' => 'Navigation#getAppsNavigation', 'url' => '/navigation/apps', 'verb' => 'GET'], ['root' => '/core', 'name' => 'Navigation#getSettingsNavigation', 'url' => '/navigation/settings', 'verb' => 'GET'], + ['root' => '/core', 'name' => 'AutoComplete#get', 'url' => '/autocomplete/get', 'verb' => 'GET'], ], ]); diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index fd37ec1ca39..32534c2a9e9 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -301,6 +301,15 @@ return array( 'OCP\\Template' => $baseDir . '/lib/public/Template.php', 'OCP\\User' => $baseDir . '/lib/public/User.php', 'OCP\\UserInterface' => $baseDir . '/lib/public/UserInterface.php', + 'OCP\\User\\Backend\\ABackend' => $baseDir . '/lib/public/User/Backend/ABackend.php', + 'OCP\\User\\Backend\\ICheckPasswordBackend' => $baseDir . '/lib/public/User/Backend/ICheckPasswordBackend.php', + 'OCP\\User\\Backend\\ICountUsersBackend' => $baseDir . '/lib/public/User/Backend/ICountUsersBackend.php', + 'OCP\\User\\Backend\\ICreateUserBackend' => $baseDir . '/lib/public/User/Backend/ICreateUserBackend.php', + 'OCP\\User\\Backend\\IGetDisplayNameBackend' => $baseDir . '/lib/public/User/Backend/IGetDisplayNameBackend.php', + 'OCP\\User\\Backend\\IGetHomeBackend' => $baseDir . '/lib/public/User/Backend/IGetHomeBackend.php', + 'OCP\\User\\Backend\\IProvideAvatarBackend' => $baseDir . '/lib/public/User/Backend/IProvideAvatarBackend.php', + 'OCP\\User\\Backend\\ISetDisplayNameBackend' => $baseDir . '/lib/public/User/Backend/ISetDisplayNameBackend.php', + 'OCP\\User\\Backend\\ISetPasswordBackend' => $baseDir . '/lib/public/User/Backend/ISetPasswordBackend.php', 'OCP\\Util' => $baseDir . '/lib/public/Util.php', 'OCP\\WorkflowEngine\\ICheck' => $baseDir . '/lib/public/WorkflowEngine/ICheck.php', 'OCP\\WorkflowEngine\\IManager' => $baseDir . '/lib/public/WorkflowEngine/IManager.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index a3e1aca34b2..d37777001b6 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -331,6 +331,15 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OCP\\Template' => __DIR__ . '/../../..' . '/lib/public/Template.php', 'OCP\\User' => __DIR__ . '/../../..' . '/lib/public/User.php', 'OCP\\UserInterface' => __DIR__ . '/../../..' . '/lib/public/UserInterface.php', + 'OCP\\User\\Backend\\ABackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/ABackend.php', + 'OCP\\User\\Backend\\ICheckPasswordBackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/ICheckPasswordBackend.php', + 'OCP\\User\\Backend\\ICountUsersBackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/ICountUsersBackend.php', + 'OCP\\User\\Backend\\ICreateUserBackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/ICreateUserBackend.php', + 'OCP\\User\\Backend\\IGetDisplayNameBackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/IGetDisplayNameBackend.php', + 'OCP\\User\\Backend\\IGetHomeBackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/IGetHomeBackend.php', + 'OCP\\User\\Backend\\IProvideAvatarBackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/IProvideAvatarBackend.php', + 'OCP\\User\\Backend\\ISetDisplayNameBackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/ISetDisplayNameBackend.php', + 'OCP\\User\\Backend\\ISetPasswordBackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/ISetPasswordBackend.php', 'OCP\\Util' => __DIR__ . '/../../..' . '/lib/public/Util.php', 'OCP\\WorkflowEngine\\ICheck' => __DIR__ . '/../../..' . '/lib/public/WorkflowEngine/ICheck.php', 'OCP\\WorkflowEngine\\IManager' => __DIR__ . '/../../..' . '/lib/public/WorkflowEngine/IManager.php', diff --git a/lib/private/Files/Node/Folder.php b/lib/private/Files/Node/Folder.php index fcadbe27393..95ceeee3698 100644 --- a/lib/private/Files/Node/Folder.php +++ b/lib/private/Files/Node/Folder.php @@ -302,18 +302,15 @@ class Folder extends Node implements \OCP\Files\Folder { return []; } - // we only need to get the cache info once, since all mounts we found point to the same storage - - $mount = $folderMounts[$mountsContainingFile[0]->getMountPoint()]; - $cacheEntry = $mount->getStorage()->getCache()->get((int)$id); - if (!$cacheEntry) { - return []; - } - // cache jails will hide the "true" internal path - $internalPath = ltrim($mountsContainingFile[0]->getRootInternalPath() . '/' . $cacheEntry->getPath(), '/'); - - $nodes = array_map(function (ICachedMountInfo $cachedMountInfo) use ($cacheEntry, $folderMounts, $internalPath) { + $nodes = array_map(function (ICachedMountInfo $cachedMountInfo) use ($folderMounts, $id) { $mount = $folderMounts[$cachedMountInfo->getMountPoint()]; + $cacheEntry = $mount->getStorage()->getCache()->get((int)$id); + if (!$cacheEntry) { + return null; + } + + // cache jails will hide the "true" internal path + $internalPath = ltrim($cachedMountInfo->getRootInternalPath() . '/' . $cacheEntry->getPath(), '/'); $pathRelativeToMount = substr($internalPath, strlen($cachedMountInfo->getRootInternalPath())); $pathRelativeToMount = ltrim($pathRelativeToMount, '/'); $absolutePath = $cachedMountInfo->getMountPoint() . $pathRelativeToMount; @@ -323,6 +320,8 @@ class Folder extends Node implements \OCP\Files\Folder { )); }, $mountsContainingFile); + $nodes = array_filter($nodes); + return array_filter($nodes, function (Node $node) { return $this->getRelativePath($node->getPath()); }); diff --git a/lib/private/User/Database.php b/lib/private/User/Database.php index 8dad3ef5fcd..d92390cdc96 100644 --- a/lib/private/User/Database.php +++ b/lib/private/User/Database.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -57,8 +58,14 @@ namespace OC\User; use OC\Cache\CappedMemoryCache; -use OC\DB\QueryBuilder\Literal; -use OCP\IUserBackend; +use OCP\User\Backend\ABackend; +use OCP\User\Backend\ICheckPasswordBackend; +use OCP\User\Backend\ICountUsersBackend; +use OCP\User\Backend\ICreateUserBackend; +use OCP\User\Backend\IGetDisplayNameBackend; +use OCP\User\Backend\IGetHomeBackend; +use OCP\User\Backend\ISetDisplayNameBackend; +use OCP\User\Backend\ISetPasswordBackend; use OCP\Util; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\GenericEvent; @@ -66,7 +73,14 @@ use Symfony\Component\EventDispatcher\GenericEvent; /** * Class for user management in a SQL Database (e.g. MySQL, SQLite) */ -class Database extends Backend implements IUserBackend { +class Database extends ABackend + implements ICreateUserBackend, + ISetPasswordBackend, + ISetDisplayNameBackend, + IGetDisplayNameBackend, + ICheckPasswordBackend, + IGetHomeBackend, + ICountUsersBackend { /** @var CappedMemoryCache */ private $cache; @@ -93,13 +107,13 @@ class Database extends Backend implements IUserBackend { * Creates a new user. Basic checking of username is done in OC_User * itself, not in its subclasses. */ - public function createUser($uid, $password) { + public function createUser(string $uid, string $password): bool { if (!$this->userExists($uid)) { $event = new GenericEvent($password); $this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event); $query = \OC_DB::prepare('INSERT INTO `*PREFIX*users` ( `uid`, `password` ) VALUES( ?, ? )'); try { - $result = $query->execute(array($uid, \OC::$server->getHasher()->hash($password))); + $result = $query->execute([$uid, \OC::$server->getHasher()->hash($password)]); } catch (\Exception $e) { $result = false; } @@ -124,7 +138,7 @@ class Database extends Backend implements IUserBackend { public function deleteUser($uid) { // Delete user-group-relation $query = \OC_DB::prepare('DELETE FROM `*PREFIX*users` WHERE `uid` = ?'); - $result = $query->execute(array($uid)); + $result = $query->execute([$uid]); if (isset($this->cache[$uid])) { unset($this->cache[$uid]); @@ -142,12 +156,12 @@ class Database extends Backend implements IUserBackend { * * Change the password of a user */ - public function setPassword($uid, $password) { + public function setPassword(string $uid, string $password): bool { if ($this->userExists($uid)) { $event = new GenericEvent($password); $this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event); $query = \OC_DB::prepare('UPDATE `*PREFIX*users` SET `password` = ? WHERE `uid` = ?'); - $result = $query->execute(array(\OC::$server->getHasher()->hash($password), $uid)); + $result = $query->execute([\OC::$server->getHasher()->hash($password), $uid]); return $result ? true : false; } @@ -164,10 +178,10 @@ class Database extends Backend implements IUserBackend { * * Change the display name of a user */ - public function setDisplayName($uid, $displayName) { + public function setDisplayName(string $uid, string $displayName): bool { if ($this->userExists($uid)) { $query = \OC_DB::prepare('UPDATE `*PREFIX*users` SET `displayname` = ? WHERE LOWER(`uid`) = LOWER(?)'); - $query->execute(array($displayName, $uid)); + $query->execute([$displayName, $uid]); $this->cache[$uid]['displayname'] = $displayName; return true; @@ -182,7 +196,7 @@ class Database extends Backend implements IUserBackend { * @param string $uid user ID of the user * @return string display name */ - public function getDisplayName($uid) { + public function getDisplayName($uid): string { $this->loadUser($uid); return empty($this->cache[$uid]['displayname']) ? $uid : $this->cache[$uid]['displayname']; } @@ -235,9 +249,9 @@ class Database extends Backend implements IUserBackend { * Check if the password is correct without logging in the user * returns the user id or false */ - public function checkPassword($uid, $password) { + public function checkPassword(string $uid, string $password) { $query = \OC_DB::prepare('SELECT `uid`, `password` FROM `*PREFIX*users` WHERE LOWER(`uid`) = LOWER(?)'); - $result = $query->execute(array($uid)); + $result = $query->execute([$uid]); $row = $result->fetchRow(); if ($row) { @@ -271,7 +285,7 @@ class Database extends Backend implements IUserBackend { } $query = \OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users` WHERE LOWER(`uid`) = LOWER(?)'); - $result = $query->execute(array($uid)); + $result = $query->execute([$uid]); if ($result === false) { Util::writeLog('core', \OC_DB::getErrorMessage(), Util::ERROR); @@ -326,9 +340,9 @@ class Database extends Backend implements IUserBackend { * @param string $uid the username * @return string|false */ - public function getHome($uid) { + public function getHome(string $uid) { if ($this->userExists($uid)) { - return \OC::$server->getConfig()->getSystemValue("datadirectory", \OC::$SERVERROOT . "/data") . '/' . $uid; + return \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/' . $uid; } return false; diff --git a/lib/public/User/Backend/ABackend.php b/lib/public/User/Backend/ABackend.php new file mode 100644 index 00000000000..a110ba5202a --- /dev/null +++ b/lib/public/User/Backend/ABackend.php @@ -0,0 +1,72 @@ +<?php +declare(strict_types=1); +/** +* @copyright Copyright (c) 2018 Roeland Jago Douma <roeland@famdouma.nl> +* +* @author Roeland Jago Douma <roeland@famdouma.nl> +* +* @license GNU AGPL version 3 or any later version +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as +* published by the Free Software Foundation, either version 3 of the +* License, or (at your option) any later version. +* +* 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 +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +*/ + +namespace OCP\User\Backend; + +use OC\User\Backend; +use OCP\IUserBackend; +use OCP\UserInterface; + +/** + * @since 14.0.0 + */ +abstract class ABackend implements IUserBackend, UserInterface { + + /** + * @deprecated 14.0.0 + * + * @param int $actions The action to check for + * @return bool + */ + public function implementsActions($actions): bool { + $implements = 0; + + if ($this instanceof ICreateUserBackend) { + $implements |= Backend::CREATE_USER; + } + if ($this instanceof ISetPasswordBackend) { + $implements |= Backend::SET_PASSWORD; + } + if ($this instanceof ICheckPasswordBackend) { + $implements |= Backend::CHECK_PASSWORD; + } + if ($this instanceof IGetHomeBackend) { + $implements |= Backend::GET_HOME; + } + if ($this instanceof IGetDisplayNameBackend) { + $implements |= Backend::GET_DISPLAYNAME; + } + if ($this instanceof ISetDisplayNameBackend) { + $implements |= Backend::SET_DISPLAYNAME; + } + if ($this instanceof IProvideAvatarBackend) { + $implements |= Backend::PROVIDE_AVATAR; + } + if ($this instanceof ICountUsersBackend) { + $implements |= Backend::COUNT_USERS; + } + + return (bool)($actions & $implements); + } +} diff --git a/lib/public/User/Backend/ICheckPasswordBackend.php b/lib/public/User/Backend/ICheckPasswordBackend.php new file mode 100644 index 00000000000..b28c94f1a6c --- /dev/null +++ b/lib/public/User/Backend/ICheckPasswordBackend.php @@ -0,0 +1,39 @@ +<?php +declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 Roeland Jago Douma <roeland@famdouma.nl> + * + * @author Roeland Jago Douma <roeland@famdouma.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP\User\Backend; + +/** + * @since 14.0.0 + */ +interface ICheckPasswordBackend { + /** + * @since 14.0.0 + * + * @param string $uid The username + * @param string $password The password + * @return string|bool The uid on success false on failure + */ + public function checkPassword(string $loginName, string $password); +} diff --git a/lib/public/User/Backend/ICountUsersBackend.php b/lib/public/User/Backend/ICountUsersBackend.php new file mode 100644 index 00000000000..1cb46712aa0 --- /dev/null +++ b/lib/public/User/Backend/ICountUsersBackend.php @@ -0,0 +1,38 @@ +<?php +declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 Roeland Jago Douma <roeland@famdouma.nl> + * + * @author Roeland Jago Douma <roeland@famdouma.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP\User\Backend; + +/** + * @since 14.0.0 + */ +interface ICountUsersBackend { + + /** + * @since 14.0.0 + * + * @return int|bool The number of users on success false on failure + */ + public function countUsers(); +} diff --git a/lib/public/User/Backend/ICreateUserBackend.php b/lib/public/User/Backend/ICreateUserBackend.php new file mode 100644 index 00000000000..09a20e12453 --- /dev/null +++ b/lib/public/User/Backend/ICreateUserBackend.php @@ -0,0 +1,40 @@ +<?php +declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 Roeland Jago Douma <roeland@famdouma.nl> + * + * @author Roeland Jago Douma <roeland@famdouma.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP\User\Backend; + +/** + * @since 14.0.0 + */ +interface ICreateUserBackend { + + /** + * @since 14.0.0 + * + * @param string $uid The username of the user to create + * @param string $password The password of the new user + * @return bool + */ + public function createUser(string $uid, string $password): bool; +} diff --git a/lib/public/User/Backend/IGetDisplayNameBackend.php b/lib/public/User/Backend/IGetDisplayNameBackend.php new file mode 100644 index 00000000000..6382ddd6eb6 --- /dev/null +++ b/lib/public/User/Backend/IGetDisplayNameBackend.php @@ -0,0 +1,39 @@ +<?php +declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 Roeland Jago Douma <roeland@famdouma.nl> + * + * @author Roeland Jago Douma <roeland@famdouma.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP\User\Backend; + +/** + * @since 14.0.0 + */ +interface IGetDisplayNameBackend { + + /** + * @since 14.0.0 + * + * @param string $uid user ID of the user + * @return string display name + */ + public function getDisplayName($uid): string; +} diff --git a/lib/public/User/Backend/IGetHomeBackend.php b/lib/public/User/Backend/IGetHomeBackend.php new file mode 100644 index 00000000000..20fcd004bba --- /dev/null +++ b/lib/public/User/Backend/IGetHomeBackend.php @@ -0,0 +1,39 @@ +<?php +declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 Roeland Jago Douma <roeland@famdouma.nl> + * + * @author Roeland Jago Douma <roeland@famdouma.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP\User\Backend; + +/** + * @since 14.0.0 + */ +interface IGetHomeBackend { + + /** + * @since 14.0.0 + * + * @param string $uid the username + * @return string|bool Datadir on success false on failure + */ + public function getHome(string $uid); +} diff --git a/lib/public/User/Backend/IProvideAvatarBackend.php b/lib/public/User/Backend/IProvideAvatarBackend.php new file mode 100644 index 00000000000..328c7450b40 --- /dev/null +++ b/lib/public/User/Backend/IProvideAvatarBackend.php @@ -0,0 +1,39 @@ +<?php +declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 Roeland Jago Douma <roeland@famdouma.nl> + * + * @author Roeland Jago Douma <roeland@famdouma.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP\User\Backend; + +/** + * @since 14.0.0 + */ +interface IProvideAvatarBackend { + + /** + * @since 14.0.0 + * + * @param string $uid + * @return bool + */ + public function canChangeAvatar(string $uid): bool; +} diff --git a/lib/public/User/Backend/ISetDisplayNameBackend.php b/lib/public/User/Backend/ISetDisplayNameBackend.php new file mode 100644 index 00000000000..ac41cd3e2c3 --- /dev/null +++ b/lib/public/User/Backend/ISetDisplayNameBackend.php @@ -0,0 +1,40 @@ +<?php +declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 Roeland Jago Douma <roeland@famdouma.nl> + * + * @author Roeland Jago Douma <roeland@famdouma.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP\User\Backend; + +/** + * @since 14.0.0 + */ +interface ISetDisplayNameBackend { + + /** + * @since 14.0.0 + * + * @param string $uid The username + * @param string $displayName The new display name + * @return bool + */ + public function setDisplayName(string $uid, string $displayName): bool; +} diff --git a/lib/public/User/Backend/ISetPasswordBackend.php b/lib/public/User/Backend/ISetPasswordBackend.php new file mode 100644 index 00000000000..687ac5f70bb --- /dev/null +++ b/lib/public/User/Backend/ISetPasswordBackend.php @@ -0,0 +1,40 @@ +<?php +declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 Roeland Jago Douma <roeland@famdouma.nl> + * + * @author Roeland Jago Douma <roeland@famdouma.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP\User\Backend; + +/** + * @since 14.0.0 + */ +interface ISetPasswordBackend { + + /** + * @since 14.0.0 + * + * @param string $uid The username + * @param string $password The new password + * @return bool + */ + public function setPassword(string $uid, string $password): bool; +} diff --git a/lib/public/UserInterface.php b/lib/public/UserInterface.php index 61136783b3c..b82fc6ba550 100644 --- a/lib/public/UserInterface.php +++ b/lib/public/UserInterface.php @@ -48,6 +48,7 @@ interface UserInterface { * Returns the supported actions as int to be * compared with \OC\User\Backend::CREATE_USER etc. * @since 4.5.0 + * @deprecated 14.0.0 Switch to the interfaces from OCP\User\Backend */ public function implementsActions($actions); diff --git a/settings/l10n/fi.js b/settings/l10n/fi.js index d571ad05af7..1bc2ec51c33 100644 --- a/settings/l10n/fi.js +++ b/settings/l10n/fi.js @@ -101,6 +101,7 @@ OC.L10N.register( "Error: This app can not be enabled because it makes the server unstable" : "Virhe: tätä sovellusta ei voi ottaa käyttöön, koska se tekee palvelimesta epävakaan", "Error while disabling broken app" : "Virhe rikkinäistä sovellusta käytöstä poistaessa", "App up to date" : "Sovellus ajan tasalla", + "Updating …" : "Päivitetään ...", "Updated" : "Päivitetty", "Removing …" : "Poistetaan…", "Could not remove app" : "Sovellusta ei voitu poistaa", diff --git a/settings/l10n/fi.json b/settings/l10n/fi.json index 92777da4584..0b40ef6c529 100644 --- a/settings/l10n/fi.json +++ b/settings/l10n/fi.json @@ -99,6 +99,7 @@ "Error: This app can not be enabled because it makes the server unstable" : "Virhe: tätä sovellusta ei voi ottaa käyttöön, koska se tekee palvelimesta epävakaan", "Error while disabling broken app" : "Virhe rikkinäistä sovellusta käytöstä poistaessa", "App up to date" : "Sovellus ajan tasalla", + "Updating …" : "Päivitetään ...", "Updated" : "Päivitetty", "Removing …" : "Poistetaan…", "Could not remove app" : "Sovellusta ei voitu poistaa", diff --git a/settings/l10n/sr.js b/settings/l10n/sr.js index edac50c5714..cddcb5e5360 100644 --- a/settings/l10n/sr.js +++ b/settings/l10n/sr.js @@ -160,6 +160,7 @@ OC.L10N.register( "Good password" : "Добра лозинка", "Strong password" : "Јака лозинка", "Groups" : "Групе", + "Unable to retrieve the group list" : "Није могуће дохватити списак група", "Unable to delete {objName}" : "Не могу да обришем {objName}", "Error creating group: {message}" : "Грешка при прављењу групе: {message}", "A valid group name must be provided" : "Мора бити наведено исправно име групе", diff --git a/settings/l10n/sr.json b/settings/l10n/sr.json index 70228a26c3c..b89afcea758 100644 --- a/settings/l10n/sr.json +++ b/settings/l10n/sr.json @@ -158,6 +158,7 @@ "Good password" : "Добра лозинка", "Strong password" : "Јака лозинка", "Groups" : "Групе", + "Unable to retrieve the group list" : "Није могуће дохватити списак група", "Unable to delete {objName}" : "Не могу да обришем {objName}", "Error creating group: {message}" : "Грешка при прављењу групе: {message}", "A valid group name must be provided" : "Мора бити наведено исправно име групе", diff --git a/tests/lib/Files/Node/FolderTest.php b/tests/lib/Files/Node/FolderTest.php index 6479dad58d3..c924c090232 100644 --- a/tests/lib/Files/Node/FolderTest.php +++ b/tests/lib/Files/Node/FolderTest.php @@ -682,7 +682,7 @@ class FolderTest extends NodeTest { $fileInfo = new CacheEntry(['path' => 'foo/qwerty', 'mimetype' => 'text/plain'], null); - $storage->expects($this->once()) + $storage->expects($this->exactly(2)) ->method('getCache') ->will($this->returnValue($cache)); |