guard = $auth; $this->users = $users; $this->identities = $identities; } public function login($providerAlias, ProviderUser $userDetails, $callback = null) { /** @var Model|Authenticatable $user */ $user = $this->getUser($providerAlias, $userDetails); $user = $this->runCallback($callback, $user, $userDetails); $this->updateUser($user, $providerAlias, $userDetails); $this->guard->login($user); } protected function getUser($providerAlias, ProviderUser $details) // returns User { if ($this->identities->userExists($providerAlias, $details, false)) { return $this->getExistingUser($providerAlias, $details); } // this is potentially unsafe - allows user to attach a social identity to an // existing account just my matching the e-mail. // we have to assume the providers are trustworthy. if ($details->email && $this->identities->userExists($providerAlias, $details, true)) { return $this->users->findByEmail($details->email); } return $this->users->create(); } protected function runCallback($callback, Model $user, ProviderUser $userDetails) { $callback = $callback ?: function () {}; $callbackUser = $callback($user, $userDetails); return $callbackUser ?: $user; } protected function updateUser(Model $user, $providerAlias, ProviderUser $details) { $this->users->store($user); $this->storeProviderIdentity($user, $providerAlias, $details); } protected function getExistingUser($providerAlias, ProviderUser $details) { $identity = $this->identities->getByProvider($providerAlias, $details); return $this->users->findByIdentity($identity); } protected function storeProviderIdentity(Model $user, string $providerAlias, ProviderUser $details) { if ($this->identities->userExists($providerAlias, $details, false)) { $this->updateProviderIdentity($providerAlias, $details); } else { $this->addProviderIdentity($user, $providerAlias, $details); } } protected function updateProviderIdentity(string $providerAlias, ProviderUser $details) { $identity = $this->identities->getByProvider($providerAlias, $details); $identity->access_token = $details->access_token; $this->identities->store($identity); } /** * @param Model $user * @param $providerAlias * @param $details */ protected function addProviderIdentity(Model $user, string $providerAlias, ProviderUser $details) { $identity = new OAuthIdentity; $identity->user_id = $user->getKey(); $identity->provider = $providerAlias; $identity->provider_user_id = $details->id; $identity->access_token = $details->access_token; $this->identities->store($identity); } }