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
3.9 KiB
3.9 KiB
AGENTS.md — working on ADconsole
Context for AI coding agents and new contributors. Keep it accurate when you change the architecture.
What this is
A Laravel 11 + LdapRecord web panel that manages an Active Directory domain: users, computers, groups and read-only GPO, plus a dashboard and an org chart. PHP 8.2+. Interface is PL/EN.
Golden rules
- No SQL storage for AD objects. Every read/write of a user, computer or
group goes through LdapRecord straight to a domain controller. The database
(
panel_settings+panel_attributes+panel_audit, plus Laravel'ssessions/cache/jobs) backs the application layer only.panel_auditrecords what the panel did to AD — it is not a mirror of AD state. - Auth is the
ldapguard (LdapRecord plain-bind, no local accounts). Only members ofAD_LOGIN_GROUPmay sign in (App\Ldap\Rules\MemberOfLoginGroup, honours nested + primary group). Every panel route is behindauth:ldap; the admin profile lives in the session keyad_admin. - i18n everywhere. User-facing strings come from
lang/{pl,en}/*.phpvia__('namespace.key'). Never hard-code copy in Blade/PHP. Add a key to both locales. Default locale ispl;config/locales.phpis the single source of the available-language list. - Some
lang/pl/*values are asserted verbatim by tests (e.g.tests/Feature/AttributeConfigTest). Changing an existing PL string can break a test — check before editing. - Docroot is
public/. Do not add.htaccessdeny rules elsewhere as a substitute.
Layout
| Path | Role |
|---|---|
app/Http/Controllers/Admin/* |
one controller per module (Users, Computers, Groups, Gpo, OrgChart, Dashboard, Audit, Config) |
app/Ldap/User.php |
AD user model + attribute map + toPanelProfile() |
app/Ldap/Rules/MemberOfLoginGroup.php |
login authorisation rule |
app/Services/ |
PanelSettingsService (config, DB-backed), AttributeCipher, LdapAttributeHelper (UAC bits, FileTime), OuTreeService (cached OU tree), AuditLogger (writes panel_audit; never throws — a log failure is only report()ed) |
app/Models/PanelSetting.php |
key→JSON row: general panel config (panel_settings) |
app/Models/PanelAttribute.php |
one row per configured AD attribute (panel_attributes, ordered by position) |
app/Models/AuditLog.php |
one row per audited panel action (panel_audit); written only via AuditLogger, read only by AuditController |
config/ldap.php |
connection, auth.login_group, default OUs, attribute map |
resources/views/admin/* |
Blade views; shared bits in components/ + partials/ |
public/css/style.css, public/js/main.js |
hand-written assets loaded directly (no Vite build needed) |
routes/web.php |
all routes; English URL segments and route names |
Configuration
- Deployment config →
.env(see.env.examplefor every key). Read-only at runtime; nothing writes back to it. - In-app config (
/settings) → viaPanelSettingsService:- general settings (password policy / generator, reset-dialog defaults,
attribute-encryption key,
audit.require_reason) → one JSON row inpanel_settings; - AD attribute / column definitions → one row each in
panel_attributes(columns:key,label,ldap,category,type,is_column,position). Both fall back toPanelSettingsService::defaults()/defaultAttributes()when empty.
- general settings (password policy / generator, reset-dialog defaults,
attribute-encryption key,
Running things
composer install
cp .env.example .env && php artisan key:generate
php artisan migrate
php artisan test # SQLite :memory:, ~40 tests
vendor/bin/pint # code style
php artisan test prints a harmless PHP 8.5 PDO::MYSQL_ATTR_SSL_CA
deprecation that PHPUnit flags on every test as DEPR — that is not a
failure.
See docs/ for installation, AD setup, deployment, architecture and
troubleshooting.