summaryrefslogtreecommitdiffstats
path: root/tests/lib/AppFramework/Middleware
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 19:28:57 +0200
commit02313013ad9094ea0ec52f30672971ab03f4ec15 (patch)
treecdc545575e7851ddd10743b61ad35feed74f9d70 /tests/lib/AppFramework/Middleware
parent5bad00d37f45df9da122f558ca3482fdd0006a3e (diff)
downloadnextcloud-server-02313013ad9094ea0ec52f30672971ab03f4ec15.tar.gz
nextcloud-server-02313013ad9094ea0ec52f30672971ab03f4ec15.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/lib/AppFramework/Middleware')
-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..252f50e8147 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 OC\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);
+ }
}