public function checkAccess(EventInterface $event)
{
if ($event->hasArgument('skipAccessControl') && $event->getArgument('skipAccessControl') === true) {
return;
}
$request = $event->getRequest();
$aclAdapter = $event->getAccessControl();
$resource = $event->getName();
$publicKey = $request->getPublicKey();
$user = $request->getUser();
$hasAccess = $aclAdapter->hasAccess($publicKey, $resource, $user);
if ($hasAccess) {
return;
}
// If we're asking for info on a public key, and that public key happens to be the one
// used to sign the request, accept this as a valid request and let the user have access
// to the resource. Note that this requires the accessToken listener to be in place -
// if disabled, any user can ask for the access rules for all public keys
if (in_array($resource, $this->ownPublicKeyAllowedResources)) {
$routePubKey = $request->getRoute()->get('publickey');
if ($routePubKey === $publicKey) {
return;
}
}
// If a public key has access to resources within a resource group, allow the
// public key to access the group resource to see which resources it contains
if (in_array($resource, $this->groupLookupResources)) {
$routeGroup = $request->getRoute()->get('group');
$aclList = $aclAdapter->getAccessListForPublicKey($publicKey);
foreach ($aclList as $aclRule) {
if (isset($aclRule['groups']) && in_array($routeGroup, $aclRule['groups'])) {
return;
}
}
}
throw new RuntimeException('Permission denied (public key)', 400);
}