summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorArthur Schiwon <blizzz@arthur-schiwon.de>2024-03-01 18:37:47 +0100
committerArthur Schiwon <blizzz@arthur-schiwon.de>2024-06-12 11:14:25 +0200
commit86a496d58980cc3dd578368c9d8e5f951ec01f17 (patch)
tree843939c3547e4cd9e848a7be4c89547fa8277f34 /tests
parent415be1f4d2a94efc1844be0d2ac7f2a1cceee9b6 (diff)
downloadnextcloud-server-86a496d58980cc3dd578368c9d8e5f951ec01f17.tar.gz
nextcloud-server-86a496d58980cc3dd578368c9d8e5f951ec01f17.zip
fix(Session): avoid password confirmation on SSO
SSO backends like SAML and OIDC tried a trick to suppress password confirmations as they are not possible by design. At least for SAML it was not reliable when existing user backends where used as user repositories. Now we are setting a special scope with the token, and also make sure that the scope is taken over when tokens are regenerated. Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
Diffstat (limited to 'tests')
-rw-r--r--tests/lib/AppFramework/Middleware/Security/Mock/PasswordConfirmationMiddlewareController.php4
-rw-r--r--tests/lib/AppFramework/Middleware/Security/PasswordConfirmationMiddlewareTest.php60
2 files changed, 63 insertions, 1 deletions
diff --git a/tests/lib/AppFramework/Middleware/Security/Mock/PasswordConfirmationMiddlewareController.php b/tests/lib/AppFramework/Middleware/Security/Mock/PasswordConfirmationMiddlewareController.php
index 5b83575f711..941906d8bb6 100644
--- a/tests/lib/AppFramework/Middleware/Security/Mock/PasswordConfirmationMiddlewareController.php
+++ b/tests/lib/AppFramework/Middleware/Security/Mock/PasswordConfirmationMiddlewareController.php
@@ -46,4 +46,8 @@ class PasswordConfirmationMiddlewareController extends \OCP\AppFramework\Control
#[PasswordConfirmationRequired]
public function testAttribute() {
}
+
+ #[PasswordConfirmationRequired]
+ public function testSSO() {
+ }
}
diff --git a/tests/lib/AppFramework/Middleware/Security/PasswordConfirmationMiddlewareTest.php b/tests/lib/AppFramework/Middleware/Security/PasswordConfirmationMiddlewareTest.php
index 3752259c61b..ed51837acbf 100644
--- a/tests/lib/AppFramework/Middleware/Security/PasswordConfirmationMiddlewareTest.php
+++ b/tests/lib/AppFramework/Middleware/Security/PasswordConfirmationMiddlewareTest.php
@@ -26,7 +26,9 @@ namespace Test\AppFramework\Middleware\Security;
use OC\AppFramework\Middleware\Security\Exceptions\NotConfirmedException;
use OC\AppFramework\Middleware\Security\PasswordConfirmationMiddleware;
use OC\AppFramework\Utility\ControllerMethodReflector;
+use OC\Authentication\Token\IProvider;
use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\Authentication\Token\IToken;
use OCP\IRequest;
use OCP\ISession;
use OCP\IUser;
@@ -49,6 +51,7 @@ class PasswordConfirmationMiddlewareTest extends TestCase {
private $controller;
/** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */
private $timeFactory;
+ private IProvider|\PHPUnit\Framework\MockObject\MockObject $tokenProvider;
protected function setUp(): void {
$this->reflector = new ControllerMethodReflector();
@@ -56,6 +59,7 @@ class PasswordConfirmationMiddlewareTest extends TestCase {
$this->userSession = $this->createMock(IUserSession::class);
$this->user = $this->createMock(IUser::class);
$this->timeFactory = $this->createMock(ITimeFactory::class);
+ $this->tokenProvider = $this->createMock(IProvider::class);
$this->controller = new PasswordConfirmationMiddlewareController(
'test',
$this->createMock(IRequest::class)
@@ -65,7 +69,8 @@ class PasswordConfirmationMiddlewareTest extends TestCase {
$this->reflector,
$this->session,
$this->userSession,
- $this->timeFactory
+ $this->timeFactory,
+ $this->tokenProvider,
);
}
@@ -107,6 +112,13 @@ class PasswordConfirmationMiddlewareTest extends TestCase {
$this->timeFactory->method('getTime')
->willReturn($currentTime);
+ $token = $this->createMock(IToken::class);
+ $token->method('getScopeAsArray')
+ ->willReturn([]);
+ $this->tokenProvider->expects($this->once())
+ ->method('getToken')
+ ->willReturn($token);
+
$thrown = false;
try {
$this->middleware->beforeController($this->controller, __FUNCTION__);
@@ -135,6 +147,13 @@ class PasswordConfirmationMiddlewareTest extends TestCase {
$this->timeFactory->method('getTime')
->willReturn($currentTime);
+ $token = $this->createMock(IToken::class);
+ $token->method('getScopeAsArray')
+ ->willReturn([]);
+ $this->tokenProvider->expects($this->once())
+ ->method('getToken')
+ ->willReturn($token);
+
$thrown = false;
try {
$this->middleware->beforeController($this->controller, __FUNCTION__);
@@ -145,6 +164,8 @@ class PasswordConfirmationMiddlewareTest extends TestCase {
$this->assertSame($exception, $thrown);
}
+
+
public function dataProvider() {
return [
['foo', 2000, 4000, true],
@@ -155,4 +176,41 @@ class PasswordConfirmationMiddlewareTest extends TestCase {
['foo', 2000, 3816, true],
];
}
+
+ public function testSSO() {
+ static $sessionId = 'mySession1d';
+
+ $this->reflector->reflect($this->controller, __FUNCTION__);
+
+ $this->user->method('getBackendClassName')
+ ->willReturn('fictional_backend');
+ $this->userSession->method('getUser')
+ ->willReturn($this->user);
+
+ $this->session->method('get')
+ ->with('last-password-confirm')
+ ->willReturn(0);
+ $this->session->method('getId')
+ ->willReturn($sessionId);
+
+ $this->timeFactory->method('getTime')
+ ->willReturn(9876);
+
+ $token = $this->createMock(IToken::class);
+ $token->method('getScopeAsArray')
+ ->willReturn(['sso-based-login' => true]);
+ $this->tokenProvider->expects($this->once())
+ ->method('getToken')
+ ->with($sessionId)
+ ->willReturn($token);
+
+ $thrown = false;
+ try {
+ $this->middleware->beforeController($this->controller, __FUNCTION__);
+ } catch (NotConfirmedException) {
+ $thrown = true;
+ }
+
+ $this->assertSame(false, $thrown);
+ }
}