diff --git a/.env.test b/.env.test index 585b660a..2ce61599 100644 --- a/.env.test +++ b/.env.test @@ -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" diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 629af03b..816f07ea 100755 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -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 diff --git a/config/services.yaml b/config/services.yaml index a568a500..4f63973e 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -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 diff --git a/src/Security/ApiAccessTokenHandler.php b/src/Security/ApiAccessTokenHandler.php new file mode 100644 index 00000000..25f5221c --- /dev/null +++ b/src/Security/ApiAccessTokenHandler.php @@ -0,0 +1,33 @@ +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'); + } + } +} diff --git a/src/Security/DovecotAccessTokenHandler.php b/src/Security/DovecotAccessTokenHandler.php deleted file mode 100644 index 83009275..00000000 --- a/src/Security/DovecotAccessTokenHandler.php +++ /dev/null @@ -1,21 +0,0 @@ -dovecotApiAccessToken) { - throw new BadCredentialsException('Invalid access token'); - } - - return new UserBadge('dovecot'); - } -} diff --git a/src/Security/KeycloakAccessTokenHandler.php b/src/Security/KeycloakAccessTokenHandler.php deleted file mode 100644 index 3a0a93c0..00000000 --- a/src/Security/KeycloakAccessTokenHandler.php +++ /dev/null @@ -1,22 +0,0 @@ -keycloakApiAccessToken) { - throw new BadCredentialsException('Invalid access token'); - } - - return new UserBadge('keycloak'); - } -} diff --git a/src/Security/PostfixAccessTokenHandler.php b/src/Security/PostfixAccessTokenHandler.php deleted file mode 100644 index 33830efb..00000000 --- a/src/Security/PostfixAccessTokenHandler.php +++ /dev/null @@ -1,23 +0,0 @@ -postfixApiAccessToken) { - throw new BadCredentialsException('Invalid access token'); - } - - return new UserBadge('postfix'); - } -} diff --git a/src/Security/RetentionAccessTokenHandler.php b/src/Security/RetentionAccessTokenHandler.php deleted file mode 100644 index 0ba9b5bf..00000000 --- a/src/Security/RetentionAccessTokenHandler.php +++ /dev/null @@ -1,23 +0,0 @@ -retentionAccessToken) { - throw new BadCredentialsException('Invalid access token'); - } - - return new UserBadge('retention'); - } -} diff --git a/tests/Controller/DovecotControllerTest.php b/tests/Controller/DovecotControllerTest.php index e9abe917..fb47dce7 100644 --- a/tests/Controller/DovecotControllerTest.php +++ b/tests/Controller/DovecotControllerTest.php @@ -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'); @@ -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/support@example.org', ['password' => 'password']); @@ -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/support@example.org', ['password' => 'wrong']); @@ -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/nonexistent@example.org', ['password' => 'password']); @@ -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/spam@example.org', ['password' => 'password']); @@ -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/mailcrypt@example.org', ['password' => 'password']); @@ -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/user@example.org'); @@ -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/mailcrypt@example.org'); @@ -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/nonexistent@example.org'); @@ -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/spam@example.org'); diff --git a/tests/Controller/KeycloakControllerTest.php b/tests/Controller/KeycloakControllerTest.php index 63cb1db1..e264a285 100644 --- a/tests/Controller/KeycloakControllerTest.php +++ b/tests/Controller/KeycloakControllerTest.php @@ -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'); @@ -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'); @@ -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'); @@ -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/user@example.org'); @@ -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/nonexistent@example.org'); @@ -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/support@example.org', ['credentialType' => 'password', 'password' => 'password']); @@ -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/support@example.org', ['credentialType' => 'otp', 'password' => '123456']); self::assertResponseStatusCodeSame(403); @@ -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/support@example.org'); self::assertResponseStatusCodeSame(404); diff --git a/tests/Controller/PostfixControllerTest.php b/tests/Controller/PostfixControllerTest.php index 29a83e4e..432154ee 100644 --- a/tests/Controller/PostfixControllerTest.php +++ b/tests/Controller/PostfixControllerTest.php @@ -19,7 +19,7 @@ public function testGetAliasUsersWrongApiToken(): void public function testGetAliasUsers(): void { $client = static::createClient([], [ - 'HTTP_Authorization' => 'Bearer insecure', + 'HTTP_Authorization' => 'Bearer postfix', ]); $client->request('GET', '/api/postfix/alias/alias@example.org'); @@ -44,7 +44,7 @@ public function testGetDomainWrongApiToken(): void public function testGetDomain(): void { $client = static::createClient([], [ - 'HTTP_Authorization' => 'Bearer insecure', + 'HTTP_Authorization' => 'Bearer postfix', ]); $client->request('GET', '/api/postfix/domain/example.org'); @@ -65,7 +65,7 @@ public function testGetMailboxWrongApiToken(): void public function testGetMailbox(): void { $client = static::createClient([], [ - 'HTTP_Authorization' => 'Bearer insecure', + 'HTTP_Authorization' => 'Bearer postfix', ]); $client->request('GET', '/api/postfix/mailbox/user@example.org'); @@ -86,7 +86,7 @@ public function testGetSendersWrongApiToken(): void public function testGetSenders(): void { $client = static::createClient([], [ - 'HTTP_Authorization' => 'Bearer insecure', + 'HTTP_Authorization' => 'Bearer postfix', ]); $client->request('GET', '/api/postfix/senders/user@example.org'); diff --git a/tests/Controller/RetentionControllerTest.php b/tests/Controller/RetentionControllerTest.php index e8c0e780..11e984e7 100644 --- a/tests/Controller/RetentionControllerTest.php +++ b/tests/Controller/RetentionControllerTest.php @@ -19,7 +19,7 @@ public function testPutTouchUserWrongApiToken(): void public function testPutTouchUserUnknownUser(): void { $client = static::createClient([], [ - 'HTTP_Authorization' => 'Bearer insecure', + 'HTTP_Authorization' => 'Bearer retention', ]); $client->request('PUT', '/api/retention/nonexistant@example.org/touch'); @@ -29,7 +29,7 @@ public function testPutTouchUserUnknownUser(): void public function testPutTouchUserTimestampInFuture(): void { $client = static::createClient([], [ - 'HTTP_Authorization' => 'Bearer insecure', + 'HTTP_Authorization' => 'Bearer retention', ]); $client->request('PUT', '/api/retention/user@example.org/touch', ['timestamp' => 999999999999]); @@ -39,7 +39,7 @@ public function testPutTouchUserTimestampInFuture(): void public function testPutTouchUser(): void { $client = static::createClient([], [ - 'HTTP_Authorization' => 'Bearer insecure', + 'HTTP_Authorization' => 'Bearer retention', ]); $client->request('PUT', '/api/retention/user@example.org/touch', ['timestamp' => 0]); @@ -50,7 +50,7 @@ public function testPutTouchUser(): void public function testGetDeletedUsersNonexistantDomain(): void { $client = static::createClient([], [ - 'HTTP_Authorization' => 'Bearer insecure', + 'HTTP_Authorization' => 'Bearer retention', ]); $client->request('GET', '/api/retention/nonexistant.org/users'); @@ -60,7 +60,7 @@ public function testGetDeletedUsersNonexistantDomain(): void public function testGetDeletedUsers(): void { $client = static::createClient([], [ - 'HTTP_Authorization' => 'Bearer insecure', + 'HTTP_Authorization' => 'Bearer retention', ]); $client->request('GET', '/api/retention/example.org/users');