Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
digitalascetic/google-api-client / Service / GoogleAuthService.php
Size: Mime:
<?php
/**
 * Created by PhpStorm.
 * User: eduarddezacastellano
 * Date: 05/09/2018
 * Time: 15:41
 */

namespace DigitalAscetic\GoogleApiClientBundle\Service;

use DigitalAscetic\GoogleApiClientBundle\Entity\GoogleApiAccessToken;
use DigitalAscetic\GoogleApiClientBundle\Entity\IGoogleApiUser;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;

class GoogleAuthService extends GoogleApiService
{
    const SERVICE_NAME = 'ascetic_google_api_client.auth';

    /** @var EntityManagerInterface $em */
    private $em;

    /** @var LoggerInterface */
    private $logger;

    /**
     * GoogleAuthService constructor.
     * @param EntityManagerInterface $em
     * @param LoggerInterface $logger
     * @param array $config
     */
    public function __construct(EntityManagerInterface $em, LoggerInterface $logger, array $config)
    {
        parent::__construct($config);
        $this->em = $em;
        $this->logger = $logger;
    }

    /**
     * @param IGoogleApiUser $user
     * @param string|null $host
     * @return \Google_Client
     */
    public function getClientAuthenticatedForUser(IGoogleApiUser $user, string $host = null)
    {
        $client = $this->getClient($host);

        if ($client->isAccessTokenExpired()) {
            $this->refreshAccessTokenWithRefreshToken($user, $user->getGoogleApiRefreshToken());
        }

        return $client;
    }

    /**
     * @param IGoogleApiUser $user
     * @param $refreshToken
     * @return GoogleApiAccessToken|bool
     * @throws \Google_Exception
     */
    public function getOauth2AccessToken(IGoogleApiUser $user, $refreshToken)
    {
        $client = $this->getClient();

        if ($client->isAccessTokenExpired()) {
            $this->refreshAccessTokenWithRefreshToken($user, $refreshToken);
        }

        if ($client->getAccessToken()) {
            return GoogleApiAccessToken::getGoogleTokenApiFromArray($client->getAccessToken());
        }

        return false;
    }


    public function getAuthUrl()
    {
        $auth_url = $this->getClient()->createAuthUrl();
        return filter_var($auth_url, FILTER_SANITIZE_URL);
    }


    /**
     * @param string $code
     * @param string $host
     * @param IGoogleApiUser|null $user
     * @return GoogleApiAccessToken|bool
     */
    public function authenticateClientWithAuthCode(string $code, string $host, ?IGoogleApiUser $user)
    {
        $client = $this->getClient($host);

        $validToken = false;

        try {
            $accessToken = $client->fetchAccessTokenWithAuthCode($code);

            if (!empty($accessToken['error'])) {
                throw new \Exception($accessToken['error']);
            } else {
                $validToken = true;
            }
        } catch (\Exception $exception) {
            $this->logger->info('GOOGLE_AUTH_FETCH_ACCESS_TOKEN_WITH_CODE: ' . $exception->getMessage());
        }

        if ($validToken) {
            $client->setAccessToken($accessToken);

            $refreshToken = $client->getRefreshToken();

            $token = GoogleApiAccessToken::getGoogleTokenApiFromArray($client->getAccessToken());

            if (isset($refreshToken) &&
                isset($user)) {
                $this->persistRefreshToken($user, $refreshToken);
            }

            return $token;
        }

        return false;
    }


    /**
     * @param IGoogleApiUser $user
     * @return bool
     * @throws \Google_Exception
     */
    public function revokeUserToken(IGoogleApiUser $user)
    {
        if ($this->revokeToken($user->getGoogleApiRefreshToken())) {
            $this->persistRefreshToken($user);
            return true;
        }

        return false;
    }


    /**
     * @param string|null $token
     * @return bool
     * @throws \Google_Exception
     */
    public function revokeToken($token = null)
    {
        $client = $this->getClient();

        if ($client->revokeToken($token)) {
            return true;
        }

        return false;
    }

    /**
     * @param $id
     * @return IGoogleApiUser
     */
    public function getUserById($id)
    {
        $userConfig = $this->config['user'];

        /** @var IGoogleApiUser $user */
        $user = $this->em->getRepository($userConfig['user_class'])->findOneBy(array($userConfig['property_id'] => $id));

        return $user;
    }


    /**
     * @param IGoogleApiUser $user
     * @return bool
     */
    public function hasAuthorization(IGoogleApiUser $user): bool
    {
        return !empty($user->getGoogleApiRefreshToken());
    }

    /**
     * @param IGoogleApiUser $user
     * @param string|null $refreshToken
     * @throws \Google_Exception
     */
    private function refreshAccessTokenWithRefreshToken(IGoogleApiUser $user, $refreshToken = null): void
    {
        $client = $this->getClient();
        $isValidToken = false;

        try {
            $accessToken = $client->fetchAccessTokenWithRefreshToken($refreshToken);

            if (!empty($accessToken['error'])) {
                throw new \Exception($accessToken['error']);
            } else {
                $isValidToken = true;
            }
        } catch (\Exception $exception) {
            $this->logger->info('GOOGLE_AUTH_FETCH_ACCESS_TOKEN_WITH_REFRESH_TOKEN: ' . $exception->getMessage());
            // IF REFRESH TOKEN IS NO LONGER VALID, WE REMOVE IT
            $this->persistRefreshToken($user);
        }

        if ($isValidToken) {
            $client->setAccessToken($accessToken);
        }

        // If refresh token has changed, we update new value
        if (!empty($client->getRefreshToken()) &&
            strcmp($client->getRefreshToken(), $refreshToken) !== 0) {
            $this->persistRefreshToken($user, $client->getRefreshToken());
        }
    }


    /**
     * @param IGoogleApiUser $user
     * @param string|null $token
     */
    private function persistRefreshToken(IGoogleApiUser $user, string $token = null)
    {
        $user->setGoogleApiRefreshToken($token);
        $this->em->persist($user);
        $this->em->flush();
    }
}