<?php
declare(strict_types=1);
namespace App\Controller\API;
use App\DTO\Auth\AuthJWTResponse;
use App\DTO\Auth\AuthUserRawData;
use App\Entity\Users;
use App\Service\User\UsersManagementService;
use Exception;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use KnpU\OAuth2ClientBundle\Client\Provider\FacebookClient;
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use League\OAuth2\Client\Token\AccessToken;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class AuthController extends AbstractController
{
private UsersManagementService $usersManagementService;
public function __construct(UsersManagementService $usersManagementService)
{
$this->usersManagementService = $usersManagementService;
}
/**
* @Route("/auth/facebook/verify", name="api.auth.facebook.check", methods={"GET"})
*/
public function getAuthFacebookCheck(
Request $request,
ClientRegistry $clientRegistry,
JWTTokenManagerInterface $jwt,
UsersManagementService $usersManagementService
) {
$accessToken = $request->get('access_token');
/** @var FacebookClient $client */
$client = $clientRegistry->getClient('facebook_main');
try {
$t = new AccessToken(
[
'access_token' => $accessToken,
]
);
$facebookUser = $client->fetchUserFromToken($t);
} catch (IdentityProviderException $e) {
return $this->json(
new AuthJWTResponse(
AuthJWTResponse::STATUS_ERROR,
null,
$e->getMessage()
),
Response::HTTP_FORBIDDEN
);
}
/** @var Users $user */
$user = $this
->getDoctrine()
->getRepository(Users::class)
->findByFacebook($facebookUser->getId());
if (!$user) {
$authUserRawData = (new AuthUserRawData())
->setIdentity($facebookUser->getId())
->setFirstName($facebookUser->getFirstName())
->setLastName($facebookUser->getLastName())
->setAvatar($facebookUser->getPictureUrl())
->setLanguage($request->getLocale());
$user = $usersManagementService->createUser(Users::AUTH_FB, $authUserRawData, $this->getUser());
}
$token = $jwt->create($user);
return $this->json(
new AuthJWTResponse(
AuthJWTResponse::STATUS_SUCCESS,
$token
)
);
}
/**
* @Route("/auth/apple/verify", name="api.auth.apple.check", methods={"GET"})
*/
public function getAuthAppleCheck(
Request $request,
ClientRegistry $clientRegistry,
JWTTokenManagerInterface $jwt,
UsersManagementService $usersManagementService
) {
$accessToken = $request->get('access_token');
$code = $request->get('code');
$firstName = (string)$request->get('first_name');
$lastName = (string)$request->get('last_name');
try {
$appleUser = $usersManagementService->decodeAppleAccessToken($accessToken);
} catch (Exception $e) {
return $this->json(
new AuthJWTResponse(
AuthJWTResponse::STATUS_ERROR,
null,
$e->getMessage()
),
Response::HTTP_FORBIDDEN
);
}
/** @var Users $user */
$user = $this
->getDoctrine()
->getRepository(Users::class)
->findByApple($appleUser['id']);
if (!$user) {
$authUserRawData = (new AuthUserRawData())
->setIdentity($appleUser['id'])
->setEmail($appleUser['email'])
->setFirstName($firstName)
->setLastName($lastName);
$user = $usersManagementService->createUser(Users::AUTH_APPLE, $authUserRawData, $this->getUser());
}
$token = $jwt->create($user);
return $this->json(
new AuthJWTResponse(
AuthJWTResponse::STATUS_SUCCESS,
$token
)
);
}
/**
* @Route("/auth/google/verify", name="api.auth.google.check", methods={"GET"})
*/
public function getAuthGoogleCheck(
Request $request,
ClientRegistry $clientRegistry,
JWTTokenManagerInterface $jwt,
UsersManagementService $usersManagementService
) {
$accessToken = $request->get('access_token');
try {
$googleUser = $usersManagementService->decodeGoogleAccessToken($accessToken);
} catch (Exception $e) {
return $this->json(
new AuthJWTResponse(
AuthJWTResponse::STATUS_ERROR,
null,
$e->getMessage()
),
Response::HTTP_FORBIDDEN
);
}
// $identity $googleUser['id']
$identity = $googleUser['email'];
/** @var Users $user */
$user = $this
->getDoctrine()
->getRepository(Users::class)
->findByGoogle($identity);
if (!$user) {
$authUserRawData = (new AuthUserRawData())
->setIdentity($identity)
->setEmail($googleUser['email'])
->setFirstName($googleUser['first_name'])
->setLastName($googleUser['last_name'])
->setAvatar($googleUser['picture'])
->setLanguage($googleUser['locale']);
$user = $usersManagementService->createUser(Users::AUTH_GOOGLE, $authUserRawData, $this->getUser());
}
$token = $jwt->create($user);
return $this->json(
new AuthJWTResponse(
AuthJWTResponse::STATUS_SUCCESS,
$token
)
);
}
/**
* @Route("/auth/huawei/verify", name="api.auth.huawei.check", methods={"GET"})
*/
public function getAuthHuaweiCheck(
Request $request,
ClientRegistry $clientRegistry,
JWTTokenManagerInterface $jwt,
UsersManagementService $usersManagementService
) {
$accessToken = $request->get('access_token');
try {
$huaweiUser = $usersManagementService->decodeHuaweiAccessToken($accessToken);
} catch (Exception $e) {
return $this->json(
new AuthJWTResponse(
AuthJWTResponse::STATUS_ERROR,
null,
$e->getMessage()
),
Response::HTTP_FORBIDDEN
);
}
// $identity $googleUser['id']
$identity = $huaweiUser['id'];
/** @var Users $user */
$user = $this
->getDoctrine()
->getRepository(Users::class)
->findByHuawei($identity);
if (!$user) {
$authUserRawData = (new AuthUserRawData())
->setIdentity($identity)
->setEmail($huaweiUser['id']."@huawei.com")
->setFirstName($huaweiUser['first_name'])
->setLastName($huaweiUser['last_name'])
->setLanguage($huaweiUser['locale']);
$user = $usersManagementService->createUser(Users::AUTH_HUAWEI, $authUserRawData, $this->getUser());
}
$token = $jwt->create($user);
return $this->json(
new AuthJWTResponse(
AuthJWTResponse::STATUS_SUCCESS,
$token
)
);
}
/**
* @Route("/auth/guest", name="api.auth.guest", methods={"GET"})
*/
public function getAuthGuest(
Request $request,
JWTTokenManagerInterface $jwt,
UsersManagementService $usersManagementService
): JsonResponse {
$deviceIdentity = $request->get('device_identity');
if ($deviceIdentity) {
$user = $usersManagementService->findOrCreateGuestUserByDeviceIdentity($deviceIdentity);
} else {
$user = $usersManagementService->createGuestUser();
}
$token = $jwt->create($user);
return $this->json(
new AuthJWTResponse(
AuthJWTResponse::STATUS_SUCCESS,
$token
)
);
}
}