mirror of
https://github.com/espocrm/espocrm.git
synced 2026-06-28 15:06:06 +00:00
acl-check command impr
This commit is contained in:
@@ -29,6 +29,8 @@
|
||||
|
||||
namespace Espo\Core\Console\Commands;
|
||||
|
||||
use Espo\Core\Exceptions\Forbidden;
|
||||
use Espo\Core\Exceptions\NotFound;
|
||||
use Espo\Entities\User;
|
||||
use Espo\ORM\EntityManager;
|
||||
use Espo\Core\AclManager;
|
||||
@@ -51,20 +53,22 @@ class AclCheck implements Command
|
||||
|
||||
public function run(Params $params, IO $io): void
|
||||
{
|
||||
$options = $params->getOptions();
|
||||
|
||||
$userId = $options['userId'] ?? null;
|
||||
$scope = $options['scope'] ?? null;
|
||||
$id = $options['id'] ?? null;
|
||||
|
||||
$userId = $params->getOption('userId');
|
||||
$scope = $params->getOption('scope');
|
||||
$id = $params->getOption('id');
|
||||
/** @var Table::ACTION_*|null $action */
|
||||
$action = $options['action'] ?? null;
|
||||
$action = $params->getOption('action');
|
||||
|
||||
if (!$userId || !$scope || !$id) {
|
||||
$io->setExitStatus(1);
|
||||
|
||||
if (!$userId || !$scope) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($params->hasOption('id') && !$id) {
|
||||
return;
|
||||
}
|
||||
|
||||
$container = $this->container;
|
||||
$entityManager = $this->container->getByClass(EntityManager::class);
|
||||
|
||||
$user = $entityManager->getRDBRepositoryByClass(User::class)->getById($userId);
|
||||
@@ -74,34 +78,22 @@ class AclCheck implements Command
|
||||
}
|
||||
|
||||
if ($user->isPortal()) {
|
||||
$portalIdList = $user->getLinkMultipleIdList('portals');
|
||||
|
||||
foreach ($portalIdList as $portalId) {
|
||||
$application = new PortalApplication($portalId);
|
||||
$containerPortal = $application->getContainer();
|
||||
$entityManager = $containerPortal->getByClass(EntityManager::class);
|
||||
|
||||
$user = $entityManager->getRDBRepositoryByClass(User::class)->getById($userId);
|
||||
|
||||
if (!$user) {
|
||||
return;
|
||||
}
|
||||
|
||||
$result = $this->check($user, $scope, $id, $action, $containerPortal);
|
||||
|
||||
if ($result) {
|
||||
$io->write('true');
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->processPortal(
|
||||
io: $io,
|
||||
userId: $userId,
|
||||
scope: $scope,
|
||||
action: $action,
|
||||
id: $id,
|
||||
user: $user,
|
||||
);
|
||||
}
|
||||
|
||||
if (!$this->check($user, $scope, $id, $action, $this->container)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->check($user, $scope, $id, $action, $container)) {
|
||||
$io->write('true');
|
||||
}
|
||||
$io->setExitStatus(0);
|
||||
$io->write('true');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,11 +103,17 @@ class AclCheck implements Command
|
||||
private function check(
|
||||
User $user,
|
||||
string $scope,
|
||||
string $id,
|
||||
?string $id,
|
||||
?string $action,
|
||||
Container $container
|
||||
): bool {
|
||||
|
||||
if (!$id) {
|
||||
$aclManager = $container->getByClass(AclManager::class);
|
||||
|
||||
return $aclManager->check($user, $scope, $action);
|
||||
}
|
||||
|
||||
$entityManager = $container->getByClass(EntityManager::class);
|
||||
|
||||
$entity = $entityManager->getEntityById($scope, $id);
|
||||
@@ -128,4 +126,48 @@ class AclCheck implements Command
|
||||
|
||||
return $aclManager->check($user, $entity, $action);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Table::ACTION_*|null $action
|
||||
* @noinspection PhpDocSignatureInspection
|
||||
*/
|
||||
private function processPortal(
|
||||
IO $io,
|
||||
string $userId,
|
||||
string $scope,
|
||||
?string $action,
|
||||
?string $id,
|
||||
User $user,
|
||||
): void {
|
||||
|
||||
$portalIds = $user->getLinkMultipleIdList('portals');
|
||||
|
||||
foreach ($portalIds as $portalId) {
|
||||
try {
|
||||
$application = new PortalApplication($portalId);
|
||||
} catch (Forbidden|NotFound) {
|
||||
return;
|
||||
}
|
||||
|
||||
$containerPortal = $application->getContainer();
|
||||
$entityManager = $containerPortal->getByClass(EntityManager::class);
|
||||
|
||||
$user = $entityManager->getRDBRepositoryByClass(User::class)->getById($userId);
|
||||
|
||||
if (!$user) {
|
||||
return;
|
||||
}
|
||||
|
||||
$result = $this->check($user, $scope, $id, $action, $containerPortal);
|
||||
|
||||
if (!$result) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$io->setExitStatus(0);
|
||||
$io->write('true');
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,9 +120,11 @@ class Pusher implements WampServerInterface
|
||||
$checkCommand = $this->getAccessCheckCommandForTopic($conn, $topic);
|
||||
|
||||
if ($checkCommand) {
|
||||
$checkResult = shell_exec($checkCommand);
|
||||
$checkCommand = $checkCommand . ' 2>&1';
|
||||
|
||||
if ($checkResult !== 'true') {
|
||||
$checkResult = exec($checkCommand, $o, $exitCode);
|
||||
|
||||
if ($checkResult !== 'true' || $exitCode !== 0) {
|
||||
if ($this->isDebugMode) {
|
||||
$this->log("$connectionId: check access failed for topic $topicId for user $userId");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user