View source
<?php
namespace Drupal\google_api_client\Controller;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Link;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Drupal\google_api_client\Service\GoogleApiClientService;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class Callback extends ControllerBase {
private $googleApiClientService;
protected $tempStoreFactory;
protected $moduleHandler;
protected $requestStack;
public function __construct(GoogleApiClientService $googleApiClient, ModuleHandlerInterface $module_handler, PrivateTempStoreFactory $temp_store_factory, RequestStack $request_stack) {
$this->googleApiClientService = $googleApiClient;
$this->moduleHandler = $module_handler;
$this->tempStoreFactory = $temp_store_factory;
$this->requestStack = $request_stack;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('google_api_client.client'), $container
->get('module_handler'), $container
->get('tempstore.private'), $container
->get('request_stack'));
}
public function callbackUrl(Request $request) {
if ($state = $request
->get('state')) {
$state = Json::decode($state);
if (isset($state['src']) && !in_array('google_api_client', $state['src'])) {
$this->moduleHandler
->invokeAll('google_api_client_google_response', [
$request,
]);
return $this
->redirect('<front>');
}
}
$tempStore = $this->tempStoreFactory
->get('google_api_client');
if ($request
->get('error')) {
if ($request
->get('error') == 'access_denied') {
$this
->messenger()
->addError($this
->t('You denied access so account is not authenticated'));
}
else {
$this
->messenger()
->addError($this
->t('Something caused error in authentication.'));
}
$tempStore
->delete('account_id');
$tempStore
->delete('account_type');
if ($tempStore
->get('state_destination')) {
$destination = $tempStore
->get('state_destination');
$tempStore
->delete('state_destination');
return new RedirectResponse(Url::fromUserInput($destination)
->toString());
}
$tempStore
->delete('state_src');
$tempStore
->delete('state_hash');
return $this
->redirect('<front>');
}
$account_id = $request
->get('id');
$entity_type = $request
->get('type');
if ($entity_type) {
$tempStore
->set('account_type', $entity_type);
}
else {
if ($tempStore
->get('account_type')) {
$entity_type = $tempStore
->get('account_type');
}
else {
$entity_type = 'google_api_client';
$tempStore
->set('account_type', $entity_type);
}
}
if (!google_api_client_load_library()) {
$status_report_link = Link::createFromRoute($this
->t('Status Report'), 'system.status')
->toString();
$this
->messenger()
->addError($this
->t("Can't authenticate with google as library is missing check %status_report for more details", [
'%status_report' => $status_report_link,
]));
return $this
->redirect('entity.google_api_client.collection');
}
if ($account_id == NULL && $tempStore
->get('account_id')) {
$account_id = $tempStore
->get('account_id');
}
elseif ($account_id) {
$tempStore
->set('account_id', $account_id);
}
if ($account_id) {
$google_api_client = $this
->entityTypeManager()
->getStorage($entity_type)
->load($account_id);
$this->googleApiClientService
->setGoogleApiClient($google_api_client);
$this->googleApiClientService->googleClient
->setApplicationName("Google OAuth2");
if ($request
->get('code')) {
$this->googleApiClientService->googleClient
->fetchAccessTokenWithAuthCode($request
->get('code'));
$google_api_client
->setAccessToken(Json::encode($this->googleApiClientService->googleClient
->getAccessToken()));
$google_api_client
->setAuthenticated(TRUE);
$google_api_client
->save();
$destination = FALSE;
if ($tempStore
->get('state_destination')) {
$destination = $tempStore
->get('state_destination');
}
$tempStore
->delete('state_destination');
$tempStore
->delete('state_src');
$tempStore
->delete('state_hash');
$tempStore
->delete('account_id');
$tempStore
->delete('account_type');
$this
->messenger()
->addMessage($this
->t('Api Account saved'));
$this->moduleHandler
->invokeAll('google_api_client_google_response', [
$request,
]);
if ($destination) {
return new RedirectResponse(Url::fromUserInput($destination)
->toString());
}
return $this
->redirect('entity.google_api_client.collection');
}
if ($this->googleApiClientService->googleClient) {
if ($tempStore
->get('state_src')) {
$state = [
'src' => $tempStore
->get('state_src'),
'hash' => $tempStore
->get('state_hash'),
];
}
else {
$state = [
'src' => [
'google_api_client',
],
'hash' => md5(rand()),
];
if ($destination = $request
->get('destination')) {
$tempStore
->set('state_destination', $destination);
$this->requestStack
->getCurrentRequest()->query
->remove('destination');
}
}
$this->moduleHandler
->alter('google_api_client_state', $state, $google_api_client);
$tempStore
->set('state_src', $state['src']);
$tempStore
->set('state_hash', $state['hash']);
$state = Json::encode($state);
$this->googleApiClientService->googleClient
->setState($state);
$auth_url = $this->googleApiClientService->googleClient
->createAuthUrl();
$request
->getSession()
->save();
$response = new TrustedRedirectResponse($auth_url);
$response
->send();
exit;
}
}
return $this
->redirect('entity.google_api_client.collection');
}
public function authenticateAccess(AccountInterface $account) {
$request = $this->requestStack
->getCurrentRequest();
if ($account
->hasPermission('administer google api settings')) {
return AccessResult::allowed();
}
if ($state = $request
->get('state')) {
$state = Json::decode($state);
$tempStore = $this->tempStoreFactory
->get('google_api_client');
if (!isset($state['hash']) || $state['hash'] != $tempStore
->get('state_hash')) {
$this
->messenger()
->addError($this
->t('Invalid state parameter'), 'error');
return AccessResult::forbidden();
}
else {
return AccessResult::allowed();
}
}
$account_id = $request
->get('id');
$account_type = $request
->get('type', 'google_api_client');
$access = $this->moduleHandler
->invokeAll('google_api_client_authenticate_account_access', [
$account_id,
$account_type,
$account,
]);
if (in_array(AccessResult::forbidden(), $access)) {
return AccessResult::forbidden();
}
elseif (in_array(AccessResult::allowed(), $access)) {
return AccessResult::allowed();
}
return AccessResult::neutral();
}
}