Skip to content

Commit

Permalink
Merge branch 'main' into context-comunication
Browse files Browse the repository at this point in the history
  • Loading branch information
zerai committed Mar 4, 2024
2 parents 698898a + 1782d36 commit 0b35c62
Show file tree
Hide file tree
Showing 10 changed files with 428 additions and 14 deletions.
39 changes: 39 additions & 0 deletions _iam/src/AdapterForApi/Auth/ConnectMeController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php declare(strict_types=1);

/*
* This file is part of the medicalmundi/marketplace-accounts
*
* @copyright (c) 2023 MedicalMundi
*
* This software consists of voluntary contributions made by many individuals
* {@link https://github.com/medicalmundi/marketplace-accounts/graphs/contributors developer} and is licensed under the MIT license.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
* @license https://github.com/MedicalMundi/marketplace-accounts/blob/main/LICENSE MIT
*/

namespace IdentityAccess\AdapterForApi\Auth;

use App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[Route('/api/v1/auth')]
class ConnectMeController extends AbstractController
{
#[Route('/connect/me', name: 'api_auth_connect_me', methods: 'GET')]
#[isGranted('ROLE_USER')]
public function index(): Response
{
/** @var User $user */
$user = $this->getUser();

return $this->json([
'id' => $user->getId(),
'email' => $user->getEmail(),
]);
}
}
116 changes: 116 additions & 0 deletions _iam/src/AdapterForCli/CreateMarketplaceOauthClientCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php declare(strict_types=1);

/*
* This file is part of the medicalmundi/marketplace-accounts
*
* @copyright (c) 2023 MedicalMundi
*
* This software consists of voluntary contributions made by many individuals
* {@link https://github.com/medicalmundi/marketplace-accounts/graphs/contributors developer} and is licensed under the MIT license.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
* @license https://github.com/MedicalMundi/marketplace-accounts/blob/main/LICENSE MIT
*/

namespace IdentityAccess\AdapterForCli;

use App\Entity\OAuth2ClientProfile;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use League\Bundle\OAuth2ServerBundle\Manager\ClientManagerInterface;
use League\Bundle\OAuth2ServerBundle\Model\AbstractClient;
use League\Bundle\OAuth2ServerBundle\Model\Client;
use League\Bundle\OAuth2ServerBundle\ValueObject\Grant;
use League\Bundle\OAuth2ServerBundle\ValueObject\RedirectUri;
use League\Bundle\OAuth2ServerBundle\ValueObject\Scope;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(
name: 'app:oauth:create-for-marketplace',
description: 'Create oAuth client for stage.marketplace website',
)]
class CreateMarketplaceOauthClientCommand extends Command
{
public function __construct(
private readonly ClientManagerInterface $clientManager,
private readonly EntityManagerInterface $em,
) {
parent::__construct();
}

protected function configure(): void
{
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);

try {
$this->checkDefaultOauthClientOrCreate($io);
} catch (Exception $exception) {
$io->error($exception->getMessage());
return Command::FAILURE;
}

return Command::SUCCESS;
}

private function createOauthClientForMarketplaceEngine()
{
$clientName = 'Marketplace Engine Client';
$clientId = 'marketplace-engine';
$clientSecret = 'marketplace';
$clientDescription = 'Marketplace website';
$scopes = ['email'];
$grantTypes = ['authorization_code', 'refresh_token'];
$redirectUris = ['https://marketplace.oe-modules.com/connect/oemodules/check'];

$oAuthClient = $this
->buildOauthClient(
$clientName,
$clientId,
$clientSecret,
$redirectUris,
$grantTypes,
$scopes,
$clientDescription
);

$this->clientManager->save($oAuthClient);

// Create Client Profile
$oAuth2ClientProfile = new OAuth2ClientProfile();
$oAuth2ClientProfile->setClient($oAuthClient)
->setName($clientName)
->setDescription($clientDescription);
$this->em->persist($oAuth2ClientProfile);
$this->em->flush();
}

private function buildOauthClient(string $name, string $identifier, string $secret, array $redirectUriStrings, array $grantStrings, array $scopeStrings, string $clientDescription): AbstractClient
{
$client = new Client($name, $identifier, $secret);
$client->setActive(true);
$client->setAllowPlainTextPkce(false);

return $client
->setRedirectUris(...array_map(static fn (string $redirectUri): RedirectUri => new RedirectUri($redirectUri), $redirectUriStrings))
->setGrants(...array_map(static fn (string $grant): Grant => new Grant($grant), $grantStrings))
->setScopes(...array_map(static fn (string $scope): Scope => new Scope($scope), $scopeStrings))
;
}

private function checkDefaultOauthClientOrCreate(SymfonyStyle $io): void
{
if (null === $this->clientManager->find('marketplace-engine')) {
$this->createOauthClientForMarketplaceEngine();
$io->success('Oauth Client with identifier \'marketplace-engine\' was created');
}
}
}
116 changes: 116 additions & 0 deletions _iam/src/AdapterForCli/CreateStageMarketplaceOauthClientCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php declare(strict_types=1);

/*
* This file is part of the medicalmundi/marketplace-accounts
*
* @copyright (c) 2023 MedicalMundi
*
* This software consists of voluntary contributions made by many individuals
* {@link https://github.com/medicalmundi/marketplace-accounts/graphs/contributors developer} and is licensed under the MIT license.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
* @license https://github.com/MedicalMundi/marketplace-accounts/blob/main/LICENSE MIT
*/

namespace IdentityAccess\AdapterForCli;

use App\Entity\OAuth2ClientProfile;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use League\Bundle\OAuth2ServerBundle\Manager\ClientManagerInterface;
use League\Bundle\OAuth2ServerBundle\Model\AbstractClient;
use League\Bundle\OAuth2ServerBundle\Model\Client;
use League\Bundle\OAuth2ServerBundle\ValueObject\Grant;
use League\Bundle\OAuth2ServerBundle\ValueObject\RedirectUri;
use League\Bundle\OAuth2ServerBundle\ValueObject\Scope;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(
name: 'app:oauth:create-for-stage-marketplace',
description: 'Create oAuth client for stage.marketplace website',
)]
class CreateStageMarketplaceOauthClientCommand extends Command
{
public function __construct(
private readonly ClientManagerInterface $clientManager,
private readonly EntityManagerInterface $em,
) {
parent::__construct();
}

protected function configure(): void
{
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);

try {
$this->checkDefaultOauthClientOrCreate($io);
} catch (Exception $exception) {
$io->error($exception->getMessage());
return Command::FAILURE;
}

return Command::SUCCESS;
}

private function createOauthClientForMarketplaceEngine()
{
$clientName = 'Stage Marketplace Engine Client';
$clientId = 'stage-marketplace-engine';
$clientSecret = 'stage-marketplace';
$clientDescription = 'Stage Marketplace website';
$scopes = ['email'];
$grantTypes = ['authorization_code', 'refresh_token'];
$redirectUris = ['https://stage.marketplace.oe-modules.com/connect/oemodules/check'];

$oAuthClient = $this
->buildOauthClient(
$clientName,
$clientId,
$clientSecret,
$redirectUris,
$grantTypes,
$scopes,
$clientDescription
);

$this->clientManager->save($oAuthClient);

// Create Client Profile
$oAuth2ClientProfile = new OAuth2ClientProfile();
$oAuth2ClientProfile->setClient($oAuthClient)
->setName($clientName)
->setDescription($clientDescription);
$this->em->persist($oAuth2ClientProfile);
$this->em->flush();
}

private function buildOauthClient(string $name, string $identifier, string $secret, array $redirectUriStrings, array $grantStrings, array $scopeStrings, string $clientDescription): AbstractClient
{
$client = new Client($name, $identifier, $secret);
$client->setActive(true);
$client->setAllowPlainTextPkce(false);

return $client
->setRedirectUris(...array_map(static fn (string $redirectUri): RedirectUri => new RedirectUri($redirectUri), $redirectUriStrings))
->setGrants(...array_map(static fn (string $grant): Grant => new Grant($grant), $grantStrings))
->setScopes(...array_map(static fn (string $scope): Scope => new Scope($scope), $scopeStrings))
;
}

private function checkDefaultOauthClientOrCreate(SymfonyStyle $io): void
{
if (null === $this->clientManager->find('stage-marketplace-engine')) {
$this->createOauthClientForMarketplaceEngine();
$io->success('Oauth Client with identifier \'stage-marketplace-engine\' was created');
}
}
}
19 changes: 5 additions & 14 deletions config/packages/security.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,23 @@ security:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
api_token:
pattern: ^/api/token$
security: false
api:
pattern: ^/api
security: true
stateless: true
oauth2: true
main:
# login_throttling:
# max_attempts: 3
# interval: '5 minutes'
login_throttling:
max_attempts: 6
interval: '5 minutes'
lazy: true
provider: app_user_provider
form_login:
login_path: app_login
check_path: app_login
enable_csrf: true
default_target_path: app_index
use_referer: true
custom_authenticators:
- App\Security\Authenticator\OeModulesLoginFormAuthenticator
logout:
path: app_logout
target: app_index

login_throttling: true

# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#the-firewall

Expand Down
7 changes: 7 additions & 0 deletions config/routes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,10 @@ iam_admin_oauth_client_controllers:
path: ../_iam/src/AdapterForWeb/Administration/OauthClient/
namespace: IdentityAccess\AdapterForWeb\Administration\OauthClient
type: attribute


api_auth_controllers:
resource:
path: ../_iam/src/AdapterForApi/Auth/
namespace: IdentityAccess\AdapterForApi\Auth
type: attribute
10 changes: 10 additions & 0 deletions phparkitect-baseline.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@
"line": 27,
"error": "depends on App\\Repository\\UserRepository, but should not depend on these namespaces: App\\Controller\\*, App\\Service\\*, App\\Repository\\* because of component architecture"
},
{
"fqcn": "IdentityAccess\\AdapterForCli\\CreateMarketplaceOauthClientCommand",
"line": 88,
"error": "depends on App\\Entity\\OAuth2ClientProfile, but should not depend on classes outside namespace IdentityAccess\\Core because or namespaces in whitelist we want isolate our identity access Adapters from ever growing dependencies."
},
{
"fqcn": "IdentityAccess\\AdapterForCli\\CreateStageMarketplaceOauthClientCommand",
"line": 88,
"error": "depends on App\\Entity\\OAuth2ClientProfile, but should not depend on classes outside namespace IdentityAccess\\Core because or namespaces in whitelist we want isolate our identity access Adapters from ever growing dependencies."
},
{
"fqcn": "IdentityAccess\\AdapterForReadingAccounts\\AccountsDataProvider",
"line": 26,
Expand Down
34 changes: 34 additions & 0 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.15.0@5c774aca4746caf3d239d9c8cadb9f882ca29352">
<file src="_iam/src/AdapterForCli/CreateMarketplaceOauthClientCommand.php">
<ArgumentTypeCoercion>
<code>$oAuthClient</code>
</ArgumentTypeCoercion>
<LessSpecificReturnStatement>
<code><![CDATA[$client
->setRedirectUris(...array_map(static fn (string $redirectUri): RedirectUri => new RedirectUri($redirectUri), $redirectUriStrings))
->setGrants(...array_map(static fn (string $grant): Grant => new Grant($grant), $grantStrings))
->setScopes(...array_map(static fn (string $scope): Scope => new Scope($scope), $scopeStrings))]]></code>
</LessSpecificReturnStatement>
<MissingReturnType>
<code>createOauthClientForMarketplaceEngine</code>
</MissingReturnType>
<MoreSpecificReturnType>
<code>AbstractClient</code>
</MoreSpecificReturnType>
</file>
<file src="_iam/src/AdapterForCli/CreateStageMarketplaceOauthClientCommand.php">
<ArgumentTypeCoercion>
<code>$oAuthClient</code>
</ArgumentTypeCoercion>
<LessSpecificReturnStatement>
<code><![CDATA[$client
->setRedirectUris(...array_map(static fn (string $redirectUri): RedirectUri => new RedirectUri($redirectUri), $redirectUriStrings))
->setGrants(...array_map(static fn (string $grant): Grant => new Grant($grant), $grantStrings))
->setScopes(...array_map(static fn (string $scope): Scope => new Scope($scope), $scopeStrings))]]></code>
</LessSpecificReturnStatement>
<MissingReturnType>
<code>createOauthClientForMarketplaceEngine</code>
</MissingReturnType>
<MoreSpecificReturnType>
<code>AbstractClient</code>
</MoreSpecificReturnType>
</file>
<file src="_iam/src/AdapterForWeb/Administration/OauthClient/OauthClientController.php">
<MixedArgument>
<code><![CDATA[$form->getData()]]></code>
Expand Down
Loading

0 comments on commit 0b35c62

Please sign in to comment.