Remove LDAP support.

This commit is contained in:
James Cole 2022-03-19 11:19:58 +01:00
parent 5ca0a9f75a
commit 52a5995bd1
No known key found for this signature in database
GPG Key ID: B49A324B7EAD6D80
15 changed files with 38 additions and 474 deletions

View File

@ -176,42 +176,14 @@ MAP_DEFAULT_ZOOM=6
#
# Firefly III supports a few authentication methods:
# - 'web' (default, uses built in DB)
# - 'ldap'
# - 'remote_user_guard' for Authelia etc
# Read more about these settings in the documentation.
# https://docs.firefly-iii.org/advanced-installation/authentication
#
# LDAP is no longer supported :(
#
AUTHENTICATION_GUARD=web
#
# Your LDAP server may speak a dialect. You can choose between 'OpenLDAP' and 'ActiveDirectory'
# Anything else defaults to 'ActiveDirectory'
#
LDAP_DIALECT=OpenLDAP
#
# LDAP connection settings:
#
LDAP_HOST=ldap.yourserver.com
LDAP_PORT=389
LDAP_TIMEOUT=5
LDAP_SSL=false
LDAP_TLS=false
LDAP_BASE_DN="o=something,dc=site,dc=com"
LDAP_USERNAME="uid=X,ou=,o=,dc=something,dc=com"
LDAP_PASSWORD=super_secret
LDAP_AUTH_FIELD=uid
#
# If you wish to only authenticate users from a specific group, use the base DN above.
#
# If you require extra/special filters please use the LDAP_EXTRA_FILTER with a valid DN.
#
# The extra filter will only be applied after the user is authenticated.
#
LDAP_EXTRA_FILTER=
#
# Remote user guard settings
#
@ -291,7 +263,6 @@ DKR_RUN_PASSPORT_INSTALL=true
# Leave the following configuration vars as is.
# Unless you like to tinker and know what you're doing.
APP_NAME=FireflyIII
ADLDAP_CONNECTION=default
BROADCAST_DRIVER=log
QUEUE_DRIVER=sync
CACHE_PREFIX=firefly

View File

@ -1,57 +0,0 @@
<?php
/*
* LDAPEventHandler.php
* Copyright (c) 2021 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Handlers\Events;
use FireflyIII\User;
use LdapRecord\Laravel\Events\Import\Imported;
use Log;
/**
* Class LDAPEventHandler
*/
class LDAPEventHandler
{
/**
* @param Imported $event
*/
public function importedUser(Imported $event)
{
Log::debug(sprintf('Now in %s', __METHOD__));
/** @var User $user */
$user = $event->eloquent;
$alternative = User::where('email', $user->email)->where('id', '!=', $user->id)->first();
if (null !== $alternative) {
Log::debug(sprintf('User #%d is created but user #%d already exists.', $user->id, $alternative->id));
$alternative->objectguid = $user->objectguid;
$alternative->domain = $user->domain;
$alternative->save();
$user->delete();
auth()->logout();
}
}
}

View File

@ -22,7 +22,6 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Auth;
use Adldap;
use Cookie;
use DB;
use FireflyIII\Events\ActuallyLoggedIn;
@ -90,15 +89,6 @@ class LoginController extends Controller
Log::channel('audit')->info(sprintf('User is trying to login using "%s"', $request->get($this->username())));
Log::info('User is trying to login.');
$guard = config('auth.defaults.guard');
// if the user logs in using LDAP the field is also changed (per LDAP config)
if ('ldap' === $guard) {
Log::debug('User wishes to login using LDAP.');
$this->username = config('firefly.ldap_auth_field');
}
$this->validateLogin($request);
Log::debug('Login data is valid.');
@ -216,17 +206,6 @@ class LoginController extends Controller
return redirect(route('register'));
}
// switch to LDAP settings:
if ('ldap' === $guard) {
Log::debug('User wishes to login using LDAP.');
$this->username = config('firefly.ldap_auth_field');
}
// throw warning if still using login_provider
$ldapWarning = false;
if ('ldap' === config('firefly.login_provider')) {
$ldapWarning = true;
}
// is allowed to register, etc.
$singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
$allowRegistration = true;
@ -251,7 +230,7 @@ class LoginController extends Controller
}
$usernameField = $this->username();
return view('auth.login', compact('allowRegistration', 'email', 'remember', 'ldapWarning', 'allowReset', 'title', 'usernameField'));
return view('auth.login', compact('allowRegistration', 'email', 'remember', 'allowReset', 'title', 'usernameField'));
}
/**

View File

@ -36,6 +36,8 @@ use Illuminate\Routing\Redirector;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;
use Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
/**
* Class RegisterController
@ -85,18 +87,7 @@ class RegisterController extends Controller
*/
public function register(Request $request)
{
// is allowed to?
$allowRegistration = true;
$singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
$userCount = User::count();
$guard = config('auth.defaults.guard');
if (true === $singleUserMode && $userCount > 0 && 'ldap' !== $guard) {
$allowRegistration = false;
}
if ('ldap' === $guard) {
$allowRegistration = false;
}
$allowRegistration = $this->allowedToRegister();
if (false === $allowRegistration) {
throw new FireflyException('Registration is currently not available :(');
@ -126,24 +117,9 @@ class RegisterController extends Controller
*/
public function showRegistrationForm(Request $request)
{
$allowRegistration = true;
$isDemoSite = app('fireflyconfig')->get('is_demo_site', config('firefly.configuration.is_demo_site'))->data;
$singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
$userCount = User::count();
$pageTitle = (string)trans('firefly.register_page_title');
$guard = config('auth.defaults.guard');
if (true === $isDemoSite) {
$allowRegistration = false;
}
if (true === $singleUserMode && $userCount > 0 && 'ldap' !== $guard) {
$allowRegistration = false;
}
if ('ldap' === $guard) {
$allowRegistration = false;
}
$allowRegistration = $this->allowedToRegister();
if (false === $allowRegistration) {
$message = 'Registration is currently not available.';
@ -156,4 +132,25 @@ class RegisterController extends Controller
return view('auth.register', compact('isDemoSite', 'email', 'pageTitle'));
}
/**
* @return bool
*/
protected function allowedToRegister(): bool {
// is allowed to register?
$allowRegistration = true;
try {
$singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
} catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) {
$singleUserMode = true;
}
$userCount = User::count();
$guard = config('auth.defaults.guard');
if (true === $singleUserMode && $userCount > 0 && 'web' === $guard) {
$allowRegistration = false;
}
if('web' !== $guard) {
$allowRegistration = false;
}
return $allowRegistration;
}
}

View File

@ -1,44 +0,0 @@
<?php
/*
* AttributeHandler.php
* Copyright (c) 2021 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Ldap;
use FireflyIII\User as DatabaseUser;
use LdapRecord\Models\Entry;
/**
* Class AttributeHandler
*/
class AttributeHandler
{
/**
* @param Entry $ldapUser
* @param DatabaseUser $database
*/
public function handle(Entry $ldapUser, DatabaseUser $database)
{
$database->email = $ldapUser->getFirstAttribute('mail');
$database->save();
}
}

View File

@ -1,88 +0,0 @@
<?php
/*
* UserDefinedRule.php
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Ldap\Rules;
use LdapRecord\Laravel\Auth\Rule;
use LdapRecord\Models\Attributes\DistinguishedName;
use LdapRecord\Query\ObjectNotFoundException;
use Log;
/**
* Class UserDefinedRule
*/
class UserDefinedRule extends Rule
{
/**
* Check if the rule passes validation.
*
* @return bool
* @throws ObjectNotFoundException
*/
public function isValid()
{
$extraFilter = config('ldap.extra_filter');
Log::debug(sprintf('UserDefinedRule with extra filter "%s"', $extraFilter));
if (empty($extraFilter)) {
Log::debug('Extra filter is empty, return true.');
return true;
}
Log::debug('Extra filter is not empty, continue.');
// group class:
// use ;
$openLDAP = class_exists(\LdapRecord\Models\OpenLDAP\Group::class) ? \LdapRecord\Models\OpenLDAP\Group::class : '';
$activeDirectory = class_exists(\LdapRecord\Models\ActiveDirectory\Group::class) ? \LdapRecord\Models\ActiveDirectory\Group::class : '';
$groupClass = config('ldap.dialect') === 'OpenLDAP' ? $openLDAP : $activeDirectory;
Log::debug(sprintf('Will use dialect group class "%s"', $groupClass));
// We've been given an invalid group filter. We will assume the
// developer is using some group ANR attribute, and attempt
// to check the user's membership with the resulting group.
if (!DistinguishedName::isValid($extraFilter)) {
Log::debug('UserDefinedRule: Is not valid DN');
return $this->user->groups()->recursive()->exists($groupClass::findByAnrOrFail($extraFilter));
}
$head = strtolower(DistinguishedName::make($extraFilter)->head());
Log::debug(sprintf('UserDefinedRule: Head is "%s"', $head));
// If the head of the DN we've been given is an OU, we will assume
// the developer is looking to filter users based on hierarchy.
// Otherwise, we'll attempt locating a group by the given
// group filter and checking the users group membership.
if ('ou' === $head) {
Log::debug('UserDefinedRule: Will return if user is a descendant of.');
return $this->user->isDescendantOf($extraFilter);
}
Log::debug('UserDefinedRule: Will return if user exists in group.');
return $this->user->groups()->recursive()->exists($groupClass::findOrFail($extraFilter));
}
}

View File

@ -1,49 +0,0 @@
<?php
/*
* UserDefinedScope.php
* Copyright (c) 2022 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Ldap\Scopes;
use LdapRecord\Models\Model;
use LdapRecord\Models\Scope;
use LdapRecord\Query\Model\Builder;
use Log;
/**
* Class UserDefinedScope
*/
class UserDefinedScope implements Scope
{
/**
* Apply the scope to the given query.
*
* @param Builder $query
* @param Model $model
*
* @return void
*/
public function apply(Builder $query, Model $model)
{
}
}

View File

@ -22,7 +22,6 @@ declare(strict_types=1);
namespace FireflyIII\Providers;
use Adldap\Laravel\Middleware\WindowsAuthenticate;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;
use Laravel\Passport\Passport;
@ -46,9 +45,6 @@ class AppServiceProvider extends ServiceProvider
if ('heroku' === config('app.env')) {
URL::forceScheme('https');
}
if (config('ldap_auth.identifiers.windows.enabled', false)) {
$this->app['router']->pushMiddlewareToGroup('web', WindowsAuthenticate::class);
}
Sanctum::ignoreMigrations();
}

View File

@ -45,7 +45,6 @@ use Illuminate\Auth\Events\Login;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Laravel\Passport\Client;
use Laravel\Passport\Events\AccessTokenCreated;
use LdapRecord\Laravel\Events\Import\Imported;
use Log;
use Mail;
use Request;
@ -135,11 +134,6 @@ class EventServiceProvider extends ServiceProvider
UpdatedAccount::class => [
'FireflyIII\Handlers\Events\UpdatedAccountEventHandler@recalculateCredit',
],
// LDAP related events:
Imported::class => [
'FireflyIII\Handlers\Events\LDAPEventHandler@importedUser',
],
];
/**

View File

@ -302,6 +302,7 @@ class User extends Authenticatable
/**
* Get the models LDAP domain.
* @deprecated
*
* @return string
*/
@ -312,6 +313,7 @@ class User extends Authenticatable
/**
* Get the database column name of the domain.
* @deprecated
*
* @return string
*/
@ -322,6 +324,7 @@ class User extends Authenticatable
/**
* Get the models LDAP GUID.
* @deprecated
*
* @return string
*/
@ -332,6 +335,7 @@ class User extends Authenticatable
/**
* Get the models LDAP GUID database column name.
* @deprecated
*
* @return string
*/
@ -452,6 +456,7 @@ class User extends Authenticatable
/**
* Set the models LDAP domain.
* @deprecated
*
* @param string $domain
*
@ -464,7 +469,7 @@ class User extends Authenticatable
/**
* Set the models LDAP GUID.
*
* @deprecated
* @param string $guid
*
* @return void

View File

@ -117,8 +117,6 @@
"phpunit/phpunit": "^9.5"
},
"suggest": {
"directorytree/ldaprecord-laravel": "If you want to login using LDAP.",
"ext-ldap": "Needed to support LDAP."
},
"autoload": {
"psr-4": {

View File

@ -21,20 +21,8 @@
declare(strict_types=1);
use FireflyIII\Ldap\AttributeHandler;
use FireflyIII\Ldap\Rules\UserDefinedRule;
# select ldap model based on configuration option
switch(env('LDAP_DIALECT')) {
case 'ActiveDirectory':
$ldapModel = class_exists(LdapRecord\Models\ActiveDirectory\User::class) ? LdapRecord\Models\ActiveDirectory\User::class : '';
break;
case 'FreeIPA':
$ldapModel = class_exists(LdapRecord\Models\FreeIPA\User::class) ? LdapRecord\Models\FreeIPA\User::class : '';
break;
default:
# default to openLDAP
$ldapModel = class_exists(LdapRecord\Models\OpenLDAP\User::class) ? LdapRecord\Models\OpenLDAP\User::class : '';
if('ldap' === strtolower(env('AUTHENTICATION_GUARD'))) {
die('LDAP is no longer supported by Firefly III v5.7+. Sorry about that. You will have to switch to "remote_user_guard", and use tools like Authelia or Keycloak to use LDAP together with Firefly III.');
}
return [
@ -78,10 +66,6 @@ return [
'driver' => 'session',
'provider' => 'users',
],
'ldap' => [
'driver' => 'session',
'provider' => 'ldap',
],
'remote_user_guard' => [
'driver' => 'remote_user_guard',
'provider' => 'remote_user_provider',
@ -118,19 +102,6 @@ return [
'driver' => 'remote_user_provider',
'model' => FireflyIII\User::class,
],
'ldap' => [
'driver' => 'ldap',
'model' => $ldapModel,
'rules' => [
UserDefinedRule::class,
],
'database' => [
'model' => FireflyIII\User::class,
'sync_passwords' => false,
'sync_attributes' => AttributeHandler::class,
],
],
],
/*

View File

@ -133,11 +133,10 @@ return [
'tracker_site_id' => env('TRACKER_SITE_ID', ''),
'tracker_url' => env('TRACKER_URL', ''),
// LDAP and authentication settings
// authentication settings
'login_provider' => envNonEmpty('LOGIN_PROVIDER', 'eloquent'),
'authentication_guard' => envNonEmpty('AUTHENTICATION_GUARD', 'web'),
'custom_logout_url' => envNonEmpty('CUSTOM_LOGOUT_URL', ''),
'ldap_auth_field' => env('LDAP_AUTH_FIELD', env('ADLDAP_AUTH_FIELD', 'distinguishedname')),
// static config (cannot be changed by user)
'update_endpoint' => 'https://version.firefly-iii.org/index.json',

View File

@ -1,97 +0,0 @@
<?php
/*
* ldap.php
* Copyright (c) 2021 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
return [
/*
|--------------------------------------------------------------------------
| Default LDAP Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the LDAP connections below you wish
| to use as your default connection for all LDAP operations. Of
| course you may add as many connections you'd like below.
|
*/
'default' => env('LDAP_CONNECTION', 'default'),
'extra_filter' => env('LDAP_EXTRA_FILTER'),
'dialect' => env('LDAP_DIALECT'),
/*
|--------------------------------------------------------------------------
| LDAP Connections
|--------------------------------------------------------------------------
|
| Below you may configure each LDAP connection your application requires
| access to. Be sure to include a valid base DN - otherwise you may
| not receive any results when performing LDAP search operations.
|
*/
'connections' => [
'default' => [
'hosts' => [env('LDAP_HOST', '127.0.0.1')],
'username' => env('LDAP_USERNAME', 'cn=user,dc=local,dc=com'),
'password' => env('LDAP_PASSWORD', 'secret'),
'port' => env('LDAP_PORT', 389),
'base_dn' => env('LDAP_BASE_DN', 'dc=local,dc=com'),
'timeout' => env('LDAP_TIMEOUT', 5),
'use_ssl' => env('LDAP_SSL', false),
'use_tls' => env('LDAP_TLS', false),
],
],
/*
|--------------------------------------------------------------------------
| LDAP Logging
|--------------------------------------------------------------------------
|
| When LDAP logging is enabled, all LDAP search and authentication
| operations are logged using the default application logging
| driver. This can assist in debugging issues and more.
|
*/
'logging' => env('LDAP_LOGGING', true),
/*
|--------------------------------------------------------------------------
| LDAP Cache
|--------------------------------------------------------------------------
|
| LDAP caching enables the ability of caching search results using the
| query builder. This is great for running expensive operations that
| may take many seconds to complete, such as a pagination request.
|
*/
'cache' => [
'enabled' => env('LDAP_CACHE', false),
'driver' => env('CACHE_DRIVER', 'file'),
],
];

View File

@ -47,17 +47,6 @@
</div>
{% endif %}
{# LDAP warning #}
{% if ldapWarning %}
<div class="row">
<div class="col-lg-12">
<div class="alert alert-danger alert-dismissible" role="alert">
<a target="_blank" href="https://docs.firefly-iii.org/firefly-iii/advanced-installation/authentication/#ldap">Please upgrade LDAP configuration</a>
</div>
</div>
</div>
{% endif %}
<div class="login-box-body">
<p class="login-box-msg">{{ 'sign_in_to_start'|_ }}</p>