Skip to content

Commit

Permalink
Check user still has access to domain on page load
Browse files Browse the repository at this point in the history
Fixes #836
  • Loading branch information
stwalkerster committed Sep 4, 2023
1 parent 9912642 commit 585c81d
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 19 deletions.
2 changes: 1 addition & 1 deletion includes/Pages/PageDomainSwitch.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ protected function main()
return;
}

$this->getDomainAccessManager()->switchDomain($currentUser, $newDomain);
$this->getDomainAccessManager()->switchDomain($currentUser, $newDomain, $this->getSecurityManager());

// try to stay on the same page if possible.
// This only checks basic ACLs and not domain privileges, so this may still result in a 403.
Expand Down
14 changes: 2 additions & 12 deletions includes/Security/DomainAccessManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,6 @@

class DomainAccessManager
{
/**
* @var SecurityManager
*/
private $securityManager;

public function __construct(SecurityManager $securityManager)
{
$this->securityManager = $securityManager;
}

/**
* @param User $user
*
Expand All @@ -41,7 +31,7 @@ public function getAllowedDomains(User $user): array
return Domain::getDomainByUser($user->getDatabase(), $user, true);
}

public function switchDomain(User $user, Domain $newDomain): void
public function switchDomain(User $user, Domain $newDomain, SecurityManager $securityManager): void
{
$mapToId = function(DataObject $object) {
return $object->getId();
Expand All @@ -53,7 +43,7 @@ public function switchDomain(User $user, Domain $newDomain): void
WebRequest::setActiveDomain($newDomain);
}
else {
throw new AccessDeniedException($this->securityManager, $this);
throw new AccessDeniedException($securityManager, $this);
}
}

Expand Down
21 changes: 20 additions & 1 deletion includes/Security/SecurityManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
use Waca\DataObjects\Domain;
use Waca\DataObjects\User;
use Waca\DataObjects\UserRole;
use Waca\Exceptions\AccessDeniedException;
use Waca\Exceptions\ApplicationLogicException;
use Waca\IdentificationVerifier;

final class SecurityManager
Expand All @@ -25,20 +27,25 @@ final class SecurityManager
*/
private $roleConfiguration;

private DomainAccessManager $domainAccessManager;

private $cache = [];

/**
* SecurityManager constructor.
*
* @param IdentificationVerifier $identificationVerifier
* @param RoleConfiguration $roleConfiguration
* @param DomainAccessManager $domainAccessManager
*/
public function __construct(
IdentificationVerifier $identificationVerifier,
RoleConfiguration $roleConfiguration
RoleConfiguration $roleConfiguration,
DomainAccessManager $domainAccessManager
) {
$this->identificationVerifier = $identificationVerifier;
$this->roleConfiguration = $roleConfiguration;
$this->domainAccessManager = $domainAccessManager;
}

/**
Expand Down Expand Up @@ -181,6 +188,18 @@ public function getActiveRoles(User $user, &$activeRoles, &$inactiveRoles)

if ($user->isActive()) {
$domain = Domain::getCurrent($user->getDatabase());

$userDomains = array_map(fn(Domain $d) => $d->getId(), $this->domainAccessManager->getAllowedDomains($user));

if (!in_array($domain->getId(), $userDomains)) {
$this->domainAccessManager->switchToDefaultDomain($user);
$domain = Domain::getCurrent($user->getDatabase());
}

if (!in_array($domain->getId(), $userDomains)) {
throw new AccessDeniedException($this, $this->domainAccessManager);
}

$ur = UserRole::getForUser($user->getId(), $user->getDatabase(), $domain->getId());

// NOTE: public is still in this array.
Expand Down
7 changes: 4 additions & 3 deletions includes/WebStart.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,17 @@ protected function setupHelpers(
$page->setTypeAheadHelper(new TypeAheadHelper());

$identificationVerifier = new IdentificationVerifier($page->getHttpHelper(), $siteConfiguration, $database);
$page->setSecurityManager(new SecurityManager($identificationVerifier, new RoleConfiguration()));

$domainAccessManager = new DomainAccessManager();
$page->setDomainAccessManager($domainAccessManager);
$page->setSecurityManager(new SecurityManager($identificationVerifier, new RoleConfiguration(), $domainAccessManager));

if ($siteConfiguration->getTitleBlacklistEnabled()) {
$page->setBlacklistHelper(new BlacklistHelper($page->getHttpHelper(), $database));
}
else {
$page->setBlacklistHelper(new FakeBlacklistHelper());
}

$page->setDomainAccessManager(new DomainAccessManager($page->getSecurityManager()));
}
}
}
Expand Down
12 changes: 10 additions & 2 deletions tests/includes/Security/SecurityManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@

use PHPUnit_Framework_MockObject_MockObject;
use PHPUnit\Framework\TestCase;
use Waca\DataObjects\Domain;
use Waca\DataObjects\User;
use Waca\IdentificationVerifier;
use Waca\Security\DomainAccessManager;
use Waca\Security\RoleConfiguration;
use Waca\Security\SecurityManager;

Expand Down Expand Up @@ -51,7 +53,10 @@ public function testPublicAccess()
));
$roleConfiguration->method('roleNeedsIdentification')->willReturn(false);

$securityManager = new SecurityManager($this->identificationVerifier, $roleConfiguration);
$securityManager = new SecurityManager(
$this->identificationVerifier,
$roleConfiguration,
new DomainAccessManager());
$this->identificationVerifier->method('isUserIdentified')->willReturn(true);

// act
Expand All @@ -76,7 +81,10 @@ public function testPublicAccessDenied()
));
$roleConfiguration->method('roleNeedsIdentification')->willReturn(false);

$securityManager = new SecurityManager($this->identificationVerifier, $roleConfiguration);
$securityManager = new SecurityManager(
$this->identificationVerifier,
$roleConfiguration,
new DomainAccessManager());
$this->identificationVerifier->method('isUserIdentified')->willReturn(true);

// act
Expand Down

0 comments on commit 585c81d

Please sign in to comment.