diff --git a/.htaccess b/.htaccess index 5bf7b321f0cc1..bd9f5af3f707a 100644 --- a/.htaccess +++ b/.htaccess @@ -56,9 +56,9 @@ RewriteRule ^\.well-known/carddav /remote.php/dav/ [R=301,L] RewriteRule ^\.well-known/caldav /remote.php/dav/ [R=301,L] RewriteRule ^remote/(.*) remote.php [QSA,L] - RewriteRule ^(build|tests|config|lib|3rdparty|templates)/.* - [R=404,L] + RewriteRule ^(?:build|tests|config|lib|3rdparty|templates)/.* - [R=404,L] RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/.* - RewriteRule ^(\.|autotest|occ|issue|indie|db_|console).* - [R=404,L] + RewriteRule ^(?:\.|autotest|occ|issue|indie|db_|console).* - [R=404,L] AddType image/svg+xml svg svgz diff --git a/apps/federatedfilesharing/l10n/pl.js b/apps/federatedfilesharing/l10n/pl.js index 9bd5edd9b565e..1d8b949c74af8 100644 --- a/apps/federatedfilesharing/l10n/pl.js +++ b/apps/federatedfilesharing/l10n/pl.js @@ -2,6 +2,7 @@ OC.L10N.register( "federatedfilesharing", { "Sharing %s failed, because this item is already shared with %s" : "Współdzielenie %s nie powiodło się, ponieważ element jest już współdzielony z %s", + "File is already shared with %s" : "Plik jest już współdzielony z %s", "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "Współdzielenie %s nie powiodło się, nie można odnaleźć %s. Prawdopobnie serwer nie jest teraz osiągalny.", "Accept" : "Akceptuj", "Open documentation" : "Otwórz dokumentację", diff --git a/apps/federatedfilesharing/l10n/pl.json b/apps/federatedfilesharing/l10n/pl.json index 5fd8fb130b7fa..c44eecbeeb7b2 100644 --- a/apps/federatedfilesharing/l10n/pl.json +++ b/apps/federatedfilesharing/l10n/pl.json @@ -1,5 +1,6 @@ { "translations": { "Sharing %s failed, because this item is already shared with %s" : "Współdzielenie %s nie powiodło się, ponieważ element jest już współdzielony z %s", + "File is already shared with %s" : "Plik jest już współdzielony z %s", "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "Współdzielenie %s nie powiodło się, nie można odnaleźć %s. Prawdopobnie serwer nie jest teraz osiągalny.", "Accept" : "Akceptuj", "Open documentation" : "Otwórz dokumentację", diff --git a/apps/federation/css/settings-admin.css b/apps/federation/css/settings-admin.css index 55b1dd64d15d7..150412c156ffd 100644 --- a/apps/federation/css/settings-admin.css +++ b/apps/federation/css/settings-admin.css @@ -17,10 +17,13 @@ cursor: pointer; } -#listOfTrustedServers li:hover { - cursor: pointer; -} - #listOfTrustedServers .status { margin-right: 10px; } + +#listOfTrustedServers .icon { + cursor: pointer; + display: inline-block; + vertical-align: middle; + margin-left: 10px; +} diff --git a/apps/federation/js/settings-admin.js b/apps/federation/js/settings-admin.js index 7d531b39d8c4c..45d5d62a5a380 100644 --- a/apps/federation/js/settings-admin.js +++ b/apps/federation/js/settings-admin.js @@ -42,8 +42,9 @@ $(document).ready(function () { $('ul#listOfTrustedServers').prepend( $('
  • ') .attr('id', data.id) - .attr('class', 'icon-delete') - .html('' + data.url) + .html('' + + data.url + + '') ); OC.msg.finishedSuccess('#ocFederationAddServer .msg', data.message); }) @@ -56,10 +57,10 @@ $(document).ready(function () { } }); - // remove trusted server from list - $( "#listOfTrustedServers" ).on('click', 'li', function() { - var id = $(this).attr('id'); - var $this = $(this); +// remove trusted server from list + $( "#listOfTrustedServers" ).on('click', 'li > .icon-delete', function() { + var $this = $(this).parent(); + id = $this.attr('id'); $.ajax({ url: OC.generateUrl('/apps/federation/trusted-servers/' + id), type: 'DELETE', diff --git a/apps/federation/templates/settings-admin.php b/apps/federation/templates/settings-admin.php index 704fc9a9acec3..ce66214de7c82 100644 --- a/apps/federation/templates/settings-admin.php +++ b/apps/federation/templates/settings-admin.php @@ -23,7 +23,7 @@

    diff --git a/apps/files/l10n/pl.js b/apps/files/l10n/pl.js index 01259a538abde..cb243f6bf4d2e 100644 --- a/apps/files/l10n/pl.js +++ b/apps/files/l10n/pl.js @@ -45,6 +45,7 @@ OC.L10N.register( "Unable to determine date" : "Nie można ustalić daty", "This operation is forbidden" : "Ta operacja jest niedozwolona", "This directory is unavailable, please check the logs or contact the administrator" : "Ten folder jest niedostępny, proszę sprawdzić logi lub skontaktować się z administratorem.", + "Could not move \"{file}\", target exists" : "Nie można było przenieść „{file}” – plik o takiej nazwie już istnieje", "Could not move \"{file}\"" : "Nie można było przenieść \"{file}\"", "Could not create file \"{file}\"" : "Nie można było utworzyć pliku \"{file}\"", "Could not create file \"{file}\" because it already exists" : "Nie można było utworzyć pliku \"{file}\", ponieważ ten plik już istnieje.", diff --git a/apps/files/l10n/pl.json b/apps/files/l10n/pl.json index fd4d5116953a8..60323d0e757e2 100644 --- a/apps/files/l10n/pl.json +++ b/apps/files/l10n/pl.json @@ -43,6 +43,7 @@ "Unable to determine date" : "Nie można ustalić daty", "This operation is forbidden" : "Ta operacja jest niedozwolona", "This directory is unavailable, please check the logs or contact the administrator" : "Ten folder jest niedostępny, proszę sprawdzić logi lub skontaktować się z administratorem.", + "Could not move \"{file}\", target exists" : "Nie można było przenieść „{file}” – plik o takiej nazwie już istnieje", "Could not move \"{file}\"" : "Nie można było przenieść \"{file}\"", "Could not create file \"{file}\"" : "Nie można było utworzyć pliku \"{file}\"", "Could not create file \"{file}\" because it already exists" : "Nie można było utworzyć pliku \"{file}\", ponieważ ten plik już istnieje.", diff --git a/apps/files_external/l10n/pl.js b/apps/files_external/l10n/pl.js index 0ba2646601bfc..8c3e394627e77 100644 --- a/apps/files_external/l10n/pl.js +++ b/apps/files_external/l10n/pl.js @@ -2,6 +2,7 @@ OC.L10N.register( "files_external", { "Fetching access tokens failed. Verify that your app key and secret are correct." : "Otrzymano błędne żądanie tokenów. Sprawdź, czy klucz aplikacji oraz klucz poufny są poprawne.", + "Please provide a valid app key and secret." : "Proszę podać prawidłowy klucz aplikacji i klucz sekretny.", "Step 1 failed. Exception: %s" : "Krok 1 błędny. Błąd: %s", "Step 2 failed. Exception: %s" : "Krok 2 błędny. Błąd: %s", "External storage" : "Zewnętrzne zasoby dyskowe", diff --git a/apps/files_external/l10n/pl.json b/apps/files_external/l10n/pl.json index 8809813c9ba76..8e00fc31863ed 100644 --- a/apps/files_external/l10n/pl.json +++ b/apps/files_external/l10n/pl.json @@ -1,5 +1,6 @@ { "translations": { "Fetching access tokens failed. Verify that your app key and secret are correct." : "Otrzymano błędne żądanie tokenów. Sprawdź, czy klucz aplikacji oraz klucz poufny są poprawne.", + "Please provide a valid app key and secret." : "Proszę podać prawidłowy klucz aplikacji i klucz sekretny.", "Step 1 failed. Exception: %s" : "Krok 1 błędny. Błąd: %s", "Step 2 failed. Exception: %s" : "Krok 2 błędny. Błąd: %s", "External storage" : "Zewnętrzne zasoby dyskowe", diff --git a/apps/files_external/lib/Lib/Storage/Google.php b/apps/files_external/lib/Lib/Storage/Google.php index 49fde7d066f7d..96f12800c108b 100644 --- a/apps/files_external/lib/Lib/Storage/Google.php +++ b/apps/files_external/lib/Lib/Storage/Google.php @@ -326,7 +326,7 @@ public function stat($path) { $stat['size'] = 0; } else { // Check if this is a Google Doc - if ($this->getMimeType($path) !== $file->getMimeType()) { + if ($this->isGoogleDocFile($file)) { // Return unknown file size $stat['size'] = \OCP\Files\FileInfo::SPACE_UNKNOWN; } else { diff --git a/apps/files_sharing/l10n/pl.js b/apps/files_sharing/l10n/pl.js index a703ef087ee53..ebdfe2aa738a0 100644 --- a/apps/files_sharing/l10n/pl.js +++ b/apps/files_sharing/l10n/pl.js @@ -21,6 +21,7 @@ OC.L10N.register( "Remote share password" : "Hasło do zdalnego zasobu", "Cancel" : "Anuluj", "Add remote share" : "Dodaj zdalny zasób", + "No ownCloud installation (7 or higher) found at {remote}" : "Nie znaleziono instalacji ownCloud (w wersji 7 lub nowszej) na {remote}", "Invalid ownCloud url" : "Błędny adres URL", "Shared by" : "Udostępniane przez", "Sharing" : "Udostępnianie", diff --git a/apps/files_sharing/l10n/pl.json b/apps/files_sharing/l10n/pl.json index 62d6ef25b3887..f5de5dd368c8d 100644 --- a/apps/files_sharing/l10n/pl.json +++ b/apps/files_sharing/l10n/pl.json @@ -19,6 +19,7 @@ "Remote share password" : "Hasło do zdalnego zasobu", "Cancel" : "Anuluj", "Add remote share" : "Dodaj zdalny zasób", + "No ownCloud installation (7 or higher) found at {remote}" : "Nie znaleziono instalacji ownCloud (w wersji 7 lub nowszej) na {remote}", "Invalid ownCloud url" : "Błędny adres URL", "Shared by" : "Udostępniane przez", "Sharing" : "Udostępnianie", diff --git a/apps/systemtags/l10n/pl.js b/apps/systemtags/l10n/pl.js index fc3616bff26aa..f5e4775d540a9 100644 --- a/apps/systemtags/l10n/pl.js +++ b/apps/systemtags/l10n/pl.js @@ -3,6 +3,8 @@ OC.L10N.register( { "Tags" : "Etykiety", "Tagged files" : "Otagowane pliki", + "Select tags to filter by" : "Wybierz tagi do filtru", + "Please select tags to filter by" : "Proszę wybrać tagi do filtrów", "No files found for the selected tags" : "Nie znaleziono plików dla wybranych etykiet", "System tags for a file have been modified" : "System etykiet dla pliku został zmieniony", "%1$s assigned system tag %3$s" : "%1$s przypisywalny system etykiet%3$s", diff --git a/apps/systemtags/l10n/pl.json b/apps/systemtags/l10n/pl.json index 543aa3be58c13..6cb103ed4a545 100644 --- a/apps/systemtags/l10n/pl.json +++ b/apps/systemtags/l10n/pl.json @@ -1,6 +1,8 @@ { "translations": { "Tags" : "Etykiety", "Tagged files" : "Otagowane pliki", + "Select tags to filter by" : "Wybierz tagi do filtru", + "Please select tags to filter by" : "Proszę wybrać tagi do filtrów", "No files found for the selected tags" : "Nie znaleziono plików dla wybranych etykiet", "System tags for a file have been modified" : "System etykiet dla pliku został zmieniony", "%1$s assigned system tag %3$s" : "%1$s przypisywalny system etykiet%3$s", diff --git a/apps/updatenotification/l10n/pl.js b/apps/updatenotification/l10n/pl.js index 6551d0808e388..d86fdf3c24349 100644 --- a/apps/updatenotification/l10n/pl.js +++ b/apps/updatenotification/l10n/pl.js @@ -1,8 +1,11 @@ OC.L10N.register( "updatenotification", { + "Update notifications" : "Powiadomienia o aktualizacji", "{version} is available. Get more information on how to update." : "Wersja {version} jest dostępna. Dowiedz się jak zaktualizować.", "Updated channel" : "Zaktualizowano kanał", + "ownCloud core" : "Rdzeń ownCloud", + "Update for %1$s to version %2$s is available." : "Jest dostępna aktualizacja dla %1$s do wersji %2$s", "Updater" : "Aktualizator", "A new version is available: %s" : "Dostępna jest nowa wersja: %s", "Open updater" : "Otwórz aktualizator", diff --git a/apps/updatenotification/l10n/pl.json b/apps/updatenotification/l10n/pl.json index fd859feae11ed..b5d7132d9f0b7 100644 --- a/apps/updatenotification/l10n/pl.json +++ b/apps/updatenotification/l10n/pl.json @@ -1,6 +1,9 @@ { "translations": { + "Update notifications" : "Powiadomienia o aktualizacji", "{version} is available. Get more information on how to update." : "Wersja {version} jest dostępna. Dowiedz się jak zaktualizować.", "Updated channel" : "Zaktualizowano kanał", + "ownCloud core" : "Rdzeń ownCloud", + "Update for %1$s to version %2$s is available." : "Jest dostępna aktualizacja dla %1$s do wersji %2$s", "Updater" : "Aktualizator", "A new version is available: %s" : "Dostępna jest nowa wersja: %s", "Open updater" : "Otwórz aktualizator", diff --git a/core/Command/Encryption/DecryptAll.php b/core/Command/Encryption/DecryptAll.php index d060918a506a9..6ceb0185acb2c 100644 --- a/core/Command/Encryption/DecryptAll.php +++ b/core/Command/Encryption/DecryptAll.php @@ -129,13 +129,13 @@ protected function execute(InputInterface $input, OutputInterface $output) { } $uid = $input->getArgument('user'); - //FIXME WHEN https://github.com/owncloud/core/issues/24994 is fixed - if ($uid === null) { + if ($uid === '') { $message = 'your ownCloud'; } else { $message = "$uid's account"; } + $output->writeln("\n"); $output->writeln("You are about to start to decrypt all files stored in $message."); $output->writeln('It will depend on the encryption module and your setup if this is possible.'); diff --git a/core/css/tooltip.css b/core/css/tooltip.css index 34d0ec6c70f6c..af25fd5533dfb 100644 --- a/core/css/tooltip.css +++ b/core/css/tooltip.css @@ -47,7 +47,7 @@ padding: 0 5px; } .tooltip-inner { - max-width: 200px; + max-width: 350px; padding: 3px 8px; color: #ffffff; text-align: center; diff --git a/core/js/setupchecks.js b/core/js/setupchecks.js index 4cc50e51ae6dc..f987c9f04e61a 100644 --- a/core/js/setupchecks.js +++ b/core/js/setupchecks.js @@ -197,7 +197,7 @@ } var afterCall = function(xhr) { var messages = []; - if (xhr.status !== 403 && xhr.status !== 307 && xhr.status !== 301 && xhr.responseText === '') { + if (xhr.status !== 403 && xhr.status !== 307 && xhr.status !== 301 && xhr.responseText !== '') { 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 @@ -208,7 +208,7 @@ $.ajax({ type: 'GET', - url: OC.linkTo('', oc_dataURL+'/.ocdata'), + url: OC.linkTo('', oc_dataURL+'/htaccesstest.txt?t=' + (new Date()).getTime()), complete: afterCall }); return deferred.promise(); diff --git a/core/js/tests/specs/setupchecksSpec.js b/core/js/tests/specs/setupchecksSpec.js index 4931ca990da48..172e6e271350c 100644 --- a/core/js/tests/specs/setupchecksSpec.js +++ b/core/js/tests/specs/setupchecksSpec.js @@ -103,7 +103,7 @@ describe('OC.SetupChecks tests', function() { it('should return an error if data directory is not protected', function(done) { var async = OC.SetupChecks.checkDataProtected(); - suite.server.requests[0].respond(200); + suite.server.requests[0].respond(200, {'Content-Type': 'text/plain'}, 'file contents'); async.done(function( data, s, x ){ expect(data).toEqual([ diff --git a/core/l10n/ja.js b/core/l10n/ja.js index 397a417eb9d44..a45c8620c6e76 100644 --- a/core/l10n/ja.js +++ b/core/l10n/ja.js @@ -295,6 +295,7 @@ OC.L10N.register( "This means only administrators can use the instance." : "これは、管理者のみがインスタンスを利用できることを意味しています。", "Contact your system administrator if this message persists or appeared unexpectedly." : "このメッセージが引き続きもしくは予期せず現れる場合は、システム管理者に問い合わせてください。", "Thank you for your patience." : "しばらくお待ちください。", + "Two-step verification" : "2段階認証", "You are accessing the server from an untrusted domain." : "信頼されていないドメインからサーバーにアクセスしています。", "Please contact your administrator. If you are an administrator of this instance, configure the \"trusted_domains\" setting in config/config.php. An example configuration is provided in config/config.sample.php." : "管理者に問い合わせてください。このサーバーの管理者の場合は、\"trusted_domain\" の設定を config/config.php に設定してください。config/config.sample.php にサンプルの設定方法が記載してあります。", "Depending on your configuration, as an administrator you might also be able to use the button below to trust this domain." : "環境により、下のボタンで信頼するドメインに追加する必要があるかもしれません。", diff --git a/core/l10n/ja.json b/core/l10n/ja.json index 11c88968ee291..b5e9ba9b9d01c 100644 --- a/core/l10n/ja.json +++ b/core/l10n/ja.json @@ -293,6 +293,7 @@ "This means only administrators can use the instance." : "これは、管理者のみがインスタンスを利用できることを意味しています。", "Contact your system administrator if this message persists or appeared unexpectedly." : "このメッセージが引き続きもしくは予期せず現れる場合は、システム管理者に問い合わせてください。", "Thank you for your patience." : "しばらくお待ちください。", + "Two-step verification" : "2段階認証", "You are accessing the server from an untrusted domain." : "信頼されていないドメインからサーバーにアクセスしています。", "Please contact your administrator. If you are an administrator of this instance, configure the \"trusted_domains\" setting in config/config.php. An example configuration is provided in config/config.sample.php." : "管理者に問い合わせてください。このサーバーの管理者の場合は、\"trusted_domain\" の設定を config/config.php に設定してください。config/config.sample.php にサンプルの設定方法が記載してあります。", "Depending on your configuration, as an administrator you might also be able to use the button below to trust this domain." : "環境により、下のボタンで信頼するドメインに追加する必要があるかもしれません。", diff --git a/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php b/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php index 2b9a072e59ab6..d84e996343616 100644 --- a/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php +++ b/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php @@ -26,13 +26,13 @@ use OC\AppFramework\Middleware\Security\Exceptions\SecurityException; use OC\AppFramework\Utility\ControllerMethodReflector; +use OC\User\Session; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; -use OCP\IRequest; -use OCP\IUserSession; use OCP\AppFramework\Http\Response; use OCP\AppFramework\Middleware; +use OCP\IRequest; /** * This middleware sets the correct CORS headers on a response if the @@ -53,18 +53,18 @@ class CORSMiddleware extends Middleware { private $reflector; /** - * @var IUserSession + * @var Session */ private $session; /** * @param IRequest $request * @param ControllerMethodReflector $reflector - * @param IUserSession $session + * @param Session $session */ public function __construct(IRequest $request, ControllerMethodReflector $reflector, - IUserSession $session) { + Session $session) { $this->request = $request; $this->reflector = $reflector; $this->session = $session; @@ -89,7 +89,7 @@ public function beforeController($controller, $methodName){ $pass = $this->request->server['PHP_AUTH_PW']; $this->session->logout(); - if(!$this->session->login($user, $pass)) { + if(!$this->session->logClientIn($user, $pass)) { throw new SecurityException('CORS requires basic auth', Http::STATUS_UNAUTHORIZED); } } diff --git a/lib/private/Files/Utils/Scanner.php b/lib/private/Files/Utils/Scanner.php index 9b55c312e268f..8beba116fe14f 100644 --- a/lib/private/Files/Utils/Scanner.php +++ b/lib/private/Files/Utils/Scanner.php @@ -160,7 +160,12 @@ public function scan($dir = '') { if ($storage->instanceOfStorage('\OC\Files\Storage\Home') and (!$storage->isCreatable('') or !$storage->isCreatable('files')) ) { - throw new ForbiddenException(); + if ($storage->file_exists('') or $storage->getCache()->inCache('')) { + throw new ForbiddenException(); + } else {// if the root exists in neither the cache nor the storage the user isn't setup yet + break; + } + } $relativePath = $mount->getInternalPath($dir); $scanner = $storage->getScanner(); diff --git a/lib/private/Log.php b/lib/private/Log.php index 6028064a8781a..49223521916db 100644 --- a/lib/private/Log.php +++ b/lib/private/Log.php @@ -60,6 +60,32 @@ class Log implements ILogger { /** @var Normalizer */ private $normalizer; + protected $methodsWithSensitiveParameters = [ + // Session/User + 'login', + 'checkPassword', + 'updatePrivateKeyPassword', + 'validateUserPass', + + // TokenProvider + 'getToken', + 'isTokenPassword', + 'getPassword', + 'decryptPassword', + 'logClientIn', + 'generateToken', + 'validateToken', + + // TwoFactorAuth + 'solveChallenge', + 'verifyChallenge', + + //ICrypto + 'calculateHMAC', + 'encrypt', + 'decrypt', + ]; + /** * @param string $logger The logger that should be used * @param SystemConfig $config the system config object @@ -286,7 +312,7 @@ public function logException($exception, array $context = array()) { 'File' => $exception->getFile(), 'Line' => $exception->getLine(), ); - $exception['Trace'] = preg_replace('!(login|checkPassword|updatePrivateKeyPassword|validateUserPass)\(.*\)!', '$1(*** username and password replaced ***)', $exception['Trace']); + $exception['Trace'] = preg_replace('!(' . implode('|', $this->methodsWithSensitiveParameters) . ')\(.*\)!', '$1(*** sensitive parameters replaced ***)', $exception['Trace']); $msg = isset($context['message']) ? $context['message'] : 'Exception'; $msg .= ': ' . json_encode($exception); $this->error($msg, $context); diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php index 362468d410986..e1ede95e2ae5a 100644 --- a/lib/private/User/Session.php +++ b/lib/private/User/Session.php @@ -470,11 +470,39 @@ public function createSessionToken(IRequest $request, $uid, $loginName, $passwor $name = isset($request->server['HTTP_USER_AGENT']) ? $request->server['HTTP_USER_AGENT'] : 'unknown browser'; try { $sessionId = $this->session->getId(); - $this->tokenProvider->generateToken($sessionId, $uid, $loginName, $password, $name); + $pwd = $this->getPassword($password); + $this->tokenProvider->generateToken($sessionId, $uid, $loginName, $pwd, $name); + return true; } catch (SessionNotAvailableException $ex) { + // This can happen with OCC, where a memory session is used + // if a memory session is used, we shouldn't create a session token anyway + return false; + } + } + /** + * Checks if the given password is a token. + * If yes, the password is extracted from the token. + * If no, the same password is returned. + * + * @param string $password either the login password or a device token + * @return string|null the password or null if none was set in the token + */ + private function getPassword($password) { + if (is_null($password)) { + // This is surely no token ;-) + return null; + } + try { + $token = $this->tokenProvider->getToken($password); + try { + return $this->tokenProvider->getPassword($token, $password); + } catch (PasswordlessTokenException $ex) { + return null; + } + } catch (InvalidTokenException $ex) { + return $password; } - return true; } /** diff --git a/lib/private/legacy/util.php b/lib/private/legacy/util.php index b744db21238aa..a863348566e60 100644 --- a/lib/private/legacy/util.php +++ b/lib/private/legacy/util.php @@ -1128,19 +1128,8 @@ public static function encodePath($component) { return $encoded; } - /** - * Check if the .htaccess file is working - * @param \OCP\IConfig $config - * @return bool - * @throws Exception - * @throws \OC\HintException If the test file can't get written. - */ - public function isHtaccessWorking(\OCP\IConfig $config) { - - if (\OC::$CLI || !$config->getSystemValue('check_for_working_htaccess', true)) { - return true; - } + public function createHtaccessTestFile(\OCP\IConfig $config) { // php dev server does not support htaccess if (php_sapi_name() === 'cli-server') { return false; @@ -1148,7 +1137,7 @@ public function isHtaccessWorking(\OCP\IConfig $config) { // testdata $fileName = '/htaccesstest.txt'; - $testContent = 'testcontent'; + $testContent = 'This is used for testing whether htaccess is properly enabled to disallow access from the outside. This file can be safely removed.'; // creating a test file $testFile = $config->getSystemValue('datadirectory', OC::$SERVERROOT . '/data') . '/' . $fileName; @@ -1164,6 +1153,28 @@ public function isHtaccessWorking(\OCP\IConfig $config) { } fwrite($fp, $testContent); fclose($fp); + } + + /** + * Check if the .htaccess file is working + * @param \OCP\IConfig $config + * @return bool + * @throws Exception + * @throws \OC\HintException If the test file can't get written. + */ + public function isHtaccessWorking(\OCP\IConfig $config) { + + if (\OC::$CLI || !$config->getSystemValue('check_for_working_htaccess', true)) { + return true; + } + + $testContent = $this->createHtaccessTestFile($config); + if ($testContent === false) { + return false; + } + + $fileName = '/htaccesstest.txt'; + $testFile = $config->getSystemValue('datadirectory', OC::$SERVERROOT . '/data') . '/' . $fileName; // accessing the file via http $url = \OC::$server->getURLGenerator()->getAbsoluteURL(OC::$WEBROOT . '/data' . $fileName); diff --git a/settings/admin.php b/settings/admin.php index 6fb65b013e6ee..3ae7455b2ea60 100644 --- a/settings/admin.php +++ b/settings/admin.php @@ -267,3 +267,7 @@ $template->assign('forms', $formsAndMore); $template->printPage(); + +$util = new \OC_Util(); +$util->createHtaccessTestFile(\OC::$server->getConfig()); + diff --git a/settings/l10n/pl.js b/settings/l10n/pl.js index 8c592ec5114c5..7f14e552192bf 100644 --- a/settings/l10n/pl.js +++ b/settings/l10n/pl.js @@ -6,6 +6,7 @@ OC.L10N.register( "Authentication error" : "Błąd uwierzytelniania", "Please provide an admin recovery password, otherwise all user data will be lost" : "Podaj hasło odzyskiwania administratora, w przeciwnym razie wszystkie dane użytkownika zostaną utracone", "Wrong admin recovery password. Please check the password and try again." : "Błędne hasło odzyskiwania. Sprawdź hasło i spróbuj ponownie.", + "Backend doesn't support password change, but the user's encryption key was successfully updated." : "Zaplecze nie obsługuje zmiany hasła, ale klucz szyfrowania użytkownika został pomyślnie zaktualizowany.", "Unable to change password" : "Nie można zmienić hasła", "Enabled" : "Włączone", "Not enabled" : "Nie włączone", diff --git a/settings/l10n/pl.json b/settings/l10n/pl.json index ded5e82af0a9d..6ab582825f7e3 100644 --- a/settings/l10n/pl.json +++ b/settings/l10n/pl.json @@ -4,6 +4,7 @@ "Authentication error" : "Błąd uwierzytelniania", "Please provide an admin recovery password, otherwise all user data will be lost" : "Podaj hasło odzyskiwania administratora, w przeciwnym razie wszystkie dane użytkownika zostaną utracone", "Wrong admin recovery password. Please check the password and try again." : "Błędne hasło odzyskiwania. Sprawdź hasło i spróbuj ponownie.", + "Backend doesn't support password change, but the user's encryption key was successfully updated." : "Zaplecze nie obsługuje zmiany hasła, ale klucz szyfrowania użytkownika został pomyślnie zaktualizowany.", "Unable to change password" : "Nie można zmienić hasła", "Enabled" : "Włączone", "Not enabled" : "Nie włączone", diff --git a/settings/l10n/ro.js b/settings/l10n/ro.js index 4f965ce5b74de..8afe595859a94 100644 --- a/settings/l10n/ro.js +++ b/settings/l10n/ro.js @@ -48,8 +48,16 @@ OC.L10N.register( "Unable to add user to group %s" : "Nu s-a putut adăuga utilizatorul în grupul %s", "Unable to remove user from group %s" : "Nu s-a putut elimina utilizatorul din grupul %s", "Couldn't update app." : "Aplicaţia nu s-a putut actualiza.", + "Add trusted domain" : "Adaugă domeniu de încredere", + "Migration in progress. Please wait until the migration is finished" : "Migrare în progres. Așteaptă până când migrarea este finalizată", + "Migration started …" : "Migrarea a început...", "Sending..." : "Se expediază...", + "Official" : "Oficial", + "Approved" : "Aprobat", + "Experimental" : "Experimental", "All" : "Toate ", + "No apps found for your version" : "Nu au fost găsite aplicații pentru versiunea ta", + "The app will be downloaded from the app store" : "Aplicația va fi descărcată din magazin", "Please wait...." : "Aşteptaţi vă rog....", "Error while disabling app" : "Eroare în timpul dezactivării aplicației", "Disable" : "Dezactivați", @@ -60,7 +68,9 @@ OC.L10N.register( "Updated" : "Actualizat", "Uninstalling ...." : "Dezinstalaza ....", "Uninstall" : "Dezinstalați", + "Valid until {date}" : "Valabil până la {date}", "Delete" : "Șterge", + "An error occurred: {message}" : "A apărut o eroare: {message}", "Select a profile picture" : "Selectează o imagine de profil", "Very weak password" : "Parolă foarte slabă", "Weak password" : "Parolă slabă", @@ -68,13 +78,21 @@ OC.L10N.register( "Good password" : "Parolă bună", "Strong password" : "Parolă puternică", "Groups" : "Grupuri", + "Unable to delete {objName}" : "Nu s-a putut șterge {objName}", + "deleted {groupName}" : "{groupName} s-a șters", "undo" : "Anulează ultima acțiune", + "no group" : "niciun grup", "never" : "niciodată", + "deleted {userName}" : "{userName} șters", "add group" : "adăugaţi grupul", "A valid username must be provided" : "Trebuie să furnizaţi un nume de utilizator valid", "A valid password must be provided" : "Trebuie să furnizaţi o parolă validă", "__language_name__" : "_language_name_", "Unlimited" : "Nelimitată", + "Personal info" : "Informații personale", + "Sessions" : "Sesiuni", + "Devices" : "Dispozitive", + "Sync clients" : "Sincronizează clienții", "None" : "Niciuna", "Login" : "Autentificare", "SSL" : "SSL", @@ -83,31 +101,75 @@ OC.L10N.register( "Open documentation" : "Deschide documentația", "Allow apps to use the Share API" : "Permite aplicațiilor să folosească API-ul de partajare", "Allow public uploads" : "Permite încărcări publice", + "Enforce password protection" : "Impune protecția prin parolă", + "Set default expiration date" : "Setează data implicită de expirare", "Allow users to send mail notification for shared files" : "Permite utilizatorilor sa expedieze notificări prin e-mail pentru dosarele comune", + "Expire after " : "Expiră după", "days" : "zile", + "Enforce expiration date" : "Impune data de expirare", "Allow resharing" : "Permite repartajarea", + "Allow sharing with groups" : "Permite partajarea cu grupuri", + "Exclude groups from sharing" : "Exclude grupuri de la partajare", "Execute one task with each page loaded" : "Execută o sarcină la fiecare pagină încărcată", + "Enable server-side encryption" : "Activează criptarea pe server", + "Please read carefully before activating server-side encryption: " : "Citește cu atenție înainte să activezi criptarea pe server:", + "This is the final warning: Do you really want to enable encryption?" : "Aceasta este avertizarea finală: Chiar vrei să activezi criptarea?", "Enable encryption" : "Activează criptarea", + "Select default encryption module:" : "Selectează modulul implicit de criptare:", + "Start migration" : "Pornește migrarea", "Send mode" : "Modul de expediere", "Encryption" : "Încriptare", + "From address" : "De la adresa", + "mail" : "poștă", "Authentication method" : "Modul de autentificare", "Authentication required" : "Autentificare necesară", "Server address" : "Adresa server-ului", "Port" : "Portul", + "Credentials" : "Detalii de autentificare", "SMTP Username" : "Nume utilizator SMTP", "SMTP Password" : "Parolă SMTP", + "Store credentials" : "Stochează datele de autentificare", "Test email settings" : "Verifică setările de e-mail", "Send email" : "Expediază mesajul", + "Download logfile" : "Descarcă fișierul cu loguri", "More" : "Mai mult", "Less" : "Mai puțin", + "The logfile is bigger than 100 MB. Downloading it may take some time!" : "Fișierul cu loguri este mai mare de 100 MB. Descărcarea acestuia ar putea dura ceva timp!", + "What to log" : "Ce să loghezi", + "SQLite is used as database. For larger installations we recommend to switch to a different database backend." : "SQLite e folosit ca o bază de date. Pentru instalări mari recomandăm folosirea unei alte baze de date.", "Especially when using the desktop client for file syncing the use of SQLite is discouraged." : "În special atunci când este folosit clientul desktop pentru sincronizarea fișierelor, utilizarea SQLite este nerecomandată.", + "How to do backups" : "Cum să faci copii de rezervă", + "Advanced monitoring" : "Monitorizare avansată", "Version" : "Versiunea", + "Developer documentation" : "Documentație pentru dezvoltatori", + "by %s" : "de %s", + "%s-licensed" : "%s-licențiat", + "Documentation:" : "Documentație:", + "User documentation" : "Documentație utilizator", + "Admin documentation" : "Documentație pentru administrare", + "Show description …" : "Arată descriere ...", + "Hide description …" : "Ascunde descriere ...", + "This app has an update available." : "Este disponibilă o actualizare pentru această aplicație.", + "Enable only for specific groups" : "Activează doar pentru grupuri specifice", + "Uninstall App" : "Dezinstalează aplicația", + "Enable experimental apps" : "Activează aplicațiile experimentale", + "SSL Root Certificates" : "Certificate SSL rădăcină", + "Common Name" : "Nume comun", + "Valid until" : "Valabil până la", + "Issued By" : "Emis de", + "Valid until %s" : "Valabil până la %s", + "Import root certificate" : "Importă certificat rădăcină", "Cheers!" : "Noroc!", + "Administrator documentation" : "Documentație pentru administrare", + "Online documentation" : "Documentație online", "Forum" : "Forum", + "Commercial support" : "Suport comercial", "Profile picture" : "Imagine de profil", "Upload new" : "Încarcă una nouă", "Remove image" : "Înlătură imagine", + "png or jpg, max. 20 MB" : "png sau jpg, max. 20 MB", "Cancel" : "Anulare", + "Full name" : "Nume complet", "Email" : "Email", "Your email address" : "Adresa ta de email", "Password" : "Parolă", @@ -115,6 +177,8 @@ OC.L10N.register( "Current password" : "Parola curentă", "New password" : "Noua parolă", "Change password" : "Schimbă parola", + "Most recent activity" : "Cea mai recentă activitate", + "You've linked these devices." : "Ai legat aceste dispozitive.", "Name" : "Nume", "Language" : "Limba", "Help translate" : "Ajută la traducere", @@ -128,12 +192,16 @@ OC.L10N.register( "Admin Recovery Password" : "Parolă de recuperare a Administratorului", "Enter the recovery password in order to recover the users files during password change" : "Introdu parola de recuperare pentru a recupera fișierele utilizatorilor în timpul schimbării parolei", "Group" : "Grup", + "Admins" : "Administratori", "Default Quota" : "Cotă implicită", "Other" : "Altele", "Full Name" : "Nume complet", + "Group Admin for" : "Administrator de grup pentru", "Quota" : "Cotă", + "Last Login" : "Ultima autentificare", "change full name" : "schimbă numele complet", "set new password" : "setează parolă nouă", + "change email address" : "schimbă adresa email", "Default" : "Implicită" }, "nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"); diff --git a/settings/l10n/ro.json b/settings/l10n/ro.json index 05540e9da9082..8682709a39ebd 100644 --- a/settings/l10n/ro.json +++ b/settings/l10n/ro.json @@ -46,8 +46,16 @@ "Unable to add user to group %s" : "Nu s-a putut adăuga utilizatorul în grupul %s", "Unable to remove user from group %s" : "Nu s-a putut elimina utilizatorul din grupul %s", "Couldn't update app." : "Aplicaţia nu s-a putut actualiza.", + "Add trusted domain" : "Adaugă domeniu de încredere", + "Migration in progress. Please wait until the migration is finished" : "Migrare în progres. Așteaptă până când migrarea este finalizată", + "Migration started …" : "Migrarea a început...", "Sending..." : "Se expediază...", + "Official" : "Oficial", + "Approved" : "Aprobat", + "Experimental" : "Experimental", "All" : "Toate ", + "No apps found for your version" : "Nu au fost găsite aplicații pentru versiunea ta", + "The app will be downloaded from the app store" : "Aplicația va fi descărcată din magazin", "Please wait...." : "Aşteptaţi vă rog....", "Error while disabling app" : "Eroare în timpul dezactivării aplicației", "Disable" : "Dezactivați", @@ -58,7 +66,9 @@ "Updated" : "Actualizat", "Uninstalling ...." : "Dezinstalaza ....", "Uninstall" : "Dezinstalați", + "Valid until {date}" : "Valabil până la {date}", "Delete" : "Șterge", + "An error occurred: {message}" : "A apărut o eroare: {message}", "Select a profile picture" : "Selectează o imagine de profil", "Very weak password" : "Parolă foarte slabă", "Weak password" : "Parolă slabă", @@ -66,13 +76,21 @@ "Good password" : "Parolă bună", "Strong password" : "Parolă puternică", "Groups" : "Grupuri", + "Unable to delete {objName}" : "Nu s-a putut șterge {objName}", + "deleted {groupName}" : "{groupName} s-a șters", "undo" : "Anulează ultima acțiune", + "no group" : "niciun grup", "never" : "niciodată", + "deleted {userName}" : "{userName} șters", "add group" : "adăugaţi grupul", "A valid username must be provided" : "Trebuie să furnizaţi un nume de utilizator valid", "A valid password must be provided" : "Trebuie să furnizaţi o parolă validă", "__language_name__" : "_language_name_", "Unlimited" : "Nelimitată", + "Personal info" : "Informații personale", + "Sessions" : "Sesiuni", + "Devices" : "Dispozitive", + "Sync clients" : "Sincronizează clienții", "None" : "Niciuna", "Login" : "Autentificare", "SSL" : "SSL", @@ -81,31 +99,75 @@ "Open documentation" : "Deschide documentația", "Allow apps to use the Share API" : "Permite aplicațiilor să folosească API-ul de partajare", "Allow public uploads" : "Permite încărcări publice", + "Enforce password protection" : "Impune protecția prin parolă", + "Set default expiration date" : "Setează data implicită de expirare", "Allow users to send mail notification for shared files" : "Permite utilizatorilor sa expedieze notificări prin e-mail pentru dosarele comune", + "Expire after " : "Expiră după", "days" : "zile", + "Enforce expiration date" : "Impune data de expirare", "Allow resharing" : "Permite repartajarea", + "Allow sharing with groups" : "Permite partajarea cu grupuri", + "Exclude groups from sharing" : "Exclude grupuri de la partajare", "Execute one task with each page loaded" : "Execută o sarcină la fiecare pagină încărcată", + "Enable server-side encryption" : "Activează criptarea pe server", + "Please read carefully before activating server-side encryption: " : "Citește cu atenție înainte să activezi criptarea pe server:", + "This is the final warning: Do you really want to enable encryption?" : "Aceasta este avertizarea finală: Chiar vrei să activezi criptarea?", "Enable encryption" : "Activează criptarea", + "Select default encryption module:" : "Selectează modulul implicit de criptare:", + "Start migration" : "Pornește migrarea", "Send mode" : "Modul de expediere", "Encryption" : "Încriptare", + "From address" : "De la adresa", + "mail" : "poștă", "Authentication method" : "Modul de autentificare", "Authentication required" : "Autentificare necesară", "Server address" : "Adresa server-ului", "Port" : "Portul", + "Credentials" : "Detalii de autentificare", "SMTP Username" : "Nume utilizator SMTP", "SMTP Password" : "Parolă SMTP", + "Store credentials" : "Stochează datele de autentificare", "Test email settings" : "Verifică setările de e-mail", "Send email" : "Expediază mesajul", + "Download logfile" : "Descarcă fișierul cu loguri", "More" : "Mai mult", "Less" : "Mai puțin", + "The logfile is bigger than 100 MB. Downloading it may take some time!" : "Fișierul cu loguri este mai mare de 100 MB. Descărcarea acestuia ar putea dura ceva timp!", + "What to log" : "Ce să loghezi", + "SQLite is used as database. For larger installations we recommend to switch to a different database backend." : "SQLite e folosit ca o bază de date. Pentru instalări mari recomandăm folosirea unei alte baze de date.", "Especially when using the desktop client for file syncing the use of SQLite is discouraged." : "În special atunci când este folosit clientul desktop pentru sincronizarea fișierelor, utilizarea SQLite este nerecomandată.", + "How to do backups" : "Cum să faci copii de rezervă", + "Advanced monitoring" : "Monitorizare avansată", "Version" : "Versiunea", + "Developer documentation" : "Documentație pentru dezvoltatori", + "by %s" : "de %s", + "%s-licensed" : "%s-licențiat", + "Documentation:" : "Documentație:", + "User documentation" : "Documentație utilizator", + "Admin documentation" : "Documentație pentru administrare", + "Show description …" : "Arată descriere ...", + "Hide description …" : "Ascunde descriere ...", + "This app has an update available." : "Este disponibilă o actualizare pentru această aplicație.", + "Enable only for specific groups" : "Activează doar pentru grupuri specifice", + "Uninstall App" : "Dezinstalează aplicația", + "Enable experimental apps" : "Activează aplicațiile experimentale", + "SSL Root Certificates" : "Certificate SSL rădăcină", + "Common Name" : "Nume comun", + "Valid until" : "Valabil până la", + "Issued By" : "Emis de", + "Valid until %s" : "Valabil până la %s", + "Import root certificate" : "Importă certificat rădăcină", "Cheers!" : "Noroc!", + "Administrator documentation" : "Documentație pentru administrare", + "Online documentation" : "Documentație online", "Forum" : "Forum", + "Commercial support" : "Suport comercial", "Profile picture" : "Imagine de profil", "Upload new" : "Încarcă una nouă", "Remove image" : "Înlătură imagine", + "png or jpg, max. 20 MB" : "png sau jpg, max. 20 MB", "Cancel" : "Anulare", + "Full name" : "Nume complet", "Email" : "Email", "Your email address" : "Adresa ta de email", "Password" : "Parolă", @@ -113,6 +175,8 @@ "Current password" : "Parola curentă", "New password" : "Noua parolă", "Change password" : "Schimbă parola", + "Most recent activity" : "Cea mai recentă activitate", + "You've linked these devices." : "Ai legat aceste dispozitive.", "Name" : "Nume", "Language" : "Limba", "Help translate" : "Ajută la traducere", @@ -126,12 +190,16 @@ "Admin Recovery Password" : "Parolă de recuperare a Administratorului", "Enter the recovery password in order to recover the users files during password change" : "Introdu parola de recuperare pentru a recupera fișierele utilizatorilor în timpul schimbării parolei", "Group" : "Grup", + "Admins" : "Administratori", "Default Quota" : "Cotă implicită", "Other" : "Altele", "Full Name" : "Nume complet", + "Group Admin for" : "Administrator de grup pentru", "Quota" : "Cotă", + "Last Login" : "Ultima autentificare", "change full name" : "schimbă numele complet", "set new password" : "setează parolă nouă", + "change email address" : "schimbă adresa email", "Default" : "Implicită" },"pluralForm" :"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));" } \ No newline at end of file diff --git a/tests/lib/AppFramework/Middleware/Security/CORSMiddlewareTest.php b/tests/lib/AppFramework/Middleware/Security/CORSMiddlewareTest.php index 8e53c9202cf38..a398dc2320cee 100644 --- a/tests/lib/AppFramework/Middleware/Security/CORSMiddlewareTest.php +++ b/tests/lib/AppFramework/Middleware/Security/CORSMiddlewareTest.php @@ -16,7 +16,6 @@ use OC\AppFramework\Middleware\Security\CORSMiddleware; use OC\AppFramework\Utility\ControllerMethodReflector; use OC\AppFramework\Middleware\Security\Exceptions\SecurityException; -use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\Response; @@ -29,7 +28,9 @@ class CORSMiddlewareTest extends \Test\TestCase { protected function setUp() { parent::setUp(); $this->reflector = new ControllerMethodReflector(); - $this->session = $this->getMock('\OCP\IUserSession'); + $this->session = $this->getMockBuilder('\OC\User\Session') + ->disableOriginalConstructor() + ->getMock(); } /** @@ -127,7 +128,7 @@ public function testNoCORSShouldAllowCookieAuth() { $this->session->expects($this->never()) ->method('logout'); $this->session->expects($this->never()) - ->method('login') + ->method('logClientIn') ->with($this->equalTo('user'), $this->equalTo('pass')) ->will($this->returnValue(true)); $this->reflector->reflect($this, __FUNCTION__); @@ -150,7 +151,7 @@ public function testCORSShouldRelogin() { $this->session->expects($this->once()) ->method('logout'); $this->session->expects($this->once()) - ->method('login') + ->method('logClientIn') ->with($this->equalTo('user'), $this->equalTo('pass')) ->will($this->returnValue(true)); $this->reflector->reflect($this, __FUNCTION__); @@ -175,7 +176,7 @@ public function testCORSShouldNotAllowCookieAuth() { $this->session->expects($this->once()) ->method('logout'); $this->session->expects($this->once()) - ->method('login') + ->method('logClientIn') ->with($this->equalTo('user'), $this->equalTo('pass')) ->will($this->returnValue(false)); $this->reflector->reflect($this, __FUNCTION__); diff --git a/tests/lib/LoggerTest.php b/tests/lib/LoggerTest.php index 4eb04b00f5859..4b80c01f34369 100644 --- a/tests/lib/LoggerTest.php +++ b/tests/lib/LoggerTest.php @@ -89,7 +89,7 @@ public function testDetectlogin($user, $password) { foreach($logLines as $logLine) { $this->assertNotContains($user, $logLine); $this->assertNotContains($password, $logLine); - $this->assertContains('login(*** username and password replaced ***)', $logLine); + $this->assertContains('login(*** sensitive parameters replaced ***)', $logLine); } } @@ -104,7 +104,7 @@ public function testDetectcheckPassword($user, $password) { foreach($logLines as $logLine) { $this->assertNotContains($user, $logLine); $this->assertNotContains($password, $logLine); - $this->assertContains('checkPassword(*** username and password replaced ***)', $logLine); + $this->assertContains('checkPassword(*** sensitive parameters replaced ***)', $logLine); } } @@ -119,7 +119,7 @@ public function testDetectvalidateUserPass($user, $password) { foreach($logLines as $logLine) { $this->assertNotContains($user, $logLine); $this->assertNotContains($password, $logLine); - $this->assertContains('validateUserPass(*** username and password replaced ***)', $logLine); + $this->assertContains('validateUserPass(*** sensitive parameters replaced ***)', $logLine); } } } diff --git a/tests/lib/User/SessionTest.php b/tests/lib/User/SessionTest.php index 36f14e85492df..eac38ebba160a 100644 --- a/tests/lib/User/SessionTest.php +++ b/tests/lib/User/SessionTest.php @@ -22,7 +22,7 @@ class SessionTest extends \Test\TestCase { private $timeFactory; /** @var \OC\Authentication\Token\DefaultTokenProvider */ - protected $defaultProvider; + protected $tokenProvider; /** @var \OCP\IConfig */ private $config; @@ -34,9 +34,7 @@ protected function setUp() { $this->timeFactory->expects($this->any()) ->method('getTime') ->will($this->returnValue(10000)); - $this->defaultProvider = $this->getMockBuilder('\OC\Authentication\Token\DefaultTokenProvider') - ->disableOriginalConstructor() - ->getMock(); + $this->tokenProvider = $this->getMock('\OC\Authentication\Token\IProvider'); $this->config = $this->getMock('\OCP\IConfig'); } @@ -61,14 +59,14 @@ public function testGetUser() { $session->expects($this->once()) ->method('getId') ->will($this->returnValue($sessionId)); - $this->defaultProvider->expects($this->once()) + $this->tokenProvider->expects($this->once()) ->method('getToken') ->will($this->returnValue($token)); $session->expects($this->at(2)) ->method('get') ->with('last_login_check') ->will($this->returnValue(null)); // No check has been run yet - $this->defaultProvider->expects($this->once()) + $this->tokenProvider->expects($this->once()) ->method('getPassword') ->with($token, $sessionId) ->will($this->returnValue('password123')); @@ -87,7 +85,7 @@ public function testGetUser() { ->method('get') ->with('last_token_update') ->will($this->returnValue(null)); // No check run so far - $this->defaultProvider->expects($this->once()) + $this->tokenProvider->expects($this->once()) ->method('updateToken') ->with($token); $session->expects($this->at(5)) @@ -99,7 +97,7 @@ public function testGetUser() { ->with($expectedUser->getUID()) ->will($this->returnValue($expectedUser)); - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->defaultProvider, $this->config); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); $user = $userSession->getUser(); $this->assertSame($expectedUser, $user); } @@ -122,7 +120,7 @@ public function testIsLoggedIn($isLoggedIn) { ->getMock(); $userSession = $this->getMockBuilder('\OC\User\Session') - ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->defaultProvider, $this->config]) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) ->setMethods([ 'getUser' ]) @@ -149,7 +147,7 @@ public function testSetUser() { ->method('getUID') ->will($this->returnValue('foo')); - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->defaultProvider, $this->config); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); $userSession->setUser($user); } @@ -201,7 +199,7 @@ public function testLoginValidPasswordEnabled() { ->will($this->returnValue($user)); $userSession = $this->getMockBuilder('\OC\User\Session') - ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->defaultProvider, $this->config]) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) ->setMethods([ 'prepareUserLogin' ]) @@ -248,7 +246,7 @@ public function testLoginValidPasswordDisabled() { ->with('foo', 'bar') ->will($this->returnValue($user)); - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->defaultProvider, $this->config); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); $userSession->login('foo', 'bar'); } @@ -284,7 +282,7 @@ public function testLoginInvalidPassword() { ->with('foo', 'bar') ->will($this->returnValue(false)); - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->defaultProvider, $this->config); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); $userSession->login('foo', 'bar'); } @@ -304,7 +302,7 @@ public function testLoginNonExisting() { ->with('foo', 'bar') ->will($this->returnValue(false)); - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->defaultProvider, $this->config); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); $userSession->login('foo', 'bar'); } @@ -316,11 +314,11 @@ public function testLogClientInNoTokenPasswordWith2fa() { /** @var \OC\User\Session $userSession */ $userSession = $this->getMockBuilder('\OC\User\Session') - ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->defaultProvider, $this->config]) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) ->setMethods(['login']) ->getMock(); - $this->defaultProvider->expects($this->once()) + $this->tokenProvider->expects($this->once()) ->method('getToken') ->with('doe') ->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException())); @@ -341,11 +339,11 @@ public function testLogClientInNoTokenPasswordNo2fa() { /** @var \OC\User\Session $userSession */ $userSession = $this->getMockBuilder('\OC\User\Session') - ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->defaultProvider, $this->config]) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) ->setMethods(['login', 'isTwoFactorEnforced']) ->getMock(); - $this->defaultProvider->expects($this->once()) + $this->tokenProvider->expects($this->once()) ->method('getToken') ->with('doe') ->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException())); @@ -413,7 +411,7 @@ public function testRememberLoginValidToken() { //override, otherwise tests will fail because of setcookie() array('setMagicInCookie'), //there are passed as parameters to the constructor - array($manager, $session, $this->timeFactory, $this->defaultProvider, $this->config)); + array($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config)); $granted = $userSession->loginWithCookie('foo', $token); @@ -458,7 +456,7 @@ public function testRememberLoginInvalidToken() { $token = 'goodToken'; \OC::$server->getConfig()->setUserValue('foo', 'login_token', $token, time()); - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->defaultProvider, $this->config); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); $granted = $userSession->loginWithCookie('foo', 'badToken'); $this->assertSame($granted, false); @@ -501,7 +499,7 @@ public function testRememberLoginInvalidUser() { $token = 'goodToken'; \OC::$server->getConfig()->setUserValue('foo', 'login_token', $token, time()); - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->defaultProvider, $this->config); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); $granted = $userSession->loginWithCookie('foo', $token); $this->assertSame($granted, false); @@ -526,7 +524,7 @@ public function testActiveUserAfterSetSession() { $session = new Memory(''); $session->set('user_id', 'foo'); $userSession = $this->getMockBuilder('\OC\User\Session') - ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->defaultProvider, $this->config]) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) ->setMethods([ 'validateSession' ]) @@ -542,6 +540,119 @@ public function testActiveUserAfterSetSession() { $this->assertEquals($users['bar'], $userSession->getUser()); } + public function testCreateSessionToken() { + $manager = $this->getMockBuilder('\OC\User\Manager') + ->disableOriginalConstructor() + ->getMock(); + $session = $this->getMock('\OCP\ISession'); + $token = $this->getMock('\OC\Authentication\Token\IToken'); + $user = $this->getMock('\OCP\IUser'); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); + + $random = $this->getMock('\OCP\Security\ISecureRandom'); + $config = $this->getMock('\OCP\IConfig'); + $csrf = $this->getMockBuilder('\OC\Security\CSRF\CsrfTokenManager') + ->disableOriginalConstructor() + ->getMock(); + $request = new \OC\AppFramework\Http\Request([ + 'server' => [ + 'HTTP_USER_AGENT' => 'Firefox', + ] + ], $random, $config, $csrf); + + $uid = 'user123'; + $loginName = 'User123'; + $password = 'passme'; + $sessionId = 'abcxyz'; + + $manager->expects($this->once()) + ->method('get') + ->with($uid) + ->will($this->returnValue($user)); + $session->expects($this->once()) + ->method('getId') + ->will($this->returnValue($sessionId)); + $this->tokenProvider->expects($this->once()) + ->method('getToken') + ->with($password) + ->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException())); + + $this->tokenProvider->expects($this->once()) + ->method('generateToken') + ->with($sessionId, $uid, $loginName, $password, 'Firefox'); + + $this->assertTrue($userSession->createSessionToken($request, $uid, $loginName, $password)); + } + + public function testCreateSessionTokenWithTokenPassword() { + $manager = $this->getMockBuilder('\OC\User\Manager') + ->disableOriginalConstructor() + ->getMock(); + $session = $this->getMock('\OCP\ISession'); + $token = $this->getMock('\OC\Authentication\Token\IToken'); + $user = $this->getMock('\OCP\IUser'); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); + + $random = $this->getMock('\OCP\Security\ISecureRandom'); + $config = $this->getMock('\OCP\IConfig'); + $csrf = $this->getMockBuilder('\OC\Security\CSRF\CsrfTokenManager') + ->disableOriginalConstructor() + ->getMock(); + $request = new \OC\AppFramework\Http\Request([ + 'server' => [ + 'HTTP_USER_AGENT' => 'Firefox', + ] + ], $random, $config, $csrf); + + $uid = 'user123'; + $loginName = 'User123'; + $password = 'iamatoken'; + $realPassword = 'passme'; + $sessionId = 'abcxyz'; + + $manager->expects($this->once()) + ->method('get') + ->with($uid) + ->will($this->returnValue($user)); + $session->expects($this->once()) + ->method('getId') + ->will($this->returnValue($sessionId)); + $this->tokenProvider->expects($this->once()) + ->method('getToken') + ->with($password) + ->will($this->returnValue($token)); + $this->tokenProvider->expects($this->once()) + ->method('getPassword') + ->with($token, $password) + ->will($this->returnValue($realPassword)); + + $this->tokenProvider->expects($this->once()) + ->method('generateToken') + ->with($sessionId, $uid, $loginName, $realPassword, 'Firefox'); + + $this->assertTrue($userSession->createSessionToken($request, $uid, $loginName, $password)); + } + + public function testCreateSessionTokenWithNonExistentUser() { + $manager = $this->getMockBuilder('\OC\User\Manager') + ->disableOriginalConstructor() + ->getMock(); + $session = $this->getMock('\OCP\ISession'); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); + $request = $this->getMock('\OCP\IRequest'); + + $uid = 'user123'; + $loginName = 'User123'; + $password = 'passme'; + + $manager->expects($this->once()) + ->method('get') + ->with($uid) + ->will($this->returnValue(null)); + + $this->assertFalse($userSession->createSessionToken($request, $uid, $loginName, $password)); + } + public function testTryTokenLoginWithDisabledUser() { $manager = $this->getMockBuilder('\OC\User\Manager') ->disableOriginalConstructor() @@ -549,14 +660,14 @@ public function testTryTokenLoginWithDisabledUser() { $session = new Memory(''); $token = $this->getMock('\OC\Authentication\Token\IToken'); $user = $this->getMock('\OCP\IUser'); - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->defaultProvider, $this->config); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); $request = $this->getMock('\OCP\IRequest'); $request->expects($this->once()) ->method('getHeader') ->with('Authorization') ->will($this->returnValue('token xxxxx')); - $this->defaultProvider->expects($this->once()) + $this->tokenProvider->expects($this->once()) ->method('validateToken') ->with('xxxxx') ->will($this->returnValue($token));