directorytree/scout
Scout is an LDAP auditing web app that periodically scans your directory to detect and log changes to objects and attributes, with customizable notifications, password change/expiry alerts, and password resets via a web UI. (Rebuilt as Watchdog)
Clone the Repository
git clone https://github.com/DirectoryTree/Scout
cd Scout
Install Dependencies
composer install
Configure LDAP Connection
Edit .env to include your LDAP server details:
LDAP_HOST=your-ldap-server
LDAP_PORT=389
LDAP_BASE_DN=dc=example,dc=com
LDAP_USERNAME=cn=admin,dc=example,dc=com
LDAP_PASSWORD=your-password
Run Migrations
php artisan migrate
Set Up Scheduling (Optional) Configure a cron job to run the scanner periodically (e.g., every 5 minutes):
* * * * * cd /path/to/scout && php artisan scout:scan
Access the Web Interface Start the Laravel development server:
php artisan serve
Navigate to http://localhost:8000 to view the dashboard.
scout:scan Artisan command to manually trigger an LDAP audit.scout:notifications table for detected changes (e.g., password resets, attribute modifications).Notifiers section in the admin panel.LDAP Scanning
app/Console/Kernel.php):
$schedule->command('scout:scan')->everyFiveMinutes();
app/Scout/Scanners/LdapScanner.php to add custom checks.Notification System
app/Scout/Notifications/NotificationRule.php:
public function shouldNotify($change)
{
return $change->attribute === 'userPassword';
}
config/scout.php:
'notifiers' => [
'email' => \DirectoryTree\Scout\Notifications\EmailNotifier::class,
'slack' => \App\Notifications\SlackNotifier::class,
],
Password Management
/password-reset route) and log changes:
// In a controller
$user = \DirectoryTree\LdapRecord\Models\User::find($id);
$user->setPassword('temp123!');
$user->save();
app/Scout/Notifications/PasswordExpiryNotifier.php.Integration with Laravel
// In EventServiceProvider
public function boot()
{
\DirectoryTree\Scout\Events\LdapChangeDetected::class => [
\App\Listeners\LogLdapChange::class,
],
}
DirectoryTree\LdapRecord\Models\Model to map custom attributes.Route::get('/api/ldap-changes', function () {
return \DirectoryTree\Scout\Models\Change::latest()->take(100)->get();
});
Http client to send changes to external systems:
use Illuminate\Support\Facades\Http;
Http::post('https://external-api.com/webhook', [
'change' => $change->toArray()
]);
LDAP Connection Issues
php -m | grep ldap)..env credentials and firewall rules.php artisan scout:test-connection to verify LDAP access.Performance with Large Directories
config/scout.php:
'scan' => [
'depth' => 3, // Reduce if scanning large trees
'batch_size' => 100,
],
$changes = Cache::remember('ldap_changes', now()->addHours(1), function () {
return \DirectoryTree\Scout\Models\Change::all();
});
Notification Delays
// In NotificationRule
public function notify($change)
{
Notification::route('mail', $change->user->email)
->notify(new LdapChangeNotification($change));
}
php artisan queue:work.Password Reset Security
app/Scout/Policies/PasswordPolicy.php:
public function passes($password)
{
return preg_match('/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/', $password);
}
config/ldaprecord.php:
'debug' => env('LDAP_DEBUG', false),
php artisan tinker
>>> $user = \DirectoryTree\LdapRecord\Models\User::find(1);
>>> $user->setAttribute('mail', 'new@example.com');
>>> $user->save();
storage/logs/laravel.log for scanner errors.Custom Scanners
DirectoryTree\Scout\Contracts\Scanner:
namespace App\Scout\Scanners;
use DirectoryTree\Scout\Contracts\Scanner;
class CustomScanner implements Scanner
{
public function scan()
{
// Custom logic here
}
}
app/Providers/ScoutServiceProvider.php:
$this->app->bind(
\DirectoryTree\Scout\Contracts\Scanner::class,
App\Scout\Scanners\CustomScanner::class
);
Plugin System
php artisan vendor:publish --provider="DirectoryTree\Scout\ScoutServiceProvider"
resources/views/vendor/scout/.Webhook Events
ldap.change.detected events to trigger external actions:
// In EventServiceProvider
\DirectoryTree\Scout\Events\LdapChangeDetected::class => [
\App\Listeners\SendWebhook::class,
];
How can I help you explore Laravel packages today?