Ldaprecord-laravel: [Feature] Resolve connections dynamically when requested, rather than upon boot

Created on 6 Oct 2020  Β·  11Comments  Β·  Source: DirectoryTree/LdapRecord-Laravel

Environment:

  • LDAP Server Type: OpenLDAP
  • PHP Version: 7.4

The bug:

I created a new Laravel 8 project and use docker in development. When running composer install --no-interaction --optimize-autoloader --ignore-platform-reqs in a specific composer container it returns the following error:

  Use of undefined constant LDAP_OPT_PROTOCOL_VERSION - assumed 'LDAP_OPT_PROTOCOL_VERSION' (this will throw an Error in a future version of PHP)

  at vendor/directorytree/ldaprecord/src/Connection.php:135
    131β–•
    132β–•         $this->ldap->setOptions(array_replace(
    133β–•             $this->configuration->get('options'),
    134β–•             [
  ➜ 135β–•                 LDAP_OPT_PROTOCOL_VERSION => $this->configuration->get('version'),
    136β–•                 LDAP_OPT_NETWORK_TIMEOUT  => $this->configuration->get('timeout'),
    137β–•                 LDAP_OPT_REFERRALS        => $this->configuration->get('follow_referrals'),
    138β–•             ]
    139β–•         ));

      +14 vendor frames
  15  [internal]:0
      Illuminate\Foundation\Application::Illuminate\Foundation\{closure}(Object(LdapRecord\Laravel\LdapServiceProvider))

      +5 vendor frames
  21  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

Unfortunately, our deployment set-up cannot be changed. Is there a way to fix this? This issue does not occur with the core LDAP Record and Adldap2 packages. I understand if this cannot be fixed (or is not worth fixing for this specific use case), but it would help immensely if it was possible.

enhancement

Most helpful comment

To elaborate on this, this is because LdapRecord registers LDAP connections during its service providers boot(), shown here:

https://github.com/DirectoryTree/LdapRecord-Laravel/blob/6cdaed0895e2847feca4ce675550eca7b449e467/src/LdapServiceProvider.php#L27

https://github.com/DirectoryTree/LdapRecord-Laravel/blob/6cdaed0895e2847feca4ce675550eca7b449e467/src/LdapServiceProvider.php#L75-L93

Adldap2-Laravel will register the connection during connection resolution -- which is handy for this scenario.

I'm going to open this back up, as I think this may be a valid use-case where connections should be instantiated when resolved, not automatically. πŸ‘

All 11 comments

Hi @aleksanderalright,

This error means that your web server is not using a PHP installation with the LDAP extension installed. I'm am absolutely 100% certain of this, since the constants are only available when PHP has the LDAP extension enabled.

Enable the LDAP extension, and you should be all set πŸ‘

Hi @stevebauman

Thank you for the fast reply. You are right, but unfortunately due to our set-up, enabling the extension is not possible. It's clearly not a bug in the package, but is there any way this could be worked around, considering that it works as expected in the Adldap2, Adldap2-Laravel and LDAP Record core packages? If not (or if it's not worth investing the time in), I understand and will use one of the other packages until hopefully one day this is fixed on our side.

but is there any way this could be worked around, considering that it works as expected in the Adldap2, Adldap2-Laravel and LDAP Record core packages?

If it works for Adldap2 and Adldap2-Laravel but not LdapRecord, something is wrong in your server. Adldap2-Laravel and Adldap2 should crash the same way without the LDAP extension enabled.

You are right, but unfortunately due to our set-up, enabling the extension is not possible.

Then you cannot use LDAP, unfortunately. LdapRecord, LdapRecord-Laravel, Adldap2, and Adldap2-Laravel all require the LDAP extension to be enabled on your PHP installation. There is no way around this.

To clarify, only the composer install --no-interaction --optimize-autoloader --ignore-platform-reqs command needs to be able to run without the LDAP extension enabled, as this command runs once separately during our deployment. We have projects with the other packages up and running who handled this smoothly, only this package causes this specific error. Either way, this is an issue that seems to have one foot in this specific package and one in our specific deployment set-up. In development it works smoothly. Any suggestions or help are most welcome, but I understand if our use-case is too specific. (And thanks again for the quick reply!)

Ah okay, understood. πŸ‘

The only way around this would be to first ignore auto-discovery of LdapRecord-Laravel inside of your applications composer.json file like so:

"extra": {
    "laravel": {
        "dont-discover": [
            "directorytree/ldaprecord-laravel"
        ]
    }
}

Then, register the LdapRecord providers manually inside of your AppServiceProvider:

// app/Providers/AppServiceProvider.php

public function register()
{
    if (in_array('ldap', get_loaded_extensions()) {
        // LDAP extension is loaded -- register LdapRecord
        $this->app->register(\DirectoryTree\LdapRecord\Laravel\LdapServiceProvider::class);
        $this->app->register(\DirectoryTree\LdapRecord\Laravel\LdapAuthServiceProvider::class);
    }
}

This should get you going! πŸ‘ Let me know how you make out.

To elaborate on this, this is because LdapRecord registers LDAP connections during its service providers boot(), shown here:

https://github.com/DirectoryTree/LdapRecord-Laravel/blob/6cdaed0895e2847feca4ce675550eca7b449e467/src/LdapServiceProvider.php#L27

https://github.com/DirectoryTree/LdapRecord-Laravel/blob/6cdaed0895e2847feca4ce675550eca7b449e467/src/LdapServiceProvider.php#L75-L93

Adldap2-Laravel will register the connection during connection resolution -- which is handy for this scenario.

I'm going to open this back up, as I think this may be a valid use-case where connections should be instantiated when resolved, not automatically. πŸ‘

Hey @stevebauman

I adjusted the composer.json and registered the LdapRecord providers in the AppServiceProvider as you suggested, and it worked like a charm!

Thank you for taking the time to go through this issue and finding a solution.

Awesome @aleksanderalright! πŸŽ‰ Happy to help!

Okay I've re-thought this being a valid use-case... For connections to be dynamically instantiated when requested I would have to change how they are instantiated in the core Connection instance, which would be a breaking change to all current devs.

Since there's a work around for this specific use-case, we can stick with that for now. If any more developers require a need for this then I can justify modifying the core LdapRecord repo.

I hope this is understandable, thanks! ❀️

Hi, I've got the same problem and worked around it with the solution above, however now I'm getting the following error:

  Authentication user provider [ldap] is not defined.
  at vendor/laravel/framework/src/Illuminate/Auth/CreatesUserProviders.php:42
     38β–•                 return $this->createDatabaseProvider($config);
     39β–•             case 'eloquent':
     40β–•                 return $this->createEloquentProvider($config);
     41β–•             default:
  ➜  42β–•                 throw new InvalidArgumentException(
     43β–•                     "Authentication user provider [{$driver}] is not defined."
     44β–•                 );
     45β–•         }
     46β–•     }
      +19 vendor frames 
  20  [internal]:0
      Illuminate\Foundation\Application::Illuminate\Foundation\{closure}(Object(App\Providers\AppServiceProvider))
      +5 vendor frames 
  26  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

Do you got any solution for this @stevebauman?

Thank you!

Hi @MTEXX!

Could you post a new issue, along with where exactly in your Laravel application that you’re manually registering the LdapRecord providers?

It’ll help with managing the status of your issue easier. Thank you!

Was this page helpful?
0 / 5 - 0 ratings