<?php
declare(strict_types=1);
namespace App\Bundles\ApiBundle\v1\Social\Controller;
use App\Bundles\ApiBundle\v1\Social\Resource\PreRegistrationResource;
use App\Bundles\SocialBundle\DTO\SocialUserDTO;
use App\Bundles\SocialBundle\Service\SocialUserService;
use App\Bundles\UserBundle\Config\UserNotificatorConfig;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use KnpU\OAuth2ClientBundle\Client\Provider\LinkedInClient;
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use League\OAuth2\Client\Provider\LinkedInResourceOwner;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class LinkedinController extends AbstractController
{
public function __construct(
private SocialUserService $socialUserService,
private JWTTokenManagerInterface $JWTTokenManager,
private UserNotificatorConfig $config
) {
}
#[Route('/api/v1/social/linkedin', name: 'api.v1.social.linkedin', methods: ["GET"])]
public function connect(ClientRegistry $clientRegistry): RedirectResponse
{
// https://www.linkedin.com/developers/apps/[APP_ID]/auth
// Block - OAuth 2.0 scopes
return $clientRegistry->getClient('linkedin_main')->redirect([
'r_emailaddress',
'r_liteprofile',
], []);
}
#[Route('/api/v1/social/linkedin/check', name: 'api.v1.social.linkedin.check', methods: ["GET"])]
public function check(Request $request, ClientRegistry $clientRegistry): Response
{
$error = $request->get('error');
$errorDescription = $request->get('error_description');
if (!empty($error) && !empty($errorDescription)) {
$result = [
'type' => 'error',
'data' => $errorDescription,
];
} else {
/** @var LinkedInClient $client */
$client = $clientRegistry->getClient('linkedin_main');
try {
/** @var LinkedInResourceOwner $linkedInUser */
$linkedInUser = $client->fetchUser();
$socialUserDTO = SocialUserDTO::createFromLinkedInUser($linkedInUser);
$user = $this->socialUserService->resolve($socialUserDTO);
if (!$user) {
$socialUser = $this->socialUserService->create($socialUserDTO);
$token = $this->socialUserService->generateRegistrationToken($socialUser);
$result = [
'type' => 'pre-registration',
'data' => (new PreRegistrationResource($token, $socialUserDTO))->jsonSerialize(),
];
} else {
$result = [
'type' => 'token',
'data' => $this->JWTTokenManager->create($user),
];
}
} catch (IdentityProviderException $e) {
$result = [
'type' => 'error',
'data' => $e->getMessage(),
];
}
}
return $this->render('@Api/api/v1/social/oauth-response.html.twig', [
'result' => $result,
'frontendBaseUrl' => $this->config->getFrontendBaseUrl(),
]);
}
}