Social Login Feature
WIP Depends-On: https://review.opendev.org/c/osf/openstackid/+/772531 Change-Id: I86cef9379fcd6ca5320f080e062fc2abaa36203c
This commit is contained in:
parent
85c1a90bc4
commit
4addff2c60
|
@ -79,4 +79,9 @@ RABBITMQ_SSL=true
|
|||
RABBITMQ_SSL_CAFILE=/certs/rabbit/ca-osf.pem
|
||||
RABBITMQ_SSL_LOCALCERT=/certs/rabbit/client-cert-osf.pem
|
||||
RABBITMQ_SSL_LOCALKEY=/certs/rabbit/client-key-osf.pem
|
||||
RABBITMQ_SSL_VERIFY_PEER=false
|
||||
RABBITMQ_SSL_VERIFY_PEER=false
|
||||
|
||||
# 3rd party idps
|
||||
FACEBOOK_CLIENT_ID=
|
||||
FACEBOOK_CLIENT_SECRET=
|
||||
FACEBOOK_REDIRECT_URI=/login/facebook/callback
|
|
@ -25,7 +25,6 @@ use OAuth2\Factories\OAuth2AuthorizationRequestFactory;
|
|||
use OAuth2\OAuth2Message;
|
||||
use OAuth2\Repositories\IClientRepository;
|
||||
use OAuth2\Services\IMementoOAuth2SerializerService;
|
||||
use Sokil\IsoCodes\IsoCodesFactory;
|
||||
use Exception;
|
||||
/**
|
||||
* Class RegisterController
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
<?php namespace App\Http\Controllers;
|
||||
/**
|
||||
* Copyright 2021 OpenStack Foundation
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
use App\Services\Auth\IUserService;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Laravel\Socialite\Facades\Socialite;
|
||||
use models\exceptions\ValidationException;
|
||||
use Strategies\ILoginStrategy;
|
||||
use Strategies\ILoginStrategyFactory;
|
||||
use Utils\Services\IAuthService;
|
||||
/**
|
||||
* Class SocialLoginController
|
||||
* @package App\Http\Controllers
|
||||
*/
|
||||
final class SocialLoginController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @var IAuthService
|
||||
*/
|
||||
private $auth_service;
|
||||
/**
|
||||
* @var IUserService
|
||||
*/
|
||||
private $user_service;
|
||||
/**
|
||||
* @var ILoginStrategy
|
||||
*/
|
||||
private $login_strategy;
|
||||
|
||||
const ValidProviders = [
|
||||
'google',
|
||||
'facebook',
|
||||
'microsoft',
|
||||
'apple',
|
||||
];
|
||||
|
||||
/**
|
||||
* SocialLoginController constructor.
|
||||
* @param IAuthService $auth_service
|
||||
* @param IUserService $user_service
|
||||
* @param ILoginStrategyFactory $login_strategy_factory
|
||||
*/
|
||||
public function __construct(
|
||||
IAuthService $auth_service,
|
||||
IUserService $user_service,
|
||||
ILoginStrategyFactory $login_strategy_factory
|
||||
){
|
||||
$this->auth_service = $auth_service;
|
||||
$this->user_service = $user_service;
|
||||
$this->middleware(function ($request, $next) use($login_strategy_factory){
|
||||
// we do it here just to ensure that user session is loaded
|
||||
Log::debug(sprintf("SocialLoginController::middleware"));
|
||||
$this->login_strategy = $login_strategy_factory->build();
|
||||
return $next($request);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $provider
|
||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Symfony\Component\HttpFoundation\RedirectResponse
|
||||
*/
|
||||
public function redirect($provider)
|
||||
{
|
||||
try {
|
||||
$memento = Session::has('oauth2.request.state');
|
||||
if(!in_array($provider, self::ValidProviders))
|
||||
throw new ValidationException(sprintf("Provider %s is not supported.", $provider));
|
||||
return Socialite::driver($provider)->redirect();
|
||||
}
|
||||
catch (\Exception $ex){
|
||||
Log::error($ex);
|
||||
}
|
||||
return view("auth.register_error");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $provider
|
||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|mixed
|
||||
*/
|
||||
public function callback($provider)
|
||||
{
|
||||
try {
|
||||
// validate provier
|
||||
if(!in_array($provider, self::ValidProviders))
|
||||
throw new ValidationException(sprintf("Provider %s is not supported.", $provider));
|
||||
|
||||
$social_user = Socialite::driver($provider)->user();
|
||||
// try to get user by primary email from our db
|
||||
$user = $this->auth_service->getUserByUsername($social_user->getEmail());
|
||||
|
||||
if (is_null($user)) {
|
||||
// if does not exists , registered it with email verified and active
|
||||
$user = $this->user_service->registerUser([
|
||||
'email' => $social_user->getEmail(),
|
||||
'full_name' => $social_user->getName(),
|
||||
'external_pic' => $social_user->getAvatar(),
|
||||
'external_id' => $social_user->getId(),
|
||||
'email_verified' => true,
|
||||
'active' => true,
|
||||
'external_provider' => $provider
|
||||
]);
|
||||
}
|
||||
|
||||
// do login
|
||||
Auth::login($user, true);
|
||||
// and continue the usual flow
|
||||
return $this->login_strategy->postLogin([ 'provider'=> $provider ]);
|
||||
}
|
||||
catch (\Exception $ex){
|
||||
Log::error($ex);
|
||||
}
|
||||
return view("auth.register_error");
|
||||
}
|
||||
|
||||
}
|
|
@ -50,6 +50,11 @@ final class EventServiceProvider extends ServiceProvider
|
|||
protected $listen = [
|
||||
'Illuminate\Database\Events\QueryExecuted' => [
|
||||
],
|
||||
\SocialiteProviders\Manager\SocialiteWasCalled::class => [
|
||||
// ... other providers
|
||||
'SocialiteProviders\\Facebook\\FacebookExtendSocialite@handle',
|
||||
'SocialiteProviders\\Google\\GoogleExtendSocialite@handle',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
@ -48,11 +48,20 @@ class DefaultLoginStrategy implements ILoginStrategy
|
|||
return Redirect::action("UserController@getProfile");
|
||||
}
|
||||
|
||||
public function postLogin()
|
||||
public function postLogin(array $params = [])
|
||||
{
|
||||
$user = $this->auth_service->getCurrentUser();
|
||||
$identifier = $user->getIdentifier();
|
||||
$this->user_action_service->addUserAction($this->auth_service->getCurrentUser()->getId(), IPHelper::getUserIp(), IUserActionService::LoginAction);
|
||||
$realm = "From Site";
|
||||
if(isset($params['provider']))
|
||||
$realm .= " using ".strtoupper($params['provider']);
|
||||
$this->user_action_service->addUserAction
|
||||
(
|
||||
$this->auth_service->getCurrentUser()->getId(),
|
||||
IPHelper::getUserIp(),
|
||||
IUserActionService::LoginAction,
|
||||
$realm
|
||||
);
|
||||
$default_url = URL::action("UserController@getIdentity", array("identifier" => $identifier));
|
||||
return Redirect::intended($default_url);
|
||||
}
|
||||
|
|
|
@ -11,9 +11,11 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
|
||||
use Illuminate\Support\Facades\Response;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
|
||||
/**
|
||||
* Class DisplayResponseUserAgentStrategy
|
||||
* @package Strategies
|
||||
|
@ -36,6 +38,10 @@ class DisplayResponseUserAgentStrategy implements IDisplayResponseStrategy
|
|||
*/
|
||||
public function getLoginResponse(array $data = [])
|
||||
{
|
||||
$provider = $data["provider"]??null;
|
||||
if(!empty($provider)) {
|
||||
return redirect()->route('social_login', ['provider' => $provider]);
|
||||
}
|
||||
return Response::view("auth.login", $data, 200);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,9 +11,10 @@ interface ILoginStrategy
|
|||
public function getLogin();
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
* @return mixed
|
||||
*/
|
||||
public function postLogin();
|
||||
public function postLogin(array $params = []);
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<?php namespace Strategies;
|
||||
/**
|
||||
* Copyright 2015 OpenStack Foundation
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
use Strategies\ILoginStrategy;
|
||||
|
||||
/**
|
||||
* Interface ILoginStrategyFactory
|
||||
* @package Strategies
|
||||
*/
|
||||
interface ILoginStrategyFactory
|
||||
{
|
||||
public function build():ILoginStrategy;
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
<?php namespace Strategies;
|
||||
/**
|
||||
* Copyright 2015 OpenStack Foundation
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
use App\Services\Auth\IUserService;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use OAuth2\Services\IMementoOAuth2SerializerService;
|
||||
use OAuth2\Services\ISecurityContextService;
|
||||
use OpenId\Services\IMementoOpenIdSerializerService;
|
||||
use Services\IUserActionService;
|
||||
use Utils\Services\IAuthService;
|
||||
|
||||
/**
|
||||
* Class LoginStrategyFactory
|
||||
* @package Strategies
|
||||
*/
|
||||
final class LoginStrategyFactory implements ILoginStrategyFactory
|
||||
{
|
||||
/**
|
||||
* @var IMementoOpenIdSerializerService
|
||||
*/
|
||||
private $openid_memento_service;
|
||||
/**
|
||||
* @var IMementoOAuth2SerializerService
|
||||
*/
|
||||
private $oauth2_memento_service;
|
||||
/**
|
||||
* @var IAuthService
|
||||
*/
|
||||
private $auth_service;
|
||||
|
||||
/**
|
||||
* @var IUserService
|
||||
*/
|
||||
private $user_service;
|
||||
|
||||
/**
|
||||
* @var IUserActionService
|
||||
*/
|
||||
private $user_action_service;
|
||||
|
||||
/**
|
||||
* @var ISecurityContextService
|
||||
*/
|
||||
private $security_context_service;
|
||||
|
||||
/**
|
||||
* LoginStrategyFactory constructor.
|
||||
* @param IMementoOpenIdSerializerService $openid_memento_service
|
||||
* @param IMementoOAuth2SerializerService $oauth2_memento_service
|
||||
* @param IAuthService $auth_service
|
||||
* @param IUserService $user_service
|
||||
* @param IUserActionService $user_action_service
|
||||
* @param ISecurityContextService $security_context_service
|
||||
*/
|
||||
public function __construct
|
||||
(
|
||||
IMementoOpenIdSerializerService $openid_memento_service,
|
||||
IMementoOAuth2SerializerService $oauth2_memento_service,
|
||||
IAuthService $auth_service,
|
||||
IUserService $user_service,
|
||||
IUserActionService $user_action_service,
|
||||
ISecurityContextService $security_context_service)
|
||||
{
|
||||
$this->openid_memento_service = $openid_memento_service;
|
||||
$this->oauth2_memento_service = $oauth2_memento_service;
|
||||
$this->auth_service = $auth_service;
|
||||
$this->user_service = $user_service;
|
||||
$this->user_action_service = $user_action_service;
|
||||
$this->security_context_service = $security_context_service;
|
||||
}
|
||||
|
||||
public function build():ILoginStrategy{
|
||||
$res = null;
|
||||
Log::debug(sprintf("LoginStrategyFactory::build"));
|
||||
if ($this->openid_memento_service->exists())
|
||||
{
|
||||
//openid stuff
|
||||
Log::debug(sprintf("LoginStrategyFactory::build OIDC"));
|
||||
return new OpenIdLoginStrategy
|
||||
(
|
||||
$this->openid_memento_service,
|
||||
$this->user_action_service,
|
||||
$this->auth_service
|
||||
);
|
||||
|
||||
}
|
||||
else if ($this->oauth2_memento_service->exists())
|
||||
{
|
||||
Log::debug(sprintf("LoginStrategyFactory::build OAUTH2"));
|
||||
return new OAuth2LoginStrategy
|
||||
(
|
||||
$this->auth_service,
|
||||
$this->oauth2_memento_service,
|
||||
$this->user_action_service,
|
||||
$this->security_context_service
|
||||
);
|
||||
}
|
||||
//default stuff
|
||||
Log::debug(sprintf("LoginStrategyFactory::build DEFAULT"));
|
||||
return new DefaultLoginStrategy($this->user_action_service, $this->auth_service);
|
||||
}
|
||||
}
|
|
@ -76,10 +76,12 @@ class OAuth2LoginStrategy extends DefaultLoginStrategy
|
|||
|
||||
$response_strategy = DisplayResponseStrategyFactory::build($auth_request->getDisplay());
|
||||
|
||||
return $response_strategy->getLoginResponse();
|
||||
return $response_strategy->getLoginResponse([
|
||||
'provider' => $auth_request->getProvider()
|
||||
]);
|
||||
}
|
||||
|
||||
public function postLogin()
|
||||
public function postLogin(array $params = [])
|
||||
{
|
||||
$auth_request = OAuth2AuthorizationRequestFactory::getInstance()->build(
|
||||
OAuth2Message::buildFromMemento(
|
||||
|
@ -87,8 +89,12 @@ class OAuth2LoginStrategy extends DefaultLoginStrategy
|
|||
)
|
||||
);
|
||||
|
||||
$realm = "From ".$auth_request->getRedirectUri();
|
||||
if(isset($params['provider']))
|
||||
$realm .= " using ".strtoupper($params['provider']);
|
||||
|
||||
$this->user_action_service->addUserAction($this->auth_service->getCurrentUser()->getId(), IPHelper::getUserIp(),
|
||||
IUserActionService::LoginAction, $auth_request->getRedirectUri());
|
||||
IUserActionService::LoginAction, $realm);
|
||||
|
||||
return Redirect::action("OAuth2\OAuth2ProviderController@auth");
|
||||
}
|
||||
|
|
|
@ -68,17 +68,21 @@ final class OpenIdLoginStrategy extends DefaultLoginStrategy
|
|||
return Redirect::action("UserController@getProfile");
|
||||
}
|
||||
|
||||
public function postLogin()
|
||||
public function postLogin(array $params = [])
|
||||
{
|
||||
//go to authentication flow again
|
||||
$msg = OpenIdMessage::buildFromMemento($this->memento_service->load());
|
||||
|
||||
$realm = "From ". $msg->getParam(OpenIdProtocol::OpenIDProtocol_Realm);
|
||||
if(isset($params['provider']))
|
||||
$realm .= " using ".strtoupper($params['provider']);
|
||||
|
||||
$this->user_action_service->addUserAction
|
||||
(
|
||||
$this->auth_service->getCurrentUser()->getId(),
|
||||
IPHelper::getUserIp(),
|
||||
IUserActionService::LoginAction,
|
||||
$msg->getParam(OpenIdProtocol::OpenIDProtocol_Realm)
|
||||
$realm
|
||||
);
|
||||
|
||||
return Redirect::action("OpenId\OpenIdProviderController@endpoint");
|
||||
|
|
|
@ -48,6 +48,10 @@ final class StrategyProvider extends ServiceProvider implements DeferrableProvid
|
|||
// authentication strategies
|
||||
App::singleton(OAuth2ServiceCatalog::AuthenticationStrategy, \Strategies\OAuth2AuthenticationStrategy::class);
|
||||
App::singleton(OpenIdServiceCatalog::AuthenticationStrategy, \Strategies\OpenIdAuthenticationStrategy::class);
|
||||
|
||||
// factories
|
||||
|
||||
App::singleton(ILoginStrategyFactory::class, LoginStrategyFactory::class);
|
||||
}
|
||||
|
||||
public function provides()
|
||||
|
@ -61,6 +65,7 @@ final class StrategyProvider extends ServiceProvider implements DeferrableProvid
|
|||
OAuth2IndirectFragmentResponse::OAuth2IndirectFragmentResponse,
|
||||
OAuth2ServiceCatalog::AuthenticationStrategy,
|
||||
OpenIdServiceCatalog::AuthenticationStrategy,
|
||||
ILoginStrategyFactory::class,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -166,6 +166,18 @@ final class UserFactory
|
|||
if(isset($payload['email_verified']) && boolval($payload['email_verified']) === true && !$user->isEmailVerified())
|
||||
$user->verifyEmail();
|
||||
|
||||
if(isset($payload['full_name']))
|
||||
$user->setFullName(trim($payload['full_name']));
|
||||
|
||||
if(isset($payload['external_id']))
|
||||
$user->setExternalId(trim($payload['external_id']));
|
||||
|
||||
if(isset($payload['external_pic']))
|
||||
$user->setExternalPic(trim($payload['external_pic']));
|
||||
|
||||
if(isset($payload['external_provider']))
|
||||
$user->setExternalProvider(trim($payload['external_provider']));
|
||||
|
||||
return $user;
|
||||
}
|
||||
}
|
|
@ -306,6 +306,24 @@ class User extends BaseEntity
|
|||
*/
|
||||
private $pic;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="external_id", type="string")
|
||||
* @var string
|
||||
*/
|
||||
private $external_id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="external_provider", type="string")
|
||||
* @var string
|
||||
*/
|
||||
private $external_provider;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="external_pic", type="string")
|
||||
* @var string
|
||||
*/
|
||||
private $external_pic;
|
||||
|
||||
// relations
|
||||
|
||||
/**
|
||||
|
@ -412,6 +430,9 @@ class User extends BaseEntity
|
|||
$this->spam_type = self::SpamTypeNone;
|
||||
$this->company = null;
|
||||
$this->phone_number = null;
|
||||
$this->external_id = null;
|
||||
$this->external_provider = null;
|
||||
$this->external_pic = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -823,6 +844,9 @@ class User extends BaseEntity
|
|||
if (!empty($this->pic)) {
|
||||
return Storage::disk('swift')->url(sprintf("%s/%s", self::getProfilePicFolder(), $this->pic));
|
||||
}
|
||||
if(!empty($this->external_pic))
|
||||
return $this->external_pic;
|
||||
|
||||
return $this->getGravatarUrl();
|
||||
}
|
||||
catch (\Exception $ex) {
|
||||
|
@ -1780,4 +1804,61 @@ SQL;
|
|||
$this->job_title = $job_title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getExternalProvider(): ?string
|
||||
{
|
||||
return $this->external_provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $external_provider
|
||||
*/
|
||||
public function setExternalProvider(string $external_provider): void
|
||||
{
|
||||
$this->external_provider = $external_provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getExternalPic(): ?string
|
||||
{
|
||||
return $this->external_pic;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $external_pic
|
||||
*/
|
||||
public function setExternalPic(string $external_pic): void
|
||||
{
|
||||
$this->external_pic = $external_pic;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getExternalId(): string
|
||||
{
|
||||
return $this->external_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $external_id
|
||||
*/
|
||||
public function setExternalId(string $external_id): void
|
||||
{
|
||||
$this->external_id = $external_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $full_name
|
||||
*/
|
||||
public function setFullName(string $full_name):void{
|
||||
$name_parts = explode(" ", $full_name);
|
||||
$this->first_name = $name_parts[0];
|
||||
$this->last_name = $name_parts[1];
|
||||
}
|
||||
|
||||
}
|
|
@ -231,6 +231,11 @@ final class OAuth2Protocol implements IOAuth2Protocol
|
|||
// http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
|
||||
const OAuth2Protocol_Nonce = 'nonce';
|
||||
|
||||
/**
|
||||
* custom param - social login
|
||||
*/
|
||||
const OAuth2Protocol_Provider = 'provider';
|
||||
|
||||
/**
|
||||
* Time when the End-User authentication occurred. Its value is a JSON number representing the number of seconds
|
||||
* from 1970-01-01T0:0:0Z as measured in UTC until the date/time. When a max_age request is made or when auth_time
|
||||
|
|
|
@ -37,6 +37,7 @@ class OAuth2AuthenticationRequest extends OAuth2AuthorizationRequest
|
|||
OAuth2Protocol::OAuth2Protocol_IDTokenHint,
|
||||
OAuth2Protocol::OAuth2Protocol_LoginHint,
|
||||
OAuth2Protocol::OAuth2Protocol_ACRValues,
|
||||
OAuth2Protocol::OAuth2Protocol_Provider,
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -111,6 +112,10 @@ class OAuth2AuthenticationRequest extends OAuth2AuthorizationRequest
|
|||
return str_contains($this->getScope(), OAuth2Protocol::OfflineAccess_Scope);
|
||||
}
|
||||
|
||||
public function getProvider():?string{
|
||||
return $this->getParam(OAuth2Protocol::OAuth2Protocol_Provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OAuth2AuthorizationRequest $auth_request
|
||||
*/
|
||||
|
|
|
@ -29,31 +29,34 @@
|
|||
"php": "^7.3|^8.0",
|
||||
"ext-json": "*",
|
||||
"ext-pdo": "*",
|
||||
"laravel/framework": "^8.0",
|
||||
"laravel/helpers": "^1.4",
|
||||
"laravel/tinker": "^2.5",
|
||||
"laravelcollective/html": "6.2.*",
|
||||
"fruitcake/laravel-cors": "^2.0",
|
||||
"laravel-doctrine/orm": "1.7.*",
|
||||
"laravel-doctrine/extensions": "1.4.*",
|
||||
"laravel-doctrine/migrations": "2.3.*",
|
||||
"beberlei/doctrineextensions": "1.3.*",
|
||||
"behat/transliterator": "^1.2",
|
||||
"vladimir-yuldashev/laravel-queue-rabbitmq": "v11.1.*",
|
||||
"s-ichikawa/laravel-sendgrid-driver": "~3.0",
|
||||
"ezyang/htmlpurifier": "v4.12.0",
|
||||
"fideloper/proxy": "^4.4",
|
||||
"fruitcake/laravel-cors": "^2.0",
|
||||
"get-stream/stream-chat": "^1.1",
|
||||
"glenscott/url-normalizer": "1.4.0",
|
||||
"greggilbert/recaptcha": "dev-feature/laravel8.x",
|
||||
"guzzlehttp/guzzle": "^7.0.1",
|
||||
"ircmaxell/random-lib": "1.1.0",
|
||||
"jenssegers/agent": "2.6.3",
|
||||
"laravel-doctrine/extensions": "1.4.*",
|
||||
"laravel-doctrine/migrations": "2.3.*",
|
||||
"laravel-doctrine/orm": "1.7.*",
|
||||
"laravel/framework": "^8.0",
|
||||
"laravel/helpers": "^1.4",
|
||||
"laravel/socialite": "^5.2",
|
||||
"laravel/tinker": "^2.5",
|
||||
"laravelcollective/html": "6.2.*",
|
||||
"php-opencloud/openstack": "dev-feature/guzzle_7_x",
|
||||
"phpseclib/phpseclib": "2.0.11",
|
||||
"predis/predis": "v1.1.6",
|
||||
"s-ichikawa/laravel-sendgrid-driver": "~3.0",
|
||||
"smarcet/jose4php": "1.0.17",
|
||||
"socialiteproviders/facebook": "^4.1",
|
||||
"socialiteproviders/google": "^4.1",
|
||||
"sokil/php-isocodes": "^3.0",
|
||||
"vladimir-yuldashev/laravel-queue-rabbitmq": "v11.1.*",
|
||||
"zendframework/zend-crypt": "3.3.0",
|
||||
"zendframework/zend-math": "3.1.1"
|
||||
},
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "c28f890e5a6afe1c57a1e232f3be5e5c",
|
||||
"content-hash": "e015af0bbb4e2dd0a442281900600087",
|
||||
"packages": [
|
||||
{
|
||||
"name": "asm89/stack-cors",
|
||||
|
@ -3362,6 +3362,75 @@
|
|||
},
|
||||
"time": "2021-02-16T15:27:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/socialite",
|
||||
"version": "v5.2.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/socialite.git",
|
||||
"reference": "1960802068f81e44b2ae9793932181cf1cb91b5c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/socialite/zipball/1960802068f81e44b2ae9793932181cf1cb91b5c",
|
||||
"reference": "1960802068f81e44b2ae9793932181cf1cb91b5c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"guzzlehttp/guzzle": "^6.0|^7.0",
|
||||
"illuminate/http": "^6.0|^7.0|^8.0",
|
||||
"illuminate/support": "^6.0|^7.0|^8.0",
|
||||
"league/oauth1-client": "^1.0",
|
||||
"php": "^7.2|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"illuminate/contracts": "^6.0|^7.0",
|
||||
"mockery/mockery": "^1.0",
|
||||
"orchestra/testbench": "^4.0|^5.0|^6.0",
|
||||
"phpunit/phpunit": "^8.0|^9.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.x-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Laravel\\Socialite\\SocialiteServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"Socialite": "Laravel\\Socialite\\Facades\\Socialite"
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Laravel\\Socialite\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "Laravel wrapper around OAuth 1 & OAuth 2 libraries.",
|
||||
"homepage": "https://laravel.com",
|
||||
"keywords": [
|
||||
"laravel",
|
||||
"oauth"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/socialite/issues",
|
||||
"source": "https://github.com/laravel/socialite"
|
||||
},
|
||||
"time": "2021-04-06T14:38:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/tinker",
|
||||
"version": "v2.6.1",
|
||||
|
@ -3754,6 +3823,81 @@
|
|||
],
|
||||
"time": "2021-01-18T20:58:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/oauth1-client",
|
||||
"version": "v1.9.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/oauth1-client.git",
|
||||
"reference": "1e7e6be2dc543bf466236fb171e5b20e1b06aee6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/1e7e6be2dc543bf466236fb171e5b20e1b06aee6",
|
||||
"reference": "1e7e6be2dc543bf466236fb171e5b20e1b06aee6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"ext-openssl": "*",
|
||||
"guzzlehttp/guzzle": "^6.0|^7.0",
|
||||
"php": ">=7.1||>=8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-simplexml": "*",
|
||||
"friendsofphp/php-cs-fixer": "^2.17",
|
||||
"mockery/mockery": "^1.3.3",
|
||||
"phpstan/phpstan": "^0.12.42",
|
||||
"phpunit/phpunit": "^7.5||9.5"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-simplexml": "For decoding XML-based responses."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev",
|
||||
"dev-develop": "2.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\OAuth1\\Client\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ben Corlett",
|
||||
"email": "bencorlett@me.com",
|
||||
"homepage": "http://www.webcomm.com.au",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "OAuth 1.0 Client Library",
|
||||
"keywords": [
|
||||
"Authentication",
|
||||
"SSO",
|
||||
"authorization",
|
||||
"bitbucket",
|
||||
"identity",
|
||||
"idp",
|
||||
"oauth",
|
||||
"oauth1",
|
||||
"single sign on",
|
||||
"trello",
|
||||
"tumblr",
|
||||
"twitter"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/oauth1-client/issues",
|
||||
"source": "https://github.com/thephpleague/oauth1-client/tree/v1.9.0"
|
||||
},
|
||||
"time": "2021-01-20T01:40:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mobiledetect/mobiledetectlib",
|
||||
"version": "2.8.37",
|
||||
|
@ -5307,6 +5451,155 @@
|
|||
},
|
||||
"time": "2019-07-12T23:35:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "socialiteproviders/facebook",
|
||||
"version": "4.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/SocialiteProviders/Facebook.git",
|
||||
"reference": "9b94a9334b5d0f61de8f5a20928d63d4d8f4e00d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/SocialiteProviders/Facebook/zipball/9b94a9334b5d0f61de8f5a20928d63d4d8f4e00d",
|
||||
"reference": "9b94a9334b5d0f61de8f5a20928d63d4d8f4e00d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": "^7.2 || ^8.0",
|
||||
"socialiteproviders/manager": "~4.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"SocialiteProviders\\Facebook\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Oleksandr Prypkhan (Alex Wells)",
|
||||
"email": "autaut03@googlemail.com"
|
||||
}
|
||||
],
|
||||
"description": "Facebook (facebook.com) OAuth2 Provider for Laravel Socialite",
|
||||
"support": {
|
||||
"source": "https://github.com/SocialiteProviders/Facebook/tree/4.1.0"
|
||||
},
|
||||
"time": "2020-12-01T23:10:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "socialiteproviders/google",
|
||||
"version": "4.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/SocialiteProviders/Google-Plus.git",
|
||||
"reference": "1cb8f6fb2c0dd0fc8b34e95f69865663fdf0b401"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/SocialiteProviders/Google-Plus/zipball/1cb8f6fb2c0dd0fc8b34e95f69865663fdf0b401",
|
||||
"reference": "1cb8f6fb2c0dd0fc8b34e95f69865663fdf0b401",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": "^7.2 || ^8.0",
|
||||
"socialiteproviders/manager": "~4.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"SocialiteProviders\\Google\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "xstoop",
|
||||
"email": "myenglishnameisx@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Google OAuth2 Provider for Laravel Socialite",
|
||||
"support": {
|
||||
"source": "https://github.com/SocialiteProviders/Google-Plus/tree/4.1.0"
|
||||
},
|
||||
"time": "2020-12-01T23:10:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "socialiteproviders/manager",
|
||||
"version": "4.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/SocialiteProviders/Manager.git",
|
||||
"reference": "0f5e82af0404df0080bdc5c105cef936c1711524"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/SocialiteProviders/Manager/zipball/0f5e82af0404df0080bdc5c105cef936c1711524",
|
||||
"reference": "0f5e82af0404df0080bdc5c105cef936c1711524",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/support": "^6.0|^7.0|^8.0",
|
||||
"laravel/socialite": "~4.0|~5.0",
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^1.2",
|
||||
"phpunit/phpunit": "^9.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"SocialiteProviders\\Manager\\ServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"SocialiteProviders\\Manager\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Andy Wendt",
|
||||
"email": "andy@awendt.com"
|
||||
},
|
||||
{
|
||||
"name": "Anton Komarev",
|
||||
"email": "a.komarev@cybercog.su"
|
||||
},
|
||||
{
|
||||
"name": "Miguel Piedrafita",
|
||||
"email": "soy@miguelpiedrafita.com"
|
||||
},
|
||||
{
|
||||
"name": "atymic",
|
||||
"email": "atymicq@gmail.com",
|
||||
"homepage": "https://atymic.dev"
|
||||
}
|
||||
],
|
||||
"description": "Easily add new or override built-in providers in Laravel Socialite.",
|
||||
"homepage": "https://socialiteproviders.com/",
|
||||
"support": {
|
||||
"issues": "https://github.com/SocialiteProviders/Manager/issues",
|
||||
"source": "https://github.com/SocialiteProviders/Manager/tree/4.0.1"
|
||||
},
|
||||
"time": "2020-12-01T23:09:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sokil/php-isocodes",
|
||||
"version": "3.3.4",
|
||||
|
|
|
@ -170,6 +170,7 @@ return [
|
|||
LaravelDoctrine\Extensions\BeberleiExtensionsServiceProvider::class,
|
||||
\App\Models\Utils\MySQLExtensionsServiceProvider::class,
|
||||
\App\libs\Utils\FileSystem\SwiftServiceProvider::class,
|
||||
Laravel\Socialite\SocialiteServiceProvider::class,
|
||||
],
|
||||
|
||||
/*
|
||||
|
@ -223,6 +224,7 @@ return [
|
|||
'EntityManager' => LaravelDoctrine\ORM\Facades\EntityManager::class,
|
||||
'Registry' => LaravelDoctrine\ORM\Facades\Registry::class,
|
||||
'Doctrine' => LaravelDoctrine\ORM\Facades\Doctrine::class,
|
||||
'Socialite' => Laravel\Socialite\Facades\Socialite::class,
|
||||
],
|
||||
|
||||
'version' => env('APP_VERSION', 'XX.XX.XX'),
|
||||
|
|
|
@ -39,4 +39,15 @@ return [
|
|||
'api_key' => env('SENDGRID_API_KEY'),
|
||||
],
|
||||
|
||||
// 3rd party idps
|
||||
'facebook' => [
|
||||
'client_id' => env('FACEBOOK_CLIENT_ID'),
|
||||
'client_secret' => env('FACEBOOK_CLIENT_SECRET'),
|
||||
'redirect' => env('FACEBOOK_REDIRECT_URI')
|
||||
],
|
||||
'google' => [
|
||||
'client_id' => env('GOOGLE_CLIENT_ID'),
|
||||
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
|
||||
'redirect' => env('GOOGLE_REDIRECT_URI')
|
||||
],
|
||||
];
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<?php namespace Database\Migrations;
|
||||
/**
|
||||
* Copyright 2021 OpenStack Foundation
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
use Doctrine\DBAL\Schema\Schema as Schema;
|
||||
use LaravelDoctrine\Migrations\Schema\Builder;
|
||||
use LaravelDoctrine\Migrations\Schema\Table;
|
||||
/**
|
||||
* Class Version20210512181715
|
||||
* @package Database\Migrations
|
||||
*/
|
||||
class Version20210512181715 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$builder = new Builder($schema);
|
||||
if($schema->hasTable("users") && !$builder->hasColumn("users","external_provider") ) {
|
||||
$builder->table('users', function (Table $table) {
|
||||
$table->string('external_provider')->setNotnull(false)->setLength(254);
|
||||
$table->string('external_id')->setNotnull(false)->setLength(254);
|
||||
$table->string('external_pic')->setNotnull(false)->setLength(254);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$builder = new Builder($schema);
|
||||
if($schema->hasTable("users") && $builder->hasColumn("users","external_provider") ) {
|
||||
$builder->table('users', function (Table $table) {
|
||||
$table->dropColumn('external_provider');
|
||||
$table->dropColumn('external_id');
|
||||
$table->dropColumn('external_pic');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11270,16 +11270,6 @@
|
|||
"marked": "*"
|
||||
}
|
||||
},
|
||||
"simplemde": {
|
||||
"version": "1.11.2",
|
||||
"resolved": "https://registry.npmjs.org/simplemde/-/simplemde-1.11.2.tgz",
|
||||
"integrity": "sha1-ojo12XjSxA7wfewAjJLwcNjggOM=",
|
||||
"requires": {
|
||||
"codemirror": "*",
|
||||
"codemirror-spell-checker": "*",
|
||||
"marked": "*"
|
||||
}
|
||||
},
|
||||
"slash": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
|
||||
|
|
|
@ -41,10 +41,15 @@ Route::group(array('middleware' => ['ssl']), function () {
|
|||
|
||||
//user interaction
|
||||
Route::group(array('prefix' => 'auth'), function () {
|
||||
|
||||
Route::group(array('prefix' => 'login'), function () {
|
||||
Route::get('', "UserController@getLogin");
|
||||
Route::post('', ['middleware' => 'csrf', 'uses' => 'UserController@postLogin']);
|
||||
Route::get('cancel', "UserController@cancelLogin");
|
||||
Route::group(array('prefix' => '{provider}'), function () {
|
||||
Route::get('', 'SocialLoginController@redirect')->name("social_login");
|
||||
Route::get('callback','SocialLoginController@callback')->name("social_login_callback");
|
||||
});
|
||||
});
|
||||
|
||||
// registration routes
|
||||
|
|
Loading…
Reference in New Issue