OAuth login and signup. Improve handling of login via API

This commit is contained in:
David Bomba 2019-05-22 10:56:47 +10:00
parent 97d3093b2b
commit ef25cfa320
5 changed files with 59 additions and 27 deletions

View File

@ -13,6 +13,8 @@ namespace App\Http\Controllers\Auth;
use App\Http\Controllers\BaseController; use App\Http\Controllers\BaseController;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Jobs\Account\CreateAccount;
use App\Libraries\MultiDB;
use App\Libraries\OAuth; use App\Libraries\OAuth;
use App\Models\User; use App\Models\User;
use App\Transformers\UserTransformer; use App\Transformers\UserTransformer;
@ -118,12 +120,33 @@ class LoginController extends BaseController
if($user = OAuth::handleAuth($socialite_user, $provider)) if($user = OAuth::handleAuth($socialite_user, $provider))
{ {
Auth::login($user, true); //Auth::login($user, true);
return $this->itemResponse($user);
//return redirect($this->redirectTo); //todo return USERACCOUNT json
}
else if(MultiDB::checkUserEmailExists($user->getEmail()))
{
return redirect($this->redirectTo); //todo return USERACCOUNT json return $this->errorResponse(['message'=>'User exists in system, but not with this authentication method'], 400);
}
/** 3. Automagically creating a new account here. */
else {
//todo
$name = OAuth::splitName($socialite_user->getName());
$new_account = [
'first_name' => $name[0],
'last_name' => $name[1],
'password' => '',
'email' => $socialite_user->getEmail(),
];
$account = CreateAccount::dispatchNow($new_account);
return $this->itemResponse($account->default_company->users->first());
} }
//throw error
} }
} }

View File

@ -81,7 +81,7 @@ class MultiDB
} }
return false; return null;
} }
public static function findAndSetDb($token) :bool public static function findAndSetDb($token) :bool

View File

@ -36,7 +36,7 @@ class OAuth
* @param Socialite $user * @param Socialite $user
*/ */
public static function handleAuth(object $user, string $provider) : ?User public static function handleAuth(object $user, string $provider)
{ {
/** 1. Ensure user arrives on the correct provider **/ /** 1. Ensure user arrives on the correct provider **/
@ -49,24 +49,19 @@ class OAuth
{ {
return $user; return $user;
} }
else
return false;
/** 2. If email exists, then they already have an account did they select the wrong provider? redirect to a guest error screen */
if(MultiDB::checkUserEmailExists($user->getEmail()))
{
Session::flash('error', 'User exists in system, but not with this authentication method'); //todo add translations
return view('auth.login');
} }
/* /* Splits a socialite user name into first and last names */
public static function splitName($name)
Session::flash('error', 'User does not exist'); //todo add translations {
return view('auth.login'); $name = trim($name);
*/ $last_name = (strpos($name, ' ') === false) ? '' : preg_replace('#.*\s([\w-]*)$#', '$1', $name);
$first_name = trim(preg_replace('#' . preg_quote($last_name, '/') . '#', '', $name));
/** 3. We will not handle automagically creating a new account here. */
return [$first_name, $last_name];
} }
public static function providerToString(int $social_provider) : string public static function providerToString(int $social_provider) : string

View File

@ -112,7 +112,7 @@ class User extends Authenticatable implements MustVerifyEmail
*/ */
public function companies() public function companies()
{ {
return $this->belongsToMany(Company::class)->withPivot('permissions', 'settings', 'is_admin', 'is_owner', 'is_locked'); return $this->belongsToMany(Company::class)->using(CompanyUser::class)->withPivot('permissions', 'settings', 'is_admin', 'is_owner', 'is_locked');
} }
/** /**
@ -129,6 +129,7 @@ class User extends Authenticatable implements MustVerifyEmail
* Returns the pivot tables for Company / User * Returns the pivot tables for Company / User
* *
* @return Collection * @return Collection
*
*/ */
public function user_companies() public function user_companies()
{ {

View File

@ -14,9 +14,11 @@ namespace App\Transformers;
use App\Models\Account; use App\Models\Account;
use App\Models\Company; use App\Models\Company;
use App\Models\CompanyToken; use App\Models\CompanyToken;
use App\Models\CompanyUser;
use App\Models\User; use App\Models\User;
use App\Transformers\CompanyTokenTransformer; use App\Transformers\CompanyTokenTransformer;
use App\Transformers\CompanyTransformer; use App\Transformers\CompanyTransformer;
use App\Transformers\CompanyUserTransformer;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
/** /**
@ -58,8 +60,8 @@ class UserTransformer extends EntityTransformer
* @var array * @var array
*/ */
protected $availableIncludes = [ protected $availableIncludes = [
'user_company',
'companies', 'companies',
'company_tokens',
]; ];
@ -82,26 +84,37 @@ class UserTransformer extends EntityTransformer
public function includeUserCompany(User $user) public function includeUserCompany(User $user)
{ {
//cannot use this here as it will fail retrieving the company as we depend on the token in the header which may not be present for this request
//$transformer = new CompanyUserTransformer($this->serializer);
$transformer = new UserCompanyTransformer($this->serializer); //return $this->includeItem($user->user_company(), $transformer, CompanyUser::class);
return $this->includeItem($user->user_company(), $transformer, CompanyUser::class);
} }
public function includeCompanies(User $user) public function includeCompanies(User $user)
{ {
$transformer = new CompanyTransformer($this->serializer); $transformer = new CompanyTransformer($this->serializer);
return $this->includeCollection($user->companies(), $transformer, Company::class); return $this->includeCollection($user->companies, $transformer, Company::class);
} }
public function includeCompanyToken(User $user) public function includeCompanyToken(User $user)
{ {
$transformer = new CompanyTokenTransformer($this->serializer); $transformer = new CompanyTokenTransformer($this->serializer);
return $this->includeItem($user->token(), $transformer, CompanyToken::class); return $this->includeItem($user->token(), $transformer, CompanyToken::class);
}
public function includeCompanyTokens(User $user)
{
$transformer = new CompanyTokenTransformer($this->serializer);
return $this->includeCollection($user->tokens, $transformer, CompanyToken::class);
} }
} }