From 52a5995bd18455aa35b2d4701fd84a26575f85fd Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 19 Mar 2022 11:19:58 +0100 Subject: [PATCH] Remove LDAP support. --- .env.example | 35 +------ app/Handlers/Events/LDAPEventHandler.php | 57 ----------- app/Http/Controllers/Auth/LoginController.php | 23 +---- .../Controllers/Auth/RegisterController.php | 53 +++++----- app/Ldap/AttributeHandler.php | 44 --------- app/Ldap/Rules/UserDefinedRule.php | 88 ----------------- app/Ldap/Scopes/UserDefinedScope.php | 49 ---------- app/Providers/AppServiceProvider.php | 4 - app/Providers/EventServiceProvider.php | 6 -- app/User.php | 7 +- composer.json | 2 - config/auth.php | 33 +------ config/firefly.php | 3 +- config/ldap.php | 97 ------------------- resources/views/auth/login.twig | 11 --- 15 files changed, 38 insertions(+), 474 deletions(-) delete mode 100644 app/Handlers/Events/LDAPEventHandler.php delete mode 100644 app/Ldap/AttributeHandler.php delete mode 100644 app/Ldap/Rules/UserDefinedRule.php delete mode 100644 app/Ldap/Scopes/UserDefinedScope.php delete mode 100644 config/ldap.php diff --git a/.env.example b/.env.example index 87a076a8ed..abf2c980b2 100644 --- a/.env.example +++ b/.env.example @@ -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 diff --git a/app/Handlers/Events/LDAPEventHandler.php b/app/Handlers/Events/LDAPEventHandler.php deleted file mode 100644 index 84253d3c79..0000000000 --- a/app/Handlers/Events/LDAPEventHandler.php +++ /dev/null @@ -1,57 +0,0 @@ -. - */ - -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(); - } - } - -} diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 0aaa0917d5..5302526e5b 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -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')); } /** diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index 8db7b333e5..138482886e 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -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; + } } diff --git a/app/Ldap/AttributeHandler.php b/app/Ldap/AttributeHandler.php deleted file mode 100644 index e3e13c6795..0000000000 --- a/app/Ldap/AttributeHandler.php +++ /dev/null @@ -1,44 +0,0 @@ -. - */ - -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(); - } -} diff --git a/app/Ldap/Rules/UserDefinedRule.php b/app/Ldap/Rules/UserDefinedRule.php deleted file mode 100644 index 1ccbbd8f75..0000000000 --- a/app/Ldap/Rules/UserDefinedRule.php +++ /dev/null @@ -1,88 +0,0 @@ -. - */ - -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)); - } -} diff --git a/app/Ldap/Scopes/UserDefinedScope.php b/app/Ldap/Scopes/UserDefinedScope.php deleted file mode 100644 index cccaa71ae1..0000000000 --- a/app/Ldap/Scopes/UserDefinedScope.php +++ /dev/null @@ -1,49 +0,0 @@ -. - */ - -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) - { - } -} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 8675bd9ec3..d496885df3 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -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(); } diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 84258e961c..788850eddd 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -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', - ], ]; /** diff --git a/app/User.php b/app/User.php index 0e69a6ca17..649d948122 100644 --- a/app/User.php +++ b/app/User.php @@ -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 diff --git a/composer.json b/composer.json index 459de1882d..79f5a12c65 100644 --- a/composer.json +++ b/composer.json @@ -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": { diff --git a/config/auth.php b/config/auth.php index 974c68a8f6..0f865b1bbc 100644 --- a/config/auth.php +++ b/config/auth.php @@ -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, - ], - ], ], /* diff --git a/config/firefly.php b/config/firefly.php index 5bba14568b..44f1ccbdd6 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -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', diff --git a/config/ldap.php b/config/ldap.php deleted file mode 100644 index 6d00ca1a16..0000000000 --- a/config/ldap.php +++ /dev/null @@ -1,97 +0,0 @@ -. - */ - -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'), - ], - -]; diff --git a/resources/views/auth/login.twig b/resources/views/auth/login.twig index 58aaa8cecf..9a96d56365 100644 --- a/resources/views/auth/login.twig +++ b/resources/views/auth/login.twig @@ -47,17 +47,6 @@ {% endif %} - {# LDAP warning #} - {% if ldapWarning %} -
- -
- {% endif %} -