mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-10-01 01:36:00 -04:00
Updated user interfaces for LDAP and added email from LDAP
This commit is contained in:
parent
1c8c9e65c5
commit
14feef3679
@ -118,11 +118,22 @@ class AuthController extends Controller
|
|||||||
*/
|
*/
|
||||||
protected function authenticated(Request $request, Authenticatable $user)
|
protected function authenticated(Request $request, Authenticatable $user)
|
||||||
{
|
{
|
||||||
|
if(!$user->exists && $user->email === null && !$request->has('email')) {
|
||||||
|
$request->flash();
|
||||||
|
session()->flash('request-email', true);
|
||||||
|
return redirect('/login');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$user->exists && $user->email === null && $request->has('email')) {
|
||||||
|
$user->email = $request->get('email');
|
||||||
|
}
|
||||||
|
|
||||||
if(!$user->exists) {
|
if(!$user->exists) {
|
||||||
$user->save();
|
$user->save();
|
||||||
$this->userRepo->attachDefaultRole($user);
|
$this->userRepo->attachDefaultRole($user);
|
||||||
auth()->login($user);
|
auth()->login($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->intended($this->redirectPath());
|
return redirect()->intended($this->redirectPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,7 +194,7 @@ class AuthController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the page to tell the user to check thier email
|
* Show the page to tell the user to check their email
|
||||||
* and confirm their address.
|
* and confirm their address.
|
||||||
*/
|
*/
|
||||||
public function getRegisterConfirmation()
|
public function getRegisterConfirmation()
|
||||||
@ -243,7 +254,7 @@ class AuthController extends Controller
|
|||||||
]);
|
]);
|
||||||
$user = $this->userRepo->getByEmail($request->get('email'));
|
$user = $this->userRepo->getByEmail($request->get('email'));
|
||||||
$this->emailConfirmationService->sendConfirmation($user);
|
$this->emailConfirmationService->sendConfirmation($user);
|
||||||
\Session::flash('success', 'Confirmation email resent, Please check your inbox.');
|
session()->flash('success', 'Confirmation email resent, Please check your inbox.');
|
||||||
return redirect('/register/confirm');
|
return redirect('/register/confirm');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,8 @@ class UserController extends Controller
|
|||||||
public function create()
|
public function create()
|
||||||
{
|
{
|
||||||
$this->checkPermission('user-create');
|
$this->checkPermission('user-create');
|
||||||
return view('users/create');
|
$authMethod = config('auth.method');
|
||||||
|
return view('users/create', ['authMethod' => $authMethod]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,10 +95,12 @@ class UserController extends Controller
|
|||||||
return $this->currentUser->id == $id;
|
return $this->currentUser->id == $id;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$authMethod = config('auth.method');
|
||||||
|
|
||||||
$user = $this->user->findOrFail($id);
|
$user = $this->user->findOrFail($id);
|
||||||
$activeSocialDrivers = $socialAuthService->getActiveDrivers();
|
$activeSocialDrivers = $socialAuthService->getActiveDrivers();
|
||||||
$this->setPageTitle('User Profile');
|
$this->setPageTitle('User Profile');
|
||||||
return view('users/edit', ['user' => $user, 'activeSocialDrivers' => $activeSocialDrivers]);
|
return view('users/edit', ['user' => $user, 'activeSocialDrivers' => $activeSocialDrivers, 'authMethod' => $authMethod]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -124,17 +127,24 @@ class UserController extends Controller
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$user = $this->user->findOrFail($id);
|
$user = $this->user->findOrFail($id);
|
||||||
$user->fill($request->except('password'));
|
$user->fill($request->all());
|
||||||
|
|
||||||
|
// Role updates
|
||||||
if ($this->currentUser->can('user-update') && $request->has('role')) {
|
if ($this->currentUser->can('user-update') && $request->has('role')) {
|
||||||
$user->attachRoleId($request->get('role'));
|
$user->attachRoleId($request->get('role'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Password updates
|
||||||
if ($request->has('password') && $request->get('password') != '') {
|
if ($request->has('password') && $request->get('password') != '') {
|
||||||
$password = $request->get('password');
|
$password = $request->get('password');
|
||||||
$user->password = bcrypt($password);
|
$user->password = bcrypt($password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// External auth id updates
|
||||||
|
if ($this->currentUser->can('user-update') && $request->has('external_auth_id')) {
|
||||||
|
$user->external_auth_id = $request->get('external_auth_id');
|
||||||
|
}
|
||||||
|
|
||||||
$user->save();
|
$user->save();
|
||||||
return redirect('/users');
|
return redirect('/users');
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,6 @@ class LdapUserProvider implements UserProvider
|
|||||||
public function updateRememberToken(Authenticatable $user, $token)
|
public function updateRememberToken(Authenticatable $user, $token)
|
||||||
{
|
{
|
||||||
$user->setRememberToken($token);
|
$user->setRememberToken($token);
|
||||||
|
|
||||||
$user->save();
|
$user->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +112,7 @@ class LdapUserProvider implements UserProvider
|
|||||||
|
|
||||||
$model->name = $userDetails['name'];
|
$model->name = $userDetails['name'];
|
||||||
$model->external_auth_id = $userDetails['uid'];
|
$model->external_auth_id = $userDetails['uid'];
|
||||||
|
$model->email = $userDetails['email'];
|
||||||
return $model;
|
return $model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ class UserRepo
|
|||||||
*/
|
*/
|
||||||
public function create(array $data)
|
public function create(array $data)
|
||||||
{
|
{
|
||||||
return $this->user->create([
|
return $this->user->forceCreate([
|
||||||
'name' => $data['name'],
|
'name' => $data['name'],
|
||||||
'email' => $data['email'],
|
'email' => $data['email'],
|
||||||
'password' => bcrypt($data['password'])
|
'password' => bcrypt($data['password'])
|
||||||
|
@ -23,7 +23,7 @@ class LdapService
|
|||||||
// Find user
|
// Find user
|
||||||
$userFilter = $this->buildFilter(config('services.ldap.user_filter'), ['user' => $userName]);
|
$userFilter = $this->buildFilter(config('services.ldap.user_filter'), ['user' => $userName]);
|
||||||
$baseDn = config('services.ldap.base_dn');
|
$baseDn = config('services.ldap.base_dn');
|
||||||
$ldapSearch = ldap_search($ldapConnection, $baseDn, $userFilter, ['cn', 'uid', 'dn']);
|
$ldapSearch = ldap_search($ldapConnection, $baseDn, $userFilter, ['cn', 'uid', 'dn', 'mail']);
|
||||||
$users = ldap_get_entries($ldapConnection, $ldapSearch);
|
$users = ldap_get_entries($ldapConnection, $ldapSearch);
|
||||||
if ($users['count'] === 0) return null;
|
if ($users['count'] === 0) return null;
|
||||||
|
|
||||||
@ -31,7 +31,8 @@ class LdapService
|
|||||||
return [
|
return [
|
||||||
'uid' => $user['uid'][0],
|
'uid' => $user['uid'][0],
|
||||||
'name' => $user['cn'][0],
|
'name' => $user['cn'][0],
|
||||||
'dn' => $user['dn']
|
'dn' => $user['dn'],
|
||||||
|
'email' => (isset($user['mail'])) ? $user['mail'][0] : null
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ class SettingService
|
|||||||
*/
|
*/
|
||||||
public function get($key, $default = false)
|
public function get($key, $default = false)
|
||||||
{
|
{
|
||||||
$value = $this->getValueFromStore($key, $default);
|
$value = $this->getValueFromStore($key, $default);
|
||||||
return $this->formatValue($value, $default);
|
return $this->formatValue($value, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,13 +50,17 @@ class SettingService
|
|||||||
*/
|
*/
|
||||||
protected function getValueFromStore($key, $default)
|
protected function getValueFromStore($key, $default)
|
||||||
{
|
{
|
||||||
|
$overrideValue = $this->getOverrideValue($key);
|
||||||
|
if ($overrideValue !== null) return $overrideValue;
|
||||||
|
|
||||||
$cacheKey = $this->cachePrefix . $key;
|
$cacheKey = $this->cachePrefix . $key;
|
||||||
if ($this->cache->has($cacheKey)) {
|
if ($this->cache->has($cacheKey)) {
|
||||||
return $this->cache->get($cacheKey);
|
return $this->cache->get($cacheKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
$settingObject = $this->getSettingObjectByKey($key);
|
$settingObject = $this->getSettingObjectByKey($key);
|
||||||
if($settingObject !== null) {
|
|
||||||
|
if ($settingObject !== null) {
|
||||||
$value = $settingObject->value;
|
$value = $settingObject->value;
|
||||||
$this->cache->forever($cacheKey, $value);
|
$this->cache->forever($cacheKey, $value);
|
||||||
return $value;
|
return $value;
|
||||||
@ -65,6 +69,10 @@ class SettingService
|
|||||||
return $default;
|
return $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear an item from the cache completely.
|
||||||
|
* @param $key
|
||||||
|
*/
|
||||||
protected function clearFromCache($key)
|
protected function clearFromCache($key)
|
||||||
{
|
{
|
||||||
$cacheKey = $this->cachePrefix . $key;
|
$cacheKey = $this->cachePrefix . $key;
|
||||||
@ -136,9 +144,23 @@ class SettingService
|
|||||||
* @param $key
|
* @param $key
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
private function getSettingObjectByKey($key)
|
protected function getSettingObjectByKey($key)
|
||||||
{
|
{
|
||||||
return $this->setting->where('setting_key', '=', $key)->first();
|
return $this->setting->where('setting_key', '=', $key)->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an override value for a setting based on certain app conditions.
|
||||||
|
* Used where certain configuration options overrule others.
|
||||||
|
* Returns null if no override value is available.
|
||||||
|
* @param $key
|
||||||
|
* @return bool|null
|
||||||
|
*/
|
||||||
|
protected function getOverrideValue($key)
|
||||||
|
{
|
||||||
|
if ($key === 'registration-enabled' && config('auth.method') === 'ldap') return false;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -24,7 +24,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
|||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $fillable = ['name', 'email', 'password', 'image_id'];
|
protected $fillable = ['name', 'email', 'image_id'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes excluded from the model's JSON form.
|
* The attributes excluded from the model's JSON form.
|
||||||
@ -68,7 +68,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the user's permissions from thier role.
|
* Loads the user's permissions from their role.
|
||||||
*/
|
*/
|
||||||
private function loadPermissions()
|
private function loadPermissions()
|
||||||
{
|
{
|
||||||
|
@ -69,7 +69,7 @@ return [
|
|||||||
|
|
||||||
'providers' => [
|
'providers' => [
|
||||||
'users' => [
|
'users' => [
|
||||||
'driver' => env('AUTH_METHOD', 'eloquent'),
|
'driver' => env('AUTH_METHOD', 'standard') === 'standard' ? 'eloquent' : env('AUTH_METHOD'),
|
||||||
'model' => BookStack\User::class,
|
'model' => BookStack\User::class,
|
||||||
],
|
],
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
<env name="QUEUE_DRIVER" value="sync"/>
|
<env name="QUEUE_DRIVER" value="sync"/>
|
||||||
<env name="DB_CONNECTION" value="mysql_testing"/>
|
<env name="DB_CONNECTION" value="mysql_testing"/>
|
||||||
<env name="MAIL_PRETEND" value="true"/>
|
<env name="MAIL_PRETEND" value="true"/>
|
||||||
|
<env name="AUTH_METHOD" value="standard"/>
|
||||||
<env name="DISABLE_EXTERNAL_SERVICES" value="false"/>
|
<env name="DISABLE_EXTERNAL_SERVICES" value="false"/>
|
||||||
</php>
|
</php>
|
||||||
</phpunit>
|
</phpunit>
|
||||||
|
@ -3,6 +3,16 @@
|
|||||||
@include('form/text', ['name' => 'username', 'tabindex' => 1])
|
@include('form/text', ['name' => 'username', 'tabindex' => 1])
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@if(session('request-email', false) === true)
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="email">Email</label>
|
||||||
|
@include('form/text', ['name' => 'email', 'tabindex' => 1])
|
||||||
|
<span class="text-neg">
|
||||||
|
Please enter an email to use for this account.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="password">Password</label>
|
<label for="password">Password</label>
|
||||||
@include('form/password', ['name' => 'password', 'tabindex' => 2])
|
@include('form/password', ['name' => 'password', 'tabindex' => 2])
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<form action="/users/create" method="post">
|
<form action="/users/create" method="post">
|
||||||
{!! csrf_field() !!}
|
{!! csrf_field() !!}
|
||||||
@include('users/form')
|
@include('users.forms.' . $authMethod)
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
<h1>Edit {{ $user->id === $currentUser->id ? 'Profile' : 'User' }}</h1>
|
<h1>Edit {{ $user->id === $currentUser->id ? 'Profile' : 'User' }}</h1>
|
||||||
{!! csrf_field() !!}
|
{!! csrf_field() !!}
|
||||||
<input type="hidden" name="_method" value="put">
|
<input type="hidden" name="_method" value="put">
|
||||||
@include('users/form', ['model' => $user])
|
@include('users.forms.' . $authMethod, ['model' => $user])
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
|
30
resources/views/users/forms/ldap.blade.php
Normal file
30
resources/views/users/forms/ldap.blade.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<div class="form-group">
|
||||||
|
<label for="name">Name</label>
|
||||||
|
@include('form.text', ['name' => 'name'])
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if($currentUser->can('user-update'))
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="email">Email</label>
|
||||||
|
@include('form.text', ['name' => 'email'])
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if($currentUser->can('user-update'))
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="role">User Role</label>
|
||||||
|
@include('form.role-select', ['name' => 'role', 'options' => \BookStack\Role::all(), 'displayKey' => 'display_name'])
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if($currentUser->can('user-update'))
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="external_auth_id">External Authentication ID</label>
|
||||||
|
@include('form.text', ['name' => 'external_auth_id'])
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<a href="/users" class="button muted">Cancel</a>
|
||||||
|
<button class="button pos" type="submit">Save</button>
|
||||||
|
</div>
|
@ -1,11 +1,11 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="name">Name</label>
|
<label for="name">Name</label>
|
||||||
@include('form/text', ['name' => 'name'])
|
@include('form.text', ['name' => 'name'])
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="email">Email</label>
|
<label for="email">Email</label>
|
||||||
@include('form/text', ['name' => 'email'])
|
@include('form.text', ['name' => 'email'])
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if($currentUser->can('user-update'))
|
@if($currentUser->can('user-update'))
|
||||||
@ -25,12 +25,12 @@
|
|||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="password">Password</label>
|
<label for="password">Password</label>
|
||||||
@include('form/password', ['name' => 'password'])
|
@include('form.password', ['name' => 'password'])
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="password-confirm">Confirm Password</label>
|
<label for="password-confirm">Confirm Password</label>
|
||||||
@include('form/password', ['name' => 'password-confirm'])
|
@include('form.password', ['name' => 'password-confirm'])
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
Loading…
Reference in New Issue
Block a user