-
-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug] Laravel Nova - Call to undefined method ...\Model\ActiveDirectoryBuilder::getKeyType() on Migrate #423
Comments
Hi @scramatte, Looks like you’re running something in your migration that is causing the exception. I’m going to need that code to be able to help in any way. Thanks! |
This migration is from "Laravel Nova" itself
|
My project use laravel 9.2 + nova 4 |
I suspect the following line
|
If you disable "ldap" auth.php provider and set back temporarily the default eloquent one you can migrate everything without issue. |
Looks like you're using an LdapRecord model in place of a Laravel Eloquent model. This won't work (as you've seen from the undefined method call). You'll have to replace the |
I think that It's not posible to custom this. So may we can add some method into LdapRecord class that return eloquent related model? In my case I've got following config
The problem is that Util class is from Nova too and it looks that is not posible to override it easily. They read model directly from config file
|
Hmm, it looks like they've hard-coded the config path for the user model... You may have to ask the Laravel Nova team this question, as I do not have a license to be able to source dive this with you to see if there is an alternate way to override this method. |
I've made a tweet to one of the creators of Laravel Nova, hopefully we can get something merged to resolve this: https://twitter.com/SteveTheBauman/status/1517492302935216129 |
|
Hi @crynobone, thanks for the reply! However, isn't the |
@stevebauman I'm also hesitant to introduce such changes fearing having to deal with regression issues or making Nova harder to maintain in multitenancy, Octane, or other environments. |
I totally understand -- though not all auth providers are created equally and have identical config pathing to their Eloquent model. If Nova will not support other authentication providers, then a notice should at least be placed to indicate such so users are aware. No fault to anyone, but I want to ensure that awareness is there so bug reports are not filed on either of our ends 👍 |
I don't use Nova, but the same problem - and the same cause - occur with spatie permissions package and an internal company package. Although I could probably make the adjustments to the internal package, I see the cause on the side of LdapRecord and accordingly as a bug of LdapRecord . In my eyes the main problem lies in the inconsistency between the configured model and the provided auth/user model. Part one of why I see this as a problem is the expectations I have when I look at the configuration. Here for a hypothetical user provider, the comments are my expectations. 'users' => [
'driver' => 'generic', // this is the key for the provider
'model' =>GenericProvider\User::class, // this is the model I get from the provider
'...' => [], // everything else is configuration for the provider
], Here is an example config for this package: 'plain_auth' => [
'driver' => 'ldap',
'model' => LdapRecord\Models\ActiveDirectory\User::class,
'rules' => [],
],
'database_auth' => [
'driver' => 'ldap',
'model' => LdapRecord\Models\ActiveDirectory\User::class,
'rules' => [],
'database' => [
'model' => App\User::class,
'sync_passwords' => false,
'sync_attributes' => [
'name' => 'cn',
'email' => 'mail',
],
],
], For the But for the Part two only exists because I can't rely on the expectations of part one. I now have to define for our package somewhere for each user provider which model is provided. And this only because I want to support LdapRecord. In my eyes a better solution would be if the configuration of LdapRecord would look something like this - so 'alternate_config' => [
'driver' => 'ldap',
'model' => App\User::class, // this is now the provided model
'rules' => [],
'database' => [
'model' => LdapRecord\Models\ActiveDirectory\User::class, // this is now the ldap model
'sync_passwords' => false,
'sync_attributes' => [
'name' => 'cn',
'email' => 'mail',
],
],
], I know this would be a breaking change, but otherwise it would be likely a breaking in Nova, spatie permissions and our internal company package. Maybe it can be considered for v3. |
Hi @lightbreaker,
Package developers need to consider variations of auth configuration. Not all auth providers are identical. Otherwise they really should state they are only compatible with Eloquent. All package providers need to do is offer a way to override either:
This issue exists for any auth provider that does not use identical configuration to Eloquent.
If you've configured a database provider, the I would argue -- of course you have to read the documentation to understand this. I wouldn't expect anyone to jump into Laravel for the first time and understand the
With your suggested configuration, how would we configure a plain LDAP auth provider? Would we still supply a |
@lightbreaker For Spatie Permission, this could easily be resolved by allowing developers to control how their models are resolved via a resolver callback -- without any breaking changes. Here's an example. Current: // laravel-permission/helpers.php
function getModelForGuard(string $guard)
{
return collect(config('auth.guards'))
->map(function ($guard) {
if (! isset($guard['provider'])) {
return;
}
return config("auth.providers.{$guard['provider']}.model"); // <-- Hard-coded model path.
})->get($guard);
} New: function getModelForGuard(string $guard)
{
return ModelResolver::resolve($guard);
} class ModelResolver
{
protected static $resolver;
public static function resolve(string $guard)
{
return collect(config('auth.guards'))
->map(function ($guard) {
if (! isset($guard['provider'])) {
return;
}
return value(static::$resolver ?? config("auth.providers.{$guard['provider']}.model"), $guard);
})->get($guard);
}
public static function resolveUsing(Closure $callback)
{
static::$resolver = $callback;
}
} // In your application...
ModelResolver::resolveUsing(function ($guard) {
return config("auth.providers.{$guard['provider']}.database.model");
}); |
This issue exists for any package in an ecosystem that not comply with conventions. An in that case the package should be responsible to get compatible with the other packages.
Why is that this way? Why isn't in both cases
Sure I read the documentation as I implement the package. But thats not granted for a dev looking at it in a couple of month and may not even currently working at the project.
The config for plain auth would remain untouched.
For more than one provider and multiple guards this quickly gets messy. And you are loosing the single source of truth |
Because LdapRecord-Laravel provides two authentication mechanisms. You can either authenticate with a database, or without. If you are authenticating without a database, then we cannot return an Eloquent model instance. You can read more about this in the docs here: https://ldaprecord.com/docs/laravel/v2/auth Some developers do not need a database for their application. Plain authentication covers this use-case. For developers who need a database and have to attach data to their users, can use Synchronized Database authentication.
The configuration you've shared replaces the root
Then determine what driver the guard is using and alter the config path. This is for the developer to implement, not Spatie: // app/Providers/AppServiceProvider.php
ModelResolver::resolveUsing(function ($guard) {
$provider = config("auth.providers.{$guard['provider']}");
return $provider['driver'] === 'ldap'
? $provider['database.model']
: $provider['model'];
}); More flexibility in general is better, not worse. We must trust developers and hand them more freedom, not restrict them in fear that they will implement incorrectly. |
From an auth perspective they are. They both implement
I don't see any added flexibility with this approach, but added configuration overhead. In summary, I really just wanted to note that there are several valid reasons that the problem of incompatibility of the configuration with, for example, Nova or Spatie permission, should be solved by LdapRecord.
The upcoming major release would be a good time to adjust the configuration. I personally just like the "convention over configuration" concept |
Sure, but that configuration would cause confusion. I.e. "Why is the LdapRecord model stored in the
Ok, although this is an extremely common approach used throughout Laravel and it's own first-party ecosystem. LdapRecord-Laravel is not primarily an Eloquent authentication driver. It is primarily an LDAP authentication driver, with Eloquent compatibility.
Check out the Laravel-Auth0 repository. It also has a unique auth driver configuration. This driver would also be incompatible with Nova -- even though it could be compatible since it implements the Authenticatable interface. FYI -- Nova used to work with LdapRecord-Laravel. Now it does not due to their update which hard-coded the config path. |
Hi @scramatte ! Have you found any solution for this? We just purchased Nova and of course it still doesn't work out of the box. |
Hi @Perzonallica , To get it running I've done the following :
https://github.com/funkjedi/composer-include-files Modify your composer.json to load plugin above.
Execute Everything should works properly with this patch Regards |
Thanks @scramatte for your time to describing this! In the meantime I managed to make it work with creating a different auth guard for Nova. |
Can you publish this here to get reference just in case somebody needs it
Thank you
Enviado desde mi iPhone
El 14 dic 2022, a las 17:01, Perzonallica ***@***.***> escribió:
Thanks @scramatte<https://github.com/scramatte> for your time to describing this!
In the meantime I managed to make it work with creating a different auth guard for Nova.
—
Reply to this email directly, view it on GitHub<#423 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AABOCXQAW5QLUO5W4KDO2DTWNHVM5ANCNFSM5UCI2KGQ>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
@scramatte Sure, at the end it turned out to be a pretty easy solution for us. All we had to do is to create another guard in
Then in the
And the last thing is to put this line in to the After this Nova should work with the eloquent driver. |
Hi, I've spoken to fast, I've still have the issue on migration ... If you add method. getKeyType that just return null, into ./Query/Model/ActiveDirectoryBuilder.php
|
Hello,
I've rollback all migration from a project. And I when I try to migrate back everything I'got the following error ...
Any Idea ?
The text was updated successfully, but these errors were encountered: