*/
public function loginUsingId($id, $remember = false)
{
- if (!is_null($user = $this->provider->retrieveById($id))) {
- $this->login($user, $remember);
-
- return $user;
- }
-
+ // Always return false as to disable this method,
+ // Logins should route through LoginService.
return false;
}
--- /dev/null
+<?php
+
+namespace BookStack\Auth\Access;
+
+use BookStack\Actions\ActivityType;
+use BookStack\Auth\User;
+use BookStack\Facades\Activity;
+use BookStack\Facades\Theme;
+use BookStack\Theming\ThemeEvents;
+
+class LoginService
+{
+
+ /**
+ * Log the given user into the system.
+ */
+ public function login(User $user, string $method): void
+ {
+ auth()->login($user);
+ Activity::add(ActivityType::AUTH_LOGIN, "{$method}; {$user->logDescriptor()}");
+ Theme::dispatch(ThemeEvents::AUTH_LOGIN, $method, $user);
+
+ // Authenticate on all session guards if a likely admin
+ if ($user->can('users-manage') && $user->can('user-roles-manage')) {
+ $guards = ['standard', 'ldap', 'saml2'];
+ foreach ($guards as $guard) {
+ auth($guard)->login($user);
+ }
+ }
+ }
+
+
+ /**
+ * Attempt the login of a user using the given credentials.
+ * Meant to mirror laravel's default guard 'attempt' method
+ * but in a manner that always routes through our login system.
+ */
+ public function attempt(array $credentials, string $method, bool $remember = false): bool
+ {
+ $result = auth()->attempt($credentials, $remember);
+ if ($result) {
+ $user = auth()->user();
+ auth()->logout();
+ $this->login($user, $method);
+ }
+
+ return $result;
+ }
+
+}
\ No newline at end of file
{
protected $config;
protected $registrationService;
- protected $user;
+ protected $loginService;
/**
* Saml2Service constructor.
*/
- public function __construct(RegistrationService $registrationService, User $user)
+ public function __construct(RegistrationService $registrationService, LoginService $loginService)
{
$this->config = config('saml2');
$this->registrationService = $registrationService;
- $this->user = $user;
+ $this->loginService = $loginService;
}
/**
*/
protected function getOrRegisterUser(array $userDetails): ?User
{
- $user = $this->user->newQuery()
+ $user = User::query()
->where('external_auth_id', '=', $userDetails['external_id'])
->first();
$this->syncWithGroups($user, $groups);
}
- auth()->login($user);
- Activity::add(ActivityType::AUTH_LOGIN, "saml2; {$user->logDescriptor()}");
- Theme::dispatch(ThemeEvents::AUTH_LOGIN, 'saml2', $user);
-
+ $this->loginService->login($user, 'saml2');
return $user;
}
}
namespace BookStack\Auth\Access;
-use BookStack\Actions\ActivityType;
use BookStack\Auth\SocialAccount;
use BookStack\Auth\User;
use BookStack\Exceptions\SocialDriverNotConfigured;
use BookStack\Exceptions\SocialSignInAccountNotUsed;
use BookStack\Exceptions\UserRegistrationException;
-use BookStack\Facades\Activity;
-use BookStack\Facades\Theme;
-use BookStack\Theming\ThemeEvents;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Str;
use Laravel\Socialite\Contracts\Factory as Socialite;
*/
protected $socialite;
+ /**
+ * @var LoginService
+ */
+ protected $loginService;
+
/**
* The default built-in social drivers we support.
*
/**
* SocialAuthService constructor.
*/
- public function __construct(Socialite $socialite)
+ public function __construct(Socialite $socialite, LoginService $loginService)
{
$this->socialite = $socialite;
+ $this->loginService = $loginService;
}
/**
// When a user is not logged in and a matching SocialAccount exists,
// Simply log the user into the application.
if (!$isLoggedIn && $socialAccount !== null) {
- auth()->login($socialAccount->user);
- Activity::add(ActivityType::AUTH_LOGIN, $socialAccount);
- Theme::dispatch(ThemeEvents::AUTH_LOGIN, $socialDriver, $socialAccount->user);
-
+ $this->loginService->login($socialAccount->user, $socialAccount);
return redirect()->intended('/');
}
use BookStack\Actions\ActivityType;
use BookStack\Auth\Access\EmailConfirmationService;
+use BookStack\Auth\Access\LoginService;
use BookStack\Auth\UserRepo;
use BookStack\Exceptions\ConfirmationEmailException;
use BookStack\Exceptions\UserTokenExpiredException;
class ConfirmEmailController extends Controller
{
protected $emailConfirmationService;
+ protected $loginService;
protected $userRepo;
/**
* Create a new controller instance.
*/
- public function __construct(EmailConfirmationService $emailConfirmationService, UserRepo $userRepo)
+ public function __construct(
+ EmailConfirmationService $emailConfirmationService,
+ LoginService $loginService,
+ UserRepo $userRepo
+ )
{
$this->emailConfirmationService = $emailConfirmationService;
+ $this->loginService = $loginService;
$this->userRepo = $userRepo;
}
$user->email_confirmed = true;
$user->save();
- auth()->login($user);
- Theme::dispatch(ThemeEvents::AUTH_LOGIN, auth()->getDefaultDriver(), $user);
- $this->logActivity(ActivityType::AUTH_LOGIN, $user);
+ $this->loginService->login($user, auth()->getDefaultDriver());
$this->showSuccessNotification(trans('auth.email_confirm_success'));
$this->emailConfirmationService->deleteByUser($user);
namespace BookStack\Http\Controllers\Auth;
use Activity;
-use BookStack\Actions\ActivityType;
+use BookStack\Auth\Access\LoginService;
use BookStack\Auth\Access\SocialAuthService;
use BookStack\Exceptions\LoginAttemptEmailNeededException;
use BookStack\Exceptions\LoginAttemptException;
-use BookStack\Facades\Theme;
use BookStack\Http\Controllers\Controller;
-use BookStack\Theming\ThemeEvents;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
protected $redirectAfterLogout = '/login';
protected $socialAuthService;
+ protected $loginService;
/**
* Create a new controller instance.
*/
- public function __construct(SocialAuthService $socialAuthService)
+ public function __construct(SocialAuthService $socialAuthService, LoginService $loginService)
{
$this->middleware('guest', ['only' => ['getLogin', 'login']]);
$this->middleware('guard:standard,ldap', ['only' => ['login', 'logout']]);
$this->socialAuthService = $socialAuthService;
+ $this->loginService = $loginService;
+
$this->redirectPath = url('/');
$this->redirectAfterLogout = url('/login');
}
return $this->sendFailedLoginResponse($request);
}
+ /**
+ * Attempt to log the user into the application.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @return bool
+ */
+ protected function attemptLogin(Request $request)
+ {
+ return $this->loginService->attempt(
+ $this->credentials($request), auth()->getDefaultDriver(), $request->filled('remember')
+ );
+ }
+
/**
* The user has been authenticated.
*
*/
protected function authenticated(Request $request, $user)
{
- // Authenticate on all session guards if a likely admin
- if ($user->can('users-manage') && $user->can('user-roles-manage')) {
- $guards = ['standard', 'ldap', 'saml2'];
- foreach ($guards as $guard) {
- auth($guard)->login($user);
- }
- }
-
- Theme::dispatch(ThemeEvents::AUTH_LOGIN, auth()->getDefaultDriver(), $user);
- $this->logActivity(ActivityType::AUTH_LOGIN, $user);
-
return redirect()->intended($this->redirectPath());
}
namespace BookStack\Http\Controllers\Auth;
-use BookStack\Actions\ActivityType;
+use BookStack\Auth\Access\LoginService;
use BookStack\Auth\Access\RegistrationService;
use BookStack\Auth\Access\SocialAuthService;
use BookStack\Auth\User;
use BookStack\Exceptions\UserRegistrationException;
-use BookStack\Facades\Theme;
use BookStack\Http\Controllers\Controller;
-use BookStack\Theming\ThemeEvents;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
protected $socialAuthService;
protected $registrationService;
+ protected $loginService;
/**
* Where to redirect users after login / registration.
/**
* Create a new controller instance.
*/
- public function __construct(SocialAuthService $socialAuthService, RegistrationService $registrationService)
+ public function __construct(
+ SocialAuthService $socialAuthService,
+ RegistrationService $registrationService,
+ LoginService $loginService
+ )
{
$this->middleware('guest');
$this->middleware('guard:standard');
$this->socialAuthService = $socialAuthService;
$this->registrationService = $registrationService;
+ $this->loginService = $loginService;
$this->redirectTo = url('/');
$this->redirectPath = url('/');
try {
$user = $this->registrationService->registerUser($userData);
- auth()->login($user);
- Theme::dispatch(ThemeEvents::AUTH_LOGIN, auth()->getDefaultDriver(), $user);
- $this->logActivity(ActivityType::AUTH_LOGIN, $user);
+ $this->loginService->login($user, auth()->getDefaultDriver());
} catch (UserRegistrationException $exception) {
if ($exception->getMessage()) {
$this->showErrorNotification($exception->getMessage());
namespace BookStack\Http\Controllers\Auth;
-use BookStack\Actions\ActivityType;
+use BookStack\Auth\Access\LoginService;
use BookStack\Auth\Access\RegistrationService;
use BookStack\Auth\Access\SocialAuthService;
use BookStack\Exceptions\SocialDriverNotConfigured;
use BookStack\Exceptions\SocialSignInAccountNotUsed;
use BookStack\Exceptions\SocialSignInException;
use BookStack\Exceptions\UserRegistrationException;
-use BookStack\Facades\Theme;
use BookStack\Http\Controllers\Controller;
-use BookStack\Theming\ThemeEvents;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Laravel\Socialite\Contracts\User as SocialUser;
{
protected $socialAuthService;
protected $registrationService;
+ protected $loginService;
/**
* SocialController constructor.
*/
- public function __construct(SocialAuthService $socialAuthService, RegistrationService $registrationService)
+ public function __construct(
+ SocialAuthService $socialAuthService,
+ RegistrationService $registrationService,
+ LoginService $loginService
+ )
{
$this->middleware('guest')->only(['getRegister', 'postRegister']);
$this->socialAuthService = $socialAuthService;
$this->registrationService = $registrationService;
+ $this->loginService = $loginService;
}
/**
}
$user = $this->registrationService->registerUser($userData, $socialAccount, $emailVerified);
- auth()->login($user);
- Theme::dispatch(ThemeEvents::AUTH_LOGIN, $socialDriver, $user);
- $this->logActivity(ActivityType::AUTH_LOGIN, $user);
+ $this->loginService->login($user, $socialDriver);
$this->showSuccessNotification(trans('auth.register_success'));
-
return redirect('/');
}
}
namespace BookStack\Http\Controllers\Auth;
use BookStack\Actions\ActivityType;
+use BookStack\Auth\Access\LoginService;
use BookStack\Auth\Access\UserInviteService;
use BookStack\Auth\UserRepo;
use BookStack\Exceptions\UserTokenExpiredException;
class UserInviteController extends Controller
{
protected $inviteService;
+ protected $loginService;
protected $userRepo;
/**
* Create a new controller instance.
*/
- public function __construct(UserInviteService $inviteService, UserRepo $userRepo)
+ public function __construct(UserInviteService $inviteService, LoginService $loginService, UserRepo $userRepo)
{
$this->middleware('guest');
$this->middleware('guard:standard');
$this->inviteService = $inviteService;
+ $this->loginService = $loginService;
$this->userRepo = $userRepo;
}
$user->email_confirmed = true;
$user->save();
- auth()->login($user);
- Theme::dispatch(ThemeEvents::AUTH_LOGIN, auth()->getDefaultDriver(), $user);
- $this->logActivity(ActivityType::AUTH_LOGIN, $user);
+ $this->loginService->login($user, auth()->getDefaultDriver());
$this->showSuccessNotification(trans('auth.user_invite_success', ['appName' => setting('app-name')]));
$this->inviteService->deleteByUser($user);
&& !$request->is('mfa/verify*', 'uploads/images/user/*')
&& $this->mfaSession->requiredForCurrentUser()
) {
- return redirect('/mfa/verify');
+// return redirect('/mfa/verify');
}
// TODO - URI wildcard exceptions above allow access to the 404 page of this user
namespace BookStack\Providers;
use Blade;
+use BookStack\Auth\Access\LoginService;
use BookStack\Auth\Access\SocialAuthService;
use BookStack\Entities\BreadcrumbsViewComposer;
use BookStack\Entities\Models\Book;
});
$this->app->singleton(SocialAuthService::class, function ($app) {
- return new SocialAuthService($app->make(SocialiteFactory::class));
+ return new SocialAuthService($app->make(SocialiteFactory::class), $app->make(LoginService::class));
});
}
}