<?php
namespace App\EventListener;
use App\Entity\ApiRefreshToken;
use App\Entity\ApiToken;
use App\Entity\Language;
use App\Entity\Permission;
use App\Entity\PermissionType;
use App\Entity\Role;
use App\Entity\User;
use App\Service\ApiService;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
class AuthenticationSuccessListener implements AuthenticationSuccessHandlerInterface
{
private EntityManagerInterface $em;
private RouterInterface $router;
private ApiService $api;
public function __construct(EntityManagerInterface $em, RouterInterface $router, ApiService $api)
{
$this->em = $em;
$this->router = $router;
$this->api = $api;
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token): \Symfony\Component\HttpFoundation\Response
{
/* @var $user User */
$user = $token->getUser();
$superAdmin = $this->em->getRepository(Role::class)->findOneBy(['keyName'=>'role.super.admin']);
$languagesArr = [];
$languages = $this->em->getRepository(Language::class)->findEnabledAndNotDeleted();
foreach ($languages as $language)
$languagesArr[] = $language->getCode();
$routePermissionType = $this->em->getRepository(PermissionType::class)->findOneBy(['keyName'=>'permission.type.route']);
$userRoutePermissions = $this->em->getRepository(Permission::class)->findByTypeAndUser($user, $routePermissionType);
$configuratorPermissionType = $this->em->getRepository(PermissionType::class)->findOneBy(['keyName'=>'permission.type.configurator']);
$userConfiguratorPermissions = $this->em->getRepository(Permission::class)->findByTypeAndUser($user, $configuratorPermissionType);
$userRoutesArr = [];
$userPermissionsArr = [];
if($user->getUserRoles()->contains($superAdmin)){
$allRoutes = $this->router->getRouteCollection();
foreach ($allRoutes as $key => $route){
if(!str_contains($route->getPath(), '/test/') AND !str_starts_with($route->getPath(), '/_')){
$a = [];
$a['name'] = $key;
$a['path'] = $route->getPath();
$a['methods'] = $route->getMethods();
$userRoutesArr[$key] = $a;
}
}
foreach ($this->em->getRepository(Permission::class)->findBy(['type'=>$configuratorPermissionType]) as $configuratorPermission) {
$userPermissionsArr[] = $configuratorPermission->getKeyName();
}
}
else{
foreach ($userRoutePermissions as $routePermission) {
foreach ($routePermission->getRoutes() as $route)
if (!is_null($this->router->getRouteCollection()->get($route->getRouteName()))) {
$a = [];
$a['name'] = $route->getRouteName();
$a['path'] = $this->router->getRouteCollection()->get($route->getRouteName())->getPath();
$a['methods'] = $this->router->getRouteCollection()->get($route->getRouteName())->getMethods();
$userRoutesArr[$route->getRouteName()] = $a;
}
}
foreach ($userConfiguratorPermissions as $configuratorPermission) {
$userPermissionsArr[] = $configuratorPermission->getKeyName();
}
//add default routes
$defaultRoutes = ['translations_for_locale', 'product_list', 'translations', 'catalogue_categories', 'catalogue_categories_show',
'catalogue_group_type_show', 'catalogue_component_show', 'catalogue_components_list'];
foreach ($defaultRoutes as $defaultRoute){
$route = $this->router->getRouteCollection()->get($defaultRoute);
if (!is_null($route)) {
$a = [];
$a['name'] = $defaultRoute;
$a['path'] = $route->getPath();
$a['methods'] = $route->getMethods();
$userRoutesArr[$defaultRoute] = $a;
}
}
}
$userData = [];
$userData['accname'] = $user->getName();
$userData['company']['id'] = $user->getCompany()->getId();
$userData['company']['name'] = $user->getCompany()->getName();
$userData['username'] = $user->getEmail();
$userData['manufacture'] = false;
$userData['workplace'] = $user->getWorker()?->getTeam()?->getWorkplaces()?->first();
$data = [
'locale' => $user->getLocale(),
'languages' => $languagesArr,
'roles' => $user->getUserRoles(),
'permissions' => [
'configurator' => $userPermissionsArr,
'routes' => $userRoutesArr,
1 => [
'key' => 'manager_code',
'type' => 'field',
],
],
'sidebar' => [[
'_name' => 'CSidebarNav',
'_children' => [[
'_name' => 'CSidebarNavItem',
'name' => 'Managers',
'to' => '/managers',
'fontIcon' => 'fa fa-users',
'exact' => false,
], [
'_name' => 'CSidebarNavItem',
'name' => 'Customers',
'to' => '/customers',
'fontIcon' => 'fa fa-cubes',
'exact' => false,
],
],
]]
];
$token = $user->getValidApiToken();
if (is_null($token)){
$token = new ApiToken($user);
$this->em->persist($token);
$token = $token->getToken();
}
$apiRefreshToken = $user->getValidApiRefreshToken();
$expiresAt = $apiRefreshToken?->getExpiresAt()->getTimestamp();
$refreshToken = $apiRefreshToken?->getToken();
if (is_null($apiRefreshToken)){
$apiRefreshToken = new ApiRefreshToken($user);
$this->em->persist($apiRefreshToken);
$refreshToken = $apiRefreshToken->getToken();
$expiresAt = $apiRefreshToken->getExpiresAt()->getTimestamp();
}
$this->em->flush();
$tokens = [];
$tokens['token'] = $token;
$tokens['refresh'] = $refreshToken;
$tokens['expiresAt'] = $expiresAt;
return $this->api->json(['token'=>$tokens, 'user' => $userData,'data' => $data, 'redirect'=>'/'],'');
}
}