<?php
namespace EADPlataforma\Controller\Admin;
use EADPlataforma\Entity\User;
use EADPlataforma\Enum\UserEnum;
use EADPlataforma\Error\ActionInvalidException;
use EADPlataforma\Error\FieldException;
use EADPlataforma\Error\NotFoundException;
use EADPlataforma\Requests\Login\AuthenticationRequest;
use EADPlataforma\Requests\Login\LoginRequest;
use EADPlataforma\Requests\Login\ResetPasswordRequest;
use EADPlataforma\Requests\Login\SendEmailAuthenticationRequest;
use EADPlataforma\Requests\Login\SendEmailRecoverPasswordRequest;
use EADPlataforma\Requests\Login\UpdateUserNotificationRequest;
use EADPlataforma\Response\HttpNoContent;
use EADPlataforma\Response\HttpOk;
use EADPlataforma\Services\EntityServices\LoginService;
use EADPlataforma\Services\EntityServices\PermissionService;
use EADPlataforma\Services\EntityServices\SessionService;
use EADPlataforma\Services\EntityServices\UserService;
use EADPlataforma\Services\EntityServices\ConfigurationIpService;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
/**
* @Route(
* path = "/auth",
* schemes = {"http|https"}
* )
* @Cache(
* maxage = "0",
* smaxage = "0",
* expires = "now",
* public = false
* )
*/
class LoginController extends AbstractController {
public function getEntityClass(): string
{
return User::class;
}
/**
* @Route(
* name = "authLogin",
* methods = {"POST"}
* )
*
* @throws ActionInvalidException
*/
public function authLogin(
LoginRequest $request,
LoginService $loginService,
PermissionService $permissionService,
SessionService $sessionService,
ConfigurationIpService $configurationIpService
): JsonResponse
{
if(!$loginService->verifyUserAgentValid($request)){
throw new ActionInvalidException(
$this->configuration->getLanguage('login_invalid', 'login')
);
}
$user = $loginService->getUserLogin($request);
if(!$user){
throw new ActionInvalidException(
$this->configuration->getLanguage('login_invalid', 'login')
);
}
if(!$configurationIpService->isValidIp($request->request->getClientIp())){
throw new ActionInvalidException(
$this->configuration->getLanguage('login_invalid', 'login')
);
}
if($user->getId() != UserEnum::YES && $user->getPassword() == UserEnum::PASSWORD_RESET){
throw new ActionInvalidException(
$this->configuration->getLanguage('password_reset', 'login')
);
}
if(!$loginService->verifyUserLoginValid($user, $request->password)){
throw new ActionInvalidException(
$this->configuration->getLanguage('login_invalid', 'login')
);
}
$platformStatus = $this->clientConfig->getPlatformStatus();
if(!$loginService->verifyPlataformStatus($user, $platformStatus)){
throw new ActionInvalidException(
$this->configuration->getLanguage('login_invalid', 'login')
);
}
if($user->getAuthenticationAllow()){
$signId = $this->generalService->signDataWithExpiration($user->getId(), 300);
$data = [
"userHash" => $signId,
"authenticationActivated" => $user->getAuthenticationAllow()
];
return new HttpOk($data);
}
$data = $sessionService->registerSession($request, $user);
if(!$data) {
throw new ActionInvalidException("ExecutionTypeInvalid");
}
return new HttpOk($data);
}
/**
* @Route(
* path = "/mfa",
* name = "authMFA",
* methods = {"POST"},
* )
*
* @throws ActionInvalidException
* @throws NotFoundException
*/
public function authMFA(
AuthenticationRequest $request,
UserService $userService,
LoginService $loginService,
SessionService $sessionService
): JsonResponse
{
$userHash = $request->data['userHash'];
$userId = $this->generalService->verifySignedDataExpire($userHash);
if(!$userId){
throw new ActionInvalidException(
$this->configuration->getLanguage('user_not_found', 'login')
);
}
$user = $userService->searchUser($userId);
if(!$user){
throw new NotFoundException(
$this->configuration->getLanguage('user_not_found', 'login')
);
}
if(!$user->getAuthenticationAllow()){
throw new NotFoundException(
$this->configuration->getLanguage('authentication_not_enabled', 'login')
);
}
if(!$loginService->verifyAuthenticationValid($request, $user)){
throw new ActionInvalidException(
$this->configuration->getLanguage('authentication_invalid', 'login')
);
}
$data = $sessionService->registerSession($request, $user);
if(!$data) {
throw new ActionInvalidException("ExecutionTypeInvalid");
}
return new HttpOk($data);
}
/**
* @Route(
* path = "/email/mfa/{userHash}",
* name = "sendEmailAuthentication",
* methods = {"PUT"}
* )
*
* @throws ActionInvalidException
* @throws NotFoundException
*/
public function sendEmailAuthentication(
SendEmailAuthenticationRequest $request,
UserService $userService,
LoginService $loginService
): JsonResponse
{
$userHash = $request->request->get('userHash');
$userId = $this->generalService->verifySignedDataExpire($userHash);
if(!$userId){
throw new ActionInvalidException(
$this->configuration->getLanguage('email_invalid', 'login')
);
}
$user = $userService->searchUser($userId);
if (!$user) {
throw new NotFoundException($this->configuration->getLanguage('user_not_found', 'login'));
}
if(!$loginService->sendEmailAuthentication($user)){
throw new ActionInvalidException(
$this->configuration->getLanguage('email_invalid', 'login')
);
}
return new HttpNoContent;
}
/**
* @Route(
* path = "/user/notification/{hash}",
* name = "updateUserNotification",
* methods = {"PUT"},
* requirements = { "hash" = "([a-zA-Z0-9_-]+)" }
* )
*
* @throws ActionInvalidException
* @throws NotFoundException
*/
public function updateUserNotification(
UpdateUserNotificationRequest $request,
UserService $userService,
LoginService $loginService
): JsonResponse
{
$hash = $request->request->get('hash');
$user = $userService->searchUserByHash($hash);
if(!$user){
throw new NotFoundException($this->configuration->getLanguage('user_not_found', 'login'));
}
$userService->updateUserNotification($request->data, $user);
return new HttpNoContent;
}
/**
* @Route(
* path = "/email/recover/password",
* name = "sendEmailRecoverPassword",
* methods = {"POST"}
* )
*
* @throws ActionInvalidException
* @throws NotFoundException
*/
public function sendEmailRecoverPassword(
SendEmailRecoverPasswordRequest $request,
UserService $userService,
LoginService $loginService
): JsonResponse
{
$email = $request->data["email"];
$user = $userService->searchUserByEmail($email, UserEnum::ITEM_NO_DELETED);
if(!$user){
throw new NotFoundException($this->configuration->getLanguage('user_not_found', 'login'));
}
if(!$loginService->sendEmailRecoverPassword($user)){
throw new ActionInvalidException(
$this->configuration->getLanguage('email_invalid', 'login')
);
}
return new HttpNoContent;
}
/**
* @Route(
* path = "/reset/password",
* name = "resetPassword",
* methods = {"POST"}
* )
*
* @throws ActionInvalidException
*/
public function resetPassword(
ResetPasswordRequest $request,
UserService $userService,
LoginService $loginService
): JsonResponse
{
$errorMessage = $loginService->verifyResetPassword($request->data);
if(!empty($errorMessage)){
throw new ActionInvalidException($errorMessage);
}
$data = [
"message" => $this->configuration->getLanguage('updated_password', 'login'),
"status" => UserEnum::YES,
"url" => "https://{$this->client->getDomainPrimary()}/login"
];
return new HttpOk($data);
}
}