Compare commits
No commits in common. "0a4cb375e954616746ce4c42b6b1bdd99f325f89" and "683766259cc28b64d6c47d0d58256816c061e2d0" have entirely different histories.
0a4cb375e9
...
683766259c
|
|
@ -19,8 +19,6 @@
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-client" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-client" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/ralouphie/getallheaders" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/ralouphie/getallheaders" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/rate-limiter" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/rate-limiter" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/remote-event" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/webhook" />
|
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
|
|
||||||
|
|
@ -181,10 +181,6 @@
|
||||||
<path value="$PROJECT_DIR$/vendor/twig/extra-bundle" />
|
<path value="$PROJECT_DIR$/vendor/twig/extra-bundle" />
|
||||||
<path value="$PROJECT_DIR$/vendor/staabm/side-effects-detector" />
|
<path value="$PROJECT_DIR$/vendor/staabm/side-effects-detector" />
|
||||||
<path value="$PROJECT_DIR$/vendor/symfony/rate-limiter" />
|
<path value="$PROJECT_DIR$/vendor/symfony/rate-limiter" />
|
||||||
<path value="$PROJECT_DIR$/vendor/dama/doctrine-test-bundle" />
|
|
||||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php85" />
|
|
||||||
<path value="$PROJECT_DIR$/vendor/symfony/remote-event" />
|
|
||||||
<path value="$PROJECT_DIR$/vendor/symfony/webhook" />
|
|
||||||
</include_path>
|
</include_path>
|
||||||
</component>
|
</component>
|
||||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.2" />
|
<component name="PhpProjectSharedConfiguration" php_language_level="8.2" />
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,7 @@ export default class extends Controller {
|
||||||
this.modalTitleTarget.textContent = "Modifier l'organisation";
|
this.modalTitleTarget.textContent = "Modifier l'organisation";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/organization/editModal/${this.currentOrgId}`);
|
const response = await fetch(`/organization/${this.currentOrgId}`);
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
// Fill targets
|
// Fill targets
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,6 @@
|
||||||
"symfony/ux-turbo": "^2.24",
|
"symfony/ux-turbo": "^2.24",
|
||||||
"symfony/validator": "7.4.*",
|
"symfony/validator": "7.4.*",
|
||||||
"symfony/web-link": "7.4.*",
|
"symfony/web-link": "7.4.*",
|
||||||
"symfony/webhook": "7.4.*",
|
|
||||||
"symfony/yaml": "7.4.*",
|
"symfony/yaml": "7.4.*",
|
||||||
"twig/twig": "^2.12|^3.0"
|
"twig/twig": "^2.12|^3.0"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ league_oauth2_server:
|
||||||
private_key_passphrase: '%env(resolve:OAUTH_PASSPHRASE)%'
|
private_key_passphrase: '%env(resolve:OAUTH_PASSPHRASE)%'
|
||||||
encryption_key: '%env(resolve:OAUTH_ENCRYPTION_KEY)%'
|
encryption_key: '%env(resolve:OAUTH_ENCRYPTION_KEY)%'
|
||||||
access_token_ttl: PT15M # 15 minutes
|
access_token_ttl: PT15M # 15 minutes
|
||||||
refresh_token_ttl: P7D # 7 days
|
refresh_token_ttl: PT7D # 7 days
|
||||||
auth_code_ttl: PT30M # 30 minutes
|
auth_code_ttl: PT30M # 30 minutes
|
||||||
require_code_challenge_for_public_clients: false
|
require_code_challenge_for_public_clients: false
|
||||||
resource_server:
|
resource_server:
|
||||||
|
|
|
||||||
|
|
@ -676,7 +676,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
|
||||||
* }>,
|
* }>,
|
||||||
* },
|
* },
|
||||||
* webhook?: bool|array{ // Webhook configuration
|
* webhook?: bool|array{ // Webhook configuration
|
||||||
* enabled?: bool|Param, // Default: true
|
* enabled?: bool|Param, // Default: false
|
||||||
* message_bus?: scalar|Param|null, // The message bus to use. // Default: "messenger.default_bus"
|
* message_bus?: scalar|Param|null, // The message bus to use. // Default: "messenger.default_bus"
|
||||||
* routing?: array<string, array{ // Default: []
|
* routing?: array<string, array{ // Default: []
|
||||||
* service: scalar|Param|null,
|
* service: scalar|Param|null,
|
||||||
|
|
@ -684,7 +684,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
|
||||||
* }>,
|
* }>,
|
||||||
* },
|
* },
|
||||||
* remote-event?: bool|array{ // RemoteEvent configuration
|
* remote-event?: bool|array{ // RemoteEvent configuration
|
||||||
* enabled?: bool|Param, // Default: true
|
* enabled?: bool|Param, // Default: false
|
||||||
* },
|
* },
|
||||||
* json_streamer?: bool|array{ // JSON streamer configuration
|
* json_streamer?: bool|array{ // JSON streamer configuration
|
||||||
* enabled?: bool|Param, // Default: false
|
* enabled?: bool|Param, // Default: false
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ parameters:
|
||||||
oauth_sso_identifier: '%env(OAUTH_SSO_IDENTIFIER)%'
|
oauth_sso_identifier: '%env(OAUTH_SSO_IDENTIFIER)%'
|
||||||
oauth_sso_identifier_login: '%env(OAUTH_SSO_IDENTIFIER_LOGIN)%'
|
oauth_sso_identifier_login: '%env(OAUTH_SSO_IDENTIFIER_LOGIN)%'
|
||||||
easycheck_url: '%env(EASYCHECK_URL)%'
|
easycheck_url: '%env(EASYCHECK_URL)%'
|
||||||
webhook_secret: '%env(WEBHOOK_SECRET)%'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# default configuration for services in *this* file
|
# default configuration for services in *this* file
|
||||||
|
|
@ -60,12 +59,11 @@ services:
|
||||||
arguments:
|
arguments:
|
||||||
$environment: '%kernel.environment%'
|
$environment: '%kernel.environment%'
|
||||||
|
|
||||||
|
# add more service definitions when explicit configuration is needed
|
||||||
|
# please note that last definitions always *replace* previous ones
|
||||||
|
|
||||||
App\EventListener\LogoutSubscriber:
|
App\EventListener\LogoutSubscriber:
|
||||||
arguments:
|
arguments:
|
||||||
$easycheckUrl: '%env(EASYCHECK_URL)%'
|
$easycheckUrl: '%env(EASYCHECK_URL)%'
|
||||||
tags:
|
tags:
|
||||||
- { name: kernel.event_subscriber }
|
- { name: kernel.event_subscriber }
|
||||||
App\Webhook\OrganizationNotifier:
|
|
||||||
arguments:
|
|
||||||
$easycheckUrl: '%easycheck_url%'
|
|
||||||
$webhookSecret: '%webhook_secret%'
|
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ use App\Form\OrganizationForm;
|
||||||
use App\Repository\OrganizationsRepository;
|
use App\Repository\OrganizationsRepository;
|
||||||
use App\Repository\UsersOrganizationsRepository;
|
use App\Repository\UsersOrganizationsRepository;
|
||||||
use App\Service\ActionService;
|
use App\Service\ActionService;
|
||||||
|
use App\Service\AwsService;
|
||||||
use App\Service\LoggerService;
|
use App\Service\LoggerService;
|
||||||
use App\Webhook\OrganizationNotifier;
|
|
||||||
use App\Service\OrganizationsService;
|
use App\Service\OrganizationsService;
|
||||||
use App\Service\UserOrganizationService;
|
use App\Service\UserOrganizationService;
|
||||||
use App\Service\UserService;
|
use App\Service\UserService;
|
||||||
|
|
@ -37,9 +37,7 @@ class OrganizationController extends AbstractController
|
||||||
private readonly ActionService $actionService,
|
private readonly ActionService $actionService,
|
||||||
private readonly UserOrganizationService $userOrganizationService,
|
private readonly UserOrganizationService $userOrganizationService,
|
||||||
private readonly OrganizationsRepository $organizationsRepository,
|
private readonly OrganizationsRepository $organizationsRepository,
|
||||||
private readonly LoggerService $loggerService,
|
private readonly LoggerService $loggerService, private readonly UsersOrganizationsRepository $usersOrganizationsRepository)
|
||||||
private readonly UsersOrganizationsRepository $usersOrganizationsRepository,
|
|
||||||
private readonly OrganizationNotifier $organizationNotifier)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,8 +111,6 @@ class OrganizationController extends AbstractController
|
||||||
$this->entityManager->persist($organization);
|
$this->entityManager->persist($organization);
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
//webhook notify
|
|
||||||
$this->organizationNotifier->notifyOrganizationCreated($organization);
|
|
||||||
// Loggers...
|
// Loggers...
|
||||||
$this->loggerService->logOrganizationInformation($organization->getId(), $actingUser->getUserIdentifier(), "Organization Created via ajax");
|
$this->loggerService->logOrganizationInformation($organization->getId(), $actingUser->getUserIdentifier(), "Organization Created via ajax");
|
||||||
|
|
||||||
|
|
@ -379,7 +375,7 @@ class OrganizationController extends AbstractController
|
||||||
/*
|
/*
|
||||||
* Path used to get data on an organization for the edit modal
|
* Path used to get data on an organization for the edit modal
|
||||||
*/
|
*/
|
||||||
#[Route(path: '/editModal/{id}', name: 'get', methods: ['GET'])]
|
#[Route(path: '/{id}', name: 'get', methods: ['GET'])]
|
||||||
public function get(int $id): JsonResponse{
|
public function get(int $id): JsonResponse{
|
||||||
$this->denyAccessUnlessGranted('ROLE_USER');
|
$this->denyAccessUnlessGranted('ROLE_USER');
|
||||||
$actingUser = $this->getUser();
|
$actingUser = $this->getUser();
|
||||||
|
|
|
||||||
|
|
@ -872,12 +872,11 @@ class UserController extends AbstractController
|
||||||
$email = $user->getEmail();
|
$email = $user->getEmail();
|
||||||
$existingUser = $this->userRepository->findOneBy(['email' => $email]);
|
$existingUser = $this->userRepository->findOneBy(['email' => $email]);
|
||||||
|
|
||||||
|
|
||||||
// CASE A: User exists -> Add to org
|
|
||||||
if ($existingUser) {
|
|
||||||
if($this->userService->checkUserOrganizationLinkExists($existingUser, $org)){
|
if($this->userService->checkUserOrganizationLinkExists($existingUser, $org)){
|
||||||
return $this->json(['error' => "L'utilisateur existe déjà dans votre organisation"], 400);
|
return $this->json(['error' => "L'utilisateur existe déjà dans votre organisation"], 400);
|
||||||
}
|
}
|
||||||
|
// CASE A: User exists -> Add to org
|
||||||
|
if ($existingUser) {
|
||||||
// Check if already in org to avoid logic errors or duplicate logs
|
// Check if already in org to avoid logic errors or duplicate logs
|
||||||
$this->userService->addExistingUserToOrganization($existingUser, $org, $selectedApps);
|
$this->userService->addExistingUserToOrganization($existingUser, $org, $selectedApps);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ class LogoutSubscriber implements EventSubscriberInterface
|
||||||
$params['redirect_app'] = $redirectApp;
|
$params['redirect_app'] = $redirectApp;
|
||||||
}
|
}
|
||||||
|
|
||||||
$easycheckLogoutUrl = rtrim($this->easycheckUrl, '/'). '/logout?' . http_build_query($params);
|
$easycheckLogoutUrl = $this->easycheckUrl . '/logout?' . http_build_query($params);
|
||||||
|
|
||||||
$this->logger->info('Redirecting to EasyCheck logout', [
|
$this->logger->info('Redirecting to EasyCheck logout', [
|
||||||
'url' => $easycheckLogoutUrl,
|
'url' => $easycheckLogoutUrl,
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ class LoginSubscriber implements EventSubscriberInterface
|
||||||
$user->setLastConnection(new \DateTime('now', new \DateTimeZone('Europe/Paris')));
|
$user->setLastConnection(new \DateTime('now', new \DateTimeZone('Europe/Paris')));
|
||||||
|
|
||||||
$easySolution = $this->entityManager->getRepository(Client::class)->findOneBy(['identifier' => $this->clientIdentifier]);
|
$easySolution = $this->entityManager->getRepository(Client::class)->findOneBy(['identifier' => $this->clientIdentifier]);
|
||||||
if ($easySolution) {
|
/*if ($easySolution) {
|
||||||
$accessToken = new AccessToken(
|
$accessToken = new AccessToken(
|
||||||
identifier: bin2hex(random_bytes(40)),
|
identifier: bin2hex(random_bytes(40)),
|
||||||
expiry: new \DateTimeImmutable('+1 hour', new \DateTimeZone('Europe/Paris')),
|
expiry: new \DateTimeImmutable('+1 hour', new \DateTimeZone('Europe/Paris')),
|
||||||
|
|
@ -70,7 +70,7 @@ class LoginSubscriber implements EventSubscriberInterface
|
||||||
$this->entityManager->persist($user);
|
$this->entityManager->persist($user);
|
||||||
$this->entityManager->persist($accessToken);
|
$this->entityManager->persist($accessToken);
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vérifier si un paramètre redirect_app est présent dans l'URL
|
// Vérifier si un paramètre redirect_app est présent dans l'URL
|
||||||
|
|
|
||||||
|
|
@ -181,11 +181,12 @@ readonly class LoggerService
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function logUOALinkDeactivated(int $uoaId, int $appId): void
|
public function logUOALinkDeactivated(int $uoaId, int $appId, int $roleId): void
|
||||||
{
|
{
|
||||||
$this->organizationManagementLogger->notice('UOA link deactivated', [
|
$this->organizationManagementLogger->notice('UOA link deactivated', [
|
||||||
'uoa_id' => $uoaId,
|
'uoa_id' => $uoaId,
|
||||||
'app_id' => $appId,
|
'app_id' => $appId,
|
||||||
|
'role_id' => $roleId,
|
||||||
'ip' => $this->requestStack->getCurrentRequest()?->getClientIp() ?? 'unknown',
|
'ip' => $this->requestStack->getCurrentRequest()?->getClientIp() ?? 'unknown',
|
||||||
'timestamp' => $this->now(),
|
'timestamp' => $this->now(),
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
|
|
@ -94,13 +94,14 @@ class UserOrganizationAppService
|
||||||
try{
|
try{
|
||||||
$uoa->setIsActive(false);
|
$uoa->setIsActive(false);
|
||||||
$this->actionService->createAction("Deactivate UOA link", $userOrganization->getUsers(),
|
$this->actionService->createAction("Deactivate UOA link", $userOrganization->getUsers(),
|
||||||
$userOrganization->getOrganization(), "App: " . $uoa->getApplication()->getName());
|
$userOrganization->getOrganization(), "App: " . $uoa->getApplication()->getName() . ", Role: " . $uoa->getRole()->getName());
|
||||||
$this->entityManager->persist($uoa);
|
$this->entityManager->persist($uoa);
|
||||||
$this->loggerService->logUOALinkDeactivated($uoa->getId(), $uoa->getApplication()->getId());
|
$this->loggerService->logUOALinkDeactivated($uoa->getId(), $uoa->getApplication()->getId(), $uoa->getRole()->getId());
|
||||||
}catch (\Exception $exception){
|
}catch (\Exception $exception){
|
||||||
$this->loggerService->logCritical("Error deactivating UOA link", [
|
$this->loggerService->logCritical("Error deactivating UOA link", [
|
||||||
'uoa_id' => $uoa->getId(),
|
'uoa_id' => $uoa->getId(),
|
||||||
'app_id' => $uoa->getApplication()->getId(),
|
'app_id' => $uoa->getApplication()->getId(),
|
||||||
|
'role_id' => $uoa->getRole()->getId(),
|
||||||
'exception_message' => $exception->getMessage(),
|
'exception_message' => $exception->getMessage(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Webhook;
|
|
||||||
|
|
||||||
use App\Entity\Organizations;
|
|
||||||
use Symfony\Component\Messenger\MessageBusInterface;
|
|
||||||
use Symfony\Component\RemoteEvent\RemoteEvent;
|
|
||||||
use Symfony\Component\Webhook\Messenger\SendWebhookMessage;
|
|
||||||
use Symfony\Component\Webhook\Subscriber;
|
|
||||||
|
|
||||||
class OrganizationNotifier
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly MessageBusInterface $messageBus,
|
|
||||||
private readonly string $easycheckUrl,
|
|
||||||
private readonly string $webhookSecret
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public function notifyOrganizationCreated(Organizations $organizations): void
|
|
||||||
{
|
|
||||||
$subscriber = new Subscriber(
|
|
||||||
url: rtrim($this->easycheckUrl, '/'). '/webhook/organization_created',
|
|
||||||
secret: $this->webhookSecret,
|
|
||||||
);
|
|
||||||
|
|
||||||
$event = new RemoteEvent(
|
|
||||||
name: 'organization_created',
|
|
||||||
id: uniqid('', true),
|
|
||||||
payload: [
|
|
||||||
'orgId' => $organizations->getId(),
|
|
||||||
'orgName' => $organizations->getName(),
|
|
||||||
'orgEmail' => $organizations->getEmail(),
|
|
||||||
'orgNumber' => $organizations->getNumber(),
|
|
||||||
'orgAddress' => $organizations->getAddress(),
|
|
||||||
'orgLogo' => $organizations->getLogoUrl(),
|
|
||||||
'created_at' => time(),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->messageBus->dispatch(
|
|
||||||
new SendWebhookMessage($subscriber, $event)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -414,11 +414,5 @@
|
||||||
"files": [
|
"files": [
|
||||||
"config/packages/messenger.yaml"
|
"config/packages/messenger.yaml"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"symfony/webhook": {
|
|
||||||
"version": "7.4",
|
|
||||||
"recipe": {
|
|
||||||
"version": "7.3"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,49 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{# New organization modal #}
|
{# New organization modal #}
|
||||||
{{ include('organization/organizationModal.html.twig') }}
|
<div class="modal fade" id="createOrganizationModal" tabindex="-1" aria-labelledby="createOrganizationModalLabel"
|
||||||
|
aria-hidden="true"
|
||||||
|
data-organization-target="modal">
|
||||||
|
<div class="modal-dialog modal-lg">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="createOrganizationModalLabel">Créer une organisation</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form data-action="submit->organization#createOrganization">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="organizationName" class="form-label">Nom de l'organisation</label>
|
||||||
|
<input type="text" class="form-control" id="organizationName" name="name" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="organizationEmail" class="form-label">Email</label>
|
||||||
|
<input class="form-control" id="organizationEmail" type="email" name="email" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="organizationPhone" class="form-label">Téléphone</label>
|
||||||
|
<input class="form-control" type="number" id="organizationPhone" name="phone">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="organizationAddress" class="form-label">Adresse</label>
|
||||||
|
<input class="form-control" id="organizationAddress" name="address">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label" for="organizationLogo">Logo de l'organisation</label>
|
||||||
|
<input type="file" name="logoUrl" id="organizationLogo" class="form-control"
|
||||||
|
accept="image/*">
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
||||||
|
Annuler
|
||||||
|
</button>
|
||||||
|
<button type="submit" class="btn btn-primary">Créer l'organisation</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
{% if is_granted('ROLE_SUPER_ADMIN') and not hasOrganizations %}
|
{% if is_granted('ROLE_SUPER_ADMIN') and not hasOrganizations %}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue