Skip to content
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

Getting error on login #117

Closed
brinkonaut opened this issue Apr 16, 2020 · 12 comments
Closed

Getting error on login #117

brinkonaut opened this issue Apr 16, 2020 · 12 comments
Labels
bug Something isn't working question Further information is requested

Comments

@brinkonaut
Copy link

brinkonaut commented Apr 16, 2020

Describe the bug
I have updated to the latest version.(1.2)
When I try to login im getting this error:
Argument 1 passed to LdapRecord\Models\Model::serializeDate() must implement interface DateTimeInterface, null given, called in /vendor/directorytree/ldaprecord/src/Models/Concerns/HasAttributes.php on line 105

When I change the code of this file to this:
protected function serializeDate(?DateTimeInterface $date) { return optional($date)->format($this->getDateFormat()); }

it works.

Environment (please complete the following information):

  • LDAP Server Type: ActiveDirectory
  • PHP Version: 7.4
  • Laravel Version: 7
@stevebauman stevebauman added the question Further information is requested label Apr 16, 2020
@stevebauman
Copy link
Member

Hi @brinkonaut,

I'm not able to reproduce this. Can you post your config/auth.php file? Also, are you serializing any LDAP models by chance?

@stevebauman
Copy link
Member

stevebauman commented Apr 16, 2020

Somewhere in your application, serialization of an LDAP model is occurring -- when this happens, dates via the $dates property on your LDAP model are converted to full date time strings.

It seems conversion is failing somewhere, but will need to know more to assist, thanks!

@brinkonaut
Copy link
Author

brinkonaut commented Apr 16, 2020

My config/auth.php:
`
[

/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/

'defaults' => [
    'guard' => 'web',
    'passwords' => 'users',
],

/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => env('AUTH_PROVIDER', 'ldap'),
    ],

    'api' => [
        'driver' => 'token',
        'provider' => 'users',
        'hash' => false,
    ],
],

/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\User::class,
    ],

    'ldap' => [
        'driver' => 'ldap',
        'model' => LdapRecord\Models\ActiveDirectory\User::class,
        'rules' => [
            \App\Ldap\Rules\OnlyKumlistUsers::class,
        ],
        'database' => [
            'model' => App\User::class,
            'sync_passwords' => true,
            'sync_attributes' => [
                'name' => 'cn',
                'email' => 'mail',
                'username' => 'samaccountname',
            ],
        ],
    ],

    // 'users' => [
    //     'driver' => 'database',
    //     'table' => 'users',
    // ],
],

/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/

'passwords' => [
    'users' => [
        'provider' => 'users',
        'table' => 'password_resets',
        'expire' => 60,
        'throttle' => 60,
    ],
],

/*
|--------------------------------------------------------------------------
| Password Confirmation Timeout
|--------------------------------------------------------------------------
|
| Here you may define the amount of seconds before a password confirmation
| times out and the user is prompted to re-enter their password via the
| confirmation screen. By default, the timeout lasts for three hours.
|
*/

'password_timeout' => 10800,

];
`

My User Model has no $dates.

@stevebauman
Copy link
Member

Can you post your stack trace of the exception?

@stevebauman
Copy link
Member

Ah okay you're using Laravel Telescope, which is serializing the model.

I'd still like to track down why conversions of the dates are failing... You're connecting to an Active Directory server I'm assuming?

@brinkonaut
Copy link
Author

Ah, you are right, when I disable telescope it works. Thank you so much!

Yes, its a Active Directory.

@stevebauman
Copy link
Member

No problem! Though, I still want this to work 100% with Telescope, so I'm going to patch this now to fallback if the date is unable to be converted.

Would you be able to call a dump-n-die dd() here and post the values?

https://github.com/DirectoryTree/LdapRecord/blob/b212a3c8f1f06e7fccd8c56a74ba69be675f4d3c/src/Models/Concerns/HasAttributes.php#L97-L112

You'll have to open up your vendor directory to navigate into the HasAttributes trait:

// vendor/directorytree/ldaprecord/src/Models/Concerns/HasAttributes.php

/**
 * Add the date attributes to the attributes array.
 *
 * @param array $attributes
 *
 * @return array
 */
protected function addDateAttributesToArray(array $attributes)
{
    foreach ($this->getDates() as $attribute => $type) {
        if (!isset($attributes[$attribute])) {
            continue;
        }

        // Add dd here:
        dd($attributes[$attribute]);

        $date = $this->serializeDate(
            $this->asDateTime($type, $attributes[$attribute])
        );

        $attributes[$attribute] = Arr::wrap($date);
    }

    return $attributes;
}

@stevebauman
Copy link
Member

I'm wondering if your AD may have a different timestamp format, or something along those lines, but will need to see to be sure.

@brinkonaut
Copy link
Author

array:1 [▼ 0 => "20200415102147.0Z" ]

@stevebauman
Copy link
Member

Ah hang on it must be failing somewhere else, as I'm able to convert this successfully:

use LdapRecord\Models\Attributes\Timestamp;

$time = new Timestamp('windows');

$carbon = $time->toDateTime('20200415102147.0Z');

Can you try this instead?

/**
 * Add the date attributes to the attributes array.
 *
 * @param array $attributes
 *
 * @return array
 */
protected function addDateAttributesToArray(array $attributes)
{
    foreach ($this->getDates() as $attribute => $type) {
        if (!isset($attributes[$attribute])) {
            continue;
        }
        
        $date = $this->asDateTime($type, $attributes[$attribute]);

        if ($date instanced Carbon) {
            $date = $this->serializeDate($date);
        } else {
            // DD Here:
            dd($attributes[$attribute]);
        }
       
        $attributes[$attribute] = Arr::wrap($date);
    }

    return $attributes;
}

@brinkonaut
Copy link
Author

array:1 [ 0 => "0" ]

@stevebauman
Copy link
Member

Perfect, thanks! Patching now... stay tuned for update 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants