From 52d8a948b17accf40286af6ae5d194768530cf6d Mon Sep 17 00:00:00 2001 From: Thomas Kuschan Date: Wed, 5 Jun 2024 12:29:21 +0200 Subject: [PATCH 1/7] Feature: login with session cookie --- src/CTConfig.php | 12 ++++++++++ src/Models/Common/Auth/AuthRequest.php | 6 +++++ src/Models/Common/Auth/AuthRequestBuilder.php | 22 +++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/src/CTConfig.php b/src/CTConfig.php index 14c97bd4..215e1e9f 100644 --- a/src/CTConfig.php +++ b/src/CTConfig.php @@ -10,6 +10,7 @@ use CTApi\Models\Groups\Person\PersonRequest; use CTApi\Utils\CTUtil; use GuzzleHttp\Cookie\CookieJar; +use GuzzleHttp\Cookie\SetCookie; use GuzzleHttp\HandlerStack; use GuzzleHttp\TransferStats; use Kevinrob\GuzzleCache\CacheMiddleware; @@ -133,6 +134,11 @@ public static function authWithLoginToken(string $loginToken): Auth return AuthRequest::authWithLoginToken($loginToken); } + public static function authWithSessionCookie(string $cookieString): Auth + { + return AuthRequest::authWithSessionCookie($cookieString); + } + /** * Auth via undocumented ajax-API. Use authWithLoginToken() instead. * @param string $userId @@ -156,6 +162,12 @@ public static function getSessionCookie(): ?array return end($cookieData); } + public static function getSessionCookieString(): ?string + { + $cookieData = self::getSessionCookie(); + return $cookieData ? (string) (new SetCookie($cookieData)) : null; + } + /** * @see CTConfig::authWithLoginToken() * @deprecated Will be removed in further version. Use CTConfig::authWithLoginToken() instead. diff --git a/src/Models/Common/Auth/AuthRequest.php b/src/Models/Common/Auth/AuthRequest.php index 665e59bb..36858b6d 100644 --- a/src/Models/Common/Auth/AuthRequest.php +++ b/src/Models/Common/Auth/AuthRequest.php @@ -18,6 +18,12 @@ public static function authWithLoginToken(string $loginToken): Auth return (new AuthRequestBuilder())->authWithLoginToken($loginToken); } + public static function authWithSessionCookie(string $sessionCookie): Auth + { + CTLog::getLog()->info('AuthRequest: Authenticate CTConfig with Session'); + return (new AuthRequestBuilder())->authWithSessionCookie($sessionCookie); + } + public static function authWithUserIdAndLoginToken(string $userId, string $loginToken): bool { CTLog::getLog()->info('AuthRequest: Authenticate CTConfig with UserId and Token.'); diff --git a/src/Models/Common/Auth/AuthRequestBuilder.php b/src/Models/Common/Auth/AuthRequestBuilder.php index d904fe7a..d91529e2 100644 --- a/src/Models/Common/Auth/AuthRequestBuilder.php +++ b/src/Models/Common/Auth/AuthRequestBuilder.php @@ -71,6 +71,28 @@ public function authWithLoginToken(string $loginToken): Auth throw new CTAuthException("Authentication was not successfull."); } + public function authWithSessionCookie(string $cookieString): Auth + { + $client = CTClient::getClient(); + + try { + $response = $client->get('/api/whoami', [ + 'headers' => [ + 'cookie' => $cookieString, + ] + ]); + $data = CTResponseUtil::dataAsArray($response); + $person = Person::createModelFromData($data); + } catch (CTRequestException $exception) { + throw new CTAuthException("Authentication was not successfull: " . $exception->getMessage(), $exception->getCode(), $exception); + } + + if ($person->getId() != null && $person->getId() != -1 && $person->getId() != "-1") { + return new Auth($person->getId(), false); + } + throw new CTAuthException("Authentication was not successfull."); + } + public function authWithUserIdAndLoginToken(string $userId, string $loginToken): bool { $client = CTClient::getClient(); From 4723a67c8cb3fa6d6b9aee41913efc852c35b138 Mon Sep 17 00:00:00 2001 From: Thomas Kuschan Date: Wed, 5 Jun 2024 13:50:19 +0200 Subject: [PATCH 2/7] Add test for auth with session cookie --- .../Integration/Requests/AuthRequestTest.php | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/Integration/Requests/AuthRequestTest.php b/tests/Integration/Requests/AuthRequestTest.php index 768655b4..bfb7e863 100644 --- a/tests/Integration/Requests/AuthRequestTest.php +++ b/tests/Integration/Requests/AuthRequestTest.php @@ -28,6 +28,28 @@ public function testAuthWithEmailAndPassword(): void $this->assertNotNull($cookie); } + public function testAuthWithSessionCookie(): void + { + $auth = IntegrationTestData::get()->authenticateUser(); + $userId = $auth->userId; + $this->assertNotNull($userId); + + $cookie = CTConfig::getSessionCookieString(); + $this->assertNotNull($cookie); + + // clear config + CTConfig::clearConfig(); + CTConfig::setApiUrl(IntegrationTestData::get()->getApiUrl()); + + // verify that we are not logged in now + $this->assertFalse(CTConfig::validateAuthentication()); + + // login using the cookie + $auth = CTConfig::authWithSessionCookie($cookie); + $this->assertSame($userId, $auth->userId); + $this->assertTrue(CTConfig::validateAuthentication()); + } + public function testAuthWithUserIdAndLoginToken() { $auth = IntegrationTestData::get()->authenticateUser(); From 1d990eca3092a04c02e8863177565c64b63730c6 Mon Sep 17 00:00:00 2001 From: DumbergerL Date: Mon, 29 Jul 2024 15:54:15 +0200 Subject: [PATCH 3/7] add pr #207 to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7ceef9c..a46e2d86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Get GroupTypeRoles ([PR197](https://github.com/5pm-HDH/churchtools-api/pull/197)) - PHP coding standard ([PR193](https://github.com/5pm-HDH/churchtools-api/pull/193)) - Added new property 'postsEnabled' to the group type model ([PR204](https://github.com/5pm-HDH/churchtools-api/pull/204)) +- Login with Session Cookie ([PR207](https://github.com/5pm-HDH/churchtools-api/pull/207)) ### Changed From 216de528bb8d535408f523fa90992612673a5925 Mon Sep 17 00:00:00 2001 From: Thomas Kuschan Date: Tue, 30 Jul 2024 17:20:48 +0200 Subject: [PATCH 4/7] Fix integration test for session cookie auth --- tests/Integration/Requests/AuthRequestTest.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/Integration/Requests/AuthRequestTest.php b/tests/Integration/Requests/AuthRequestTest.php index bfb7e863..6c5c2cdd 100644 --- a/tests/Integration/Requests/AuthRequestTest.php +++ b/tests/Integration/Requests/AuthRequestTest.php @@ -42,12 +42,20 @@ public function testAuthWithSessionCookie(): void CTConfig::setApiUrl(IntegrationTestData::get()->getApiUrl()); // verify that we are not logged in now - $this->assertFalse(CTConfig::validateAuthentication()); + $this->assertNull(CTConfig::getSessionCookieString()); // login using the cookie $auth = CTConfig::authWithSessionCookie($cookie); - $this->assertSame($userId, $auth->userId); + $this->assertEquals($userId, $auth->userId); $this->assertTrue(CTConfig::validateAuthentication()); + + // confirm we are still logged in + $authValid = CTConfig::validateAuthentication(); + $this->assertTrue($authValid); + + // confirm the session cookie was updated (but not replaced) + $updatedCookie = CTConfig::getSessionCookieString(); + $this->assertSame(explode(';', $cookie, 2)[0], explode(';', $updatedCookie, 2)[0]); } public function testAuthWithUserIdAndLoginToken() From 7aeb9f7d1ee02285926818ee78855b8e0eff2373 Mon Sep 17 00:00:00 2001 From: Thomas Kuschan Date: Tue, 30 Jul 2024 17:21:37 +0200 Subject: [PATCH 5/7] Make session cookie auth more robust --- src/CTConfig.php | 2 +- src/Models/Common/Auth/AuthRequestBuilder.php | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/CTConfig.php b/src/CTConfig.php index 215e1e9f..23260718 100644 --- a/src/CTConfig.php +++ b/src/CTConfig.php @@ -159,7 +159,7 @@ public static function getSessionCookie(): ?array if (empty($cookieData)) { return null; } - return end($cookieData); + return array_pop($cookieData); } public static function getSessionCookieString(): ?string diff --git a/src/Models/Common/Auth/AuthRequestBuilder.php b/src/Models/Common/Auth/AuthRequestBuilder.php index d91529e2..00d02f9c 100644 --- a/src/Models/Common/Auth/AuthRequestBuilder.php +++ b/src/Models/Common/Auth/AuthRequestBuilder.php @@ -7,6 +7,7 @@ use CTApi\Exceptions\CTRequestException; use CTApi\Models\Groups\Person\Person; use CTApi\Utils\CTResponseUtil; +use GuzzleHttp\Cookie\SetCookie; class AuthRequestBuilder { @@ -74,12 +75,13 @@ public function authWithLoginToken(string $loginToken): Auth public function authWithSessionCookie(string $cookieString): Auth { $client = CTClient::getClient(); + $cookie = SetCookie::fromString($cookieString); try { $response = $client->get('/api/whoami', [ 'headers' => [ - 'cookie' => $cookieString, - ] + 'cookie' => $cookie->getName() . '=' . $cookie->getValue(), + ], ]); $data = CTResponseUtil::dataAsArray($response); $person = Person::createModelFromData($data); From ec796c12431ff00d2912889f89bc0dced7012b8e Mon Sep 17 00:00:00 2001 From: Thomas Kuschan Date: Tue, 30 Jul 2024 17:32:59 +0200 Subject: [PATCH 6/7] Minor improvements to session cookie test --- tests/Integration/Requests/AuthRequestTest.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/Integration/Requests/AuthRequestTest.php b/tests/Integration/Requests/AuthRequestTest.php index 6c5c2cdd..8780c517 100644 --- a/tests/Integration/Requests/AuthRequestTest.php +++ b/tests/Integration/Requests/AuthRequestTest.php @@ -38,11 +38,14 @@ public function testAuthWithSessionCookie(): void $this->assertNotNull($cookie); // clear config - CTConfig::clearConfig(); - CTConfig::setApiUrl(IntegrationTestData::get()->getApiUrl()); + CTConfig::clearCookies(); // verify that we are not logged in now - $this->assertNull(CTConfig::getSessionCookieString()); + CTConfig::setApiUrl(IntegrationTestData::get()->getApiUrl()); + $this->assertFalse(CTConfig::validateAuthentication()); + + // clear again + CTConfig::clearCookies(); // login using the cookie $auth = CTConfig::authWithSessionCookie($cookie); @@ -55,6 +58,7 @@ public function testAuthWithSessionCookie(): void // confirm the session cookie was updated (but not replaced) $updatedCookie = CTConfig::getSessionCookieString(); + $this->assertNotNull($updatedCookie); $this->assertSame(explode(';', $cookie, 2)[0], explode(';', $updatedCookie, 2)[0]); } From e3642b137f6832780105214ea76f8ec8843de66c Mon Sep 17 00:00:00 2001 From: Thomas Kuschan Date: Tue, 30 Jul 2024 17:38:58 +0200 Subject: [PATCH 7/7] Add matching method for setting the session cookie in config --- src/CTConfig.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/CTConfig.php b/src/CTConfig.php index 23260718..63e075ea 100644 --- a/src/CTConfig.php +++ b/src/CTConfig.php @@ -168,6 +168,12 @@ public static function getSessionCookieString(): ?string return $cookieData ? (string) (new SetCookie($cookieData)) : null; } + public static function setSessionCookie(string $cookieString): void + { + $cookie = SetCookie::fromString($cookieString); + self::getConfig()->cookieJar->setCookie($cookie); + } + /** * @see CTConfig::authWithLoginToken() * @deprecated Will be removed in further version. Use CTConfig::authWithLoginToken() instead.