foreign access filters support collaborators and multiple assigned users
This commit is contained in:
@@ -29,10 +29,14 @@
|
||||
|
||||
namespace Espo\Core\Select\AccessControl\Filters;
|
||||
|
||||
use Espo\Core\Acl\AssignmentChecker\Helper;
|
||||
use Espo\Core\Name\Field;
|
||||
use Espo\Core\Select\AccessControl\Filter;
|
||||
use Espo\ORM\Defs;
|
||||
use Espo\ORM\Name\Attribute;
|
||||
use Espo\ORM\Query\Part\Condition as Cond;
|
||||
use Espo\ORM\Query\Part\Expression as Expr;
|
||||
use Espo\ORM\Query\Part\Where\OrGroup;
|
||||
use Espo\ORM\Query\SelectBuilder;
|
||||
use Espo\Core\Utils\Metadata;
|
||||
use Espo\Entities\User;
|
||||
@@ -45,7 +49,8 @@ class ForeignOnlyOwn implements Filter
|
||||
private string $entityType,
|
||||
private User $user,
|
||||
private Metadata $metadata,
|
||||
private Defs $defs
|
||||
private Defs $defs,
|
||||
private Helper $helper,
|
||||
) {}
|
||||
|
||||
public function apply(SelectBuilder $queryBuilder): void
|
||||
@@ -53,7 +58,7 @@ class ForeignOnlyOwn implements Filter
|
||||
$link = $this->metadata->get(['aclDefs', $this->entityType, 'link']);
|
||||
|
||||
if (!$link) {
|
||||
throw new LogicException("No `link` in aclDefs for {$this->entityType}.");
|
||||
throw new LogicException("No `link` in aclDefs for $this->entityType.");
|
||||
}
|
||||
|
||||
$alias = $link . 'Access';
|
||||
@@ -67,18 +72,82 @@ class ForeignOnlyOwn implements Filter
|
||||
|
||||
$foreignEntityDefs = $this->defs->getEntity($foreignEntityType);
|
||||
|
||||
$orBuilder = OrGroup::createBuilder();
|
||||
|
||||
if ($this->helper->hasCollaboratorsField($foreignEntityType)) {
|
||||
$orBuilder->add(
|
||||
Cond::equal(
|
||||
Expr::column("$alias." . Attribute::ID),
|
||||
SelectBuilder::create()
|
||||
->from(User::RELATIONSHIP_ENTITY_COLLABORATOR, 's')
|
||||
->select('s.entityId')
|
||||
->where(
|
||||
Cond::and(
|
||||
Cond::equal(
|
||||
Expr::column('s.entityType'),
|
||||
$foreignEntityType,
|
||||
),
|
||||
Cond::equal(
|
||||
Expr::column('s.userId'),
|
||||
$this->user->getId(),
|
||||
)
|
||||
)
|
||||
)
|
||||
->build()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->helper->hasAssignedUsersField($foreignEntityType)) {
|
||||
$orBuilder->add(
|
||||
Cond::equal(
|
||||
Expr::column("$alias." . Attribute::ID),
|
||||
SelectBuilder::create()
|
||||
->from(User::RELATIONSHIP_ENTITY_USER, 's')
|
||||
->select('s.entityId')
|
||||
->where(
|
||||
Cond::and(
|
||||
Cond::equal(
|
||||
Expr::column('s.entityType'),
|
||||
$foreignEntityType,
|
||||
),
|
||||
Cond::equal(
|
||||
Expr::column('s.userId'),
|
||||
$this->user->getId(),
|
||||
)
|
||||
)
|
||||
)
|
||||
->build()
|
||||
)
|
||||
);
|
||||
|
||||
$queryBuilder->where($orBuilder->build());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($foreignEntityDefs->hasField(Field::ASSIGNED_USER)) {
|
||||
$queryBuilder->where([
|
||||
"{$alias}.assignedUserId" => $this->user->getId(),
|
||||
]);
|
||||
$orBuilder->add(
|
||||
Cond::equal(
|
||||
Expr::column("$alias.assignedUserId"),
|
||||
$this->user->getId()
|
||||
)
|
||||
);
|
||||
|
||||
$queryBuilder->where($orBuilder->build());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($foreignEntityDefs->hasField(Field::CREATED_BY)) {
|
||||
$queryBuilder->where([
|
||||
"{$alias}.createdById" => $this->user->getId(),
|
||||
]);
|
||||
$orBuilder->add(
|
||||
Cond::equal(
|
||||
Expr::column("$alias.createdById"),
|
||||
$this->user->getId()
|
||||
)
|
||||
);
|
||||
|
||||
$queryBuilder->where($orBuilder->build());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -29,13 +29,15 @@
|
||||
|
||||
namespace Espo\Core\Select\AccessControl\Filters;
|
||||
|
||||
use Espo\Core\Acl\AssignmentChecker\Helper;
|
||||
use Espo\Core\Name\Field;
|
||||
use Espo\Core\Select\AccessControl\Filter;
|
||||
use Espo\Entities\Team;
|
||||
use Espo\ORM\Name\Attribute;
|
||||
use Espo\ORM\Query\Part\Condition;
|
||||
use Espo\ORM\Query\Part\Expression;
|
||||
use Espo\ORM\Query\Part\Condition as Cond;
|
||||
use Espo\ORM\Query\Part\Expression as Expr;
|
||||
use Espo\ORM\Query\Part\Where\OrGroup;
|
||||
use Espo\ORM\Query\Part\Where\OrGroupBuilder;
|
||||
use Espo\ORM\Query\SelectBuilder;
|
||||
use Espo\Core\Utils\Metadata;
|
||||
use Espo\ORM\Defs;
|
||||
@@ -52,7 +54,8 @@ class ForeignOnlyTeam implements Filter
|
||||
private string $entityType,
|
||||
private User $user,
|
||||
private Metadata $metadata,
|
||||
private Defs $defs
|
||||
private Defs $defs,
|
||||
private Helper $helper,
|
||||
) {}
|
||||
|
||||
public function apply(SelectBuilder $queryBuilder): void
|
||||
@@ -65,33 +68,149 @@ class ForeignOnlyTeam implements Filter
|
||||
|
||||
$alias = "{$link}Access";
|
||||
|
||||
$ownerAttribute = $this->getOwnerAttribute($link);
|
||||
$foreignEntityType = $this->getForeignEntityType($link);
|
||||
|
||||
if (!$ownerAttribute) {
|
||||
$queryBuilder->leftJoin($link, $alias);
|
||||
|
||||
$orBuilder = OrGroup::createBuilder();
|
||||
|
||||
$this->applyCollaborators($foreignEntityType, $orBuilder, $alias);
|
||||
$this->applyAssignedUsers($foreignEntityType, $orBuilder, $alias);
|
||||
$this->applyAssignedUser($foreignEntityType, $orBuilder, $alias);
|
||||
$this->applyCreatedBy($foreignEntityType, $orBuilder, $alias);
|
||||
$this->applyTeams($foreignEntityType, $orBuilder, $alias);
|
||||
|
||||
if ($orBuilder->build()->getItemCount() === 0) {
|
||||
$queryBuilder->where([Attribute::ID => null]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$teamIdList = $this->user->getTeamIdList();
|
||||
$queryBuilder
|
||||
->where($orBuilder->build())
|
||||
->where(["$alias.id!=" => null]);
|
||||
}
|
||||
|
||||
if (count($teamIdList) === 0) {
|
||||
$queryBuilder
|
||||
->leftJoin($link, $alias)
|
||||
->where(["$alias.$ownerAttribute" => $this->user->getId()]);
|
||||
private function getForeignEntityType(string $link): string
|
||||
{
|
||||
return $this->defs
|
||||
->getEntity($this->entityType)
|
||||
->getRelation($link)
|
||||
->getForeignEntityType();
|
||||
}
|
||||
|
||||
private function applyCollaborators(string $foreignEntityType, OrGroupBuilder $orBuilder, string $alias): void
|
||||
{
|
||||
if (!$this->helper->hasCollaboratorsField($foreignEntityType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$foreignEntityType = $this->getForeignEntityType($link);
|
||||
$orBuilder->add(
|
||||
Cond::equal(
|
||||
Expr::column("$alias." . Attribute::ID),
|
||||
SelectBuilder::create()
|
||||
->from(User::RELATIONSHIP_ENTITY_COLLABORATOR, 's')
|
||||
->select('s.entityId')
|
||||
->where(
|
||||
Cond::and(
|
||||
Cond::equal(
|
||||
Expr::column('s.entityType'),
|
||||
$foreignEntityType,
|
||||
),
|
||||
Cond::equal(
|
||||
Expr::column('s.userId'),
|
||||
$this->user->getId(),
|
||||
)
|
||||
)
|
||||
)
|
||||
->build()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$orGroup = OrGroup::create(
|
||||
Condition::equal(
|
||||
Expression::column("$alias.$ownerAttribute"),
|
||||
private function applyAssignedUsers(
|
||||
string $foreignEntityType,
|
||||
OrGroupBuilder $orBuilder,
|
||||
string $alias,
|
||||
): void {
|
||||
|
||||
if (!$this->helper->hasAssignedUsersField($foreignEntityType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$orBuilder->add(
|
||||
Cond::equal(
|
||||
Expr::column("$alias." . Attribute::ID),
|
||||
SelectBuilder::create()
|
||||
->from(User::RELATIONSHIP_ENTITY_USER, 's')
|
||||
->select('s.entityId')
|
||||
->where(
|
||||
Cond::and(
|
||||
Cond::equal(
|
||||
Expr::column('s.entityType'),
|
||||
$foreignEntityType,
|
||||
),
|
||||
Cond::equal(
|
||||
Expr::column('s.userId'),
|
||||
$this->user->getId(),
|
||||
)
|
||||
)
|
||||
)
|
||||
->build()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function applyAssignedUser(string $foreignEntityType, OrGroupBuilder $orBuilder, string $alias): void
|
||||
{
|
||||
$foreignEntityDefs = $this->defs->getEntity($foreignEntityType);
|
||||
|
||||
if (
|
||||
$this->helper->hasAssignedUsersField($foreignEntityType) ||
|
||||
!$foreignEntityDefs->hasField(Field::ASSIGNED_USER)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$orBuilder->add(
|
||||
Cond::equal(
|
||||
Expr::column("$alias.assignedUserId"),
|
||||
$this->user->getId()
|
||||
),
|
||||
Condition::in(
|
||||
Expression::column("$alias.id"),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function applyCreatedBy(string $foreignEntityType, OrGroupBuilder $orBuilder, string $alias): void
|
||||
{
|
||||
$foreignEntityDefs = $this->defs->getEntity($foreignEntityType);
|
||||
|
||||
if (
|
||||
$this->helper->hasAssignedUsersField($foreignEntityType) ||
|
||||
$foreignEntityDefs->hasField(Field::ASSIGNED_USER) ||
|
||||
!$foreignEntityDefs->hasField(Field::CREATED_BY)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$orBuilder->add(
|
||||
Cond::equal(
|
||||
Expr::column("$alias.createdById"),
|
||||
$this->user->getId()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function applyTeams(string $foreignEntityType, OrGroupBuilder $orBuilder, string $alias): void
|
||||
{
|
||||
$teamIdList = $this->user->getTeamIdList();
|
||||
|
||||
if (count($teamIdList) === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$orBuilder->add(
|
||||
Cond::in(
|
||||
Expr::column("$alias.id"),
|
||||
SelectBuilder::create()
|
||||
->from(Team::RELATIONSHIP_ENTITY_TEAM)
|
||||
->select('entityId')
|
||||
@@ -102,35 +221,5 @@ class ForeignOnlyTeam implements Filter
|
||||
->build()
|
||||
)
|
||||
);
|
||||
|
||||
$queryBuilder
|
||||
->leftJoin($link, $alias)
|
||||
->where($orGroup)
|
||||
->where(["$alias.id!=" => null]);
|
||||
}
|
||||
|
||||
private function getOwnerAttribute(string $link): ?string
|
||||
{
|
||||
$foreignEntityType = $this->getForeignEntityType($link);
|
||||
|
||||
$foreignEntityDefs = $this->defs->getEntity($foreignEntityType);
|
||||
|
||||
if ($foreignEntityDefs->hasField(Field::ASSIGNED_USER)) {
|
||||
return 'assignedUserId';
|
||||
}
|
||||
|
||||
if ($foreignEntityDefs->hasField(Field::CREATED_BY)) {
|
||||
return 'createdById';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getForeignEntityType(string $link): string
|
||||
{
|
||||
return $this->defs
|
||||
->getEntity($this->entityType)
|
||||
->getRelation($link)
|
||||
->getForeignEntityType();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user