Add error messages, fix LDAP error
This commit is contained in:
		
							parent
							
								
									03dbe32f99
								
							
						
					
					
						commit
						8e723f10dc
					
				| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use BookStack\Auth\Role;
 | 
					use BookStack\Auth\Role;
 | 
				
			||||||
use BookStack\Auth\User;
 | 
					use BookStack\Auth\User;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ExternalAuthService
 | 
					class ExternalAuthService
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -57,19 +58,19 @@ class ExternalAuthService
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Sync the groups to the user roles for the current user
 | 
					     * Sync the groups to the user roles for the current user
 | 
				
			||||||
     * @param \BookStack\Auth\User $user
 | 
					     * @param \BookStack\Auth\User $user
 | 
				
			||||||
     * @param array $samlAttributes
 | 
					     * @param array $userGroups
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function syncWithGroups(User $user, array $userGroups)
 | 
					    public function syncWithGroups(User $user, array $userGroups)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // Get the ids for the roles from the names
 | 
					        // Get the ids for the roles from the names
 | 
				
			||||||
        $samlGroupsAsRoles = $this->matchGroupsToSystemsRoles($userSamlGroups);
 | 
					        $groupsAsRoles = $this->matchGroupsToSystemsRoles($userGroups);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Sync groups
 | 
					        // Sync groups
 | 
				
			||||||
        if ($this->config['remove_from_groups']) {
 | 
					        if ($this->config['remove_from_groups']) {
 | 
				
			||||||
            $user->roles()->sync($samlGroupsAsRoles);
 | 
					            $user->roles()->sync($groupsAsRoles);
 | 
				
			||||||
            $this->userRepo->attachDefaultRole($user);
 | 
					            $this->userRepo->attachDefaultRole($user);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            $user->roles()->syncWithoutDetaching($samlGroupsAsRoles);
 | 
					            $user->roles()->syncWithoutDetaching($groupsAsRoles);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,6 @@ use BookStack\Auth\User;
 | 
				
			||||||
use BookStack\Auth\UserRepo;
 | 
					use BookStack\Auth\UserRepo;
 | 
				
			||||||
use BookStack\Exceptions\LdapException;
 | 
					use BookStack\Exceptions\LdapException;
 | 
				
			||||||
use Illuminate\Contracts\Auth\Authenticatable;
 | 
					use Illuminate\Contracts\Auth\Authenticatable;
 | 
				
			||||||
use Illuminate\Database\Eloquent\Builder;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class LdapService
 | 
					 * Class LdapService
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,8 +5,6 @@ use BookStack\Auth\User;
 | 
				
			||||||
use BookStack\Auth\UserRepo;
 | 
					use BookStack\Auth\UserRepo;
 | 
				
			||||||
use BookStack\Exceptions\SamlException;
 | 
					use BookStack\Exceptions\SamlException;
 | 
				
			||||||
use Illuminate\Contracts\Auth\Authenticatable;
 | 
					use Illuminate\Contracts\Auth\Authenticatable;
 | 
				
			||||||
use Illuminate\Database\Eloquent\Builder;
 | 
					 | 
				
			||||||
use Illuminate\Support\Facades\Log;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -117,6 +115,27 @@ class Saml2Service extends Access\ExternalAuthService
 | 
				
			||||||
        return $userGroups;
 | 
					        return $userGroups;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  For an array of strings, return a default for an empty array,
 | 
				
			||||||
 | 
					     *  a string for an array with one element and the full array for
 | 
				
			||||||
 | 
					     *  more than one element.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *  @param array $data
 | 
				
			||||||
 | 
					     *  @param $defaultValue
 | 
				
			||||||
 | 
					     *  @return string
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected function simplifyValue(array $data, $defaultValue) {
 | 
				
			||||||
 | 
					        switch (count($data)) {
 | 
				
			||||||
 | 
					            case 0:
 | 
				
			||||||
 | 
					                $data = $defaultValue;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 1:
 | 
				
			||||||
 | 
					                $data = $data[0];
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Get a property from an SAML response.
 | 
					     * Get a property from an SAML response.
 | 
				
			||||||
     * Handles properties potentially being an array.
 | 
					     * Handles properties potentially being an array.
 | 
				
			||||||
| 
						 | 
					@ -128,16 +147,9 @@ class Saml2Service extends Access\ExternalAuthService
 | 
				
			||||||
    protected function getSamlResponseAttribute(array $samlAttributes, string $propertyKey, $defaultValue)
 | 
					    protected function getSamlResponseAttribute(array $samlAttributes, string $propertyKey, $defaultValue)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (isset($samlAttributes[$propertyKey])) {
 | 
					        if (isset($samlAttributes[$propertyKey])) {
 | 
				
			||||||
            $data = $samlAttributes[$propertyKey];
 | 
					            $data = $this->simplifyValue($samlAttributes[$propertyKey], $defaultValue);
 | 
				
			||||||
            if (is_array($data)) {
 | 
					 | 
				
			||||||
              if (count($data) == 0) {
 | 
					 | 
				
			||||||
                $data = $defaultValue;
 | 
					 | 
				
			||||||
              } else if (count($data) == 1) {
 | 
					 | 
				
			||||||
                $data = $data[0];
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          $data = $defaultValue;
 | 
					            $data = $defaultValue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $data;
 | 
					        return $data;
 | 
				
			||||||
| 
						 | 
					@ -190,6 +202,7 @@ class Saml2Service extends Access\ExternalAuthService
 | 
				
			||||||
     *  they exist, optionally registering them automatically.
 | 
					     *  they exist, optionally registering them automatically.
 | 
				
			||||||
     *  @param string $samlID
 | 
					     *  @param string $samlID
 | 
				
			||||||
     *  @param array $samlAttributes
 | 
					     *  @param array $samlAttributes
 | 
				
			||||||
 | 
					     *  @throws SamlException
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function processLoginCallback($samlID, $samlAttributes)
 | 
					    public function processLoginCallback($samlID, $samlAttributes)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
| 
						 | 
					@ -197,12 +210,14 @@ class Saml2Service extends Access\ExternalAuthService
 | 
				
			||||||
        $isLoggedIn = auth()->check();
 | 
					        $isLoggedIn = auth()->check();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($isLoggedIn) {
 | 
					        if ($isLoggedIn) {
 | 
				
			||||||
            logger()->error("Already logged in");
 | 
					            throw new SamlException(trans('errors.saml_already_logged_in'), '/login');
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            $user = $this->getOrRegisterUser($userDetails);
 | 
					            $user = $this->getOrRegisterUser($userDetails);
 | 
				
			||||||
            if ($user === null) {
 | 
					            if ($user === null) {
 | 
				
			||||||
                logger()->error("User does not exist");
 | 
					                throw new SamlException(trans('errors.saml_user_not_registered', ['name' => $userDetails['uid']]), '/login');
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
 | 
					                $groups = $this->getUserGroups($samlAttributes);
 | 
				
			||||||
 | 
					                $this->syncWithGroups($user, $groups);
 | 
				
			||||||
                auth()->login($user);
 | 
					                auth()->login($user);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -150,12 +150,14 @@ return [
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    'saml' => [
 | 
					    'saml' => [
 | 
				
			||||||
 | 
					        'name' => env('SAML_NAME', 'SSO'),
 | 
				
			||||||
        'enabled' => env('SAML2_ENABLED', false),
 | 
					        'enabled' => env('SAML2_ENABLED', false),
 | 
				
			||||||
        'auto_register' => env('SAML_AUTO_REGISTER', false),
 | 
					        'auto_register' => env('SAML_AUTO_REGISTER', false),
 | 
				
			||||||
        'email_attribute' => env('SAML_EMAIL_ATTRIBUTE', 'email'),
 | 
					        'email_attribute' => env('SAML_EMAIL_ATTRIBUTE', 'email'),
 | 
				
			||||||
        'display_name_attribute' => explode('|', env('SAML_DISPLAY_NAME_ATTRIBUTE', 'username')),
 | 
					        'display_name_attribute' => explode('|', env('SAML_DISPLAY_NAME_ATTRIBUTE', 'username')),
 | 
				
			||||||
        'user_name_attribute' => env('SAML_USER_NAME_ATTRIBUTE', null),
 | 
					        'user_name_attribute' => env('SAML_USER_NAME_ATTRIBUTE', null),
 | 
				
			||||||
        'group_attribute' => env('SAML_GROUP_ATTRIBUTE', 'group'),
 | 
					        'group_attribute' => env('SAML_GROUP_ATTRIBUTE', 'group'),
 | 
				
			||||||
 | 
					        'remove_from_groups' => env('SAML_REMOVE_FROM_GROUPS',false),
 | 
				
			||||||
        'user_to_groups' => env('SAML_USER_TO_GROUPS', false),
 | 
					        'user_to_groups' => env('SAML_USER_TO_GROUPS', false),
 | 
				
			||||||
        'id_is_user_name' => env('SAML_ID_IS_USER_NAME', true),
 | 
					        'id_is_user_name' => env('SAML_ID_IS_USER_NAME', true),
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
<?php namespace BookStack\Exceptions;
 | 
					<?php namespace BookStack\Exceptions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SamlException extends PrettyException
 | 
					class SamlException extends NotifyException
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,8 @@ return [
 | 
				
			||||||
    'ldap_fail_authed' => 'LDAP-Zugriff mit DN und Passwort ist fehlgeschlagen',
 | 
					    'ldap_fail_authed' => 'LDAP-Zugriff mit DN und Passwort ist fehlgeschlagen',
 | 
				
			||||||
    'ldap_extension_not_installed' => 'LDAP-PHP-Erweiterung ist nicht installiert.',
 | 
					    'ldap_extension_not_installed' => 'LDAP-PHP-Erweiterung ist nicht installiert.',
 | 
				
			||||||
    'ldap_cannot_connect' => 'Die Verbindung zum LDAP-Server ist fehlgeschlagen. Beim initialen Verbindungsaufbau trat ein Fehler auf.',
 | 
					    'ldap_cannot_connect' => 'Die Verbindung zum LDAP-Server ist fehlgeschlagen. Beim initialen Verbindungsaufbau trat ein Fehler auf.',
 | 
				
			||||||
 | 
					    'saml_already_logged_in' => 'Sie sind bereits angemeldet',
 | 
				
			||||||
 | 
					    'saml_user_not_registered' => 'Kein Benutzer mit ID :name registriert und die automatische Registrierung ist deaktiviert',
 | 
				
			||||||
    'social_no_action_defined' => 'Es ist keine Aktion definiert',
 | 
					    'social_no_action_defined' => 'Es ist keine Aktion definiert',
 | 
				
			||||||
    'social_login_bad_response' => "Fehler bei der :socialAccount-Anmeldung: \n:error",
 | 
					    'social_login_bad_response' => "Fehler bei der :socialAccount-Anmeldung: \n:error",
 | 
				
			||||||
    'social_account_in_use' => 'Dieses :socialAccount-Konto wird bereits verwendet. Bitte melden Sie sich mit dem :socialAccount-Konto an.',
 | 
					    'social_account_in_use' => 'Dieses :socialAccount-Konto wird bereits verwendet. Bitte melden Sie sich mit dem :socialAccount-Konto an.',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,7 @@ return [
 | 
				
			||||||
    // Auth
 | 
					    // Auth
 | 
				
			||||||
    'email_already_confirmed' => 'Die E-Mail-Adresse ist bereits bestätigt. Bitte melde dich an.',
 | 
					    'email_already_confirmed' => 'Die E-Mail-Adresse ist bereits bestätigt. Bitte melde dich an.',
 | 
				
			||||||
    'email_confirmation_invalid' => 'Der Bestätigungslink ist nicht gültig oder wurde bereits verwendet. Bitte registriere dich erneut.',
 | 
					    'email_confirmation_invalid' => 'Der Bestätigungslink ist nicht gültig oder wurde bereits verwendet. Bitte registriere dich erneut.',
 | 
				
			||||||
 | 
					    'saml_already_logged_in' => 'Du bist bereits angemeldet',
 | 
				
			||||||
    'social_account_in_use' => 'Dieses :socialAccount-Konto wird bereits verwendet. Bitte melde dich mit dem :socialAccount-Konto an.',
 | 
					    'social_account_in_use' => 'Dieses :socialAccount-Konto wird bereits verwendet. Bitte melde dich mit dem :socialAccount-Konto an.',
 | 
				
			||||||
    'social_account_email_in_use' => 'Die E-Mail-Adresse ":email" ist bereits registriert. Wenn Du bereits registriert bist, kannst Du Dein :socialAccount-Konto in Deinen Profil-Einstellungen verknüpfen.',
 | 
					    'social_account_email_in_use' => 'Die E-Mail-Adresse ":email" ist bereits registriert. Wenn Du bereits registriert bist, kannst Du Dein :socialAccount-Konto in Deinen Profil-Einstellungen verknüpfen.',
 | 
				
			||||||
    'social_account_not_used' => 'Dieses :socialAccount-Konto ist bisher keinem Benutzer zugeordnet. Du kannst das in Deinen Profil-Einstellungen tun.',
 | 
					    'social_account_not_used' => 'Dieses :socialAccount-Konto ist bisher keinem Benutzer zugeordnet. Du kannst das in Deinen Profil-Einstellungen tun.',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,8 @@ return [
 | 
				
			||||||
    'ldap_fail_authed' => 'LDAP access failed using given dn & password details',
 | 
					    'ldap_fail_authed' => 'LDAP access failed using given dn & password details',
 | 
				
			||||||
    'ldap_extension_not_installed' => 'LDAP PHP extension not installed',
 | 
					    'ldap_extension_not_installed' => 'LDAP PHP extension not installed',
 | 
				
			||||||
    'ldap_cannot_connect' => 'Cannot connect to ldap server, Initial connection failed',
 | 
					    'ldap_cannot_connect' => 'Cannot connect to ldap server, Initial connection failed',
 | 
				
			||||||
 | 
					    'saml_already_logged_in' => 'Already logged in',
 | 
				
			||||||
 | 
					    'saml_user_not_registered' => 'The user :name is not registered and automatic registration is disabled',
 | 
				
			||||||
    'social_no_action_defined' => 'No action defined',
 | 
					    'social_no_action_defined' => 'No action defined',
 | 
				
			||||||
    'social_login_bad_response' => "Error received during :socialAccount login: \n:error",
 | 
					    'social_login_bad_response' => "Error received during :socialAccount login: \n:error",
 | 
				
			||||||
    'social_account_in_use' => 'This :socialAccount account is already in use, Try logging in via the :socialAccount option.',
 | 
					    'social_account_in_use' => 'This :socialAccount account is already in use, Try logging in via the :socialAccount option.',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,7 +51,7 @@
 | 
				
			||||||
              <div>
 | 
					              <div>
 | 
				
			||||||
                  <a id="saml-login" class="button outline block svg" href="{{ url("/saml2/login") }}">
 | 
					                  <a id="saml-login" class="button outline block svg" href="{{ url("/saml2/login") }}">
 | 
				
			||||||
                      {{-- @icon('auth/github') --}}
 | 
					                      {{-- @icon('auth/github') --}}
 | 
				
			||||||
                      {{ trans('auth.log_in_with', ['socialDriver' => 'SAML']) }}
 | 
					                      {{ trans('auth.log_in_with', ['socialDriver' => config('services.saml.name')]) }}
 | 
				
			||||||
                  </a>
 | 
					                  </a>
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            @endif
 | 
					            @endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue