Skip to content

Commit

Permalink
Merge pull request #675 from systemli/unify-access-token-handlers
Browse files Browse the repository at this point in the history
Unify Api Access Token Handlers
  • Loading branch information
y3n4 authored Dec 18, 2024
2 parents f48f610 + 424a779 commit d39202c
Show file tree
Hide file tree
Showing 12 changed files with 78 additions and 145 deletions.
9 changes: 4 additions & 5 deletions .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,16 @@ WEBMAIL_URL="https://webmail.example.org"
WKD_DIRECTORY="/tmp/.well-known/openpgpkey"
WKD_FORMAT="advanced"
RETENTION_API_ENABLED=true
RETENTION_API_ACCESS_TOKEN="insecure"
RETENTION_API_ACCESS_TOKEN="retention"
RETENTION_API_IP_ALLOWLIST="127.0.0.1, ::1"
KEYCLOAK_API_ENABLED=true
KEYCLOAK_API_ACCESS_TOKEN="insecure"
KEYCLOAK_API_ACCESS_TOKEN="keycloak"
KEYCLOAK_API_IP_ALLOWLIST="127.0.0.1, ::1"
POSTFIX_API_ENABLED=true
POSTFIX_API_ACCESS_TOKEN="insecure"
POSTFIX_API_ACCESS_TOKEN="postfix"
POSTFIX_API_IP_ALLOWLIST="127.0.0.1, ::1"
ROUNDCUBE_API_ENABLED=true
ROUNDCUBE_API_ACCESS_TOKEN="insecure"
ROUNDCUBE_API_IP_ALLOWLIST="127.0.0.1, ::1"
DOVECOT_API_ENABLED=true
DOVECOT_API_ACCESS_TOKEN="insecure"
DOVECOT_API_ACCESS_TOKEN="dovecot"
DOVECOT_API_IP_ALLOWLIST="127.0.0.1, ::1"
18 changes: 9 additions & 9 deletions config/packages/security.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -130,31 +130,31 @@ security:
stateless: true
provider: retention
access_token:
token_handler: App\Security\RetentionAccessTokenHandler
token_handler: App\Security\ApiAccessTokenHandler
keycloak:
pattern: ^/api/keycloak
stateless: true
provider: keycloak
access_token:
token_handler: App\Security\KeycloakAccessTokenHandler
token_handler: App\Security\ApiAccessTokenHandler
postfix:
pattern: ^/api/postfix
stateless: true
provider: postfix
access_token:
token_handler: App\Security\PostfixAccessTokenHandler
token_handler: App\Security\ApiAccessTokenHandler
dovecot:
pattern: ^/api/dovecot
stateless: true
provider: dovecot
access_token:
token_handler: App\Security\ApiAccessTokenHandler
roundcube:
pattern: ^/api/roundcube
stateless: true
provider: user
http_basic:
realm: Roundcube API
dovecot:
pattern: ^/api/dovecot
stateless: true
provider: dovecot
access_token:
token_handler: App\Security\DovecotAccessTokenHandler
main:
pattern: ^/
provider: user
Expand Down
19 changes: 5 additions & 14 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -171,21 +171,12 @@ services:
- '@Doctrine\ORM\EntityManagerInterface'
public: true

App\Security\RetentionAccessTokenHandler:
App\Security\ApiAccessTokenHandler:
arguments:
$retentionAccessToken: "%env(RETENTION_API_ACCESS_TOKEN)%"

App\Security\KeycloakAccessTokenHandler:
arguments:
$keycloakApiAccessToken: "%env(KEYCLOAK_API_ACCESS_TOKEN)%"

App\Security\PostfixAccessTokenHandler:
arguments:
$postfixApiAccessToken: "%env(POSTFIX_API_ACCESS_TOKEN)%"

App\Security\DovecotAccessTokenHandler:
arguments:
$dovecotApiAccessToken: "%env(DOVECOT_API_ACCESS_TOKEN)%"
$accessTokenDovecot: '%env(DOVECOT_API_ACCESS_TOKEN)%'
$accessTokenKeycloak: '%env(KEYCLOAK_API_ACCESS_TOKEN)%'
$accessTokenRetention: '%env(RETENTION_API_ACCESS_TOKEN)%'
$accessTokenPostfix: '%env(POSTFIX_API_ACCESS_TOKEN)%'

App\Sender\WelcomeMessageSender:
public: true
Expand Down
33 changes: 33 additions & 0 deletions src/Security/ApiAccessTokenHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace App\Security;

use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Http\AccessToken\AccessTokenHandlerInterface;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;

class ApiAccessTokenHandler implements AccessTokenHandlerInterface
{
public function __construct(
private string $accessTokenDovecot,
private string $accessTokenKeycloak,
private string $accessTokenPostfix,
private string $accessTokenRetention,
) {}

public function getUserBadgeFrom(#[\SensitiveParameter] string $accessToken): UserBadge
{
switch ($accessToken) {
case $this->accessTokenDovecot:
return new UserBadge('dovecot');
case $this->accessTokenKeycloak:
return new UserBadge('keycloak');
case $this->accessTokenRetention:
return new UserBadge('retention');
case $this->accessTokenPostfix:
return new UserBadge('postfix');
default:
throw new BadCredentialsException('Invalid access token');
}
}
}
21 changes: 0 additions & 21 deletions src/Security/DovecotAccessTokenHandler.php

This file was deleted.

22 changes: 0 additions & 22 deletions src/Security/KeycloakAccessTokenHandler.php

This file was deleted.

23 changes: 0 additions & 23 deletions src/Security/PostfixAccessTokenHandler.php

This file was deleted.

23 changes: 0 additions & 23 deletions src/Security/RetentionAccessTokenHandler.php

This file was deleted.

21 changes: 10 additions & 11 deletions tests/Controller/DovecotControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class DovecotControllerTest extends WebTestCase
public function testStatus(): void
{
$client = static::createClient([], [
'HTTP_Authorization' => 'Bearer insecure',
'HTTP_Authorization' => 'Bearer dovecot',
]);
$client->request('GET', '/api/dovecot/status');

Expand All @@ -29,7 +29,7 @@ public function testStatusWrongApiToken(): void
public function testPassdbUser(): void
{
$client = static::createClient([], [
'HTTP_Authorization' => 'Bearer insecure',
'HTTP_Authorization' => 'Bearer dovecot',
]);
$client->request('POST', '/api/dovecot/[email protected]', ['password' => 'password']);

Expand All @@ -39,7 +39,7 @@ public function testPassdbUser(): void
public function testPassdbUserWrongPassword(): void
{
$client = static::createClient([], [
'HTTP_Authorization' => 'Bearer insecure',
'HTTP_Authorization' => 'Bearer dovecot',
]);
$client->request('POST', '/api/dovecot/[email protected]', ['password' => 'wrong']);

Expand All @@ -49,7 +49,7 @@ public function testPassdbUserWrongPassword(): void
public function testPassdbNonexistentUser(): void
{
$client = static::createClient([], [
'HTTP_Authorization' => 'Bearer insecure',
'HTTP_Authorization' => 'Bearer dovecot',
]);
$client->request('POST', '/api/dovecot/[email protected]', ['password' => 'password']);

Expand All @@ -59,7 +59,7 @@ public function testPassdbNonexistentUser(): void
public function testPassdbSpamUser(): void
{
$client = static::createClient([], [
'HTTP_Authorization' => 'Bearer insecure',
'HTTP_Authorization' => 'Bearer dovecot',
]);
$client->request('POST', '/api/dovecot/[email protected]', ['password' => 'password']);

Expand All @@ -69,7 +69,7 @@ public function testPassdbSpamUser(): void
public function testPassdbMailCrypt(): void
{
$client = static::createClient([], [
'HTTP_Authorization' => 'Bearer insecure',
'HTTP_Authorization' => 'Bearer dovecot',
]);
$client->request('POST', '/api/dovecot/[email protected]', ['password' => 'password']);

Expand All @@ -82,7 +82,7 @@ public function testPassdbMailCrypt(): void
public function testUserdbUser(): void
{
$client = static::createClient([], [
'HTTP_Authorization' => 'Bearer insecure',
'HTTP_Authorization' => 'Bearer dovecot',
]);
$client->request('GET', '/api/dovecot/[email protected]');

Expand All @@ -96,13 +96,12 @@ public function testUserdbUser(): void
self::assertIsInt($data['body']['gid']);
self::assertIsInt($data['body']['uid']);
self::assertNotEquals($data['body']['home'], '');

}

public function testUserdbMailcrypt(): void
{
$client = static::createClient([], [
'HTTP_Authorization' => 'Bearer insecure',
'HTTP_Authorization' => 'Bearer dovecot',
]);
$client->request('GET', '/api/dovecot/[email protected]');

Expand All @@ -119,7 +118,7 @@ public function testUserdbMailcrypt(): void
public function testUserdbNonexistentUser(): void
{
$client = static::createClient([], [
'HTTP_Authorization' => 'Bearer insecure',
'HTTP_Authorization' => 'Bearer dovecot',
]);
$client->request('GET', '/api/dovecot/[email protected]');

Expand All @@ -130,7 +129,7 @@ public function testUserdbNonexistentUser(): void
public function testUserdbSpamUser(): void
{
$client = static::createClient([], [
'HTTP_Authorization' => 'Bearer insecure',
'HTTP_Authorization' => 'Bearer dovecot',
]);
$client->request('GET', '/api/dovecot/[email protected]');

Expand Down
16 changes: 8 additions & 8 deletions tests/Controller/KeycloakControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function testGetUsersSearchWrongApiToken(): void
public function testGetUsersSearch(): void
{
$client = static::createClient([], [
'HTTP_Authorization' => 'Bearer insecure',
'HTTP_Authorization' => 'Bearer keycloak',
]);
$client->request('GET', '/api/keycloak/example.org?search=example&max=2');

Expand All @@ -37,7 +37,7 @@ public function testGetUsersSearch(): void
public function testGetUsersSearchNonexistentDomain(): void
{
$client = static::createClient([], [
'HTTP_Authorization' => 'Bearer insecure',
'HTTP_Authorization' => 'Bearer keycloak',
]);
$client->request('GET', '/api/keycloak/nonexistent.org?search=example&max=2');

Expand All @@ -47,7 +47,7 @@ public function testGetUsersSearchNonexistentDomain(): void
public function testGetUsersCount(): void
{
$client = static::createClient([], [
'HTTP_Authorization' => 'Bearer insecure',
'HTTP_Authorization' => 'Bearer keycloak',
]);
$client->request('GET', '/api/keycloak/example.org/count');

Expand All @@ -60,7 +60,7 @@ public function testGetUsersCount(): void
public function testGetOneUser(): void
{
$client = static::createClient([], [
'HTTP_Authorization' => 'Bearer insecure',
'HTTP_Authorization' => 'Bearer keycloak',
]);
$client->request('GET', '/api/keycloak/example.org/user/[email protected]');

Expand All @@ -74,7 +74,7 @@ public function testGetOneUser(): void
public function testGetOneNonexistentUser(): void
{
$client = static::createClient([], [
'HTTP_Authorization' => 'Bearer insecure',
'HTTP_Authorization' => 'Bearer keycloak',
]);
$client->request('GET', '/api/keycloak/example.org/user/[email protected]');

Expand All @@ -84,7 +84,7 @@ public function testGetOneNonexistentUser(): void
public function testPostUserValidate(): void
{
$client = static::createClient([], [
'HTTP_Authorization' => 'Bearer insecure',
'HTTP_Authorization' => 'Bearer keycloak',
]);
$client->request('POST', '/api/keycloak/example.org/validate/[email protected]', ['credentialType' => 'password', 'password' => 'password']);

Expand Down Expand Up @@ -114,7 +114,7 @@ public function testPostUserValidate(): void
public function testPostUserValidateOTP(): void
{
$client = static::createClient([], [
'HTTP_Authorization' => 'Bearer insecure',
'HTTP_Authorization' => 'Bearer keycloak',
]);
$client->request('POST', '/api/keycloak/example.org/validate/[email protected]', ['credentialType' => 'otp', 'password' => '123456']);
self::assertResponseStatusCodeSame(403);
Expand All @@ -131,7 +131,7 @@ public function testPostUserValidateOTP(): void
public function testGetIsConfiguredFor(): void
{
$client = static::createClient([], [
'HTTP_Authorization' => 'Bearer insecure',
'HTTP_Authorization' => 'Bearer keycloak',
]);
$client->request('GET', '/api/keycloak/example.org/configured/otp/[email protected]');
self::assertResponseStatusCodeSame(404);
Expand Down
Loading

0 comments on commit d39202c

Please sign in to comment.