Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
m---------3rdparty0
-rw-r--r--apps/dav/lib/Connector/Sabre/FilesPlugin.php21
-rw-r--r--apps/federatedfilesharing/lib/Controller/RequestHandlerController.php18
-rw-r--r--apps/federatedfilesharing/tests/Controller/RequestHandlerControllerTest.php10
-rw-r--r--apps/settings/lib/Controller/AuthSettingsController.php8
-rw-r--r--apps/settings/lib/Controller/CheckSetupController.php35
-rw-r--r--apps/settings/tests/Controller/CheckSetupControllerTest.php12
-rw-r--r--apps/user_ldap/lib/Wizard.php2
-rw-r--r--core/Controller/ClientFlowLoginController.php17
-rw-r--r--core/js/setupchecks.js18
-rw-r--r--core/js/tests/specs/setupchecksSpec.js154
-rw-r--r--core/templates/loginflow/authpicker.php5
-rw-r--r--core/templates/loginflow/grant.php15
-rw-r--r--lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php3
-rw-r--r--lib/private/Authentication/Token/IProvider.php2
-rw-r--r--lib/private/Authentication/Token/Manager.php6
-rw-r--r--lib/private/Authentication/Token/PublicKeyTokenProvider.php4
-rw-r--r--lib/private/Preview/Bundled.php2
-rw-r--r--tests/Core/Controller/ClientFlowLoginControllerTest.php2
-rw-r--r--tests/lib/Authentication/Token/ManagerTest.php31
-rw-r--r--tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php83
-rw-r--r--tests/lib/Authentication/TwoFactorAuth/ManagerTest.php48
22 files changed, 383 insertions, 113 deletions
diff --git a/3rdparty b/3rdparty
-Subproject 747d4ceb41b707622a960d79ac2694b2919b7c2
+Subproject 05ca07b2981cbe64e58825aeb9362d88c8fc5ac
diff --git a/apps/dav/lib/Connector/Sabre/FilesPlugin.php b/apps/dav/lib/Connector/Sabre/FilesPlugin.php
index 156507e4467..0fc7ac4af4e 100644
--- a/apps/dav/lib/Connector/Sabre/FilesPlugin.php
+++ b/apps/dav/lib/Connector/Sabre/FilesPlugin.php
@@ -76,6 +76,8 @@ class FilesPlugin extends ServerPlugin {
public const UPLOAD_TIME_PROPERTYNAME = '{http://nextcloud.org/ns}upload_time';
public const CREATION_TIME_PROPERTYNAME = '{http://nextcloud.org/ns}creation_time';
public const SHARE_NOTE = '{http://nextcloud.org/ns}note';
+ public const SUBFOLDER_COUNT_PROPERTYNAME = '{http://nextcloud.org/ns}contained-folder-count';
+ public const SUBFILE_COUNT_PROPERTYNAME = '{http://nextcloud.org/ns}contained-file-count';
/**
* Reference to main server object
@@ -429,7 +431,7 @@ class FilesPlugin extends ServerPlugin {
});
}
- if ($node instanceof \OCA\DAV\Connector\Sabre\Directory) {
+ if ($node instanceof Directory) {
$propFind->handle(self::SIZE_PROPERTYNAME, function () use ($node) {
return $node->getSize();
});
@@ -437,6 +439,23 @@ class FilesPlugin extends ServerPlugin {
$propFind->handle(self::IS_ENCRYPTED_PROPERTYNAME, function () use ($node) {
return $node->getFileInfo()->isEncrypted() ? '1' : '0';
});
+
+ $requestProperties = $propFind->getRequestedProperties();
+ if (in_array(self::SUBFILE_COUNT_PROPERTYNAME, $requestProperties, true)
+ || in_array(self::SUBFOLDER_COUNT_PROPERTYNAME, $requestProperties, true)) {
+ $nbFiles = 0;
+ $nbFolders = 0;
+ foreach ($node->getChildren() as $child) {
+ if ($child instanceof File) {
+ $nbFiles++;
+ } elseif ($child instanceof Directory) {
+ $nbFolders++;
+ }
+ }
+
+ $propFind->handle(self::SUBFILE_COUNT_PROPERTYNAME, $nbFiles);
+ $propFind->handle(self::SUBFOLDER_COUNT_PROPERTYNAME, $nbFolders);
+ }
}
}
diff --git a/apps/federatedfilesharing/lib/Controller/RequestHandlerController.php b/apps/federatedfilesharing/lib/Controller/RequestHandlerController.php
index f19e251fc7a..fe0c7a11ab7 100644
--- a/apps/federatedfilesharing/lib/Controller/RequestHandlerController.php
+++ b/apps/federatedfilesharing/lib/Controller/RequestHandlerController.php
@@ -36,6 +36,7 @@ use OCP\AppFramework\OCS\OCSException;
use OCP\AppFramework\OCS\OCSForbiddenException;
use OCP\AppFramework\OCSController;
use OCP\Constants;
+use OCP\EventDispatcher\IEventDispatcher;
use OCP\Federation\Exceptions\ProviderCouldNotAddShareException;
use OCP\Federation\Exceptions\ProviderDoesNotExistsException;
use OCP\Federation\ICloudFederationFactory;
@@ -44,6 +45,7 @@ use OCP\Federation\ICloudIdManager;
use OCP\IDBConnection;
use OCP\IRequest;
use OCP\IUserManager;
+use OCP\Log\Audit\CriticalActionPerformedEvent;
use OCP\Share;
use OCP\Share\Exceptions\ShareNotFound;
use Psr\Log\LoggerInterface;
@@ -83,6 +85,9 @@ class RequestHandlerController extends OCSController {
/** @var ICloudFederationProviderManager */
private $cloudFederationProviderManager;
+ /** @var IEventDispatcher */
+ private $eventDispatcher;
+
public function __construct(string $appName,
IRequest $request,
FederatedShareProvider $federatedShareProvider,
@@ -94,7 +99,8 @@ class RequestHandlerController extends OCSController {
ICloudIdManager $cloudIdManager,
LoggerInterface $logger,
ICloudFederationFactory $cloudFederationFactory,
- ICloudFederationProviderManager $cloudFederationProviderManager
+ ICloudFederationProviderManager $cloudFederationProviderManager,
+ IEventDispatcher $eventDispatcher
) {
parent::__construct($appName, $request);
@@ -108,6 +114,7 @@ class RequestHandlerController extends OCSController {
$this->logger = $logger;
$this->cloudFederationFactory = $cloudFederationFactory;
$this->cloudFederationProviderManager = $cloudFederationProviderManager;
+ $this->eventDispatcher = $eventDispatcher;
}
/**
@@ -156,6 +163,11 @@ class RequestHandlerController extends OCSController {
try {
$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
$provider->shareReceived($share);
+ if ($sharedByFederatedId === $ownerFederatedId) {
+ $this->eventDispatcher->dispatchTyped(new CriticalActionPerformedEvent('A new federated share with "%s" was created by "%s" and shared with "%s"', [$name, $ownerFederatedId, $shareWith]));
+ } else {
+ $this->eventDispatcher->dispatchTyped(new CriticalActionPerformedEvent('A new federated share with "%s" was shared by "%s" (resource owner is: "%s") and shared with "%s"', [$name, $sharedByFederatedId, $ownerFederatedId, $shareWith]));
+ }
} catch (ProviderDoesNotExistsException $e) {
throw new OCSException('Server does not support federated cloud sharing', 503);
} catch (ProviderCouldNotAddShareException $e) {
@@ -243,6 +255,7 @@ class RequestHandlerController extends OCSController {
try {
$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
$provider->notificationReceived('SHARE_ACCEPTED', $id, $notification);
+ $this->eventDispatcher->dispatchTyped(new CriticalActionPerformedEvent('Federated share with id "%s" was accepted', [$id]));
} catch (ProviderDoesNotExistsException $e) {
throw new OCSException('Server does not support federated cloud sharing', 503);
} catch (ShareNotFound $e) {
@@ -275,6 +288,7 @@ class RequestHandlerController extends OCSController {
try {
$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
$provider->notificationReceived('SHARE_DECLINED', $id, $notification);
+ $this->eventDispatcher->dispatchTyped(new CriticalActionPerformedEvent('Federated share with id "%s" was declined', [$id]));
} catch (ProviderDoesNotExistsException $e) {
throw new OCSException('Server does not support federated cloud sharing', 503);
} catch (ShareNotFound $e) {
@@ -307,6 +321,7 @@ class RequestHandlerController extends OCSController {
$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
$notification = ['sharedSecret' => $token];
$provider->notificationReceived('SHARE_UNSHARED', $id, $notification);
+ $this->eventDispatcher->dispatchTyped(new CriticalActionPerformedEvent('Federated share with id "%s" was unshared', [$id]));
} catch (\Exception $e) {
$this->logger->debug('processing unshare notification failed: ' . $e->getMessage(), ['exception' => $e]);
}
@@ -381,6 +396,7 @@ class RequestHandlerController extends OCSController {
$ocmPermissions = $this->ncPermissions2ocmPermissions((int)$ncPermissions);
$notification = ['sharedSecret' => $token, 'permission' => $ocmPermissions];
$provider->notificationReceived('RESHARE_CHANGE_PERMISSION', $id, $notification);
+ $this->eventDispatcher->dispatchTyped(new CriticalActionPerformedEvent('Federated share with id "%s" has updated permissions "%s"', [$id, implode(', ', $ocmPermissions)]));
} catch (\Exception $e) {
$this->logger->debug($e->getMessage(), ['exception' => $e]);
throw new OCSBadRequestException();
diff --git a/apps/federatedfilesharing/tests/Controller/RequestHandlerControllerTest.php b/apps/federatedfilesharing/tests/Controller/RequestHandlerControllerTest.php
index 0cb91fac1ae..77f7fde70fa 100644
--- a/apps/federatedfilesharing/tests/Controller/RequestHandlerControllerTest.php
+++ b/apps/federatedfilesharing/tests/Controller/RequestHandlerControllerTest.php
@@ -34,6 +34,7 @@ use OCP\Federation\ICloudFederationProvider;
use OCP\Federation\ICloudFederationProviderManager;
use OCP\Federation\ICloudFederationShare;
use OCP\Federation\ICloudIdManager;
+use OCP\EventDispatcher\IEventDispatcher;
use OCP\IDBConnection;
use OCP\IRequest;
use OCP\IUserManager;
@@ -100,6 +101,9 @@ class RequestHandlerControllerTest extends \Test\TestCase {
/** @var ICloudFederationShare|\PHPUnit\Framework\MockObject\MockObject */
private $cloudFederationShare;
+ /** @var IEventDispatcher|\PHPUnit\Framework\MockObject\MockObject */
+ private $eventDispatcher;
+
protected function setUp(): void {
$this->share = $this->getMockBuilder(IShare::class)->getMock();
$this->federatedShareProvider = $this->getMockBuilder('OCA\FederatedFileSharing\FederatedShareProvider')
@@ -124,7 +128,8 @@ class RequestHandlerControllerTest extends \Test\TestCase {
$this->cloudFederationProviderManager = $this->createMock(ICloudFederationProviderManager::class);
$this->cloudFederationProvider = $this->createMock(ICloudFederationProvider::class);
$this->cloudFederationShare = $this->createMock(ICloudFederationShare::class);
-
+ $this->eventDispatcher = $this->createMock(IEventDispatcher::class);
+ $this->eventDispatcher->expects($this->any())->method('dispatchTyped');
$this->logger = $this->createMock(LoggerInterface::class);
@@ -140,7 +145,8 @@ class RequestHandlerControllerTest extends \Test\TestCase {
$this->cloudIdManager,
$this->logger,
$this->cloudFederationFactory,
- $this->cloudFederationProviderManager
+ $this->cloudFederationProviderManager,
+ $this->eventDispatcher
);
}
diff --git a/apps/settings/lib/Controller/AuthSettingsController.php b/apps/settings/lib/Controller/AuthSettingsController.php
index 3255fcce56e..38db7be1e91 100644
--- a/apps/settings/lib/Controller/AuthSettingsController.php
+++ b/apps/settings/lib/Controller/AuthSettingsController.php
@@ -145,6 +145,10 @@ class AuthSettingsController extends Controller {
return $this->getServiceNotAvailableResponse();
}
+ if (mb_strlen($name) > 128) {
+ $name = mb_substr($name, 0, 120) . '…';
+ }
+
$token = $this->generateRandomDeviceToken();
$deviceToken = $this->tokenProvider->generateToken($token, $this->uid, $loginName, $password, $name, IToken::PERMANENT_TOKEN);
$tokenData = $deviceToken->jsonSerialize();
@@ -241,6 +245,10 @@ class AuthSettingsController extends Controller {
$this->publishActivity($scope['filesystem'] ? Provider::APP_TOKEN_FILESYSTEM_GRANTED : Provider::APP_TOKEN_FILESYSTEM_REVOKED, $token->getId(), ['name' => $currentName]);
}
+ if (mb_strlen($name) > 128) {
+ $name = mb_substr($name, 0, 120) . '…';
+ }
+
if ($token instanceof INamedToken && $name !== $currentName) {
$token->setName($name);
$this->publishActivity(Provider::APP_TOKEN_RENAMED, $token->getId(), ['name' => $currentName, 'newName' => $name]);
diff --git a/apps/settings/lib/Controller/CheckSetupController.php b/apps/settings/lib/Controller/CheckSetupController.php
index 4b825c2622f..b9f176f97c5 100644
--- a/apps/settings/lib/Controller/CheckSetupController.php
+++ b/apps/settings/lib/Controller/CheckSetupController.php
@@ -713,20 +713,6 @@ Raw output
$recommendedPHPModules[] = 'intl';
}
- if (!extension_loaded('bcmath')) {
- $recommendedPHPModules[] = 'bcmath';
- }
-
- if (!extension_loaded('gmp')) {
- $recommendedPHPModules[] = 'gmp';
- }
-
- if ($this->config->getAppValue('theming', 'enabled', 'no') === 'yes') {
- if (!extension_loaded('imagick')) {
- $recommendedPHPModules[] = 'imagick';
- }
- }
-
if (!defined('PASSWORD_ARGON2I') && PHP_VERSION_ID >= 70400) {
// Installing php-sodium on >=php7.4 will provide PASSWORD_ARGON2I
// on previous version argon2 wasn't part of the "standard" extension
@@ -738,6 +724,25 @@ Raw output
return $recommendedPHPModules;
}
+ protected function isImagickEnabled(): bool {
+ if ($this->config->getAppValue('theming', 'enabled', 'no') === 'yes') {
+ if (!extension_loaded('imagick')) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ protected function areWebauthnExtensionsEnabled(): bool {
+ if (!extension_loaded('bcmath')) {
+ return false;
+ }
+ if (!extension_loaded('gmp')) {
+ return false;
+ }
+ return true;
+ }
+
protected function isMysqlUsedWithoutUTF8MB4(): bool {
return ($this->config->getSystemValue('dbtype', 'sqlite') === 'mysql') && ($this->config->getSystemValue('mysql.utf8mb4', false) === false);
}
@@ -869,6 +874,8 @@ Raw output
'databaseConversionDocumentation' => $this->urlGenerator->linkToDocs('admin-db-conversion'),
'isMemoryLimitSufficient' => $this->memoryInfo->isMemoryLimitSufficient(),
'appDirsWithDifferentOwner' => $this->getAppDirsWithDifferentOwner(),
+ 'isImagickEnabled' => $this->isImagickEnabled(),
+ 'areWebauthnExtensionsEnabled' => $this->areWebauthnExtensionsEnabled(),
'recommendedPHPModules' => $this->hasRecommendedPHPModules(),
'pendingBigIntConversionColumns' => $this->hasBigIntConversionPendingColumns(),
'isMysqlUsedWithoutUTF8MB4' => $this->isMysqlUsedWithoutUTF8MB4(),
diff --git a/apps/settings/tests/Controller/CheckSetupControllerTest.php b/apps/settings/tests/Controller/CheckSetupControllerTest.php
index 4349994570b..8a1e062f58b 100644
--- a/apps/settings/tests/Controller/CheckSetupControllerTest.php
+++ b/apps/settings/tests/Controller/CheckSetupControllerTest.php
@@ -550,6 +550,16 @@ class CheckSetupControllerTest extends TestCase {
$this->checkSetupController
->expects($this->once())
+ ->method('isImagickEnabled')
+ ->willReturn(false);
+
+ $this->checkSetupController
+ ->expects($this->once())
+ ->method('areWebauthnExtensionsEnabled')
+ ->willReturn(false);
+
+ $this->checkSetupController
+ ->expects($this->once())
->method('hasRecommendedPHPModules')
->willReturn([]);
@@ -642,6 +652,8 @@ class CheckSetupControllerTest extends TestCase {
'missingColumns' => [],
'isMemoryLimitSufficient' => true,
'appDirsWithDifferentOwner' => [],
+ 'isImagickEnabled' => false,
+ 'areWebauthnExtensionsEnabled' => false,
'recommendedPHPModules' => [],
'pendingBigIntConversionColumns' => [],
'isMysqlUsedWithoutUTF8MB4' => false,
diff --git a/apps/user_ldap/lib/Wizard.php b/apps/user_ldap/lib/Wizard.php
index 9b037b47134..6e0d6f80f8d 100644
--- a/apps/user_ldap/lib/Wizard.php
+++ b/apps/user_ldap/lib/Wizard.php
@@ -1331,7 +1331,7 @@ class Wizard extends LDAPUtility {
$this->configuration->ldapAgentName,
$this->configuration->ldapAgentPassword);
if ($lo === true) {
- $this->$cr = $cr;
+ $this->cr = $cr;
return $cr;
}
diff --git a/core/Controller/ClientFlowLoginController.php b/core/Controller/ClientFlowLoginController.php
index 2ba26deb0e7..d67a065a14e 100644
--- a/core/Controller/ClientFlowLoginController.php
+++ b/core/Controller/ClientFlowLoginController.php
@@ -162,12 +162,8 @@ class ClientFlowLoginController extends Controller {
* @PublicPage
* @NoCSRFRequired
* @UseSession
- *
- * @param string $clientIdentifier
- *
- * @return StandaloneTemplateResponse
*/
- public function showAuthPickerPage($clientIdentifier = '') {
+ public function showAuthPickerPage(string $clientIdentifier = '', int $direct = 0): StandaloneTemplateResponse {
$clientName = $this->getClientName();
$client = null;
if ($clientIdentifier !== '') {
@@ -218,6 +214,7 @@ class ClientFlowLoginController extends Controller {
'stateToken' => $stateToken,
'serverHost' => $this->getServerPath(),
'oauthState' => $this->session->get('oauth.state'),
+ 'direct' => $direct,
],
'guest'
);
@@ -231,13 +228,10 @@ class ClientFlowLoginController extends Controller {
* @NoCSRFRequired
* @NoSameSiteCookieRequired
* @UseSession
- *
- * @param string $stateToken
- * @param string $clientIdentifier
- * @return StandaloneTemplateResponse
*/
- public function grantPage($stateToken = '',
- $clientIdentifier = '') {
+ public function grantPage(string $stateToken = '',
+ string $clientIdentifier = '',
+ int $direct = 0): StandaloneTemplateResponse {
if (!$this->isValidToken($stateToken)) {
return $this->stateTokenForbiddenResponse();
}
@@ -267,6 +261,7 @@ class ClientFlowLoginController extends Controller {
'stateToken' => $stateToken,
'serverHost' => $this->getServerPath(),
'oauthState' => $this->session->get('oauth.state'),
+ 'direct' => $direct,
],
'guest'
);
diff --git a/core/js/setupchecks.js b/core/js/setupchecks.js
index fa67528de5d..266f35a9552 100644
--- a/core/js/setupchecks.js
+++ b/core/js/setupchecks.js
@@ -423,6 +423,24 @@
type: OC.SetupChecks.MESSAGE_TYPE_INFO
})
}
+ if (!data.isImagickEnabled) {
+ messages.push({
+ msg: t(
+ 'core',
+ 'The PHP module "imagick" is not enabled although the theming app is. For favicon generation to work correctly, you need to install and enable this module.'
+ ),
+ type: OC.SetupChecks.MESSAGE_TYPE_INFO
+ })
+ }
+ if (!data.areWebauthnExtensionsEnabled) {
+ messages.push({
+ msg: t(
+ 'core',
+ 'The PHP modules "gmp" and/or "bcmath" are not enabled. If you use WebAuthn passwordless authentication, these modules are required.'
+ ),
+ type: OC.SetupChecks.MESSAGE_TYPE_INFO
+ })
+ }
if (data.imageMagickLacksSVGSupport) {
messages.push({
msg: t(
diff --git a/core/js/tests/specs/setupchecksSpec.js b/core/js/tests/specs/setupchecksSpec.js
index 5975c875c3b..5914a6f2449 100644
--- a/core/js/tests/specs/setupchecksSpec.js
+++ b/core/js/tests/specs/setupchecksSpec.js
@@ -249,6 +249,8 @@ describe('OC.SetupChecks tests', function() {
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
@@ -307,6 +309,8 @@ describe('OC.SetupChecks tests', function() {
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
@@ -366,6 +370,8 @@ describe('OC.SetupChecks tests', function() {
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
@@ -423,6 +429,8 @@ describe('OC.SetupChecks tests', function() {
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
@@ -478,6 +486,8 @@ describe('OC.SetupChecks tests', function() {
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
@@ -533,6 +543,8 @@ describe('OC.SetupChecks tests', function() {
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
@@ -590,6 +602,8 @@ describe('OC.SetupChecks tests', function() {
appDirsWithDifferentOwner: [
'/some/path'
],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
@@ -645,6 +659,8 @@ describe('OC.SetupChecks tests', function() {
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
@@ -700,6 +716,8 @@ describe('OC.SetupChecks tests', function() {
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
@@ -755,6 +773,8 @@ describe('OC.SetupChecks tests', function() {
},
isMemoryLimitSufficient: false,
appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
@@ -831,6 +851,8 @@ describe('OC.SetupChecks tests', function() {
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
@@ -886,6 +908,8 @@ describe('OC.SetupChecks tests', function() {
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
@@ -941,6 +965,8 @@ describe('OC.SetupChecks tests', function() {
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
@@ -996,6 +1022,8 @@ describe('OC.SetupChecks tests', function() {
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: true,
@@ -1055,6 +1083,8 @@ describe('OC.SetupChecks tests', function() {
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
@@ -1111,6 +1141,8 @@ describe('OC.SetupChecks tests', function() {
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
@@ -1164,6 +1196,8 @@ describe('OC.SetupChecks tests', function() {
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
@@ -1183,6 +1217,122 @@ describe('OC.SetupChecks tests', function() {
});
});
+
+ it('should return an error if imagick is not enabled', function(done) {
+ var async = OC.SetupChecks.checkSetup();
+
+ suite.server.requests[0].respond(
+ 200,
+ {
+ 'Content-Type': 'application/json',
+ },
+ JSON.stringify({
+ hasFileinfoInstalled: true,
+ isGetenvServerWorking: true,
+ isReadOnlyConfig: false,
+ wasEmailTestSuccessful: true,
+ hasWorkingFileLocking: true,
+ hasValidTransactionIsolationLevel: true,
+ suggestedOverwriteCliURL: '',
+ isRandomnessSecure: true,
+ securityDocs: 'https://docs.nextcloud.com/myDocs.html',
+ isFairUseOfFreePushService: true,
+ serverHasInternetConnectionProblems: false,
+ isMemcacheConfigured: true,
+ forwardedForHeadersWorking: true,
+ isCorrectMemcachedPHPModuleInstalled: true,
+ hasPassedCodeIntegrityCheck: true,
+ OpcacheSetupRecommendations: [],
+ isSettimelimitAvailable: true,
+ hasFreeTypeSupport: true,
+ missingIndexes: [],
+ missingPrimaryKeys: [],
+ missingColumns: [],
+ cronErrors: [],
+ cronInfo: {
+ diffInSeconds: 0
+ },
+ isMemoryLimitSufficient: true,
+ appDirsWithDifferentOwner: [],
+ isImagickEnabled: false,
+ areWebauthnExtensionsEnabled: true,
+ recommendedPHPModules: [],
+ pendingBigIntConversionColumns: [],
+ isMysqlUsedWithoutUTF8MB4: false,
+ isDefaultPhoneRegionSet: true,
+ isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
+ reverseProxyGeneratedURL: 'https://server',
+ temporaryDirectoryWritable: true,
+ })
+ );
+
+ async.done(function( data, s, x ){
+ expect(data).toEqual([{
+ msg: 'The PHP module "imagick" is not enabled although the theming app is. For favicon generation to work correctly, you need to install and enable this module.',
+ type: OC.SetupChecks.MESSAGE_TYPE_INFO
+ }]);
+ done();
+ });
+ });
+
+
+ it('should return an error if gmp or bcmath are not enabled', function(done) {
+ var async = OC.SetupChecks.checkSetup();
+
+ suite.server.requests[0].respond(
+ 200,
+ {
+ 'Content-Type': 'application/json',
+ },
+ JSON.stringify({
+ hasFileinfoInstalled: true,
+ isGetenvServerWorking: true,
+ isReadOnlyConfig: false,
+ wasEmailTestSuccessful: true,
+ hasWorkingFileLocking: true,
+ hasValidTransactionIsolationLevel: true,
+ suggestedOverwriteCliURL: '',
+ isRandomnessSecure: true,
+ securityDocs: 'https://docs.nextcloud.com/myDocs.html',
+ isFairUseOfFreePushService: true,
+ serverHasInternetConnectionProblems: false,
+ isMemcacheConfigured: true,
+ forwardedForHeadersWorking: true,
+ isCorrectMemcachedPHPModuleInstalled: true,
+ hasPassedCodeIntegrityCheck: true,
+ OpcacheSetupRecommendations: [],
+ isSettimelimitAvailable: true,
+ hasFreeTypeSupport: true,
+ missingIndexes: [],
+ missingPrimaryKeys: [],
+ missingColumns: [],
+ cronErrors: [],
+ cronInfo: {
+ diffInSeconds: 0
+ },
+ isMemoryLimitSufficient: true,
+ appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: false,
+ recommendedPHPModules: [],
+ pendingBigIntConversionColumns: [],
+ isMysqlUsedWithoutUTF8MB4: false,
+ isDefaultPhoneRegionSet: true,
+ isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
+ reverseProxyGeneratedURL: 'https://server',
+ temporaryDirectoryWritable: true,
+ })
+ );
+
+ async.done(function( data, s, x ){
+ expect(data).toEqual([{
+ msg: 'The PHP modules "gmp" and/or "bcmath" are not enabled. If you use WebAuthn passwordless authentication, these modules are required.',
+ type: OC.SetupChecks.MESSAGE_TYPE_INFO
+ }]);
+ done();
+ });
+ });
+
it('should return an info if there is no default phone region', function(done) {
var async = OC.SetupChecks.checkSetup();
@@ -1219,6 +1369,8 @@ describe('OC.SetupChecks tests', function() {
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
@@ -1274,6 +1426,8 @@ describe('OC.SetupChecks tests', function() {
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
+ isImagickEnabled: true,
+ areWebauthnExtensionsEnabled: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
diff --git a/core/templates/loginflow/authpicker.php b/core/templates/loginflow/authpicker.php
index 02b4b9cc003..4c4c8fd6d53 100644
--- a/core/templates/loginflow/authpicker.php
+++ b/core/templates/loginflow/authpicker.php
@@ -46,7 +46,7 @@ $urlGenerator = $_['urlGenerator'];
<br/>
<p id="redirect-link">
- <a href="<?php p($urlGenerator->linkToRoute('core.ClientFlowLogin.grantPage', ['stateToken' => $_['stateToken'], 'clientIdentifier' => $_['clientIdentifier'], 'oauthState' => $_['oauthState']])) ?>">
+ <a href="<?php p($urlGenerator->linkToRoute('core.ClientFlowLogin.grantPage', ['stateToken' => $_['stateToken'], 'clientIdentifier' => $_['clientIdentifier'], 'oauthState' => $_['oauthState'], 'direct' => $_['direct']])) ?>">
<input type="submit" class="login primary icon-confirm-white" value="<?php p($l->t('Log in')) ?>">
</a>
</p>
@@ -62,6 +62,9 @@ $urlGenerator = $_['urlGenerator'];
</p>
<input type="hidden" name="stateToken" value="<?php p($_['stateToken']) ?>" />
<input type="hidden" name="requesttoken" value="<?php p($_['requesttoken']) ?>">
+ <?php if ($_['direct'] !== 0) { ?>
+ <input type="hidden" name="direct" value="<?php p($_['direct']) ?>">
+ <?php } ?>
<input id="submit-app-token-login" type="submit" class="login primary icon-confirm-white" value="<?php p($l->t('Grant access')) ?>">
</form>
</div>
diff --git a/core/templates/loginflow/grant.php b/core/templates/loginflow/grant.php
index 0f1b9235a89..c537c47ea64 100644
--- a/core/templates/loginflow/grant.php
+++ b/core/templates/loginflow/grant.php
@@ -39,14 +39,17 @@ $urlGenerator = $_['urlGenerator'];
<br/>
<p id="redirect-link">
- <form method="POST" action="<?php p($urlGenerator->linkToRouteAbsolute('core.ClientFlowLogin.generateAppPassword')) ?>">
- <input type="hidden" name="clientIdentifier" value="<?php p($_['clientIdentifier']) ?>" />
- <input type="hidden" name="requesttoken" value="<?php p($_['requesttoken']) ?>" />
- <input type="hidden" name="stateToken" value="<?php p($_['stateToken']) ?>" />
- <input type="hidden" name="oauthState" value="<?php p($_['oauthState']) ?>" />
+ <form method="POST" action="<?php p($urlGenerator->linkToRouteAbsolute('core.ClientFlowLogin.generateAppPassword')) ?>">
+ <input type="hidden" name="clientIdentifier" value="<?php p($_['clientIdentifier']) ?>" />
+ <input type="hidden" name="requesttoken" value="<?php p($_['requesttoken']) ?>" />
+ <input type="hidden" name="stateToken" value="<?php p($_['stateToken']) ?>" />
+ <input type="hidden" name="oauthState" value="<?php p($_['oauthState']) ?>" />
+ <?php if (p($_['direct'])) { ?>
+ <input type="hidden" name="direct" value="1" />
+ <?php } ?>
<div id="submit-wrapper">
<input type="submit" class="login primary icon-confirm-white" title="" value="<?php p($l->t('Grant access')); ?>" />
- </div>
+ </div>
</form>
</p>
</div>
diff --git a/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php b/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php
index d162bb54108..041535e54bd 100644
--- a/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php
+++ b/lib/private/AppFramework/Middleware/Security/SecurityMiddleware.php
@@ -260,6 +260,9 @@ class SecurityMiddleware extends Middleware {
if (isset($this->request->server['REQUEST_URI'])) {
$params['redirect_url'] = $this->request->server['REQUEST_URI'];
}
+ if ($this->request->getParam('direct')) {
+ $params['direct'] = 1;
+ }
$url = $this->urlGenerator->linkToRoute('core.login.showLoginForm', $params);
$response = new RedirectResponse($url);
} else {
diff --git a/lib/private/Authentication/Token/IProvider.php b/lib/private/Authentication/Token/IProvider.php
index e604ac715c2..0a145bfd7e6 100644
--- a/lib/private/Authentication/Token/IProvider.php
+++ b/lib/private/Authentication/Token/IProvider.php
@@ -44,7 +44,7 @@ interface IProvider {
* @param string $uid
* @param string $loginName
* @param string|null $password
- * @param string $name
+ * @param string $name Name will be trimmed to 120 chars when longer
* @param int $type token type
* @param int $remember whether the session token should be used for remember-me
* @return IToken
diff --git a/lib/private/Authentication/Token/Manager.php b/lib/private/Authentication/Token/Manager.php
index b718ce73ea4..cadc5f408e4 100644
--- a/lib/private/Authentication/Token/Manager.php
+++ b/lib/private/Authentication/Token/Manager.php
@@ -53,7 +53,7 @@ class Manager implements IProvider {
* @param string $uid
* @param string $loginName
* @param string|null $password
- * @param string $name
+ * @param string $name Name will be trimmed to 120 chars when longer
* @param int $type token type
* @param int $remember whether the session token should be used for remember-me
* @return IToken
@@ -65,6 +65,10 @@ class Manager implements IProvider {
string $name,
int $type = IToken::TEMPORARY_TOKEN,
int $remember = IToken::DO_NOT_REMEMBER): IToken {
+ if (mb_strlen($name) > 128) {
+ $name = mb_substr($name, 0, 120) . '…';
+ }
+
try {
return $this->publicKeyTokenProvider->generateToken(
$token,
diff --git a/lib/private/Authentication/Token/PublicKeyTokenProvider.php b/lib/private/Authentication/Token/PublicKeyTokenProvider.php
index b7c8a8e9c24..ddf477b3463 100644
--- a/lib/private/Authentication/Token/PublicKeyTokenProvider.php
+++ b/lib/private/Authentication/Token/PublicKeyTokenProvider.php
@@ -84,6 +84,10 @@ class PublicKeyTokenProvider implements IProvider {
string $name,
int $type = IToken::TEMPORARY_TOKEN,
int $remember = IToken::DO_NOT_REMEMBER): IToken {
+ if (mb_strlen($name) > 128) {
+ throw new InvalidTokenException('The given name is too long');
+ }
+
$dbToken = $this->newToken($token, $uid, $loginName, $password, $name, $type, $remember);
$this->mapper->insert($dbToken);
diff --git a/lib/private/Preview/Bundled.php b/lib/private/Preview/Bundled.php
index f026d3259f5..6b5a8aa2d12 100644
--- a/lib/private/Preview/Bundled.php
+++ b/lib/private/Preview/Bundled.php
@@ -46,7 +46,7 @@ abstract class Bundled extends ProviderV2 {
$image->fixOrientation();
return $image;
- } catch (\Exception $e) {
+ } catch (\Throwable $e) {
return null;
}
}
diff --git a/tests/Core/Controller/ClientFlowLoginControllerTest.php b/tests/Core/Controller/ClientFlowLoginControllerTest.php
index 51a17743c93..c60c89407bd 100644
--- a/tests/Core/Controller/ClientFlowLoginControllerTest.php
+++ b/tests/Core/Controller/ClientFlowLoginControllerTest.php
@@ -183,6 +183,7 @@ class ClientFlowLoginControllerTest extends TestCase {
'stateToken' => 'StateToken',
'serverHost' => 'https://example.com',
'oauthState' => 'OauthStateToken',
+ 'direct' => 0,
],
'guest'
);
@@ -246,6 +247,7 @@ class ClientFlowLoginControllerTest extends TestCase {
'stateToken' => 'StateToken',
'serverHost' => 'https://example.com',
'oauthState' => 'OauthStateToken',
+ 'direct' => 0,
],
'guest'
);
diff --git a/tests/lib/Authentication/Token/ManagerTest.php b/tests/lib/Authentication/Token/ManagerTest.php
index fb92b3e5018..ee2b3cdc768 100644
--- a/tests/lib/Authentication/Token/ManagerTest.php
+++ b/tests/lib/Authentication/Token/ManagerTest.php
@@ -127,6 +127,37 @@ class ManagerTest extends TestCase {
$this->assertSame($token, $actual);
}
+ public function testGenerateTokenTooLongName() {
+ $token = $this->createMock(IToken::class);
+ $token->method('getName')
+ ->willReturn(str_repeat('a', 120) . '…');
+
+
+ $this->publicKeyTokenProvider->expects($this->once())
+ ->method('generateToken')
+ ->with(
+ 'token',
+ 'uid',
+ 'loginName',
+ 'password',
+ str_repeat('a', 120) . '…',
+ IToken::TEMPORARY_TOKEN,
+ IToken::REMEMBER
+ )->willReturn($token);
+
+ $actual = $this->manager->generateToken(
+ 'token',
+ 'uid',
+ 'loginName',
+ 'password',
+ str_repeat('a', 200),
+ IToken::TEMPORARY_TOKEN,
+ IToken::REMEMBER
+ );
+
+ $this->assertSame(121, mb_strlen($actual->getName()));
+ }
+
public function tokenData(): array {
return [
[new DefaultToken()],
diff --git a/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php b/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php
index 486660f17c6..767e7897c58 100644
--- a/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php
+++ b/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php
@@ -82,10 +82,7 @@ class PublicKeyTokenProviderTest extends TestCase {
$uid = 'user';
$user = 'User';
$password = 'passme';
- $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
+ $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
$type = IToken::PERMANENT_TOKEN;
$actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
@@ -98,6 +95,22 @@ class PublicKeyTokenProviderTest extends TestCase {
$this->assertSame($password, $this->tokenProvider->getPassword($actual, $token));
}
+ public function testGenerateTokenInvalidName() {
+ $this->expectException(\OC\Authentication\Exceptions\InvalidTokenException::class);
+
+ $token = 'token';
+ $uid = 'user';
+ $user = 'User';
+ $password = 'passme';
+ $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
+ . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
+ . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
+ . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
+ $type = IToken::PERMANENT_TOKEN;
+
+ $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
+ }
+
public function testUpdateToken() {
$tk = new PublicKeyToken();
$this->mapper->expects($this->once())
@@ -139,10 +152,7 @@ class PublicKeyTokenProviderTest extends TestCase {
$uid = 'user';
$user = 'User';
$password = 'passme';
- $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
+ $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
$type = IToken::PERMANENT_TOKEN;
$actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
@@ -169,10 +179,7 @@ class PublicKeyTokenProviderTest extends TestCase {
$uid = 'user';
$user = 'User';
$password = 'passme';
- $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
+ $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
$type = IToken::PERMANENT_TOKEN;
$actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
@@ -185,10 +192,7 @@ class PublicKeyTokenProviderTest extends TestCase {
$uid = 'user';
$user = 'User';
$password = 'passme';
- $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
+ $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
$type = IToken::PERMANENT_TOKEN;
$actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
@@ -248,12 +252,12 @@ class PublicKeyTokenProviderTest extends TestCase {
['session_lifetime', $defaultSessionLifetime, 150],
['remember_login_cookie_lifetime', $defaultRememberMeLifetime, 300],
]);
- $this->mapper->expects($this->at(0))
- ->method('invalidateOld')
- ->with($this->time - 150);
- $this->mapper->expects($this->at(1))
+ $this->mapper->expects($this->exactly(2))
->method('invalidateOld')
- ->with($this->time - 300);
+ ->withConsecutive(
+ [$this->time - 150],
+ [$this->time - 300]
+ );
$this->tokenProvider->invalidateOldTokens();
}
@@ -263,21 +267,18 @@ class PublicKeyTokenProviderTest extends TestCase {
$uid = 'user';
$user = 'User';
$password = null;
- $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
+ $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
$type = IToken::PERMANENT_TOKEN;
$oldToken = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
$this->mapper
- ->expects($this->at(0))
+ ->expects($this->once())
->method('getToken')
->with(hash('sha512', 'oldId' . '1f4h9s'))
->willReturn($oldToken);
$this->mapper
- ->expects($this->at(1))
+ ->expects($this->once())
->method('insert')
->with($this->callback(function (PublicKeyToken $token) use ($user, $uid, $name) {
return $token->getUID() === $uid &&
@@ -288,7 +289,7 @@ class PublicKeyTokenProviderTest extends TestCase {
$token->getPassword() === null;
}));
$this->mapper
- ->expects($this->at(2))
+ ->expects($this->once())
->method('delete')
->with($this->callback(function ($token) use ($oldToken) {
return $token === $oldToken;
@@ -302,21 +303,18 @@ class PublicKeyTokenProviderTest extends TestCase {
$uid = 'user';
$user = 'User';
$password = 'password';
- $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
+ $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
$type = IToken::PERMANENT_TOKEN;
$oldToken = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
$this->mapper
- ->expects($this->at(0))
+ ->expects($this->once())
->method('getToken')
->with(hash('sha512', 'oldId' . '1f4h9s'))
->willReturn($oldToken);
$this->mapper
- ->expects($this->at(1))
+ ->expects($this->once())
->method('insert')
->with($this->callback(function (PublicKeyToken $token) use ($user, $uid, $name) {
return $token->getUID() === $uid &&
@@ -328,7 +326,7 @@ class PublicKeyTokenProviderTest extends TestCase {
$this->tokenProvider->getPassword($token, 'newId') === 'password';
}));
$this->mapper
- ->expects($this->at(2))
+ ->expects($this->once())
->method('delete')
->with($this->callback(function ($token) use ($oldToken) {
return $token === $oldToken;
@@ -372,10 +370,7 @@ class PublicKeyTokenProviderTest extends TestCase {
$uid = 'user';
$user = 'User';
$password = 'passme';
- $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
+ $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
$type = IToken::PERMANENT_TOKEN;
$actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
@@ -440,10 +435,7 @@ class PublicKeyTokenProviderTest extends TestCase {
$uid = 'user';
$user = 'User';
$password = 'password';
- $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
+ $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
$type = IToken::PERMANENT_TOKEN;
$actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
@@ -458,10 +450,7 @@ class PublicKeyTokenProviderTest extends TestCase {
$uid = 'user';
$user = 'User';
$password = null;
- $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'
- . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
+ $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
$type = IToken::PERMANENT_TOKEN;
$actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER);
diff --git a/tests/lib/Authentication/TwoFactorAuth/ManagerTest.php b/tests/lib/Authentication/TwoFactorAuth/ManagerTest.php
index fc921b8016b..ae6fadc790c 100644
--- a/tests/lib/Authentication/TwoFactorAuth/ManagerTest.php
+++ b/tests/lib/Authentication/TwoFactorAuth/ManagerTest.php
@@ -376,13 +376,13 @@ class ManagerTest extends TestCase {
->method('get')
->with('two_factor_remember_login')
->willReturn(false);
- $this->session->expects($this->at(1))
+ $this->session->expects($this->exactly(2))
->method('remove')
- ->with('two_factor_auth_uid');
- $this->session->expects($this->at(2))
- ->method('remove')
- ->with('two_factor_remember_login');
- $this->session->expects($this->at(3))
+ ->withConsecutive(
+ ['two_factor_auth_uid'],
+ ['two_factor_remember_login']
+ );
+ $this->session->expects($this->once())
->method('set')
->with(Manager::SESSION_UID_DONE, 'jos');
$this->session->method('getId')
@@ -494,17 +494,13 @@ class ManagerTest extends TestCase {
public function testNeedsSecondFactor() {
$user = $this->createMock(IUser::class);
- $this->session->expects($this->at(0))
- ->method('exists')
- ->with('app_password')
- ->willReturn(false);
- $this->session->expects($this->at(1))
+ $this->session->expects($this->exactly(3))
->method('exists')
- ->with('two_factor_auth_uid')
- ->willReturn(false);
- $this->session->expects($this->at(2))
- ->method('exists')
- ->with(Manager::SESSION_UID_DONE)
+ ->withConsecutive(
+ ['app_password'],
+ ['two_factor_auth_uid'],
+ [Manager::SESSION_UID_DONE],
+ )
->willReturn(false);
$this->session->method('getId')
@@ -575,12 +571,12 @@ class ManagerTest extends TestCase {
$this->user->method('getUID')
->willReturn('ferdinand');
- $this->session->expects($this->at(0))
- ->method('set')
- ->with('two_factor_auth_uid', 'ferdinand');
- $this->session->expects($this->at(1))
+ $this->session->expects($this->exactly(2))
->method('set')
- ->with('two_factor_remember_login', true);
+ ->withConsecutive(
+ ['two_factor_auth_uid', 'ferdinand'],
+ ['two_factor_remember_login', true]
+ );
$this->session->method('getId')
->willReturn('mysessionid');
@@ -605,12 +601,12 @@ class ManagerTest extends TestCase {
$this->user->method('getUID')
->willReturn('ferdinand');
- $this->session->expects($this->at(0))
- ->method('set')
- ->with('two_factor_auth_uid', 'ferdinand');
- $this->session->expects($this->at(1))
+ $this->session->expects($this->exactly(2))
->method('set')
- ->with('two_factor_remember_login', false);
+ ->withConsecutive(
+ ['two_factor_auth_uid', 'ferdinand'],
+ ['two_factor_remember_login', false]
+ );
$this->session->method('getId')
->willReturn('mysessionid');