From aac3027480266e750b9afd9b1d9b4149a49e3acc Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 30 Apr 2021 19:51:50 +0200 Subject: [PATCH 1/8] First attempt --- composer.json | 1 + composer.lock | 191 ++++++++++++- config/ldap.php | 333 ++++------------------- config/xldap.php | 294 ++++++++++++++++++++ config/{ldap_auth.php => xldap_auth.php} | 0 5 files changed, 541 insertions(+), 278 deletions(-) create mode 100644 config/xldap.php rename config/{ldap_auth.php => xldap_auth.php} (100%) diff --git a/composer.json b/composer.json index a18d293aca..e8f8ebc65e 100644 --- a/composer.json +++ b/composer.json @@ -84,6 +84,7 @@ "ext-xml": "*", "bacon/bacon-qr-code": "2.*", "diglactic/laravel-breadcrumbs": "^6.0", + "directorytree/ldaprecord-laravel": "^2.2", "doctrine/dbal": "3.*", "fideloper/proxy": "4.*", "gdbots/query-parser": "^2.0", diff --git a/composer.lock b/composer.lock index e3b9f18cb7..dfd2f4dadd 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "bd033cd41088c7c19fba9031a13c2286", + "content-hash": "28d6c78fd071d01b11d366d5595195fd", "packages": [ { "name": "bacon/bacon-qr-code", @@ -375,6 +375,141 @@ }, "time": "2021-04-12T18:06:07+00:00" }, + { + "name": "directorytree/ldaprecord", + "version": "v2.4.3", + "source": { + "type": "git", + "url": "https://github.com/DirectoryTree/LdapRecord.git", + "reference": "d384f2fa8926ffbef01e00e67068afdffcc9a781" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DirectoryTree/LdapRecord/zipball/d384f2fa8926ffbef01e00e67068afdffcc9a781", + "reference": "d384f2fa8926ffbef01e00e67068afdffcc9a781", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-ldap": "*", + "illuminate/contracts": "^5.0|^6.0|^7.0|^8.0", + "nesbot/carbon": "^1.0|^2.0", + "php": ">=7.2", + "psr/log": "^1.0", + "psr/simple-cache": "^1.0", + "tightenco/collect": "^5.6|^6.0|^7.0|^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "LdapRecord\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Steve Bauman", + "email": "steven_bauman@outlook.com", + "role": "Developer" + } + ], + "description": "A fully-featured LDAP ORM.", + "homepage": "https://www.ldaprecord.com", + "keywords": [ + "active directory", + "ad", + "adLDAP", + "adldap2", + "directory", + "ldap", + "ldaprecord", + "orm", + "windows" + ], + "support": { + "docs": "https://ldaprecord.com", + "email": "steven_bauman@outlook.com", + "issues": "https://github.com/DirectoryTree/LdapRecord/issues", + "source": "https://github.com/DirectoryTree/LdapRecord" + }, + "funding": [ + { + "url": "https://github.com/stevebauman", + "type": "github" + } + ], + "time": "2021-04-25T02:35:23+00:00" + }, + { + "name": "directorytree/ldaprecord-laravel", + "version": "v2.2.3", + "source": { + "type": "git", + "url": "https://github.com/DirectoryTree/LdapRecord-Laravel.git", + "reference": "c84b7a1528f4bd0f98476a2591f80421625148cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DirectoryTree/LdapRecord-Laravel/zipball/c84b7a1528f4bd0f98476a2591f80421625148cc", + "reference": "c84b7a1528f4bd0f98476a2591f80421625148cc", + "shasum": "" + }, + "require": { + "directorytree/ldaprecord": "^2.3", + "ext-ldap": "*", + "illuminate/support": "^5.6|^6.0|^7.0|^8.0", + "php": ">=7.2", + "ramsey/uuid": "*" + }, + "require-dev": { + "mockery/mockery": "~1.0", + "orchestra/testbench": "~3.7|~4.0|~5.0|~6.0", + "phpunit/phpunit": "~7.0|~8.0|~9.0" + }, + "type": "project", + "extra": { + "laravel": { + "providers": [ + "LdapRecord\\Laravel\\LdapServiceProvider", + "LdapRecord\\Laravel\\LdapAuthServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "LdapRecord\\Laravel\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "LDAP Authentication & Management for Laravel.", + "keywords": [ + "adldap2", + "laravel", + "ldap", + "ldaprecord" + ], + "support": { + "issues": "https://github.com/DirectoryTree/LdapRecord-Laravel/issues", + "source": "https://github.com/DirectoryTree/LdapRecord-Laravel/tree/v2.2.3" + }, + "funding": [ + { + "url": "https://github.com/stevebauman", + "type": "github" + } + ], + "time": "2021-04-18T21:19:55+00:00" + }, { "name": "doctrine/cache", "version": "1.11.0", @@ -6707,6 +6842,60 @@ ], "time": "2021-03-28T09:42:18+00:00" }, + { + "name": "tightenco/collect", + "version": "v8.34.0", + "source": { + "type": "git", + "url": "https://github.com/tighten/collect.git", + "reference": "b069783ab0c547bb894ebcf8e7f6024bb401f9d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tighten/collect/zipball/b069783ab0c547bb894ebcf8e7f6024bb401f9d2", + "reference": "b069783ab0c547bb894ebcf8e7f6024bb401f9d2", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "symfony/var-dumper": "^3.4 || ^4.0 || ^5.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "nesbot/carbon": "^2.23.0", + "phpunit/phpunit": "^8.3" + }, + "type": "library", + "autoload": { + "files": [ + "src/Collect/Support/helpers.php", + "src/Collect/Support/alias.php" + ], + "psr-4": { + "Tightenco\\Collect\\": "src/Collect" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylorotwell@gmail.com" + } + ], + "description": "Collect - Illuminate Collections as a separate package.", + "keywords": [ + "collection", + "laravel" + ], + "support": { + "issues": "https://github.com/tighten/collect/issues", + "source": "https://github.com/tighten/collect/tree/v8.34.0" + }, + "time": "2021-03-29T21:29:00+00:00" + }, { "name": "tijsverkoyen/css-to-inline-styles", "version": "2.2.3", diff --git a/config/ldap.php b/config/ldap.php index 1c2d1b52be..fd94d32e78 100644 --- a/config/ldap.php +++ b/config/ldap.php @@ -1,294 +1,73 @@ . - */ - -declare(strict_types=1); - -use Adldap\Schemas\ActiveDirectory; -use Adldap\Schemas\FreeIPA; -use Adldap\Schemas\OpenLDAP; - -/* - * Get schema from .env file. - */ -$schema = OpenLDAP::class; - -if ('FreeIPA' === envNonEmpty('ADLDAP_CONNECTION_SCHEME', 'OpenLDAP')) { - $schema = FreeIPA::class; -} -if ('ActiveDirectory' === envNonEmpty('ADLDAP_CONNECTION_SCHEME', 'OpenLDAP')) { - $schema = ActiveDirectory::class; -} - -/* - * Get SSL parameters from .env file. - */ -$ssl_ca_dir = envNonEmpty('ADLDAP_SSL_CACERTDIR', null); -$ssl_ca_file = envNonEmpty('ADLDAP_SSL_CACERTFILE', null); -$ssl_cert = envNonEmpty('ADLDAP_SSL_CERTFILE', null); -$ssl_key = envNonEmpty('ADLDAP_SSL_KEYFILE', null); -$ssl_ciphers = envNonEmpty('ADLDAP_SSL_CIPHER_SUITE', null); -$ssl_require = envNonEmpty('ADLDAP_SSL_REQUIRE_CERT', null); - -$sslOptions = []; -if (null !== $ssl_ca_dir) { - $sslOptions[LDAP_OPT_X_TLS_CACERTDIR] = $ssl_ca_dir; -} -if (null !== $ssl_ca_file) { - $sslOptions[LDAP_OPT_X_TLS_CACERTFILE] = $ssl_ca_file; -} -if (null !== $ssl_cert) { - $sslOptions[LDAP_OPT_X_TLS_CERTFILE] = $ssl_cert; -} -if (null !== $ssl_key) { - $sslOptions[LDAP_OPT_X_TLS_KEYFILE] = $ssl_key; -} -if (null !== $ssl_ciphers) { - $sslOptions[LDAP_OPT_X_TLS_CIPHER_SUITE] = $ssl_ciphers; -} -if (null !== $ssl_require) { - $sslOptions[LDAP_OPT_X_TLS_REQUIRE_CERT] = $ssl_require; -} - return [ + /* |-------------------------------------------------------------------------- - | Connections + | Default LDAP Connection Name |-------------------------------------------------------------------------- | - | This array stores the connections that are added to Adldap. You can add - | as many connections as you like. - | - | The key is the name of the connection you wish to use and the value is - | an array of configuration settings. + | 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'), + + /* + |-------------------------------------------------------------------------- + | 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' => [ - - /* - |-------------------------------------------------------------------------- - | Auto Connect - |-------------------------------------------------------------------------- - | - | If auto connect is true, Adldap will try to automatically connect to - | your LDAP server in your configuration. This allows you to assume - | connectivity rather than having to connect manually - | in your application. - | - | If this is set to false, you **must** connect manually before running - | LDAP operations. - | - */ - - 'auto_connect' => env('ADLDAP_AUTO_CONNECT', true), - - /* - |-------------------------------------------------------------------------- - | Connection - |-------------------------------------------------------------------------- - | - | The connection class to use to run raw LDAP operations on. - | - | Custom connection classes must implement: - | - | Adldap\Connections\ConnectionInterface - | - */ - - 'connection' => Adldap\Connections\Ldap::class, - - /* - |-------------------------------------------------------------------------- - | Connection Settings - |-------------------------------------------------------------------------- - | - | This connection settings array is directly passed into the Adldap constructor. - | - | Feel free to add or remove settings you don't need. - | - */ - - 'settings' => [ - - /* - |-------------------------------------------------------------------------- - | Schema - |-------------------------------------------------------------------------- - | - | The schema class to use for retrieving attributes and generating models. - | - | You can also set this option to `null` to use the default schema class. - | - | For OpenLDAP, you must use the schema: - | - | Adldap\Schemas\OpenLDAP::class - | - | For FreeIPA, you must use the schema: - | - | Adldap\Schemas\FreeIPA::class - | - | Custom schema classes must implement Adldap\Schemas\SchemaInterface - | - */ - - 'schema' => $schema, - - /* - |-------------------------------------------------------------------------- - | Account Prefix - |-------------------------------------------------------------------------- - | - | The account prefix option is the prefix of your user accounts in LDAP directory. - | - | This string is prepended to authenticating users usernames. - | - */ - - 'account_prefix' => env('ADLDAP_ACCOUNT_PREFIX', ''), - - /* - |-------------------------------------------------------------------------- - | Account Suffix - |-------------------------------------------------------------------------- - | - | The account suffix option is the suffix of your user accounts in your LDAP directory. - | - | This string is appended to authenticating users usernames. - | - */ - - 'account_suffix' => env('ADLDAP_ACCOUNT_SUFFIX', ''), - - /* - |-------------------------------------------------------------------------- - | Domain Controllers - |-------------------------------------------------------------------------- - | - | The domain controllers option is an array of servers located on your - | network that serve Active Directory. You can insert as many servers or - | as little as you'd like depending on your forest (with the - | minimum of one of course). - | - | These can be IP addresses of your server(s), or the host name. - | - */ - - 'hosts' => explode(' ', env('ADLDAP_CONTROLLERS', '127.0.0.1')), - - /* - |-------------------------------------------------------------------------- - | Port - |-------------------------------------------------------------------------- - | - | The port option is used for authenticating and binding to your LDAP server. - | - */ - - 'port' => env('ADLDAP_PORT', 389), - - /* - |-------------------------------------------------------------------------- - | Timeout - |-------------------------------------------------------------------------- - | - | The timeout option allows you to configure the amount of time in - | seconds that your application waits until a response - | is received from your LDAP server. - | - */ - - 'timeout' => env('ADLDAP_TIMEOUT', 5), - - /* - |-------------------------------------------------------------------------- - | Base Distinguished Name - |-------------------------------------------------------------------------- - | - | The base distinguished name is the base distinguished name you'd - | like to perform query operations on. An example base DN would be: - | - | dc=corp,dc=acme,dc=org - | - | A correct base DN is required for any query results to be returned. - | - */ - - 'base_dn' => env('ADLDAP_BASEDN', 'dc=temp'), - - /* - |-------------------------------------------------------------------------- - | Administrator Username & Password - |-------------------------------------------------------------------------- - | - | When connecting to your LDAP server, a username and password is required - | to be able to query and run operations on your server(s). You can - | use any user account that has these permissions. This account - | does not need to be a domain administrator unless you - | require changing and resetting user passwords. - | - */ - - 'username' => env('ADLDAP_ADMIN_USERNAME', ''), - 'password' => env('ADLDAP_ADMIN_PASSWORD', ''), - - /* - |-------------------------------------------------------------------------- - | Follow Referrals - |-------------------------------------------------------------------------- - | - | The follow referrals option is a boolean to tell active directory - | to follow a referral to another server on your network if the - | server queried knows the information your asking for exists, - | but does not yet contain a copy of it locally. - | - | This option is defaulted to false. - | - */ - - 'follow_referrals' => env('ADLDAP_FOLLOW_REFFERALS', false), - - /* - |-------------------------------------------------------------------------- - | SSL & TLS - |-------------------------------------------------------------------------- - | - | If you need to be able to change user passwords on your server, then an - | SSL or TLS connection is required. All other operations are allowed - | on unsecured protocols. - | - | One of these options are definitely recommended if you - | have the ability to connect to your server securely. - | - */ - - 'use_ssl' => env('ADLDAP_USE_SSL', false), - 'use_tls' => env('ADLDAP_USE_TLS', false), - - 'custom_options' => $sslOptions, - ], - + '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/config/xldap.php b/config/xldap.php new file mode 100644 index 0000000000..1c2d1b52be --- /dev/null +++ b/config/xldap.php @@ -0,0 +1,294 @@ +. + */ + +declare(strict_types=1); + +use Adldap\Schemas\ActiveDirectory; +use Adldap\Schemas\FreeIPA; +use Adldap\Schemas\OpenLDAP; + +/* + * Get schema from .env file. + */ +$schema = OpenLDAP::class; + +if ('FreeIPA' === envNonEmpty('ADLDAP_CONNECTION_SCHEME', 'OpenLDAP')) { + $schema = FreeIPA::class; +} +if ('ActiveDirectory' === envNonEmpty('ADLDAP_CONNECTION_SCHEME', 'OpenLDAP')) { + $schema = ActiveDirectory::class; +} + +/* + * Get SSL parameters from .env file. + */ +$ssl_ca_dir = envNonEmpty('ADLDAP_SSL_CACERTDIR', null); +$ssl_ca_file = envNonEmpty('ADLDAP_SSL_CACERTFILE', null); +$ssl_cert = envNonEmpty('ADLDAP_SSL_CERTFILE', null); +$ssl_key = envNonEmpty('ADLDAP_SSL_KEYFILE', null); +$ssl_ciphers = envNonEmpty('ADLDAP_SSL_CIPHER_SUITE', null); +$ssl_require = envNonEmpty('ADLDAP_SSL_REQUIRE_CERT', null); + +$sslOptions = []; +if (null !== $ssl_ca_dir) { + $sslOptions[LDAP_OPT_X_TLS_CACERTDIR] = $ssl_ca_dir; +} +if (null !== $ssl_ca_file) { + $sslOptions[LDAP_OPT_X_TLS_CACERTFILE] = $ssl_ca_file; +} +if (null !== $ssl_cert) { + $sslOptions[LDAP_OPT_X_TLS_CERTFILE] = $ssl_cert; +} +if (null !== $ssl_key) { + $sslOptions[LDAP_OPT_X_TLS_KEYFILE] = $ssl_key; +} +if (null !== $ssl_ciphers) { + $sslOptions[LDAP_OPT_X_TLS_CIPHER_SUITE] = $ssl_ciphers; +} +if (null !== $ssl_require) { + $sslOptions[LDAP_OPT_X_TLS_REQUIRE_CERT] = $ssl_require; +} + +return [ + /* + |-------------------------------------------------------------------------- + | Connections + |-------------------------------------------------------------------------- + | + | This array stores the connections that are added to Adldap. You can add + | as many connections as you like. + | + | The key is the name of the connection you wish to use and the value is + | an array of configuration settings. + | + */ + 'connections' => [ + + 'default' => [ + + /* + |-------------------------------------------------------------------------- + | Auto Connect + |-------------------------------------------------------------------------- + | + | If auto connect is true, Adldap will try to automatically connect to + | your LDAP server in your configuration. This allows you to assume + | connectivity rather than having to connect manually + | in your application. + | + | If this is set to false, you **must** connect manually before running + | LDAP operations. + | + */ + + 'auto_connect' => env('ADLDAP_AUTO_CONNECT', true), + + /* + |-------------------------------------------------------------------------- + | Connection + |-------------------------------------------------------------------------- + | + | The connection class to use to run raw LDAP operations on. + | + | Custom connection classes must implement: + | + | Adldap\Connections\ConnectionInterface + | + */ + + 'connection' => Adldap\Connections\Ldap::class, + + /* + |-------------------------------------------------------------------------- + | Connection Settings + |-------------------------------------------------------------------------- + | + | This connection settings array is directly passed into the Adldap constructor. + | + | Feel free to add or remove settings you don't need. + | + */ + + 'settings' => [ + + /* + |-------------------------------------------------------------------------- + | Schema + |-------------------------------------------------------------------------- + | + | The schema class to use for retrieving attributes and generating models. + | + | You can also set this option to `null` to use the default schema class. + | + | For OpenLDAP, you must use the schema: + | + | Adldap\Schemas\OpenLDAP::class + | + | For FreeIPA, you must use the schema: + | + | Adldap\Schemas\FreeIPA::class + | + | Custom schema classes must implement Adldap\Schemas\SchemaInterface + | + */ + + 'schema' => $schema, + + /* + |-------------------------------------------------------------------------- + | Account Prefix + |-------------------------------------------------------------------------- + | + | The account prefix option is the prefix of your user accounts in LDAP directory. + | + | This string is prepended to authenticating users usernames. + | + */ + + 'account_prefix' => env('ADLDAP_ACCOUNT_PREFIX', ''), + + /* + |-------------------------------------------------------------------------- + | Account Suffix + |-------------------------------------------------------------------------- + | + | The account suffix option is the suffix of your user accounts in your LDAP directory. + | + | This string is appended to authenticating users usernames. + | + */ + + 'account_suffix' => env('ADLDAP_ACCOUNT_SUFFIX', ''), + + /* + |-------------------------------------------------------------------------- + | Domain Controllers + |-------------------------------------------------------------------------- + | + | The domain controllers option is an array of servers located on your + | network that serve Active Directory. You can insert as many servers or + | as little as you'd like depending on your forest (with the + | minimum of one of course). + | + | These can be IP addresses of your server(s), or the host name. + | + */ + + 'hosts' => explode(' ', env('ADLDAP_CONTROLLERS', '127.0.0.1')), + + /* + |-------------------------------------------------------------------------- + | Port + |-------------------------------------------------------------------------- + | + | The port option is used for authenticating and binding to your LDAP server. + | + */ + + 'port' => env('ADLDAP_PORT', 389), + + /* + |-------------------------------------------------------------------------- + | Timeout + |-------------------------------------------------------------------------- + | + | The timeout option allows you to configure the amount of time in + | seconds that your application waits until a response + | is received from your LDAP server. + | + */ + + 'timeout' => env('ADLDAP_TIMEOUT', 5), + + /* + |-------------------------------------------------------------------------- + | Base Distinguished Name + |-------------------------------------------------------------------------- + | + | The base distinguished name is the base distinguished name you'd + | like to perform query operations on. An example base DN would be: + | + | dc=corp,dc=acme,dc=org + | + | A correct base DN is required for any query results to be returned. + | + */ + + 'base_dn' => env('ADLDAP_BASEDN', 'dc=temp'), + + /* + |-------------------------------------------------------------------------- + | Administrator Username & Password + |-------------------------------------------------------------------------- + | + | When connecting to your LDAP server, a username and password is required + | to be able to query and run operations on your server(s). You can + | use any user account that has these permissions. This account + | does not need to be a domain administrator unless you + | require changing and resetting user passwords. + | + */ + + 'username' => env('ADLDAP_ADMIN_USERNAME', ''), + 'password' => env('ADLDAP_ADMIN_PASSWORD', ''), + + /* + |-------------------------------------------------------------------------- + | Follow Referrals + |-------------------------------------------------------------------------- + | + | The follow referrals option is a boolean to tell active directory + | to follow a referral to another server on your network if the + | server queried knows the information your asking for exists, + | but does not yet contain a copy of it locally. + | + | This option is defaulted to false. + | + */ + + 'follow_referrals' => env('ADLDAP_FOLLOW_REFFERALS', false), + + /* + |-------------------------------------------------------------------------- + | SSL & TLS + |-------------------------------------------------------------------------- + | + | If you need to be able to change user passwords on your server, then an + | SSL or TLS connection is required. All other operations are allowed + | on unsecured protocols. + | + | One of these options are definitely recommended if you + | have the ability to connect to your server securely. + | + */ + + 'use_ssl' => env('ADLDAP_USE_SSL', false), + 'use_tls' => env('ADLDAP_USE_TLS', false), + + 'custom_options' => $sslOptions, + ], + + ], + + ], + +]; diff --git a/config/ldap_auth.php b/config/xldap_auth.php similarity index 100% rename from config/ldap_auth.php rename to config/xldap_auth.php From daf7d79a21d8ffe45f65b7357dbed8478ec0387c Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 9 May 2021 06:40:21 +0200 Subject: [PATCH 2/8] Remove old files. --- app/Scopes/LdapFilterScope.php | 47 ---- config/xldap.php | 294 ------------------------ config/xldap_auth.php | 394 --------------------------------- 3 files changed, 735 deletions(-) delete mode 100644 app/Scopes/LdapFilterScope.php delete mode 100644 config/xldap.php delete mode 100644 config/xldap_auth.php diff --git a/app/Scopes/LdapFilterScope.php b/app/Scopes/LdapFilterScope.php deleted file mode 100644 index 0def667abe..0000000000 --- a/app/Scopes/LdapFilterScope.php +++ /dev/null @@ -1,47 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Scopes; - -use Adldap\Laravel\Scopes\ScopeInterface; -use Adldap\Query\Builder; - -// @phpstan-ignore-next-line -class LdapFilterScope implements ScopeInterface // @phpstan-ignore-line -{ - /** - * If the ADLDAP_AUTH_FILTER is provided, apply the filter to the LDAP query. - * - * @param Builder $query - * - * @return void - */ - public function apply(Builder $query) - { - $filter = (string)config('ldap_auth.custom_filter'); - if ('' !== $filter) { - $query->rawFilter($filter); - } - } -} diff --git a/config/xldap.php b/config/xldap.php deleted file mode 100644 index 1c2d1b52be..0000000000 --- a/config/xldap.php +++ /dev/null @@ -1,294 +0,0 @@ -. - */ - -declare(strict_types=1); - -use Adldap\Schemas\ActiveDirectory; -use Adldap\Schemas\FreeIPA; -use Adldap\Schemas\OpenLDAP; - -/* - * Get schema from .env file. - */ -$schema = OpenLDAP::class; - -if ('FreeIPA' === envNonEmpty('ADLDAP_CONNECTION_SCHEME', 'OpenLDAP')) { - $schema = FreeIPA::class; -} -if ('ActiveDirectory' === envNonEmpty('ADLDAP_CONNECTION_SCHEME', 'OpenLDAP')) { - $schema = ActiveDirectory::class; -} - -/* - * Get SSL parameters from .env file. - */ -$ssl_ca_dir = envNonEmpty('ADLDAP_SSL_CACERTDIR', null); -$ssl_ca_file = envNonEmpty('ADLDAP_SSL_CACERTFILE', null); -$ssl_cert = envNonEmpty('ADLDAP_SSL_CERTFILE', null); -$ssl_key = envNonEmpty('ADLDAP_SSL_KEYFILE', null); -$ssl_ciphers = envNonEmpty('ADLDAP_SSL_CIPHER_SUITE', null); -$ssl_require = envNonEmpty('ADLDAP_SSL_REQUIRE_CERT', null); - -$sslOptions = []; -if (null !== $ssl_ca_dir) { - $sslOptions[LDAP_OPT_X_TLS_CACERTDIR] = $ssl_ca_dir; -} -if (null !== $ssl_ca_file) { - $sslOptions[LDAP_OPT_X_TLS_CACERTFILE] = $ssl_ca_file; -} -if (null !== $ssl_cert) { - $sslOptions[LDAP_OPT_X_TLS_CERTFILE] = $ssl_cert; -} -if (null !== $ssl_key) { - $sslOptions[LDAP_OPT_X_TLS_KEYFILE] = $ssl_key; -} -if (null !== $ssl_ciphers) { - $sslOptions[LDAP_OPT_X_TLS_CIPHER_SUITE] = $ssl_ciphers; -} -if (null !== $ssl_require) { - $sslOptions[LDAP_OPT_X_TLS_REQUIRE_CERT] = $ssl_require; -} - -return [ - /* - |-------------------------------------------------------------------------- - | Connections - |-------------------------------------------------------------------------- - | - | This array stores the connections that are added to Adldap. You can add - | as many connections as you like. - | - | The key is the name of the connection you wish to use and the value is - | an array of configuration settings. - | - */ - 'connections' => [ - - 'default' => [ - - /* - |-------------------------------------------------------------------------- - | Auto Connect - |-------------------------------------------------------------------------- - | - | If auto connect is true, Adldap will try to automatically connect to - | your LDAP server in your configuration. This allows you to assume - | connectivity rather than having to connect manually - | in your application. - | - | If this is set to false, you **must** connect manually before running - | LDAP operations. - | - */ - - 'auto_connect' => env('ADLDAP_AUTO_CONNECT', true), - - /* - |-------------------------------------------------------------------------- - | Connection - |-------------------------------------------------------------------------- - | - | The connection class to use to run raw LDAP operations on. - | - | Custom connection classes must implement: - | - | Adldap\Connections\ConnectionInterface - | - */ - - 'connection' => Adldap\Connections\Ldap::class, - - /* - |-------------------------------------------------------------------------- - | Connection Settings - |-------------------------------------------------------------------------- - | - | This connection settings array is directly passed into the Adldap constructor. - | - | Feel free to add or remove settings you don't need. - | - */ - - 'settings' => [ - - /* - |-------------------------------------------------------------------------- - | Schema - |-------------------------------------------------------------------------- - | - | The schema class to use for retrieving attributes and generating models. - | - | You can also set this option to `null` to use the default schema class. - | - | For OpenLDAP, you must use the schema: - | - | Adldap\Schemas\OpenLDAP::class - | - | For FreeIPA, you must use the schema: - | - | Adldap\Schemas\FreeIPA::class - | - | Custom schema classes must implement Adldap\Schemas\SchemaInterface - | - */ - - 'schema' => $schema, - - /* - |-------------------------------------------------------------------------- - | Account Prefix - |-------------------------------------------------------------------------- - | - | The account prefix option is the prefix of your user accounts in LDAP directory. - | - | This string is prepended to authenticating users usernames. - | - */ - - 'account_prefix' => env('ADLDAP_ACCOUNT_PREFIX', ''), - - /* - |-------------------------------------------------------------------------- - | Account Suffix - |-------------------------------------------------------------------------- - | - | The account suffix option is the suffix of your user accounts in your LDAP directory. - | - | This string is appended to authenticating users usernames. - | - */ - - 'account_suffix' => env('ADLDAP_ACCOUNT_SUFFIX', ''), - - /* - |-------------------------------------------------------------------------- - | Domain Controllers - |-------------------------------------------------------------------------- - | - | The domain controllers option is an array of servers located on your - | network that serve Active Directory. You can insert as many servers or - | as little as you'd like depending on your forest (with the - | minimum of one of course). - | - | These can be IP addresses of your server(s), or the host name. - | - */ - - 'hosts' => explode(' ', env('ADLDAP_CONTROLLERS', '127.0.0.1')), - - /* - |-------------------------------------------------------------------------- - | Port - |-------------------------------------------------------------------------- - | - | The port option is used for authenticating and binding to your LDAP server. - | - */ - - 'port' => env('ADLDAP_PORT', 389), - - /* - |-------------------------------------------------------------------------- - | Timeout - |-------------------------------------------------------------------------- - | - | The timeout option allows you to configure the amount of time in - | seconds that your application waits until a response - | is received from your LDAP server. - | - */ - - 'timeout' => env('ADLDAP_TIMEOUT', 5), - - /* - |-------------------------------------------------------------------------- - | Base Distinguished Name - |-------------------------------------------------------------------------- - | - | The base distinguished name is the base distinguished name you'd - | like to perform query operations on. An example base DN would be: - | - | dc=corp,dc=acme,dc=org - | - | A correct base DN is required for any query results to be returned. - | - */ - - 'base_dn' => env('ADLDAP_BASEDN', 'dc=temp'), - - /* - |-------------------------------------------------------------------------- - | Administrator Username & Password - |-------------------------------------------------------------------------- - | - | When connecting to your LDAP server, a username and password is required - | to be able to query and run operations on your server(s). You can - | use any user account that has these permissions. This account - | does not need to be a domain administrator unless you - | require changing and resetting user passwords. - | - */ - - 'username' => env('ADLDAP_ADMIN_USERNAME', ''), - 'password' => env('ADLDAP_ADMIN_PASSWORD', ''), - - /* - |-------------------------------------------------------------------------- - | Follow Referrals - |-------------------------------------------------------------------------- - | - | The follow referrals option is a boolean to tell active directory - | to follow a referral to another server on your network if the - | server queried knows the information your asking for exists, - | but does not yet contain a copy of it locally. - | - | This option is defaulted to false. - | - */ - - 'follow_referrals' => env('ADLDAP_FOLLOW_REFFERALS', false), - - /* - |-------------------------------------------------------------------------- - | SSL & TLS - |-------------------------------------------------------------------------- - | - | If you need to be able to change user passwords on your server, then an - | SSL or TLS connection is required. All other operations are allowed - | on unsecured protocols. - | - | One of these options are definitely recommended if you - | have the ability to connect to your server securely. - | - */ - - 'use_ssl' => env('ADLDAP_USE_SSL', false), - 'use_tls' => env('ADLDAP_USE_TLS', false), - - 'custom_options' => $sslOptions, - ], - - ], - - ], - -]; diff --git a/config/xldap_auth.php b/config/xldap_auth.php deleted file mode 100644 index 446b9c831a..0000000000 --- a/config/xldap_auth.php +++ /dev/null @@ -1,394 +0,0 @@ -. - */ - -declare(strict_types=1); - -use FireflyIII\Scopes\LdapFilterScope; - -use Adldap\Laravel\Events\Authenticated; -use Adldap\Laravel\Events\AuthenticatedModelTrashed; -use Adldap\Laravel\Events\AuthenticatedWithWindows; -use Adldap\Laravel\Events\Authenticating; -use Adldap\Laravel\Events\AuthenticationFailed; -use Adldap\Laravel\Events\AuthenticationRejected; -use Adldap\Laravel\Events\AuthenticationSuccessful; -use Adldap\Laravel\Events\DiscoveredWithCredentials; -use Adldap\Laravel\Events\Importing; -use Adldap\Laravel\Events\Synchronized; -use Adldap\Laravel\Events\Synchronizing; -use Adldap\Laravel\Listeners\LogAuthenticated; -use Adldap\Laravel\Listeners\LogAuthentication; -use Adldap\Laravel\Listeners\LogAuthenticationFailure; -use Adldap\Laravel\Listeners\LogAuthenticationRejection; -use Adldap\Laravel\Listeners\LogAuthenticationSuccess; -use Adldap\Laravel\Listeners\LogDiscovery; -use Adldap\Laravel\Listeners\LogImport; -use Adldap\Laravel\Listeners\LogSynchronized; -use Adldap\Laravel\Listeners\LogSynchronizing; -use Adldap\Laravel\Listeners\LogTrashedModel; -use Adldap\Laravel\Listeners\LogWindowsAuth; -use Adldap\Laravel\Scopes\UidScope; -use Adldap\Laravel\Scopes\UpnScope; - -// default OpenLDAP scopes. -$scopes = [ - LdapFilterScope::class, - UidScope::class, -]; -if ('FreeIPA' === env('ADLDAP_CONNECTION_SCHEME')) { - $scopes = [ - LdapFilterScope::class, - ]; -} -if ('ActiveDirectory' === env('ADLDAP_CONNECTION_SCHEME')) { - $scopes = [ - LdapFilterScope::class, - UpnScope::class, - ]; -} - -return [ - /* - |-------------------------------------------------------------------------- - | Connection - |-------------------------------------------------------------------------- - | - | The LDAP connection to use for laravel authentication. - | - | You must specify connections in your `config/adldap.php` configuration file. - | - | This must be a string. - | - */ - - 'connection' => envNonEmpty('ADLDAP_CONNECTION', 'default'), - - /* - |-------------------------------------------------------------------------- - | Provider - |-------------------------------------------------------------------------- - | - | The LDAP authentication provider to use depending - | if you require database synchronization. - | - | For synchronizing LDAP users to your local applications database, use the provider: - | - | Adldap\Laravel\Auth\DatabaseUserProvider::class - | - | Otherwise, if you just require LDAP authentication, use the provider: - | - | Adldap\Laravel\Auth\NoDatabaseUserProvider::class - | - */ - - 'provider' => Adldap\Laravel\Auth\DatabaseUserProvider::class, - //'provider' => Adldap\Laravel\Auth\NoDatabaseUserProvider::class, - - /* - |-------------------------------------------------------------------------- - | Model - |-------------------------------------------------------------------------- - | - | The model to utilize for authentication and importing. - | - | This option is only applicable to the DatabaseUserProvider. - | - */ - - 'model' => FireflyIII\User::class, - - /* - |-------------------------------------------------------------------------- - | Rules - |-------------------------------------------------------------------------- - | - | Rules allow you to control user authentication requests depending on scenarios. - | - | You can create your own rules and insert them here. - | - | All rules must extend from the following class: - | - | Adldap\Laravel\Validation\Rules\Rule - | - */ - - 'rules' => [ - - // Denys deleted users from authenticating. - Adldap\Laravel\Validation\Rules\DenyTrashed::class, - - // Allows only manually imported users to authenticate. - // Adldap\Laravel\Validation\Rules\OnlyImported::class, - - ], - - /* - |-------------------------------------------------------------------------- - | Scopes - |-------------------------------------------------------------------------- - | - | Scopes allow you to restrict the LDAP query that locates - | users upon import and authentication. - | - | All scopes must implement the following interface: - | - | Adldap\Laravel\Scopes\ScopeInterface - |[ - - // Only allows users with a user principal name to authenticate. - // Remove this if you're using OpenLDAP. - //Adldap\Laravel\Scopes\UpnScope::class, - - // Only allows users with a uid to authenticate. - // Uncomment if you're using OpenLDAP. - Adldap\Laravel\Scopes\UidScope::class, - - ], - */ - - 'scopes' => $scopes, - - 'identifiers' => [ - - /* - |-------------------------------------------------------------------------- - | LDAP - |-------------------------------------------------------------------------- - | - | Discover: - | - | The discover value is the users attribute you would - | like to locate LDAP users by in your directory. - | - | For example, using the default configuration below, if you're - | authenticating users with an email address, your LDAP server - | will be queried for a user with the a `userprincipalname` - | equal to the entered email address. - | - | Authenticate: - | - | The authenticate value is the users attribute you would - | like to use to bind to your LDAP server. - | - | For example, when a user is located by the above 'discover' - | attribute, the users attribute you specify below will - | be used as the username to bind to your LDAP server. - | - */ - - 'ldap' => [ - - 'locate_users_by' => envNonEmpty('ADLDAP_DISCOVER_FIELD', 'userprincipalname'), - 'bind_users_by' => envNonEmpty('ADLDAP_AUTH_FIELD', 'distinguishedname'), - - ], - - /* - |-------------------------------------------------------------------------- - | Eloquent - |-------------------------------------------------------------------------- - | - | The value you enter is the database column name used for locating - | the local database record of the authenticating user. - | - | If you're using a `username` column instead, change this to `username`. - | - | This option is only applicable to the DatabaseUserProvider. - | - */ - - 'eloquent' => 'email', - - /* - |-------------------------------------------------------------------------- - | Windows Authentication Middleware (SSO) - |-------------------------------------------------------------------------- - | - | Enabled: - | - | The middleware will be registered only if enabled is set to true. - | If you update this file, beware, this is not a standard - | AdLdap2-Laravel configuration key. - | - | Locate Users By: - | - | This value is the users attribute you would like to locate LDAP - | users by in your directory. - | - | For example, if 'samaccountname' is the value, then your LDAP server is - | queried for a user with the 'samaccountname' equal to the value of - | $_SERVER['AUTH_USER']. - | - | If a user is found, they are imported (if using the DatabaseUserProvider) - | into your local database, then logged in. - | - | Server Key: - | - | This value represents the 'key' of the $_SERVER - | array to pull the users account name from. - | - | For example, $_SERVER['AUTH_USER']. - | - */ - - 'windows' => [ - 'enabled' => false, - 'locate_users_by' => 'samaccountname', - 'server_key' => 'AUTH_USER', - ], - ], - - 'passwords' => [ - - /* - |-------------------------------------------------------------------------- - | Password Sync - |-------------------------------------------------------------------------- - | - | The password sync option allows you to automatically synchronize users - | LDAP passwords to your local database. These passwords are hashed - | natively by Laravel using the bcrypt() method. - | - | Enabling this option would also allow users to login to their accounts - | using the password last used when an LDAP connection was present. - | - | If this option is disabled, the local database account is applied a - | random 16 character hashed password upon every login, and will - | lose access to this account upon loss of LDAP connectivity. - | - | This option must be true or false and is only applicable - | to the DatabaseUserProvider. - | - */ - - 'sync' => env('ADLDAP_PASSWORD_SYNC', false), - - /* - |-------------------------------------------------------------------------- - | Column - |-------------------------------------------------------------------------- - | - | This is the column of your users database table - | that is used to store passwords. - | - | Set this to `null` if you do not have a password column. - | - | This option is only applicable to the DatabaseUserProvider. - | - */ - - 'column' => 'password', - - ], - - /* - |-------------------------------------------------------------------------- - | Login Fallback - |-------------------------------------------------------------------------- - | - | The login fallback option allows you to login as a user located on the - | local database if active directory authentication fails. - | - | Set this to true if you would like to enable it. - | - | This option must be true or false and is only - | applicable to the DatabaseUserProvider. - | - */ - - 'login_fallback' => env('ADLDAP_LOGIN_FALLBACK', false), - - /* - |-------------------------------------------------------------------------- - | Sync Attributes - |-------------------------------------------------------------------------- - | - | Attributes specified here will be added / replaced on the user model - | upon login, automatically synchronizing and keeping the attributes - | up to date. - | - | The array key represents the users Laravel model key, and - | the value represents the users LDAP attribute. - | - | This option must be an array and is only applicable - | to the DatabaseUserProvider. - | - */ - - 'sync_attributes' => [ - - 'email' => envNonEmpty('ADLDAP_SYNC_FIELD', 'userprincipalname'), - - ], - - /* - |-------------------------------------------------------------------------- - | Logging - |-------------------------------------------------------------------------- - | - | User authentication attempts will be logged using Laravel's - | default logger if this setting is enabled. - | - | No credentials are logged, only usernames. - | - | This is usually stored in the '/storage/logs' directory - | in the root of your application. - | - | This option is useful for debugging as well as auditing. - | - | You can freely remove any events you would not like to log below, - | as well as use your own listeners if you would prefer. - | - */ - - 'logging' => [ - 'enabled' => true, - 'events' => [ - - Importing::class => LogImport::class, - Synchronized::class => LogSynchronized::class, - Synchronizing::class => LogSynchronizing::class, - Authenticated::class => LogAuthenticated::class, - Authenticating::class => LogAuthentication::class, - AuthenticationFailed::class => LogAuthenticationFailure::class, - AuthenticationRejected::class => LogAuthenticationRejection::class, - AuthenticationSuccessful::class => LogAuthenticationSuccess::class, - DiscoveredWithCredentials::class => LogDiscovery::class, - AuthenticatedWithWindows::class => LogWindowsAuth::class, - AuthenticatedModelTrashed::class => LogTrashedModel::class, - - ], - ], - - /* - |-------------------------------------------------------------------------- - | Custom LDAP Filter - |-------------------------------------------------------------------------- - | - | This value can be optionally provided to restrict LDAP queries to the - | given filter. It should be in LDAP filter format, and will be - | applied in the LdapFilterScope. - | - */ - 'custom_filter' => env('ADLDAP_AUTH_FILTER', ''), - -]; From 15fde3a22024522a07285a0dd482b257a547effd Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 9 May 2021 07:47:49 +0200 Subject: [PATCH 3/8] Update meta files. --- .env.example | 63 +++++++++++++++++++++++++++++++++++++++++++++++++-- composer.lock | 11 +++++---- 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/.env.example b/.env.example index 35d098523e..c6ea3b0215 100644 --- a/.env.example +++ b/.env.example @@ -170,6 +170,7 @@ MAP_DEFAULT_LAT=51.983333 MAP_DEFAULT_LONG=5.916667 MAP_DEFAULT_ZOOM=6 +# TODO update me. # Firefly III has two options for user authentication. "eloquent" is the default, # and "ldap" for LDAP servers. # For full instructions on these settings please visit: @@ -179,8 +180,6 @@ MAP_DEFAULT_ZOOM=6 # If you enable 'ldap' AND you run Docker, the Docker image will contact packagist.org # This is necessary to download the required packages. # -LOGIN_PROVIDER=eloquent - # It's also possible to change the way users are authenticated. You could use Authelia for example. # Authentication via the REMOTE_USER header is supported. Change the value below to "remote_user_guard". # @@ -265,6 +264,66 @@ ADLDAP_AUTH_FIELD=distinguishedname # You can set the following variable from a file by appending it with _FILE: ADLDAP_SYNC_FIELD=userprincipalname + +# Login provider is obsolete +#LOGIN_PROVIDER=eloquent +AUTHENTICATION_GUARD=ldap +#CUSTOM_LOGOUT_URI=https://nu.nl + +# start new LDAP settings +LDAP_LOGGING=true +LDAP_CONNECTION=default +LDAP_HOST=ldap.jumpcloud.com +LDAP_USERNAME="uid=authelia,ou=Users,o=5fdddb09ae7868233b9d26d6,dc=jumpcloud,dc=com" +LDAP_PASSWORD=FZWhDnXVb_.ciGFVwuQC@m9CVo@vdVMx +LDAP_PORT=389 +LDAP_BASE_DN="ou=Users,o=5fdddb09ae7868233b9d26d6,dc=jumpcloud,dc=com" +LDAP_TIMEOUT=5 +LDAP_SSL=true +LDAP_TLS=false +# end new LDAP settings + +# start custom LDAP settings +LDAP_AUTH_FIELD=uid +# end custom LDAP settings + + +# LDAP connection configuration +# OpenLDAP, FreeIPA or ActiveDirectory +#ADLDAP_CONNECTION_SCHEME=OpenLDAP +#ADLDAP_AUTO_CONNECT=true + +# LDAP connection settings +#ADLDAP_CONTROLLERS= +#ADLDAP_PORT=389 +#ADLDAP_TIMEOUT=5 +#ADLDAP_BASEDN="" +#ADLDAP_FOLLOW_REFFERALS=false +#ADLDAP_USE_SSL=false +#ADLDAP_USE_TLS=false +#ADLDAP_SSL_CACERTDIR= +#ADLDAP_SSL_CACERTFILE= +#ADLDAP_SSL_CERTFILE= +#ADLDAP_SSL_KEYFILE= +#ADLDAP_SSL_CIPHER_SUITE= +#ADLDAP_SSL_REQUIRE_CERT= +#ADLDAP_ADMIN_USERNAME= +#ADLDAP_ADMIN_PASSWORD= +#ADLDAP_ACCOUNT_PREFIX= +#ADLDAP_ACCOUNT_SUFFIX= +# LDAP authentication settings. +#ADLDAP_PASSWORD_SYNC=false +#ADLDAP_LOGIN_FALLBACK=false +#ADLDAP_DISCOVER_FIELD=distinguishedname +#ADLDAP_AUTH_FIELD=distinguishedname + +# Will allow SSO if your server provides an AUTH_USER field. +#WINDOWS_SSO_DISCOVER=samaccountname +#WINDOWS_SSO_KEY=AUTH_USER + +# field to sync as local username. +#ADLDAP_SYNC_FIELD=userprincipalname + # You can disable the X-Frame-Options header if it interferes with tools like # Organizr. This is at your own risk. Applications running in frames run the risk # of leaking information to their parent frame. diff --git a/composer.lock b/composer.lock index c08cc08a6b..08570aff06 100644 --- a/composer.lock +++ b/composer.lock @@ -377,16 +377,16 @@ }, { "name": "directorytree/ldaprecord", - "version": "v2.4.3", + "version": "v2.4.5", "source": { "type": "git", "url": "https://github.com/DirectoryTree/LdapRecord.git", - "reference": "d384f2fa8926ffbef01e00e67068afdffcc9a781" + "reference": "eefed3d8a3f3734f851a9d158452b8f711be6f23" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/DirectoryTree/LdapRecord/zipball/d384f2fa8926ffbef01e00e67068afdffcc9a781", - "reference": "d384f2fa8926ffbef01e00e67068afdffcc9a781", + "url": "https://api.github.com/repos/DirectoryTree/LdapRecord/zipball/eefed3d8a3f3734f851a9d158452b8f711be6f23", + "reference": "eefed3d8a3f3734f851a9d158452b8f711be6f23", "shasum": "" }, "require": { @@ -400,6 +400,7 @@ "tightenco/collect": "^5.6|^6.0|^7.0|^8.0" }, "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", "mockery/mockery": "^1.0", "phpunit/phpunit": "^8.0" }, @@ -445,7 +446,7 @@ "type": "github" } ], - "time": "2021-04-25T02:35:23+00:00" + "time": "2021-05-08T20:00:49+00:00" }, { "name": "directorytree/ldaprecord-laravel", From 47ef9a010209a7fea961aa26181684be776f9b4e Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 9 May 2021 07:47:58 +0200 Subject: [PATCH 4/8] Add custom fields to user model. --- app/User.php | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/app/User.php b/app/User.php index bfb66bb0b0..018db3a675 100644 --- a/app/User.php +++ b/app/User.php @@ -140,6 +140,14 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @property-read int|null $object_groups_count * @property-read \Illuminate\Database\Eloquent\Collection|Webhook[] $webhooks * @property-read int|null $webhooks_count + * @property string|null $two_factor_secret + * @property string|null $two_factor_recovery_codes + * @property string|null $guid + * @property string|null $domain + * @method static Builder|User whereDomain($value) + * @method static Builder|User whereGuid($value) + * @method static Builder|User whereTwoFactorRecoveryCodes($value) + * @method static Builder|User whereTwoFactorSecret($value) */ class User extends Authenticatable { @@ -439,4 +447,70 @@ class User extends Authenticatable { return $this->hasManyThrough(Transaction::class, TransactionJournal::class); } + + // start LDAP related code + /** + * Get the database column name of the domain. + * + * @return string + */ + public function getLdapDomainColumn() + { + return 'domain'; + } + + /** + * Get the models LDAP domain. + * + * @return string + */ + public function getLdapDomain() + { + return $this->{$this->getLdapDomainColumn()}; + } + + /** + * Set the models LDAP domain. + * + * @param string $domain + * + * @return void + */ + public function setLdapDomain($domain) + { + $this->{$this->getLdapDomainColumn()} = $domain; + } + + /** + * Get the models LDAP GUID database column name. + * + * @return string + */ + public function getLdapGuidColumn() + { + return 'objectguid'; + } + + /** + * Get the models LDAP GUID. + * + * @return string + */ + public function getLdapGuid() + { + return $this->{$this->getLdapGuidColumn()}; + } + + /** + * Set the models LDAP GUID. + * + * @param string $guid + * + * @return void + */ + public function setLdapGuid($guid) + { + $this->{$this->getLdapGuidColumn()} = $guid; + } + // end LDAP related code } From 1157625f6ddb614cdf5dd719da9393edcfbd22a5 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 9 May 2021 07:48:30 +0200 Subject: [PATCH 5/8] Login controller (needs more work) --- app/Http/Controllers/Auth/LoginController.php | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 0295bc0388..c5969e691f 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -57,6 +57,8 @@ class LoginController extends Controller */ protected $redirectTo = RouteServiceProvider::HOME; + private string $username; + /** * Create a new controller instance. * @@ -65,6 +67,7 @@ class LoginController extends Controller public function __construct() { parent::__construct(); + $this->username = 'email'; $this->middleware('guest')->except('logout'); } @@ -81,24 +84,27 @@ class LoginController extends Controller { Log::channel('audit')->info(sprintf('User is trying to login using "%s"', $request->get('email'))); Log::info(sprintf('User is trying to login.')); - if ('ldap' === config('auth.providers.users.driver')) { - /** @var Adldap\Connections\Provider $provider */ - Adldap::getProvider('default'); // @phpstan-ignore-line + + // switch to LDAP + if ('ldap' === config('auth.defaults.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.'); /** Copied directly from AuthenticatesUsers, but with logging added: */ // If the class is using the ThrottlesLogins trait, we can automatically throttle // the login attempts for this application. We'll key this by the username and // the IP address of the client making these requests into this application. if (method_exists($this, 'hasTooManyLoginAttempts') && $this->hasTooManyLoginAttempts($request)) { - Log::channel('audit')->info(sprintf('Login for user "%s" was locked out.', $request->get('email'))); + Log::channel('audit')->info(sprintf('Login for user "%s" was locked out.', $request->get($this->username()))); + Log::error(sprintf('Login for user "%s" was locked out.', $request->get($this->username()))); $this->fireLockoutEvent($request); $this->sendLockoutResponse($request); } - /** Copied directly from AuthenticatesUsers, but with logging added: */ if ($this->attemptLogin($request)) { Log::channel('audit')->info(sprintf('User "%s" has been logged in.', $request->get('email'))); @@ -108,6 +114,7 @@ class LoginController extends Controller return $this->sendLoginResponse($request); } + Log::warning('Login attempt failed.'); /** Copied directly from AuthenticatesUsers, but with logging added: */ // If the login attempt was unsuccessful we will increment the number of attempts @@ -190,7 +197,13 @@ class LoginController extends Controller $loginProvider = config('firefly.login_provider'); $title = (string)trans('firefly.login_page_title'); if (0 === $count && 'eloquent' === $loginProvider) { - return redirect(route('register')); + return redirect(route('register')); + } + + // switch to LDAP + if ('ldap' === config('auth.defaults.guard')) { + Log::debug('User wishes to login using LDAP.'); + $this->username = config('firefly.ldap_auth_field'); } // is allowed to? @@ -215,8 +228,18 @@ class LoginController extends Controller $cookieName = config('google2fa.cookie_name', 'google2fa_token'); request()->cookies->set($cookieName, 'invalid'); } + $usernameField = $this->username(); - return prefixView('auth.login', compact('allowRegistration', 'email', 'remember', 'allowReset', 'title')); + return prefixView('auth.login', compact('allowRegistration', 'email', 'remember', 'allowReset', 'title', 'usernameField')); } + /** + * Get the login username to be used by the controller. + * + * @return string + */ + public function username() + { + return $this->username; + } } From 2488e444aaf479315e5ec254957bdb16c54341b5 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 9 May 2021 07:48:47 +0200 Subject: [PATCH 6/8] Update auth config and firefly config --- config/auth.php | 31 ++++++++++++++++++++++++++++++- config/firefly.php | 5 +++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/config/auth.php b/config/auth.php index 732c35d54c..26bf8496ab 100644 --- a/config/auth.php +++ b/config/auth.php @@ -21,6 +21,17 @@ declare(strict_types=1); +// TODO die with error if LOGIN_PROVIDER = eloquent +// because it must be changed to "users". +// login provider no longer used? +if (null !== env('LOGIN_PROVIDER', null)) { + die('The "LOGIN_PROVIDER" environment variable must be removed.'); +} + +// kill ADLDAP values? + +// AUTHENTICATION_GUARD + return [ /* |-------------------------------------------------------------------------- @@ -62,6 +73,10 @@ return [ 'driver' => 'session', 'provider' => 'users', ], + 'ldap' => [ + 'driver' => 'session', + 'provider' => 'ldap', + ], 'remote_user_guard' => [ 'driver' => 'remote_user_guard', 'provider' => 'remote_user_provider', @@ -91,13 +106,27 @@ return [ 'providers' => [ 'users' => [ - 'driver' => envNonEmpty('LOGIN_PROVIDER', 'eloquent'), + 'driver' => 'eloquent', 'model' => FireflyIII\User::class, ], 'remote_user_provider' => [ 'driver' => 'remote_user_provider', 'model' => FireflyIII\User::class, ], + + 'ldap' => [ + 'driver' => 'ldap', + //'model' => LdapRecord\Models\ActiveDirectory\User::class, + 'model' => LdapRecord\Models\OpenLDAP\User::class, + 'rules' => [], + 'database' => [ + 'model' => FireflyIII\User::class, + 'sync_passwords' => false, + 'sync_attributes' => [ + 'email' => 'mail', + ], + ], + ], ], /* diff --git a/config/firefly.php b/config/firefly.php index a6eebbc793..68090c4b2e 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -121,9 +121,14 @@ return [ 'tracker_url' => env('TRACKER_URL', ''), 'disable_frame_header' => env('DISABLE_FRAME_HEADER', false), 'disable_csp_header' => env('DISABLE_CSP_HEADER', false), + + // ldap and auth settings 'login_provider' => envNonEmpty('LOGIN_PROVIDER', 'eloquent'), 'authentication_guard' => envNonEmpty('AUTHENTICATION_GUARD', 'web'), 'custom_logout_uri' => envNonEmpty('CUSTOM_LOGOUT_URI', ''), + 'ldap_auth_field' => env('LDAP_AUTH_FIELD', env('ADLDAP_AUTH_FIELD', 'distinguishedname')), + + // other settings 'ipinfo_token' => env('IPINFO_TOKEN', ''), 'update_endpoint' => 'https://version.firefly-iii.org/index.json', 'send_telemetry' => env('SEND_TELEMETRY', false), From 22c09b7849c86335721e8aa2f860883423e5a5cf Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 9 May 2021 07:48:55 +0200 Subject: [PATCH 7/8] Add migration --- ...064644_add_ldap_columns_to_users_table.php | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 database/migrations/2021_05_09_064644_add_ldap_columns_to_users_table.php diff --git a/database/migrations/2021_05_09_064644_add_ldap_columns_to_users_table.php b/database/migrations/2021_05_09_064644_add_ldap_columns_to_users_table.php new file mode 100644 index 0000000000..48e0f08e50 --- /dev/null +++ b/database/migrations/2021_05_09_064644_add_ldap_columns_to_users_table.php @@ -0,0 +1,28 @@ +string('domain')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down() + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn(['domain']); + }); + } +} From 33f6725d379ae5d8871a8ca5b567ba6f033d2acc Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 9 May 2021 07:49:04 +0200 Subject: [PATCH 8/8] Update login --- resources/views/v1/auth/login.twig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/views/v1/auth/login.twig b/resources/views/v1/auth/login.twig index 109e53f734..29249337fd 100644 --- a/resources/views/v1/auth/login.twig +++ b/resources/views/v1/auth/login.twig @@ -53,10 +53,10 @@
- {% if config('firefly.login_provider') == 'eloquent' %} + {% if config('firefly.authentication_guard') == 'web' %} {% else %} - + {% endif %}