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
93 lines
2.6 KiB
PHP
93 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace Tests\Unit;
|
|
|
|
use App\Ldap\Rules\MemberOfLoginGroup;
|
|
use App\Ldap\User;
|
|
use LdapRecord\Models\Model;
|
|
use PHPUnit\Framework\Attributes\Test;
|
|
use Tests\TestCase;
|
|
|
|
class MemberOfLoginGroupTest extends TestCase
|
|
{
|
|
/**
|
|
* Wariant reguły z podmienioną ścieżką "grup zagnieżdżonych", żeby test
|
|
* był deterministyczny i nie wołał LDAP.
|
|
*/
|
|
private function rule(array $nestedGroupDns = []): MemberOfLoginGroup
|
|
{
|
|
return new class($nestedGroupDns) extends MemberOfLoginGroup
|
|
{
|
|
public function __construct(private array $nested) {}
|
|
|
|
protected function nestedGroupDns(Model $user): array
|
|
{
|
|
return $this->nested;
|
|
}
|
|
};
|
|
}
|
|
|
|
private function user(array $memberOf): User
|
|
{
|
|
return new User(['memberof' => $memberOf]);
|
|
}
|
|
|
|
#[Test]
|
|
public function it_rejects_everyone_when_no_group_is_configured(): void
|
|
{
|
|
config(['ldap.auth.login_group' => '']);
|
|
|
|
$this->assertFalse(
|
|
$this->rule()->passes($this->user(['CN=Anything,DC=corp,DC=example,DC=com']))
|
|
);
|
|
}
|
|
|
|
#[Test]
|
|
public function it_accepts_direct_membership_by_dn_ignoring_case_and_spacing(): void
|
|
{
|
|
config(['ldap.auth.login_group' => 'CN=ADconsole,OU=Aplikacje,OU=Grupy,DC=example,DC=com']);
|
|
|
|
$user = $this->user([
|
|
'CN=Domain Users,CN=Users,DC=example,DC=com',
|
|
'cn=adconsole, ou=aplikacje, ou=grupy, dc=example, dc=com',
|
|
]);
|
|
|
|
$this->assertTrue($this->rule()->passes($user));
|
|
}
|
|
|
|
#[Test]
|
|
public function it_accepts_membership_configured_by_cn_only(): void
|
|
{
|
|
config(['ldap.auth.login_group' => 'ADconsole']);
|
|
|
|
$user = $this->user(['CN=ADconsole,OU=Aplikacje,OU=Grupy,DC=example,DC=com']);
|
|
|
|
$this->assertTrue($this->rule()->passes($user));
|
|
}
|
|
|
|
#[Test]
|
|
public function it_accepts_nested_membership(): void
|
|
{
|
|
config(['ldap.auth.login_group' => 'CN=ADconsole,OU=Aplikacje,OU=Grupy,DC=example,DC=com']);
|
|
|
|
$user = $this->user(['CN=Helpdesk,OU=Grupy,DC=example,DC=com']);
|
|
|
|
$rule = $this->rule(['CN=ADconsole,OU=Aplikacje,OU=Grupy,DC=example,DC=com']);
|
|
|
|
$this->assertTrue($rule->passes($user));
|
|
}
|
|
|
|
#[Test]
|
|
public function it_rejects_a_user_who_is_not_a_member(): void
|
|
{
|
|
config(['ldap.auth.login_group' => 'CN=ADconsole,OU=Aplikacje,OU=Grupy,DC=example,DC=com']);
|
|
|
|
$user = $this->user([
|
|
'CN=Domain Users,CN=Users,DC=example,DC=com',
|
|
'CN=Helpdesk,OU=Grupy,DC=example,DC=com',
|
|
]);
|
|
|
|
$this->assertFalse($this->rule()->passes($user));
|
|
}
|
|
}
|