use BookStack\Auth\Role;
use BookStack\Auth\User;
+use Illuminate\Database\Eloquent\Builder;
class ExternalAuthService
{
/**
* Sync the groups to the user roles for the current user
* @param \BookStack\Auth\User $user
- * @param array $samlAttributes
+ * @param array $userGroups
*/
public function syncWithGroups(User $user, array $userGroups)
{
// Get the ids for the roles from the names
- $samlGroupsAsRoles = $this->matchGroupsToSystemsRoles($userSamlGroups);
+ $groupsAsRoles = $this->matchGroupsToSystemsRoles($userGroups);
// Sync groups
if ($this->config['remove_from_groups']) {
- $user->roles()->sync($samlGroupsAsRoles);
+ $user->roles()->sync($groupsAsRoles);
$this->userRepo->attachDefaultRole($user);
} else {
- $user->roles()->syncWithoutDetaching($samlGroupsAsRoles);
+ $user->roles()->syncWithoutDetaching($groupsAsRoles);
}
}
}
use BookStack\Auth\UserRepo;
use BookStack\Exceptions\LdapException;
use Illuminate\Contracts\Auth\Authenticatable;
-use Illuminate\Database\Eloquent\Builder;
/**
* Class LdapService
use BookStack\Auth\UserRepo;
use BookStack\Exceptions\SamlException;
use Illuminate\Contracts\Auth\Authenticatable;
-use Illuminate\Database\Eloquent\Builder;
-use Illuminate\Support\Facades\Log;
/**
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.
* Handles properties potentially being an array.
protected function getSamlResponseAttribute(array $samlAttributes, string $propertyKey, $defaultValue)
{
if (isset($samlAttributes[$propertyKey])) {
- $data = $samlAttributes[$propertyKey];
- if (is_array($data)) {
- if (count($data) == 0) {
- $data = $defaultValue;
- } else if (count($data) == 1) {
- $data = $data[0];
- }
- }
+ $data = $this->simplifyValue($samlAttributes[$propertyKey], $defaultValue);
} else {
- $data = $defaultValue;
+ $data = $defaultValue;
}
return $data;
* they exist, optionally registering them automatically.
* @param string $samlID
* @param array $samlAttributes
+ * @throws SamlException
*/
public function processLoginCallback($samlID, $samlAttributes)
{
$isLoggedIn = auth()->check();
if ($isLoggedIn) {
- logger()->error("Already logged in");
+ throw new SamlException(trans('errors.saml_already_logged_in'), '/login');
} else {
$user = $this->getOrRegisterUser($userDetails);
if ($user === null) {
- logger()->error("User does not exist");
+ throw new SamlException(trans('errors.saml_user_not_registered', ['name' => $userDetails['uid']]), '/login');
} else {
+ $groups = $this->getUserGroups($samlAttributes);
+ $this->syncWithGroups($user, $groups);
auth()->login($user);
}
}
],
'saml' => [
+ 'name' => env('SAML_NAME', 'SSO'),
'enabled' => env('SAML2_ENABLED', false),
'auto_register' => env('SAML_AUTO_REGISTER', false),
'email_attribute' => env('SAML_EMAIL_ATTRIBUTE', 'email'),
'display_name_attribute' => explode('|', env('SAML_DISPLAY_NAME_ATTRIBUTE', 'username')),
'user_name_attribute' => env('SAML_USER_NAME_ATTRIBUTE', null),
'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),
'id_is_user_name' => env('SAML_ID_IS_USER_NAME', true),
]
<?php namespace BookStack\Exceptions;
-class SamlException extends PrettyException
+class SamlException extends NotifyException
{
}
'ldap_fail_authed' => 'LDAP-Zugriff mit DN und Passwort ist fehlgeschlagen',
'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.',
+ '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_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.',
// Auth
'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.',
+ '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_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.',
'ldap_fail_authed' => 'LDAP access failed using given dn & password details',
'ldap_extension_not_installed' => 'LDAP PHP extension not installed',
'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_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.',
<div>
<a id="saml-login" class="button outline block svg" href="{{ url("/saml2/login") }}">
{{-- @icon('auth/github') --}}
- {{ trans('auth.log_in_with', ['socialDriver' => 'SAML']) }}
+ {{ trans('auth.log_in_with', ['socialDriver' => config('services.saml.name')]) }}
</a>
</div>
@endif