use BookStack\Exceptions\UserRegistrationException;
use Illuminate\Support\Str;
use Laravel\Socialite\Contracts\Factory as Socialite;
+use Laravel\Socialite\Contracts\Provider;
use Laravel\Socialite\Contracts\User as SocialUser;
+use Symfony\Component\HttpFoundation\RedirectResponse;
class SocialAuthService
{
/**
* SocialAuthService constructor.
- * @param \BookStack\Auth\UserRepo $userRepo
- * @param Socialite $socialite
- * @param SocialAccount $socialAccount
*/
public function __construct(UserRepo $userRepo, Socialite $socialite, SocialAccount $socialAccount)
{
/**
* Start the social login path.
- * @param string $socialDriver
- * @return \Symfony\Component\HttpFoundation\RedirectResponse
* @throws SocialDriverNotConfigured
*/
- public function startLogIn($socialDriver)
+ public function startLogIn(string $socialDriver): RedirectResponse
{
$driver = $this->validateDriver($socialDriver);
return $this->getSocialDriver($driver)->redirect();
/**
* Start the social registration process
- * @param string $socialDriver
- * @return \Symfony\Component\HttpFoundation\RedirectResponse
* @throws SocialDriverNotConfigured
*/
- public function startRegister($socialDriver)
+ public function startRegister(string $socialDriver): RedirectResponse
{
$driver = $this->validateDriver($socialDriver);
return $this->getSocialDriver($driver)->redirect();
/**
* Handle the social registration process on callback.
- * @param string $socialDriver
- * @param SocialUser $socialUser
- * @return SocialUser
* @throws UserRegistrationException
*/
- public function handleRegistrationCallback(string $socialDriver, SocialUser $socialUser)
+ public function handleRegistrationCallback(string $socialDriver, SocialUser $socialUser): SocialUser
{
// Check social account has not already been used
if ($this->socialAccount->where('driver_id', '=', $socialUser->getId())->exists()) {
if ($this->userRepo->getByEmail($socialUser->getEmail())) {
$email = $socialUser->getEmail();
- throw new UserRegistrationException(trans('errors.social_account_in_use', ['socialAccount'=>$socialDriver, 'email' => $email]), '/login');
+ throw new UserRegistrationException(trans('errors.error_user_exists_different_creds', ['email' => $email]), '/login');
}
return $socialUser;
/**
* Get the social user details via the social driver.
- * @param string $socialDriver
- * @return SocialUser
* @throws SocialDriverNotConfigured
*/
- public function getSocialUser(string $socialDriver)
+ public function getSocialUser(string $socialDriver): SocialUser
{
$driver = $this->validateDriver($socialDriver);
return $this->socialite->driver($driver)->user();
/**
* Handle the login process on a oAuth callback.
- * @param $socialDriver
- * @param SocialUser $socialUser
- * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
* @throws SocialSignInAccountNotUsed
*/
- public function handleLoginCallback($socialDriver, SocialUser $socialUser)
+ public function handleLoginCallback(string $socialDriver, SocialUser $socialUser)
{
$socialId = $socialUser->getId();
// Otherwise let the user know this social account is not used by anyone.
$message = trans('errors.social_account_not_used', ['socialAccount' => $titleCaseDriver]);
- if (setting('registration-enabled')) {
+ if (setting('registration-enabled') && config('auth.method') !== 'ldap' && config('auth.method') !== 'saml2') {
$message .= trans('errors.social_account_register_instructions', ['socialAccount' => $titleCaseDriver]);
}
/**
* Ensure the social driver is correct and supported.
- *
- * @param $socialDriver
- * @return string
* @throws SocialDriverNotConfigured
*/
- private function validateDriver($socialDriver)
+ protected function validateDriver(string $socialDriver): string
{
$driver = trim(strtolower($socialDriver));
if (!in_array($driver, $this->validSocialDrivers)) {
abort(404, trans('errors.social_driver_not_found'));
}
+
if (!$this->checkDriverConfigured($driver)) {
throw new SocialDriverNotConfigured(trans('errors.social_driver_not_configured', ['socialAccount' => Str::title($socialDriver)]));
}
/**
* Check a social driver has been configured correctly.
- * @param $driver
- * @return bool
*/
- private function checkDriverConfigured($driver)
+ protected function checkDriverConfigured(string $driver): bool
{
$lowerName = strtolower($driver);
$configPrefix = 'services.' . $lowerName . '.';
/**
* Gets the names of the active social drivers.
- * @return array
*/
- public function getActiveDrivers()
+ public function getActiveDrivers(): array
{
$activeDrivers = [];
+
foreach ($this->validSocialDrivers as $driverKey) {
if ($this->checkDriverConfigured($driverKey)) {
$activeDrivers[$driverKey] = $this->getDriverName($driverKey);
}
}
+
return $activeDrivers;
}
/**
* Get the presentational name for a driver.
- * @param $driver
- * @return mixed
*/
- public function getDriverName($driver)
+ public function getDriverName(string $driver): string
{
return config('services.' . strtolower($driver) . '.name');
}
/**
* Check if the current config for the given driver allows auto-registration.
- * @param string $driver
- * @return bool
*/
- public function driverAutoRegisterEnabled(string $driver)
+ public function driverAutoRegisterEnabled(string $driver): bool
{
return config('services.' . strtolower($driver) . '.auto_register') === true;
}
/**
* Check if the current config for the given driver allow email address auto-confirmation.
- * @param string $driver
- * @return bool
*/
- public function driverAutoConfirmEmailEnabled(string $driver)
+ public function driverAutoConfirmEmailEnabled(string $driver): bool
{
return config('services.' . strtolower($driver) . '.auto_confirm') === true;
}
/**
- * @param string $socialDriver
- * @param SocialUser $socialUser
- * @return SocialAccount
+ * Fill and return a SocialAccount from the given driver name and SocialUser.
*/
- public function fillSocialAccount($socialDriver, $socialUser)
+ public function fillSocialAccount(string $socialDriver, SocialUser $socialUser): SocialAccount
{
$this->socialAccount->fill([
'driver' => $socialDriver,
/**
* Detach a social account from a user.
- * @param $socialDriver
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
- public function detachSocialAccount($socialDriver)
+ public function detachSocialAccount(string $socialDriver)
{
user()->socialAccounts()->where('driver', '=', $socialDriver)->delete();
- session()->flash('success', trans('settings.users_social_disconnected', ['socialAccount' => Str::title($socialDriver)]));
- return redirect(user()->getEditUrl());
}
/**
* Provide redirect options per service for the Laravel Socialite driver
- * @param $driverName
- * @return \Laravel\Socialite\Contracts\Provider
*/
- public function getSocialDriver(string $driverName)
+ public function getSocialDriver(string $driverName): Provider
{
$driver = $this->socialite->driver($driverName);
if ($driverName === 'google' && config('services.google.select_account')) {
$driver->with(['prompt' => 'select_account']);
}
+ if ($driverName === 'azure') {
+ $driver->with(['resource' => 'https://graph.windows.net']);
+ }
return $driver;
}