WS-2: Firmen-Scope für PMs & Magic-Link-Zugang für Pressekontakte
Firmen-Scope (Fundament): - PM-Zugriff war hart an user_id (Autor) gebunden. Jetzt additiv: Autor ODER Mitglied der zugeordneten Firma (Owner via owner_user_id oder company_user- Pivot). Geändert in PressReleasePolicy (canManage) sowie den Queries der Listen-, Show- und Edit-Komponenten. Helfer User::accessibleCompanyIds()/ canAccessCompany(). Solo-Owner unverändert; Firmenmitglieder sehen/bearbeiten alle PMs ihrer Firma. Magic-Link-Zugang für Pressekontakte (ContactAccessService): - Öffentliches, enumeration-sicheres Formular (/pressekontakt-zugang) mit Honeypot + Rate-Limit. Eine hinterlegte Kontakt-E-Mail führt zu einem lazy angelegten, de-duplizierten customer-Account (aktiv, verifiziert über den Magic-Link-Kanal), der den Firmen seiner Kontakte als Mitglied zugeordnet wird. Versand über den bestehenden Login-Magic-Link (Generator + Consume wiederverwendet) – keine Schema-Änderung, kein paralleles System. - Dezenter Einstiegslink von der Login-Seite (PM-Frontend-Wiring später). Tests: PressReleaseCompanyScopeTest (3), ContactAccessTest (6, inkl. De-Dup, Enumeration-Sicherheit, Honeypot). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
f06650a641
commit
c6b2b67d00
11 changed files with 493 additions and 7 deletions
|
|
@ -24,7 +24,7 @@ class PressReleasePolicy
|
|||
return true;
|
||||
}
|
||||
|
||||
return $this->isAuthor($user, $pressRelease);
|
||||
return $this->canManage($user, $pressRelease);
|
||||
}
|
||||
|
||||
public function create(User $user): bool
|
||||
|
|
@ -34,7 +34,7 @@ class PressReleasePolicy
|
|||
|
||||
public function update(User $user, PressRelease $pressRelease): bool
|
||||
{
|
||||
if (! $this->isAuthor($user, $pressRelease) && ! $user->canAccessAdmin()) {
|
||||
if (! $this->canManage($user, $pressRelease) && ! $user->canAccessAdmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ class PressReleasePolicy
|
|||
|
||||
public function submitForReview(User $user, PressRelease $pressRelease): bool
|
||||
{
|
||||
return $this->isAuthor($user, $pressRelease)
|
||||
return $this->canManage($user, $pressRelease)
|
||||
&& in_array($pressRelease->status, [PressReleaseStatus::Draft, PressReleaseStatus::Rejected], true);
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ class PressReleasePolicy
|
|||
return true;
|
||||
}
|
||||
|
||||
return $this->isAuthor($user, $pressRelease)
|
||||
return $this->canManage($user, $pressRelease)
|
||||
&& $pressRelease->status !== PressReleaseStatus::Published;
|
||||
}
|
||||
|
||||
|
|
@ -76,6 +76,17 @@ class PressReleasePolicy
|
|||
return $user->canAccessAdmin() && $user->can('press-releases:publish');
|
||||
}
|
||||
|
||||
/**
|
||||
* Zugriff auf eine PM hat der Autor ODER ein Mitglied der zugeordneten
|
||||
* Firma (Owner/Team-Mitglied). So sehen/bearbeiten Firmenkontakte – inkl.
|
||||
* der per Magic-Link lazy angelegten Accounts – die PMs ihrer Firma.
|
||||
*/
|
||||
private function canManage(User $user, PressRelease $pressRelease): bool
|
||||
{
|
||||
return $this->isAuthor($user, $pressRelease)
|
||||
|| $user->canAccessCompany($pressRelease->company_id);
|
||||
}
|
||||
|
||||
private function isAuthor(User $user, PressRelease $pressRelease): bool
|
||||
{
|
||||
return $pressRelease->user_id === $user->id;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue