Skip to content

Commit 221fb5b

Browse files
committed
5124: Refactored settings
1 parent b57261b commit 221fb5b

File tree

11 files changed

+421
-218
lines changed

11 files changed

+421
-218
lines changed

web/profiles/custom/os2loop/modules/os2loop_cura_login/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ drush --uri='http://nginx:8080' os2loop-cura-login:get-login-url [email protected]
4545

4646
``` php
4747
# settings.local.php
48-
$config['os2loop_cura_login.settings']['log_level'] = \Drupal\Core\Logger\RfcLogLevel::DEBUG;
48+
$config['os2loop_cura_login.settings']['general']['log_level'] = \Drupal\Core\Logger\RfcLogLevel::DEBUG;
4949
```
5050

5151
Run

web/profiles/custom/os2loop/modules/os2loop_cura_login/os2loop_cura_login.routing.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ os2loop_cura_login.start_get_jwt:
1717
_role: "anonymous"
1818

1919
os2loop_cura_login.authenticate:
20-
path: "/os2loop-cura-login/authenticate"
20+
path: "/os2loop-cura-login/authenticate/{jwt}"
2121
defaults:
2222
_title: "Authenticate with Cura login"
2323
_controller: '\Drupal\os2loop_cura_login\Controller\Os2loopCuraLoginController::authenticate'

web/profiles/custom/os2loop/modules/os2loop_cura_login/os2loop_cura_login.services.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,9 @@ services:
77
arguments: ["os2loop_cura_login"]
88

99
Drupal\os2loop_cura_login\Settings:
10+
11+
Drupal\os2loop_cura_login\CuraHelper:
12+
13+
Drupal\os2loop_cura_login\IdPHelper:
14+
15+
Drupal\os2loop_cura_login\UserHelper:

web/profiles/custom/os2loop/modules/os2loop_cura_login/src/Controller/Os2loopCuraLoginController.php

Lines changed: 36 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
use Drupal\Core\Controller\ControllerBase;
99
use Drupal\Core\Logger\RfcLogLevel;
1010
use Drupal\Core\Url;
11+
use Drupal\os2loop_cura_login\CuraHelper;
12+
use Drupal\os2loop_cura_login\IdPHelper;
1113
use Drupal\os2loop_cura_login\Settings;
14+
use Drupal\os2loop_cura_login\UserHelper;
1215
use Drupal\user\UserInterface;
13-
use Drupal\user\UserStorageInterface;
1416
use Firebase\JWT\JWT;
15-
use Firebase\JWT\Key;
1617
use Psr\Log\LoggerInterface;
1718
use Psr\Log\LoggerTrait;
1819
use Psr\Log\LogLevel;
@@ -30,21 +31,18 @@ final class Os2loopCuraLoginController extends ControllerBase {
3031

3132
private const JWT_KEY = 'os2loop_cura_login';
3233

33-
/**
34-
* The user storage.
35-
*/
36-
private readonly UserStorageInterface $userStorage;
37-
3834
/**
3935
* Constructor.
4036
*/
4137
public function __construct(
38+
private readonly CuraHelper $curaHelper,
39+
private readonly IdPHelper $idPHelper,
40+
private readonly UserHelper $userHelper,
4241
private readonly Settings $settings,
4342
private readonly TimeInterface $time,
4443
#[Autowire(service: 'logger.channel.os2loop_cura_login')]
4544
private readonly LoggerInterface $logger,
4645
) {
47-
$this->userStorage = $this->entityTypeManager()->getStorage('user');
4846
}
4947

5048
/**
@@ -68,7 +66,7 @@ public function start(Request $request, ?string $jwt): Response {
6866
]);
6967

7068
if (empty($jwt)) {
71-
$name = $this->settings->getPayloadName();
69+
$name = $this->settings->getCuraSettings()->getPayloadName();
7270
$jwt = Request::METHOD_POST === $request->getMethod()
7371
? $request->request->getString($name)
7472
: $request->query->getString($name);
@@ -84,21 +82,14 @@ public function start(Request $request, ?string $jwt): Response {
8482
throw new BadRequestHttpException('Missing or empty JWT');
8583
}
8684

87-
$payload = $this->decodeJwt($jwt);
88-
89-
$this->debug('@debug', [
90-
'@debug' => json_encode([
91-
'payload' => $payload,
92-
]),
93-
]);
85+
[$payload, $username] = $this->curaHelper->decodeJwt($jwt);
9486

95-
$username = $payload['username'] ?? $payload['brugerId'] ?? NULL;
9687
if (empty($username)) {
9788
throw new BadRequestHttpException('Missing username');
9889
}
9990

10091
// Check that we can get userinfo.
101-
$userinfo = $this->fetchUserinfo($username);
92+
$userinfo = $this->idPHelper->fetchUserInfo($username);
10293

10394
$this->debug('@debug', [
10495
'@debug' => json_encode([
@@ -111,7 +102,7 @@ public function start(Request $request, ?string $jwt): Response {
111102
throw new BadRequestHttpException();
112103
}
113104

114-
$user = $this->ensureUser($username, $userinfo);
105+
$user = $this->userHelper->ensureUser($username, $userinfo);
115106

116107
$this->debug('@debug', [
117108
'@debug' => json_encode([
@@ -134,44 +125,22 @@ public function start(Request $request, ?string $jwt): Response {
134125
}
135126
}
136127

137-
/**
138-
* Create authenticate response.
139-
*/
140-
private function createAuthenticateResponse(UserInterface $user): Response {
141-
// https://github.com/firebase/php-jwt?tab=readme-ov-file#example
142-
$payload = [
143-
// Issued at.
144-
'iat' => $this->time->getRequestTime(),
145-
// Expire af 60 seconds.
146-
'exp' => $this->time->getRequestTime() + 60,
147-
'username' => $user->getAccountName(),
148-
];
149-
$jwt = $this->encodeJwt($payload);
150-
151-
$url = Url::fromRoute('os2loop_cura_login.authenticate', [
152-
'jwt' => $jwt,
153-
])->setAbsolute()->toString(TRUE)->getGeneratedUrl();
154-
155-
return new Response($url);
156-
}
157-
158128
/**
159129
* Authenticate action.
160130
*/
161-
public function authenticate(Request $request): Response {
131+
public function authenticate(Request $request, string $jwt): Response {
162132
try {
163-
$jwt = $request->get('jwt');
164133
if (empty($jwt)) {
165134
throw new BadRequestHttpException();
166135
}
167136

168-
$payload = $this->decodeJwt($jwt);
137+
[$payload, $_] = $this->curaHelper->decodeJwt($jwt);
169138
$username = $payload['username'] ?? NULL;
170139
if (empty($username)) {
171140
throw new BadRequestHttpException();
172141
}
173142

174-
$user = $this->loadUser($username);
143+
$user = $this->userHelper->loadUser($username);
175144
if (empty($user)) {
176145
// Don't disclose whether or not the user exists.
177146
throw new BadRequestHttpException();
@@ -185,6 +154,27 @@ public function authenticate(Request $request): Response {
185154
}
186155
}
187156

157+
/**
158+
* Create authenticate response.
159+
*/
160+
private function createAuthenticateResponse(UserInterface $user): Response {
161+
// https://github.com/firebase/php-jwt?tab=readme-ov-file#example
162+
$payload = [
163+
// Issued at.
164+
'iat' => $this->time->getRequestTime(),
165+
// Expire af 60 seconds.
166+
'exp' => $this->time->getRequestTime() + 60,
167+
'username' => $user->getAccountName(),
168+
];
169+
$jwt = $this->encodeJwt($payload);
170+
171+
$url = Url::fromRoute('os2loop_cura_login.authenticate', [
172+
'jwt' => $jwt,
173+
])->setAbsolute()->toString(TRUE)->getGeneratedUrl();
174+
175+
return new Response($url);
176+
}
177+
188178
/**
189179
* Authenticate user.
190180
*/
@@ -200,99 +190,9 @@ private function authenticateUser($user): Response {
200190
* Encode JWT.
201191
*/
202192
private function encodeJwt(array $payload): string {
203-
$secret = $this->settings->getSigningSecret();
204-
// @todo Get rid of the double base64 encoding.
205-
$secret = base64_decode($secret);
206-
207-
return JWT::encode($payload, $secret, $this->settings->getSigningAlgorithm());
208-
}
209-
210-
/**
211-
* Decode JWT.
212-
*/
213-
private function decodeJwt(string $jwt): array {
214-
$secret = $this->settings->getSigningSecret();
215-
// @todo Get rid of the double base64 encoding.
216-
$secret = base64_decode($secret);
217-
218-
$originalLeeway = JWT::$leeway;
219-
$leeway = $this->settings->getJwtLeeway();
220-
if ($leeway > 0) {
221-
JWT::$leeway = $leeway;
222-
}
223-
$payload = (array) JWT::decode($jwt, new Key($secret, $this->settings->getSigningAlgorithm()));
224-
JWT::$leeway = $originalLeeway;
225-
226-
return $payload;
227-
}
228-
229-
/**
230-
* Get user info from userinfo endpoint.
231-
*/
232-
private function fetchUserinfo(string $username): array {
233-
return [
234-
// Drupal user fields.
235-
'name' => $username,
236-
'mail' => $username . '@cura.example.com',
237-
238-
// OS2Lloop fields
239-
// 'os2loop_user_address' => '',
240-
// 'os2loop_user_areas_of_expertise' => '',
241-
// 'os2loop_user_biography' => '',
242-
// 'os2loop_user_city' => '',
243-
// 'os2loop_user_external_list' => '',.
244-
'os2loop_user_family_name' => 'Cura',
245-
'os2loop_user_given_name' => 'User',
246-
// 'os2loop_user_image' => '',
247-
// 'os2loop_user_internal_list' => '',
248-
// 'os2loop_user_job_title' => '',
249-
// 'os2loop_user_phone_number' => '',
250-
// 'os2loop_user_place' => '',
251-
// 'os2loop_user_postal_code' => '',
252-
// 'os2loop_user_professions' => '',
253-
];
254-
}
255-
256-
/**
257-
* Ensure user exists.
258-
*
259-
* @param string $username
260-
* The username.
261-
* @param array $userinfo
262-
* The user info to set on the user.
263-
*
264-
* @return \Drupal\user\Entity\UserInterface
265-
* The newly created or updated user.
266-
*/
267-
private function ensureUser(string $username, array $userinfo): UserInterface {
268-
$user = $this->loadUser($username);
269-
270-
if (NULL === $user) {
271-
$user = $this->userStorage->create();
272-
}
273-
274-
foreach ($userinfo as $field => $value) {
275-
$currentValue = $user->get($field);
276-
if ($currentValue !== $value) {
277-
$user->set($field, $value);
278-
}
279-
}
280-
281-
// Make sure that the user is active.
282-
$user
283-
->activate()
284-
->save();
285-
286-
return $user;
287-
}
288-
289-
/**
290-
* Load user by username.
291-
*/
292-
private function loadUser(string $username) : ?UserInterface {
293-
$users = $this->userStorage->loadByProperties(['name' => $username]);
193+
$settings = $this->settings->getCuraSettings();
294194

295-
return reset($users) ?: NULL;
195+
return JWT::encode($payload, $settings->getSigningSecret(), $settings->getSigningAlgorithm());
296196
}
297197

298198
/**
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace Drupal\os2loop_cura_login;
4+
5+
use Drupal\os2loop_cura_login\Settings\Cura;
6+
use Firebase\JWT\JWT;
7+
use Firebase\JWT\Key;
8+
9+
/**
10+
* Cura helper.
11+
*/
12+
final class CuraHelper {
13+
/**
14+
* The settings.
15+
*/
16+
private Cura $settings;
17+
18+
public function __construct(
19+
Settings $settings,
20+
) {
21+
$this->settings = $settings->getCuraSettings();
22+
}
23+
24+
/**
25+
* Decode JWT.
26+
*/
27+
public function decodeJwt(string $jwt): array {
28+
$secret = $this->settings->getSigningSecret();
29+
30+
$originalLeeway = JWT::$leeway;
31+
$leeway = $this->settings->getJwtLeeway();
32+
if ($leeway > 0) {
33+
JWT::$leeway = $leeway;
34+
}
35+
$payload = (array) JWT::decode($jwt, new Key($secret, $this->settings->getSigningAlgorithm()));
36+
JWT::$leeway = $originalLeeway;
37+
38+
return [$payload, $payload['username'] ?? $payload['brugerId'] ?? NULL];
39+
}
40+
41+
}

0 commit comments

Comments
 (0)