Added login/register theme events
This commit is contained in:
parent
2ae89f2c32
commit
691db40a33
12 changed files with 95 additions and 16 deletions
|
@ -5,14 +5,12 @@ namespace BookStack\Auth\Access\Guards;
|
|||
use BookStack\Auth\Access\LdapService;
|
||||
use BookStack\Auth\Access\RegistrationService;
|
||||
use BookStack\Auth\User;
|
||||
use BookStack\Auth\UserRepo;
|
||||
use BookStack\Exceptions\LdapException;
|
||||
use BookStack\Exceptions\LoginAttemptException;
|
||||
use BookStack\Exceptions\LoginAttemptEmailNeededException;
|
||||
use BookStack\Exceptions\UserRegistrationException;
|
||||
use Illuminate\Contracts\Auth\UserProvider;
|
||||
use Illuminate\Contracts\Session\Session;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class LdapSessionGuard extends ExternalBaseSessionGuard
|
||||
|
|
|
@ -6,6 +6,8 @@ use BookStack\Auth\User;
|
|||
use BookStack\Auth\UserRepo;
|
||||
use BookStack\Exceptions\UserRegistrationException;
|
||||
use BookStack\Facades\Activity;
|
||||
use BookStack\Facades\Theme;
|
||||
use BookStack\Theming\ThemeEvents;
|
||||
use Exception;
|
||||
|
||||
class RegistrationService
|
||||
|
@ -71,6 +73,7 @@ class RegistrationService
|
|||
}
|
||||
|
||||
Activity::add(ActivityType::AUTH_REGISTER, $socialAccount ?? $newUser);
|
||||
Theme::dispatch(ThemeEvents::AUTH_REGISTER, $socialAccount ? $socialAccount->driver : auth()->getDefaultDriver(), $newUser);
|
||||
|
||||
// Start email confirmation flow if required
|
||||
if ($this->emailConfirmationService->confirmationRequired() && !$emailConfirmed) {
|
||||
|
|
|
@ -6,6 +6,8 @@ use BookStack\Exceptions\JsonDebugException;
|
|||
use BookStack\Exceptions\SamlException;
|
||||
use BookStack\Exceptions\UserRegistrationException;
|
||||
use BookStack\Facades\Activity;
|
||||
use BookStack\Facades\Theme;
|
||||
use BookStack\Theming\ThemeEvents;
|
||||
use Exception;
|
||||
use Illuminate\Support\Str;
|
||||
use OneLogin\Saml2\Auth;
|
||||
|
@ -375,6 +377,7 @@ class Saml2Service extends ExternalAuthService
|
|||
|
||||
auth()->login($user);
|
||||
Activity::add(ActivityType::AUTH_LOGIN, "saml2; {$user->logDescriptor()}");
|
||||
Theme::dispatch(ThemeEvents::AUTH_LOGIN, 'saml2', $user);
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ 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;
|
||||
|
@ -58,7 +60,7 @@ class SocialAuthService
|
|||
{
|
||||
// Check social account has not already been used
|
||||
if (SocialAccount::query()->where('driver_id', '=', $socialUser->getId())->exists()) {
|
||||
throw new UserRegistrationException(trans('errors.social_account_in_use', ['socialAccount'=>$socialDriver]), '/login');
|
||||
throw new UserRegistrationException(trans('errors.social_account_in_use', ['socialAccount' => $socialDriver]), '/login');
|
||||
}
|
||||
|
||||
if (User::query()->where('email', '=', $socialUser->getEmail())->exists()) {
|
||||
|
@ -98,6 +100,7 @@ class SocialAuthService
|
|||
if (!$isLoggedIn && $socialAccount !== null) {
|
||||
auth()->login($socialAccount->user);
|
||||
Activity::add(ActivityType::AUTH_LOGIN, $socialAccount);
|
||||
Theme::dispatch(ThemeEvents::AUTH_LOGIN, $socialDriver, $socialAccount->user);
|
||||
return redirect()->intended('/');
|
||||
}
|
||||
|
||||
|
@ -127,7 +130,7 @@ class SocialAuthService
|
|||
if (setting('registration-enabled') && config('auth.method') !== 'ldap' && config('auth.method') !== 'saml2') {
|
||||
$message .= trans('errors.social_account_register_instructions', ['socialAccount' => $titleCaseDriver]);
|
||||
}
|
||||
|
||||
|
||||
throw new SocialSignInAccountNotUsed($message, '/login');
|
||||
}
|
||||
|
||||
|
@ -207,9 +210,9 @@ class SocialAuthService
|
|||
public function newSocialAccount(string $socialDriver, SocialUser $socialUser): SocialAccount
|
||||
{
|
||||
return new SocialAccount([
|
||||
'driver' => $socialDriver,
|
||||
'driver' => $socialDriver,
|
||||
'driver_id' => $socialUser->getId(),
|
||||
'avatar' => $socialUser->getAvatar()
|
||||
'avatar' => $socialUser->getAvatar()
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,12 +2,15 @@
|
|||
|
||||
namespace BookStack\Http\Controllers\Auth;
|
||||
|
||||
use BookStack\Actions\ActivityType;
|
||||
use BookStack\Auth\Access\EmailConfirmationService;
|
||||
use BookStack\Auth\UserRepo;
|
||||
use BookStack\Exceptions\ConfirmationEmailException;
|
||||
use BookStack\Exceptions\UserTokenExpiredException;
|
||||
use BookStack\Exceptions\UserTokenNotFoundException;
|
||||
use BookStack\Facades\Theme;
|
||||
use BookStack\Http\Controllers\Controller;
|
||||
use BookStack\Theming\ThemeEvents;
|
||||
use Exception;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
@ -80,6 +83,8 @@ class ConfirmEmailController extends Controller
|
|||
$user->save();
|
||||
|
||||
auth()->login($user);
|
||||
Theme::dispatch(ThemeEvents::AUTH_LOGIN, auth()->getDefaultDriver(), $user);
|
||||
$this->logActivity(ActivityType::AUTH_LOGIN, $user);
|
||||
$this->showSuccessNotification(trans('auth.email_confirm_success'));
|
||||
$this->emailConfirmationService->deleteByUser($user);
|
||||
|
||||
|
|
|
@ -7,7 +7,9 @@ use BookStack\Actions\ActivityType;
|
|||
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;
|
||||
|
||||
|
@ -150,6 +152,7 @@ class LoginController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
Theme::dispatch(ThemeEvents::AUTH_LOGIN, auth()->getDefaultDriver(), $user);
|
||||
$this->logActivity(ActivityType::AUTH_LOGIN, $user);
|
||||
return redirect()->intended($this->redirectPath());
|
||||
}
|
||||
|
|
|
@ -2,11 +2,14 @@
|
|||
|
||||
namespace BookStack\Http\Controllers\Auth;
|
||||
|
||||
use BookStack\Actions\ActivityType;
|
||||
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;
|
||||
|
@ -93,6 +96,8 @@ class RegisterController extends Controller
|
|||
try {
|
||||
$user = $this->registrationService->registerUser($userData);
|
||||
auth()->login($user);
|
||||
Theme::dispatch(ThemeEvents::AUTH_LOGIN, auth()->getDefaultDriver(), $user);
|
||||
$this->logActivity(ActivityType::AUTH_LOGIN, $user);
|
||||
} catch (UserRegistrationException $exception) {
|
||||
if ($exception->getMessage()) {
|
||||
$this->showErrorNotification($exception->getMessage());
|
||||
|
|
|
@ -2,13 +2,16 @@
|
|||
|
||||
namespace BookStack\Http\Controllers\Auth;
|
||||
|
||||
use BookStack\Actions\ActivityType;
|
||||
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;
|
||||
|
@ -127,6 +130,8 @@ class SocialController extends Controller
|
|||
|
||||
$user = $this->registrationService->registerUser($userData, $socialAccount, $emailVerified);
|
||||
auth()->login($user);
|
||||
Theme::dispatch(ThemeEvents::AUTH_LOGIN, $socialDriver, $user);
|
||||
$this->logActivity(ActivityType::AUTH_LOGIN, $user);
|
||||
|
||||
$this->showSuccessNotification(trans('auth.register_success'));
|
||||
return redirect('/');
|
||||
|
|
|
@ -2,11 +2,14 @@
|
|||
|
||||
namespace BookStack\Http\Controllers\Auth;
|
||||
|
||||
use BookStack\Actions\ActivityType;
|
||||
use BookStack\Auth\Access\UserInviteService;
|
||||
use BookStack\Auth\UserRepo;
|
||||
use BookStack\Exceptions\UserTokenExpiredException;
|
||||
use BookStack\Exceptions\UserTokenNotFoundException;
|
||||
use BookStack\Facades\Theme;
|
||||
use BookStack\Http\Controllers\Controller;
|
||||
use BookStack\Theming\ThemeEvents;
|
||||
use Exception;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
@ -68,6 +71,8 @@ class UserInviteController extends Controller
|
|||
$user->save();
|
||||
|
||||
auth()->login($user);
|
||||
Theme::dispatch(ThemeEvents::AUTH_LOGIN, auth()->getDefaultDriver(), $user);
|
||||
$this->logActivity(ActivityType::AUTH_LOGIN, $user);
|
||||
$this->showSuccessNotification(trans('auth.user_invite_success', ['appName' => setting('app-name')]));
|
||||
$this->inviteService->deleteByUser($user);
|
||||
|
||||
|
|
|
@ -41,6 +41,26 @@ class ThemeEvents
|
|||
*/
|
||||
const WEB_MIDDLEWARE_AFTER = 'web_middleware_after';
|
||||
|
||||
/**
|
||||
* Auth login event.
|
||||
* Runs right after a user is logged-in to the application by any authentication
|
||||
* system as a standard app user. This includes a user becoming logged in
|
||||
* after registration. This is not emitted upon API usage.
|
||||
* @param string $authSystem
|
||||
* @param \BookStack\Auth\User $user
|
||||
*/
|
||||
const AUTH_LOGIN = 'auth_login';
|
||||
|
||||
/**
|
||||
* Auth register event.
|
||||
* Runs right after a user is newly registered to the application by any authentication
|
||||
* system as a standard app user. This includes auto-registration systems used
|
||||
* by LDAP, SAML and social systems. It only includes self-registrations.
|
||||
* @param string $authSystem
|
||||
* @param \BookStack\Auth\User $user
|
||||
*/
|
||||
const AUTH_REGISTER = 'auth_register';
|
||||
|
||||
/**
|
||||
* Commonmark environment configure.
|
||||
* Provides the commonmark library environment for customization
|
||||
|
|
|
@ -17,8 +17,7 @@ class SocialAuthTest extends TestCase
|
|||
$this->setSettings(['registration-enabled' => 'true']);
|
||||
config(['GOOGLE_APP_ID' => 'abc123', 'GOOGLE_APP_SECRET' => '123abc', 'APP_URL' => 'http://localhost']);
|
||||
|
||||
$mockSocialite = Mockery::mock(Factory::class);
|
||||
$this->app[Factory::class] = $mockSocialite;
|
||||
$mockSocialite = $this->mock(Factory::class);
|
||||
$mockSocialDriver = Mockery::mock(Provider::class);
|
||||
$mockSocialUser = Mockery::mock(\Laravel\Socialite\Contracts\User::class);
|
||||
|
||||
|
@ -46,8 +45,7 @@ class SocialAuthTest extends TestCase
|
|||
'APP_URL' => 'http://localhost'
|
||||
]);
|
||||
|
||||
$mockSocialite = Mockery::mock(Factory::class);
|
||||
$this->app[Factory::class] = $mockSocialite;
|
||||
$mockSocialite = $this->mock(Factory::class);
|
||||
$mockSocialDriver = Mockery::mock(Provider::class);
|
||||
$mockSocialUser = Mockery::mock(\Laravel\Socialite\Contracts\User::class);
|
||||
|
||||
|
@ -93,8 +91,7 @@ class SocialAuthTest extends TestCase
|
|||
]);
|
||||
|
||||
$user = factory(User::class)->make();
|
||||
$mockSocialite = Mockery::mock(Factory::class);
|
||||
$this->app[Factory::class] = $mockSocialite;
|
||||
$mockSocialite = $this->mock(Factory::class);
|
||||
$mockSocialDriver = Mockery::mock(Provider::class);
|
||||
$mockSocialUser = Mockery::mock(\Laravel\Socialite\Contracts\User::class);
|
||||
|
||||
|
@ -132,8 +129,7 @@ class SocialAuthTest extends TestCase
|
|||
]);
|
||||
|
||||
$user = factory(User::class)->make();
|
||||
$mockSocialite = Mockery::mock(Factory::class);
|
||||
$this->app[Factory::class] = $mockSocialite;
|
||||
$mockSocialite = $this->mock(Factory::class);
|
||||
$mockSocialDriver = Mockery::mock(Provider::class);
|
||||
$mockSocialUser = Mockery::mock(\Laravel\Socialite\Contracts\User::class);
|
||||
|
||||
|
@ -169,8 +165,7 @@ class SocialAuthTest extends TestCase
|
|||
$this->setSettings(['registration-enabled' => 'true']);
|
||||
config(['GITHUB_APP_ID' => 'abc123', 'GITHUB_APP_SECRET' => '123abc', 'APP_URL' => 'http://localhost']);
|
||||
|
||||
$mockSocialite = Mockery::mock(Factory::class);
|
||||
$this->app[Factory::class] = $mockSocialite;
|
||||
$mockSocialite = $this->mock(Factory::class);
|
||||
$mockSocialDriver = Mockery::mock(Provider::class);
|
||||
$mockSocialUser = Mockery::mock(\Laravel\Socialite\Contracts\User::class);
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php namespace Tests;
|
||||
|
||||
use BookStack\Auth\Access\SocialAuthService;
|
||||
use BookStack\Auth\User;
|
||||
use BookStack\Entities\Models\Page;
|
||||
use BookStack\Entities\Tools\PageContent;
|
||||
use BookStack\Facades\Theme;
|
||||
|
@ -122,6 +124,38 @@ class ThemeTest extends TestCase
|
|||
$resp->assertStatus(443);
|
||||
}
|
||||
|
||||
public function test_event_auth_login_standard()
|
||||
{
|
||||
$args = [];
|
||||
$callback = function (...$eventArgs) use (&$args) {
|
||||
$args = $eventArgs;
|
||||
};
|
||||
|
||||
Theme::listen(ThemeEvents::AUTH_LOGIN, $callback);
|
||||
$this->post('/login', ['email' => 'admin@admin.com', 'password' => 'password']);
|
||||
|
||||
$this->assertCount(2, $args);
|
||||
$this->assertEquals('standard', $args[0]);
|
||||
$this->assertInstanceOf(User::class, $args[1]);
|
||||
}
|
||||
|
||||
public function test_event_auth_register_standard()
|
||||
{
|
||||
$args = [];
|
||||
$callback = function (...$eventArgs) use (&$args) {
|
||||
$args = $eventArgs;
|
||||
};
|
||||
Theme::listen(ThemeEvents::AUTH_REGISTER, $callback);
|
||||
$this->setSettings(['registration-enabled' => 'true']);
|
||||
|
||||
$user = factory(User::class)->make();
|
||||
$this->post('/register', ['email' => $user->email, 'name' => $user->name, 'password' => 'password']);
|
||||
|
||||
$this->assertCount(2, $args);
|
||||
$this->assertEquals('standard', $args[0]);
|
||||
$this->assertInstanceOf(User::class, $args[1]);
|
||||
}
|
||||
|
||||
public function test_add_social_driver()
|
||||
{
|
||||
Theme::addSocialDriver('catnet', [
|
||||
|
|
Loading…
Reference in a new issue