First public release. - docs: document the audit log, user offboarding, CSV export and the "require a reason for destructive actions" setting across README, docs/ and CLAUDE/AGENTS.md; note retention for panel_audit - docs: fill the publishing placeholders (repo URL, security contact, issue-template links) and add a semantic-versioning policy - move agent/contributor context into CLAUDE/ (AGENTS.md + a README); root CLAUDE.md is now a thin @-import pointer - add a favicon (shield-lock, matching the login screen) to the login page and the app layout - CHANGELOG: promote [Unreleased] to [1.0.0]; keep the earlier internal build as [0.1.0] Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UfuvfwexztdS7LDpGuKsuK
144 lines
4.4 KiB
PHP
144 lines
4.4 KiB
PHP
<?php
|
|
|
|
namespace App\Ldap;
|
|
|
|
use App\Services\PanelSettingsService;
|
|
use LdapRecord\Models\ActiveDirectory\User as ActiveDirectoryUser;
|
|
|
|
/**
|
|
* Model użytkownika Active Directory używany przez panel.
|
|
*
|
|
* Mapowanie pól panelu na atrybuty AD nie jest już zaszyte w kodzie -
|
|
* pochodzi z konfiguracji panelu (zakładka "Atrybuty"), obsługiwanej przez
|
|
* {@see PanelSettingsService}. Ta klasa jest cienką nakładką, która z tej
|
|
* konfiguracji buduje:
|
|
* - listę atrybutów pobieranych z LDAP (patrz panelAttributes()),
|
|
* - mapę wartości do odpowiedzi JSON w UserController@show (mappedAttributes()),
|
|
* - listę pól edytowalnych używaną przy zapisie (editableAttributes()).
|
|
*/
|
|
class User extends ActiveDirectoryUser
|
|
{
|
|
/**
|
|
* Pełne definicje atrybutów z konfiguracji panelu.
|
|
*
|
|
* @return list<array<string, mixed>>
|
|
*/
|
|
public static function attributeDefinitions(): array
|
|
{
|
|
return app(PanelSettingsService::class)->attributes();
|
|
}
|
|
|
|
/**
|
|
* Mapa: klucz pola panelu => nazwa atrybutu AD.
|
|
*
|
|
* @return array<string, string>
|
|
*/
|
|
public static function attributeMap(): array
|
|
{
|
|
$map = [];
|
|
|
|
foreach (self::attributeDefinitions() as $attr) {
|
|
if (! empty($attr['computed'])) {
|
|
continue; // kolumny wyliczane nie są atrybutami AD
|
|
}
|
|
|
|
if (! empty($attr['fixed'])) {
|
|
continue; // np. accountExpires - odczyt / zapis ma dedykowaną obsługę
|
|
}
|
|
|
|
if ($attr['key'] !== '' && $attr['ldap'] !== '') {
|
|
$map[$attr['key']] = $attr['ldap'];
|
|
}
|
|
}
|
|
|
|
return $map;
|
|
}
|
|
|
|
/**
|
|
* Mapa pól, które panel pozwala edytować w formularzu profilu.
|
|
* Klucz = nazwa pola formularza, wartość = nazwa atrybutu AD w formie
|
|
* akceptowanej przez LdapRecord przy zapisie (małe litery).
|
|
*
|
|
* @return array<string, string>
|
|
*/
|
|
public static function editableAttributes(): array
|
|
{
|
|
$map = [];
|
|
|
|
foreach (self::attributeDefinitions() as $attr) {
|
|
if (! empty($attr['editable']) && $attr['key'] !== '' && $attr['ldap'] !== '') {
|
|
$map[$attr['key']] = strtolower($attr['ldap']);
|
|
}
|
|
}
|
|
|
|
return $map;
|
|
}
|
|
|
|
/**
|
|
* Wszystkie atrybuty AD, które panel powinien pobrać dla użytkownika:
|
|
* wartości z mapy atrybutów + atrybuty techniczne potrzebne do wyliczenia
|
|
* statusu konta, dat haseł i członkostwa w grupach.
|
|
*
|
|
* @return list<string>
|
|
*/
|
|
public static function panelAttributes(): array
|
|
{
|
|
return array_values(array_unique(array_merge(
|
|
array_values(self::attributeMap()),
|
|
[
|
|
'cn',
|
|
'userPrincipalName',
|
|
'userAccountControl',
|
|
'pwdLastSet',
|
|
'lockoutTime',
|
|
'lastLogonTimestamp',
|
|
'memberOf',
|
|
'accountExpires',
|
|
],
|
|
)));
|
|
}
|
|
|
|
/**
|
|
* Zwraca wartości atrybutów z mapy jako płaską tablicę kluczowaną
|
|
* kluczami mapy (np. 'firstName', 'employeeID', 'google').
|
|
*
|
|
* @return array<string, string|null>
|
|
*/
|
|
public function mappedAttributes(): array
|
|
{
|
|
$values = [];
|
|
|
|
foreach (self::attributeMap() as $key => $ldapAttribute) {
|
|
$values[$key] = $this->getFirstAttribute(strtolower($ldapAttribute));
|
|
}
|
|
|
|
return $values;
|
|
}
|
|
|
|
/**
|
|
* Lekki profil zalogowanego administratora trzymany w sesji pod kluczem
|
|
* 'ad_admin' (zgodnie z konwencją projektu - patrz config/ldap.php).
|
|
* Buduje się na statycznym mapowaniu config('ldap.attributes.user').
|
|
*
|
|
* @return array{login: ?string, display_name: string, mail: ?string, dn: string}
|
|
*/
|
|
public function toPanelProfile(): array
|
|
{
|
|
$map = config('ldap.attributes.user', []);
|
|
|
|
$get = fn (string $key, string $fallback): ?string => $this->getFirstAttribute($map[$key] ?? $fallback);
|
|
|
|
$login = $get('login', 'samaccountname');
|
|
$display = $get('display_name', 'displayname')
|
|
?: trim(($get('first_name', 'givenname') ?? '').' '.($get('last_name', 'sn') ?? ''))
|
|
?: $this->getFirstAttribute('cn');
|
|
|
|
return [
|
|
'login' => $login,
|
|
'display_name' => $display ?: ($login ?? 'Administrator'),
|
|
'mail' => $get('mail', 'mail'),
|
|
'dn' => (string) $this->getDn(),
|
|
];
|
|
}
|
|
}
|