laravel-6 support

This commit is contained in:
RafficMohammed
2023-01-08 01:17:22 +05:30
parent 1a5c16ae4b
commit 774eed8b0e
4962 changed files with 279380 additions and 297961 deletions

View File

@@ -3,8 +3,9 @@
namespace Laravel\Socialite;
use ArrayAccess;
use Laravel\Socialite\Contracts\User;
abstract class AbstractUser implements ArrayAccess, Contracts\User
abstract class AbstractUser implements ArrayAccess, User
{
/**
* The unique identifier for the user.

View File

@@ -6,6 +6,7 @@ use Illuminate\Support\Facades\Facade;
use Laravel\Socialite\Contracts\Factory;
/**
* @method static \Laravel\Socialite\Contracts\Provider driver(string $driver = null)
* @see \Laravel\Socialite\SocialiteManager
*/
class Socialite extends Facade

View File

@@ -2,12 +2,12 @@
namespace Laravel\Socialite\One;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use InvalidArgumentException;
use Illuminate\Http\RedirectResponse;
use League\OAuth1\Client\Server\Server;
use League\OAuth1\Client\Credentials\TokenCredentials;
use Laravel\Socialite\Contracts\Provider as ProviderContract;
use League\OAuth1\Client\Credentials\TokenCredentials;
use League\OAuth1\Client\Server\Server;
abstract class AbstractProvider implements ProviderContract
{
@@ -25,6 +25,13 @@ abstract class AbstractProvider implements ProviderContract
*/
protected $server;
/**
* A hash representing the last requested user.
*
* @var string
*/
protected $userHash;
/**
* Create a new provider instance.
*
@@ -55,8 +62,9 @@ abstract class AbstractProvider implements ProviderContract
/**
* Get the User instance for the authenticated user.
*
* @throws \InvalidArgumentException
* @return \Laravel\Socialite\One\User
*
* @throws \InvalidArgumentException
*/
public function user()
{
@@ -64,14 +72,21 @@ abstract class AbstractProvider implements ProviderContract
throw new InvalidArgumentException('Invalid request. Missing OAuth verifier.');
}
$user = $this->server->getUserDetails($token = $this->getToken());
$token = $this->getToken();
$user = $this->server->getUserDetails(
$token, $this->shouldBypassCache($token->getIdentifier(), $token->getSecret())
);
$instance = (new User)->setRaw($user->extra)
->setToken($token->getIdentifier(), $token->getSecret());
return $instance->map([
'id' => $user->uid, 'nickname' => $user->nickname,
'name' => $user->name, 'email' => $user->email, 'avatar' => $user->imageUrl,
'id' => $user->uid,
'nickname' => $user->nickname,
'name' => $user->name,
'email' => $user->email,
'avatar' => $user->imageUrl,
]);
}
@@ -89,14 +104,19 @@ abstract class AbstractProvider implements ProviderContract
$tokenCredentials->setIdentifier($token);
$tokenCredentials->setSecret($secret);
$user = $this->server->getUserDetails($tokenCredentials);
$user = $this->server->getUserDetails(
$tokenCredentials, $this->shouldBypassCache($token, $secret)
);
$instance = (new User)->setRaw($user->extra)
->setToken($tokenCredentials->getIdentifier(), $tokenCredentials->getSecret());
return $instance->map([
'id' => $user->uid, 'nickname' => $user->nickname,
'name' => $user->name, 'email' => $user->email, 'avatar' => $user->imageUrl,
'id' => $user->uid,
'nickname' => $user->nickname,
'name' => $user->name,
'email' => $user->email,
'avatar' => $user->imageUrl,
]);
}
@@ -124,6 +144,28 @@ abstract class AbstractProvider implements ProviderContract
return $this->request->has('oauth_token') && $this->request->has('oauth_verifier');
}
/**
* Determine if the user information cache should be bypassed.
*
* @param string $token
* @param string $secret
* @return bool
*/
protected function shouldBypassCache($token, $secret)
{
$newHash = sha1($token.'_'.$secret);
if (! empty($this->userHash) && $newHash !== $this->userHash) {
$this->userHash = $newHash;
return true;
}
$this->userHash = $this->userHash ?: $newHash;
return false;
}
/**
* Set the request instance.
*

View File

@@ -15,7 +15,7 @@ class TwitterProvider extends AbstractProvider
throw new InvalidArgumentException('Invalid request. Missing OAuth verifier.');
}
$user = $this->server->getUserDetails($token = $this->getToken());
$user = $this->server->getUserDetails($token = $this->getToken(), $this->shouldBypassCache($token->getIdentifier(), $token->getSecret()));
$extraDetails = [
'location' => $user->location,
@@ -26,8 +26,11 @@ class TwitterProvider extends AbstractProvider
->setToken($token->getIdentifier(), $token->getSecret());
return $instance->map([
'id' => $user->uid, 'nickname' => $user->nickname,
'name' => $user->name, 'email' => $user->email, 'avatar' => $user->imageUrl,
'id' => $user->uid,
'nickname' => $user->nickname,
'name' => $user->name,
'email' => $user->email,
'avatar' => $user->imageUrl,
'avatar_original' => str_replace('_normal', '', $user->imageUrl),
]);
}

View File

@@ -3,15 +3,16 @@
namespace Laravel\Socialite;
use Illuminate\Support\Arr;
use Illuminate\Support\Manager;
use Illuminate\Support\Str;
use InvalidArgumentException;
use Illuminate\Support\Manager;
use Laravel\Socialite\Two\GithubProvider;
use Laravel\Socialite\Two\GoogleProvider;
use Laravel\Socialite\One\TwitterProvider;
use Laravel\Socialite\Two\FacebookProvider;
use Laravel\Socialite\Two\LinkedInProvider;
use Laravel\Socialite\Two\BitbucketProvider;
use Laravel\Socialite\Two\FacebookProvider;
use Laravel\Socialite\Two\GithubProvider;
use Laravel\Socialite\Two\GitlabProvider;
use Laravel\Socialite\Two\GoogleProvider;
use Laravel\Socialite\Two\LinkedInProvider;
use League\OAuth1\Client\Server\Twitter as TwitterServer;
class SocialiteManager extends Manager implements Contracts\Factory
@@ -34,7 +35,7 @@ class SocialiteManager extends Manager implements Contracts\Factory
*/
protected function createGithubDriver()
{
$config = $this->app['config']['services.github'];
$config = $this->app->make('config')['services.github'];
return $this->buildProvider(
GithubProvider::class, $config
@@ -48,7 +49,7 @@ class SocialiteManager extends Manager implements Contracts\Factory
*/
protected function createFacebookDriver()
{
$config = $this->app['config']['services.facebook'];
$config = $this->app->make('config')['services.facebook'];
return $this->buildProvider(
FacebookProvider::class, $config
@@ -62,7 +63,7 @@ class SocialiteManager extends Manager implements Contracts\Factory
*/
protected function createGoogleDriver()
{
$config = $this->app['config']['services.google'];
$config = $this->app->make('config')['services.google'];
return $this->buildProvider(
GoogleProvider::class, $config
@@ -76,7 +77,7 @@ class SocialiteManager extends Manager implements Contracts\Factory
*/
protected function createLinkedinDriver()
{
$config = $this->app['config']['services.linkedin'];
$config = $this->app->make('config')['services.linkedin'];
return $this->buildProvider(
LinkedInProvider::class, $config
@@ -90,13 +91,27 @@ class SocialiteManager extends Manager implements Contracts\Factory
*/
protected function createBitbucketDriver()
{
$config = $this->app['config']['services.bitbucket'];
$config = $this->app->make('config')['services.bitbucket'];
return $this->buildProvider(
BitbucketProvider::class, $config
);
}
/**
* Create an instance of the specified driver.
*
* @return \Laravel\Socialite\Two\AbstractProvider
*/
protected function createGitlabDriver()
{
$config = $this->app->make('config')['services.gitlab'];
return $this->buildProvider(
GitlabProvider::class, $config
);
}
/**
* Build an OAuth 2 provider instance.
*
@@ -107,7 +122,7 @@ class SocialiteManager extends Manager implements Contracts\Factory
public function buildProvider($provider, $config)
{
return new $provider(
$this->app['request'], $config['client_id'],
$this->app->make('request'), $config['client_id'],
$config['client_secret'], $this->formatRedirectUrl($config),
Arr::get($config, 'guzzle', [])
);
@@ -120,10 +135,10 @@ class SocialiteManager extends Manager implements Contracts\Factory
*/
protected function createTwitterDriver()
{
$config = $this->app['config']['services.twitter'];
$config = $this->app->make('config')['services.twitter'];
return new TwitterProvider(
$this->app['request'], new TwitterServer($this->formatConfig($config))
$this->app->make('request'), new TwitterServer($this->formatConfig($config))
);
}
@@ -153,16 +168,16 @@ class SocialiteManager extends Manager implements Contracts\Factory
$redirect = value($config['redirect']);
return Str::startsWith($redirect, '/')
? $this->app['url']->to($redirect)
? $this->app->make('url')->to($redirect)
: $redirect;
}
/**
* Get the default driver name.
*
* @throws \InvalidArgumentException
*
* @return string
*
* @throws \InvalidArgumentException
*/
public function getDefaultDriver()
{

View File

@@ -7,13 +7,6 @@ use Laravel\Socialite\Contracts\Factory;
class SocialiteServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
@@ -35,4 +28,14 @@ class SocialiteServiceProvider extends ServiceProvider
{
return [Factory::class];
}
/**
* Determine if the provider is deferred.
*
* @return bool
*/
public function isDeferred()
{
return true;
}
}

View File

@@ -3,11 +3,10 @@
namespace Laravel\Socialite\Two;
use GuzzleHttp\Client;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use GuzzleHttp\ClientInterface;
use Illuminate\Http\RedirectResponse;
use Laravel\Socialite\Contracts\Provider as ProviderContract;
abstract class AbstractProvider implements ProviderContract
@@ -156,7 +155,7 @@ abstract class AbstractProvider implements ProviderContract
}
/**
* Get the authentication URL for the provider.
* Build the authentication URL for the provider from the given base URL.
*
* @param string $url
* @param string $state
@@ -176,7 +175,8 @@ abstract class AbstractProvider implements ProviderContract
protected function getCodeFields($state = null)
{
$fields = [
'client_id' => $this->clientId, 'redirect_uri' => $this->redirectUrl,
'client_id' => $this->clientId,
'redirect_uri' => $this->redirectUrl,
'scope' => $this->formatScopes($this->getScopes(), $this->scopeSeparator),
'response_type' => 'code',
];
@@ -257,11 +257,9 @@ abstract class AbstractProvider implements ProviderContract
*/
public function getAccessTokenResponse($code)
{
$postKey = (version_compare(ClientInterface::VERSION, '6') === 1) ? 'form_params' : 'body';
$response = $this->getHttpClient()->post($this->getTokenUrl(), [
'headers' => ['Accept' => 'application/json'],
$postKey => $this->getTokenFields($code),
'form_params' => $this->getTokenFields($code),
]);
return json_decode($response->getBody(), true);
@@ -276,8 +274,10 @@ abstract class AbstractProvider implements ProviderContract
protected function getTokenFields($code)
{
return [
'client_id' => $this->clientId, 'client_secret' => $this->clientSecret,
'code' => $code, 'redirect_uri' => $this->redirectUrl,
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'code' => $code,
'redirect_uri' => $this->redirectUrl,
];
}

View File

@@ -3,7 +3,7 @@
namespace Laravel\Socialite\Two;
use Exception;
use GuzzleHttp\ClientInterface;
use Illuminate\Support\Arr;
class BitbucketProvider extends AbstractProvider implements ProviderInterface
{
@@ -86,9 +86,11 @@ class BitbucketProvider extends AbstractProvider implements ProviderInterface
protected function mapUserToObject(array $user)
{
return (new User)->setRaw($user)->map([
'id' => $user['uuid'], 'nickname' => $user['username'],
'name' => array_get($user, 'display_name'), 'email' => array_get($user, 'email'),
'avatar' => array_get($user, 'links.avatar.href'),
'id' => $user['uuid'],
'nickname' => $user['username'],
'name' => Arr::get($user, 'display_name'),
'email' => Arr::get($user, 'email'),
'avatar' => Arr::get($user, 'links.avatar.href'),
]);
}
@@ -100,12 +102,10 @@ class BitbucketProvider extends AbstractProvider implements ProviderInterface
*/
public function getAccessToken($code)
{
$postKey = (version_compare(ClientInterface::VERSION, '6') === 1) ? 'form_params' : 'body';
$response = $this->getHttpClient()->post($this->getTokenUrl(), [
'auth' => [$this->clientId, $this->clientSecret],
'headers' => ['Accept' => 'application/json'],
$postKey => $this->getTokenFields($code),
'form_params' => $this->getTokenFields($code),
]);
return json_decode($response->getBody(), true)['access_token'];

View File

@@ -3,7 +3,6 @@
namespace Laravel\Socialite\Two;
use Illuminate\Support\Arr;
use GuzzleHttp\ClientInterface;
class FacebookProvider extends AbstractProvider implements ProviderInterface
{
@@ -19,7 +18,7 @@ class FacebookProvider extends AbstractProvider implements ProviderInterface
*
* @var string
*/
protected $version = 'v3.0';
protected $version = 'v3.3';
/**
* The user fields being requested.
@@ -70,14 +69,10 @@ class FacebookProvider extends AbstractProvider implements ProviderInterface
*/
public function getAccessTokenResponse($code)
{
$postKey = (version_compare(ClientInterface::VERSION, '6') === 1) ? 'form_params' : 'body';
$response = $this->getHttpClient()->post($this->getTokenUrl(), [
$postKey => $this->getTokenFields($code),
'form_params' => $this->getTokenFields($code),
]);
$data = [];
$data = json_decode($response->getBody(), true);
return Arr::add($data, 'expires_in', Arr::pull($data, 'expires'));
@@ -113,10 +108,13 @@ class FacebookProvider extends AbstractProvider implements ProviderInterface
$avatarUrl = $this->graphUrl.'/'.$this->version.'/'.$user['id'].'/picture';
return (new User)->setRaw($user)->map([
'id' => $user['id'], 'nickname' => null, 'name' => isset($user['name']) ? $user['name'] : null,
'email' => isset($user['email']) ? $user['email'] : null, 'avatar' => $avatarUrl.'?type=normal',
'id' => $user['id'],
'nickname' => null,
'name' => $user['name'] ?? null,
'email' => $user['email'] ?? null,
'avatar' => $avatarUrl.'?type=normal',
'avatar_original' => $avatarUrl.'?width=1920',
'profileUrl' => isset($user['link']) ? $user['link'] : null,
'profileUrl' => $user['link'] ?? null,
]);
}
@@ -174,4 +172,17 @@ class FacebookProvider extends AbstractProvider implements ProviderInterface
return $this;
}
/**
* Specify which graph version should be used.
*
* @param string $version
* @return $this
*/
public function usingGraphVersion(string $version)
{
$this->version = $version;
return $this;
}
}

View File

@@ -35,10 +35,10 @@ class GithubProvider extends AbstractProvider implements ProviderInterface
*/
protected function getUserByToken($token)
{
$userUrl = 'https://api.github.com/user?access_token='.$token;
$userUrl = 'https://api.github.com/user';
$response = $this->getHttpClient()->get(
$userUrl, $this->getRequestOptions()
$userUrl, $this->getRequestOptions($token)
);
$user = json_decode($response->getBody(), true);
@@ -58,11 +58,11 @@ class GithubProvider extends AbstractProvider implements ProviderInterface
*/
protected function getEmailByToken($token)
{
$emailsUrl = 'https://api.github.com/user/emails?access_token='.$token;
$emailsUrl = 'https://api.github.com/user/emails';
try {
$response = $this->getHttpClient()->get(
$emailsUrl, $this->getRequestOptions()
$emailsUrl, $this->getRequestOptions($token)
);
} catch (Exception $e) {
return;
@@ -81,21 +81,26 @@ class GithubProvider extends AbstractProvider implements ProviderInterface
protected function mapUserToObject(array $user)
{
return (new User)->setRaw($user)->map([
'id' => $user['id'], 'nickname' => $user['login'], 'name' => Arr::get($user, 'name'),
'email' => Arr::get($user, 'email'), 'avatar' => $user['avatar_url'],
'id' => $user['id'],
'nickname' => $user['login'],
'name' => Arr::get($user, 'name'),
'email' => Arr::get($user, 'email'),
'avatar' => $user['avatar_url'],
]);
}
/**
* Get the default options for an HTTP request.
*
* @param string $token
* @return array
*/
protected function getRequestOptions()
protected function getRequestOptions($token)
{
return [
'headers' => [
'Accept' => 'application/vnd.github.v3+json',
'Authorization' => 'token '.$token,
],
];
}

View File

@@ -0,0 +1,58 @@
<?php
namespace Laravel\Socialite\Two;
class GitlabProvider extends AbstractProvider implements ProviderInterface
{
/**
* {@inheritdoc}
*/
protected function getAuthUrl($state)
{
return $this->buildAuthUrlFromBase('https://gitlab.com/oauth/authorize', $state);
}
/**
* {@inheritdoc}
*/
protected function getTokenUrl()
{
return 'https://gitlab.com/oauth/token';
}
/**
* {@inheritdoc}
*/
protected function getUserByToken($token)
{
$userUrl = 'https://gitlab.com/api/v3/user?access_token='.$token;
$response = $this->getHttpClient()->get($userUrl);
$user = json_decode($response->getBody(), true);
return $user;
}
/**
* {@inheritdoc}
*/
protected function mapUserToObject(array $user)
{
return (new User)->setRaw($user)->map([
'id' => $user['id'],
'nickname' => $user['username'],
'name' => $user['name'],
'email' => $user['email'],
'avatar' => $user['avatar_url'],
]);
}
/**
* {@inheritdoc}
*/
protected function getTokenFields($code)
{
return parent::getTokenFields($code) + ['grant_type' => 'authorization_code'];
}
}

View File

@@ -37,7 +37,7 @@ class GoogleProvider extends AbstractProvider implements ProviderInterface
*/
protected function getTokenUrl()
{
return 'https://accounts.google.com/o/oauth2/token';
return 'https://www.googleapis.com/oauth2/v4/token';
}
/**
@@ -48,7 +48,7 @@ class GoogleProvider extends AbstractProvider implements ProviderInterface
*/
protected function getTokenFields($code)
{
return array_add(
return Arr::add(
parent::getTokenFields($code), 'grant_type', 'authorization_code'
);
}
@@ -58,7 +58,7 @@ class GoogleProvider extends AbstractProvider implements ProviderInterface
*/
protected function getUserByToken($token)
{
$response = $this->getHttpClient()->get('https://www.googleapis.com/plus/v1/people/me?', [
$response = $this->getHttpClient()->get('https://www.googleapis.com/oauth2/v3/userinfo', [
'query' => [
'prettyPrint' => 'false',
],
@@ -76,10 +76,18 @@ class GoogleProvider extends AbstractProvider implements ProviderInterface
*/
protected function mapUserToObject(array $user)
{
// Deprecated: Fields added to keep backwards compatibility in 4.0. These will be removed in 5.0
$user['id'] = Arr::get($user, 'sub');
$user['verified_email'] = Arr::get($user, 'email_verified');
$user['link'] = Arr::get($user, 'profile');
return (new User)->setRaw($user)->map([
'id' => $user['id'], 'nickname' => Arr::get($user, 'nickname'), 'name' => $user['displayName'],
'email' => $user['emails'][0]['value'], 'avatar' => Arr::get($user, 'image')['url'],
'avatar_original' => preg_replace('/\?sz=([0-9]+)/', '', Arr::get($user, 'image')['url']),
'id' => Arr::get($user, 'sub'),
'nickname' => Arr::get($user, 'nickname'),
'name' => Arr::get($user, 'name'),
'email' => Arr::get($user, 'email'),
'avatar' => $avatarUrl = Arr::get($user, 'picture'),
'avatar_original' => $avatarUrl,
]);
}
}

View File

@@ -11,7 +11,7 @@ class LinkedInProvider extends AbstractProvider implements ProviderInterface
*
* @var array
*/
protected $scopes = ['r_basicprofile', 'r_emailaddress'];
protected $scopes = ['r_liteprofile', 'r_emailaddress'];
/**
* The separating character for the requested scopes.
@@ -20,17 +20,6 @@ class LinkedInProvider extends AbstractProvider implements ProviderInterface
*/
protected $scopeSeparator = ' ';
/**
* The fields that are included in the profile.
*
* @var array
*/
protected $fields = [
'id', 'first-name', 'last-name', 'formatted-name',
'email-address', 'headline', 'location', 'industry',
'public-profile-url', 'picture-url', 'picture-urls::(original)',
];
/**
* {@inheritdoc}
*/
@@ -63,18 +52,50 @@ class LinkedInProvider extends AbstractProvider implements ProviderInterface
*/
protected function getUserByToken($token)
{
$fields = implode(',', $this->fields);
$basicProfile = $this->getBasicProfile($token);
$emailAddress = $this->getEmailAddress($token);
$url = 'https://api.linkedin.com/v1/people/~:('.$fields.')';
return array_merge($basicProfile, $emailAddress);
}
/**
* Get the basic profile fields for the user.
*
* @param string $token
* @return array
*/
protected function getBasicProfile($token)
{
$url = 'https://api.linkedin.com/v2/me?projection=(id,firstName,lastName,profilePicture(displayImage~:playableStreams))';
$response = $this->getHttpClient()->get($url, [
'headers' => [
'x-li-format' => 'json',
'Authorization' => 'Bearer '.$token,
'X-RestLi-Protocol-Version' => '2.0.0',
],
]);
return json_decode($response->getBody(), true);
return (array) json_decode($response->getBody(), true);
}
/**
* Get the email address for the user.
*
* @param string $token
* @return array
*/
protected function getEmailAddress($token)
{
$url = 'https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))';
$response = $this->getHttpClient()->get($url, [
'headers' => [
'Authorization' => 'Bearer '.$token,
'X-RestLi-Protocol-Version' => '2.0.0',
],
]);
return (array) Arr::get((array) json_decode($response->getBody(), true), 'elements.0.handle~');
}
/**
@@ -82,23 +103,27 @@ class LinkedInProvider extends AbstractProvider implements ProviderInterface
*/
protected function mapUserToObject(array $user)
{
$preferredLocale = Arr::get($user, 'firstName.preferredLocale.language').'_'.Arr::get($user, 'firstName.preferredLocale.country');
$firstName = Arr::get($user, 'firstName.localized.'.$preferredLocale);
$lastName = Arr::get($user, 'lastName.localized.'.$preferredLocale);
$images = (array) Arr::get($user, 'profilePicture.displayImage~.elements', []);
$avatar = Arr::first($images, function ($image) {
return $image['data']['com.linkedin.digitalmedia.mediaartifact.StillImage']['storageSize']['width'] === 100;
});
$originalAvatar = Arr::first($images, function ($image) {
return $image['data']['com.linkedin.digitalmedia.mediaartifact.StillImage']['storageSize']['width'] === 800;
});
return (new User)->setRaw($user)->map([
'id' => $user['id'], 'nickname' => null, 'name' => Arr::get($user, 'formattedName'),
'email' => Arr::get($user, 'emailAddress'), 'avatar' => Arr::get($user, 'pictureUrl'),
'avatar_original' => Arr::get($user, 'pictureUrls.values.0'),
'id' => $user['id'],
'nickname' => null,
'name' => $firstName.' '.$lastName,
'first_name' => $firstName,
'last_name' => $lastName,
'email' => Arr::get($user, 'emailAddress'),
'avatar' => Arr::get($avatar, 'identifiers.0.identifier'),
'avatar_original' => Arr::get($originalAvatar, 'identifiers.0.identifier'),
]);
}
/**
* Set the user fields to request from LinkedIn.
*
* @param array $fields
* @return $this
*/
public function fields(array $fields)
{
$this->fields = $fields;
return $this;
}
}