DirectoryTree / LdapRecord-Laravel

Multi-domain LDAP Authentication & Management for Laravel.
https://ldaprecord.com/docs/laravel/v3
MIT License
508 stars 54 forks source link

[Bug] Soft-deletes and restores are not working during command based import #349

Closed dereknutile closed 3 years ago

dereknutile commented 3 years ago

Environment:

Soft-deleting/restoring isn't working on import/sync. For example, choosing a user to import and including the -d and -r switches seems to successfully sync, even syncs attributes like a name change, but doesn't flag the user as soft-deleted or set deleted_at to NULL based on AD.

php artisan ldap:import ccso -d -r --filter "(samAccountName=fmulder)"

steps

Additional Information

The User model does have SoftDeletes enabled I have 2 "providers" configured in config/auth - each using an AttributeHandler to prepare certain fields, e.g.:

'providers' => [
        'ccso' => [
            'driver' => 'ldap',
            'model' => App\Ldap\Ccso\User::class,
            'rules' => [],
            'database' => [
                'model' => App\Models\User\User::class,
                'sync_passwords' => true,
                'sync_attributes' => \App\Ldap\Ccso\AttributeHandler::class,
                'sync_existing' => [
                    'email' => 'mail',
                    'username' => 'samaccountname',
                    'name' => 'cn',
                    'last_name' => 'sn',
                    'first_name' => 'givenname',
                    'phone_primary' => 'telephonenumber',
                    'phone_mobile' => 'mobile',
                    'phone_ip' => 'ipphone',
                    'title' => 'title',
                    'description' => 'description',
                    'distinguishedname' => 'distinguishedname',
                    'manager' => 'manager',
                    'division' => 'division'
                ],
            ],
        ],

The terminal output and the log don't suggest errors.

[2021-08-23 17:00:09] local.INFO: LDAP (ldap://myProvider.ds.myDomain.us:389) - Operation: Binding - Username: myProvider\svc_intranet_ldap  
[2021-08-23 17:00:09] local.INFO: LDAP (ldap://myProvider.ds.myDomain.us:389) - Operation: Bound - Username: myProvider\svc_intranet_ldap  
[2021-08-23 17:00:09] local.INFO: LDAP (ldap://myProvider.ds.myDomain.us:389) - Operation: Paginate - Base DN: DC=myProvider,DC=ds,DC=myDomain,DC=us - Filter: (&(samAccountName=fmulder)(objectclass=\75\73\65\72)(objectclass=\50\65\72\73\6f\6e)) - Selected: (objectguid,*) - Time Elapsed: 19.51  
[2021-08-23 17:00:13] local.INFO: Starting import of [1] LDAP objects.  
[2021-08-23 17:00:13] local.INFO: Object with name [Mulder, Fox] is being synchronized.  
[2021-08-23 17:00:13] local.INFO: Object with name [Mulder, Fox] has been successfully synchronized.  
[2021-08-23 17:00:13] local.INFO: Completed import. Imported [0] new LDAP objects. Synchronized [1] existing LDAP objects. 

Is this something mis-configured on my end or is the soft-delete not working?

Thank you, Derek

stevebauman commented 3 years ago

Hi there @dereknutile!

Can you post your App\Ldap\Ccso\User model code?

dereknutile commented 3 years ago

Hi @stevebauman, sure thing.

<?php

namespace App\Ldap\Ccso;

use LdapRecord\Models\Model;

class User extends Model
{
    protected $connection = 'ccso';

    /**
     * The object classes of the LDAP model.
     *
     * @var array
     */
    public static $objectClasses = [
        'user',
        'Person',
    ];
}
stevebauman commented 3 years ago

Thanks @dereknutile. Your model must extend the built-in ActiveDirectory\User model so that LdapRecord knows the user is in-fact from Active Directory. This model implements an interface which is checked during import:

https://github.com/DirectoryTree/LdapRecord-Laravel/blob/1f6c40bbd8857236225c0ce7aa3a088c484e2efd/src/Commands/LdapUserImporter.php#L47

For example:

<?php

namespace App\Ldap\Ccso;

use LdapRecord\Models\ActiveDirectory\User as BaseUser;

class User extends BaseUser
{
    protected $connection = 'ccso';
}

Give that a shot 👍

dereknutile commented 3 years ago

Ah, that makes perfect sense. It worked, thank you @stevebauman!

stevebauman commented 3 years ago

Awesome, happy to help @dereknutile! Glad you're up and running 🎉

wardpieters commented 2 years ago

Your model must extend the built-in ActiveDirectory\User model so that LdapRecord knows the user is in-fact from Active Directory. This model implements an interface which is checked during import:

https://github.com/DirectoryTree/LdapRecord-Laravel/blob/1f6c40bbd8857236225c0ce7aa3a088c484e2efd/src/Commands/LdapUserImporter.php#L47

Hi @stevebauman! What if I'm using FreeIPA instead of ActiveDirectory and my User model looks like this?

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements LdapAuthenticatable, MustVerifyEmail, Auditable
{
    use HasApiTokens, AuthenticatesWithLdap, HasLdapUser, HasFactory, Notifiable, SoftDeletes, HasRoles, \OwenIt\Auditing\Auditable;

Thanks, Ward