AuthorizationManager::isAuthCheckExecuted()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 4
nc 4
nop 0
1
<?php
2
3
namespace Jabe\Impl\Persistence\Entity;
4
5
use Jabe\Authorization\{
6
    AuthorizationInterface,
7
    GroupsInterface,
8
    HistoricProcessInstancePermissions,
9
    HistoricTaskPermissions,
10
    MissingAuthorization,
11
    PermissionInterface,
12
    Permissions,
13
    ProcessDefinitionPermissions,
14
    ResourceInterface,
15
    Resources,
16
    TaskPermissions
17
};
18
use Jabe\{
19
    AuthorizationException,
20
    ProcessEngineConfiguration
21
};
22
use Jabe\Impl\{
23
    AbstractQuery,
24
    ActivityStatisticsQueryImpl,
25
    AuthorizationQueryImpl,
26
    DeploymentQueryImpl,
27
    DeploymentStatisticsQueryImpl,
28
    EventSubscriptionQueryImpl,
29
    ExternalTaskQueryImpl,
30
    HistoricActivityInstanceQueryImpl,
31
    //HistoricDecisionInstanceQueryImpl,
32
    HistoricDetailQueryImpl,
33
    HistoricExternalTaskLogQueryImpl,
34
    HistoricIdentityLinkLogQueryImpl,
35
    HistoricIncidentQueryImpl,
36
    HistoricJobLogQueryImpl,
37
    HistoricProcessInstanceQueryImpl,
38
    HistoricTaskInstanceQueryImpl,
39
    HistoricVariableInstanceQueryImpl,
40
    IncidentQueryImpl,
41
    JobDefinitionQueryImpl,
42
    JobQueryImpl,
43
    ProcessDefinitionQueryImpl,
44
    ProcessDefinitionStatisticsQueryImpl,
45
    ProcessEngineLogger,
46
    TaskQueryImpl,
47
    UserOperationLogQueryImpl,
48
    VariableInstanceQueryImpl
49
};
50
use Jabe\Impl\Batch\{
51
    BatchQueryImpl,
52
    BatchStatisticsQueryImpl
53
};
54
use Jabe\Impl\Batch\History\HistoricBatchQueryImpl;
55
use Jabe\Impl\Context\Context;
56
use Jabe\Impl\Db\{
57
    AuthorizationCheck,
58
    CompositePermissionCheck,
59
    DbEntityInterface,
60
    EnginePersistenceLogger,
61
    ListQueryParameterObject,
62
    PermissionCheck,
63
    PermissionCheckBuilder
64
};
65
use Jabe\Impl\Db\EntityManager\Operation\DbOperation;
66
use Jabe\Impl\Identity\Authentication;
67
use Jabe\Impl\Persistence\AbstractManager;
68
use Jabe\Impl\Persistence\Entity\Util\{
69
    AuthManagerUtil,
70
    VariablePermissions
71
};
72
use Jabe\Impl\Util\ResourceTypeUtil;
73
74
class AuthorizationManager extends AbstractManager
75
{
76
    //protected static final EnginePersistenceLogger LOG = ProcessEngineLogger.PERSISTENCE_LOGGER;
77
78
    // Used instead of Collections.emptyList() as mybatis uses reflection to call methods
79
    // like size() which can lead to problems as Collections.EmptyList is a private implementation
80
    protected const EMPTY_LIST = [];
81
82
    /**
83
     * Group ids for which authorizations exist in the database.
84
     * This is initialized once per command by the {@link #filterAuthenticatedGroupIds(List)} method. (Manager
85
     * instances are command scoped).
86
     * It is used to only check authorizations for groups for which authorizations exist. In other words,
87
     * if for a given group no authorization exists in the DB, then auth checks are not performed for this group.
88
     */
89
    protected $availableAuthorizedGroupIds = [];
90
91
    protected $isRevokeAuthCheckUsed = null;
92
93
    public function newPermissionCheckBuilder(): PermissionCheckBuilder
94
    {
95
        return new PermissionCheckBuilder();
96
    }
97
98
    public function createNewAuthorization(int $type): AuthorizationInterface
99
    {
100
        $this->checkAuthorization(Permissions::create(), Resources::authorization(), null);
101
        return new AuthorizationEntity($type);
102
    }
103
104
    public function insert(DbEntityInterface $authorization): void
105
    {
106
        $this->checkAuthorization(Permissions::create(), Resources::authorization(), null);
107
        $this->getDbEntityManager()->insert($authorization);
108
    }
109
110
    public function selectAuthorizationByQueryCriteria(AuthorizationQueryImpl $authorizationQuery): array
111
    {
112
        $this->configureQuery($authorizationQuery, Resources::authorization());
113
        return $this->getDbEntityManager()->selectList("selectAuthorizationByQueryCriteria", $authorizationQuery);
114
    }
115
116
    public function selectAuthorizationCountByQueryCriteria(AuthorizationQueryImpl $authorizationQuery): int
117
    {
118
        $this->configureQuery($authorizationQuery, Resources::authorization());
119
        return $this->getDbEntityManager()->selectOne("selectAuthorizationCountByQueryCriteria", $authorizationQuery);
120
    }
121
122
    public function findAuthorizationByUserIdAndResourceId(int $type, string $userId, ResourceInterface $resource, string $resourceId): ?AuthorizationEntity
123
    {
124
        return $this->findAuthorization($type, $userId, null, $resource, $resourceId);
125
    }
126
127
    public function findAuthorizationByGroupIdAndResourceId(int $type, string $groupId, ResourceInterface $resource, string $resourceId): ?AuthorizationEntity
128
    {
129
        return $this->findAuthorization($type, null, $groupId, $resource, $resourceId);
130
    }
131
132
    public function findAuthorization(int $type, ?string $userId, ?string $groupId, ?ResourceInterface $resource, string $resourceId): ?AuthorizationEntity
133
    {
134
        $params = [];
135
136
        $params["type"] = $type;
137
        $params["userId"] = $userId;
138
        $params["groupId"] = $groupId;
139
        $params["resourceId"] = $resourceId;
140
141
        if ($resource !== null) {
142
            $params["resourceType"] = $resource->resourceType();
143
        }
144
145
        return $this->getDbEntityManager()->selectOne("selectAuthorizationByParameters", $params);
146
    }
147
148
    public function update(AuthorizationEntity $authorization): void
149
    {
150
        $this->checkAuthorization(Permissions::update(), Resources::authorization(), $authorization->getId());
151
        $this->getDbEntityManager()->merge($authorization);
152
    }
153
154
    public function delete(DbEntityInterface $authorization): void
155
    {
156
        $this->checkAuthorization(Permissions::delete(), Resources::authorization(), $authorization->getId());
157
        $this->deleteAuthorizationsByResourceId(Resources::authorization(), $authorization->getId());
158
        parent::delete($authorization);
159
    }
160
161
    // authorization checks ///////////////////////////////////////////
162
163
    public function checkAuthorization($permission, ?ResourceInterface $resource = null, ?string $resourceId = null): void
164
    {
165
        if ($permission instanceof CompositePermissionCheck) {
166
            if ($this->isAuthCheckExecuted()) {
167
                $currentAuthentication = $this->getCurrentAuthentication();
168
                $userId = $currentAuthentication->getUserId();
169
170
                $isAuthorized = $this->isAuthorized(null, [], $permission);
0 ignored issues
show
Unused Code introduced by
The assignment to $isAuthorized is dead and can be removed.
Loading history...
171
                if (!$this->isAuthorized) {
0 ignored issues
show
Bug Best Practice introduced by
The property isAuthorized does not exist on Jabe\Impl\Persistence\Entity\AuthorizationManager. Did you maybe forget to declare it?
Loading history...
172
                    $missingAuthorizations = [];
173
174
                    foreach ($permission->getAllPermissionChecks() as $check) {
175
                        $missingAuthorizations[] = new MissingAuthorization(
176
                            $check->getPermission()->getName(),
177
                            $check->getResource()->resourceName(),
178
                            $check->getResourceId()
179
                        );
180
                    }
181
182
                    throw new AuthorizationException($userId, $missingAuthorizations);
0 ignored issues
show
Unused Code introduced by
The call to Jabe\AuthorizationException::__construct() has too many arguments starting with $missingAuthorizations. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

182
                    throw /** @scrutinizer ignore-call */ new AuthorizationException($userId, $missingAuthorizations);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
183
                }
184
            }
185
        } else {
186
            if ($this->isAuthCheckExecuted()) {
187
                $currentAuthentication = $this->getCurrentAuthentication();
188
                $isAuthorized = $this->isAuthorized($currentAuthentication->getUserId(), $currentAuthentication->getGroupIds(), $permission, $resource, $resourceId);
0 ignored issues
show
Bug introduced by
It seems like $currentAuthentication->getGroupIds() can also be of type null; however, parameter $groupIds of Jabe\Impl\Persistence\En...Manager::isAuthorized() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

188
                $isAuthorized = $this->isAuthorized($currentAuthentication->getUserId(), /** @scrutinizer ignore-type */ $currentAuthentication->getGroupIds(), $permission, $resource, $resourceId);
Loading history...
189
                if (!$isAuthorized) {
190
                    throw new AuthorizationException(
191
                        $currentAuthentication->getUserId(),
192
                        $permission->getName(),
193
                        $resource->resourceName(),
0 ignored issues
show
Bug introduced by
The method resourceName() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

193
                        $resource->/** @scrutinizer ignore-call */ 
194
                                   resourceName(),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
194
                        $resourceId
195
                    );
196
                }
197
            }
198
        }
199
    }
200
201
    public function isAuthorized(
202
        ?string $userId,
203
        array $groupIds,
204
        $permission,
205
        ?ResourceInterface $resource = null,
206
        ?string $resourceId = null
207
    ): bool {
208
        if ($userId === null) {
209
            $currentAuthentication = $this->getCurrentAuthentication();
210
            if ($currentAuthentication === null) {
211
                return true;
212
            }
213
            $userId = $currentAuthentication->getUserId();
214
            $groupIds = $currentAuthentication->getGroupIds();
215
        }
216
        if ($permission instanceof PermissionInterface) {
217
            if (!$this->isPermissionDisabled($permission)) {
218
                $permCheck = new PermissionCheck();
219
                $permCheck->setPermission($permission);
220
                $permCheck->setResource($resource);
0 ignored issues
show
Bug introduced by
It seems like $resource can also be of type null; however, parameter $resource of Jabe\Impl\Db\PermissionCheck::setResource() does only seem to accept Jabe\Authorization\ResourceInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

220
                $permCheck->setResource(/** @scrutinizer ignore-type */ $resource);
Loading history...
221
                $permCheck->setResourceId($resourceId);
0 ignored issues
show
Bug introduced by
It seems like $resourceId can also be of type null; however, parameter $resourceId of Jabe\Impl\Db\PermissionCheck::setResourceId() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

221
                $permCheck->setResourceId(/** @scrutinizer ignore-type */ $resourceId);
Loading history...
222
223
                return $this->isAuthorized($userId, $groupIds, $permCheck);
0 ignored issues
show
Bug introduced by
It seems like $groupIds can also be of type null; however, parameter $groupIds of Jabe\Impl\Persistence\En...Manager::isAuthorized() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

223
                return $this->isAuthorized($userId, /** @scrutinizer ignore-type */ $groupIds, $permCheck);
Loading history...
224
            } else {
225
                return true;
226
            }
227
        } elseif ($permission instanceof PermissionCheck) {
228
            if (!$this->isAuthorizationEnabled()) {
229
                return true;
230
            }
231
232
            if (!$this->isResourceValidForPermission($permission)) {
233
                //throw LOG.invalidResourceForPermission(permissionCheck.getResource().resourceName(), permissionCheck.getPermission().getName());
234
            }
235
236
            $filteredGroupIds = $this->filterAuthenticatedGroupIds($groupIds);
237
238
            $isRevokeAuthorizationCheckEnabled = $this->isRevokeAuthCheckEnabled($userId, $groupIds);
0 ignored issues
show
Bug introduced by
It seems like $groupIds can also be of type null; however, parameter $groupIds of Jabe\Impl\Persistence\En...evokeAuthCheckEnabled() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

238
            $isRevokeAuthorizationCheckEnabled = $this->isRevokeAuthCheckEnabled($userId, /** @scrutinizer ignore-type */ $groupIds);
Loading history...
239
            $compositePermissionCheck = $this->createCompositePermissionCheck($permission);
240
            $authCheck = new AuthorizationCheck($userId, $filteredGroupIds, $compositePermissionCheck, $isRevokeAuthorizationCheckEnabled);
241
            return $this->getDbEntityManager()->selectBoolean("isUserAuthorizedForResource", $authCheck);
242
        } elseif ($permission instanceof CompositePermissionCheck) {
243
            foreach ($permission->getAllPermissionChecks() as $permissionCheck) {
244
                if (!$this->isResourceValidForPermission($permissionCheck)) {
245
                    //throw LOG.invalidResourceForPermission(permissionCheck->getResource().resourceName(), permissionCheck->getPermission()->getName());
246
                }
247
            }
248
            $filteredGroupIds = $this->filterAuthenticatedGroupIds($groupIds);
249
            $isRevokeAuthorizationCheckEnabled = $this->isRevokeAuthCheckEnabled($userId, $groupIds);
250
            $authCheck = new AuthorizationCheck($userId, $filteredGroupIds, $permission, $isRevokeAuthorizationCheckEnabled);
251
            return $this->getDbEntityManager()->selectBoolean("isUserAuthorizedForResource", $authCheck);
252
        }
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return boolean. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
253
    }
254
255
    protected function isRevokeAuthCheckEnabled(string $userId, array $groupIds): bool
256
    {
257
        $isRevokeAuthCheckEnabled = $this->isRevokeAuthCheckUsed;
258
259
        if ($this->isRevokeAuthCheckEnabled === null) {
0 ignored issues
show
Bug introduced by
The property isRevokeAuthCheckEnabled does not exist on Jabe\Impl\Persistence\Entity\AuthorizationManager. Did you mean isRevokeAuthCheckUsed?
Loading history...
260
            $configuredMode = Context::getProcessEngineConfiguration()->getAuthorizationCheckRevokes();
261
            if ($configuredMode !== null) {
0 ignored issues
show
introduced by
The condition $configuredMode !== null is always true.
Loading history...
262
                $configuredMode = strtolower($configuredMode);
263
            }
264
            if (ProcessEngineConfiguration::AUTHORIZATION_CHECK_REVOKE_ALWAYS == $configuredMode) {
265
                $isRevokeAuthCheckEnabled = true;
266
            } elseif (ProcessEngineConfiguration::AUTHORIZATION_CHECK_REVOKE_NEVER == $configuredMode) {
267
                $isRevokeAuthCheckEnabled = false;
268
            } else {
269
                $params = [];
270
                $params["userId"] = $userId;
271
                $params["authGroupIds"] = $this->filterAuthenticatedGroupIds($groupIds);
272
                $isRevokeAuthCheckEnabled = $this->getDbEntityManager()->selectBoolean("selectRevokeAuthorization", $params);
273
            }
274
            $this->isRevokeAuthCheckUsed = $isRevokeAuthCheckEnabled;
275
        }
276
277
        return $isRevokeAuthCheckEnabled;
278
    }
279
280
    protected function createCompositePermissionCheck(PermissionCheck $permissionCheck): CompositePermissionCheck
281
    {
282
        $compositePermissionCheck = new CompositePermissionCheck();
283
        $compositePermissionCheck->setAtomicChecks([$permissionCheck]);
284
        return $compositePermissionCheck;
285
    }
286
287
    protected function isResourceValidForPermission(PermissionCheck $permissionCheck): bool
288
    {
289
        $permissionResources = $permissionCheck->getPermission()->getTypes();
290
        $givenResource = $permissionCheck->getResource();
291
        return ResourceTypeUtil::resourceIsContainedInArray($givenResource->resourceType(), $permissionResources);
292
    }
293
294
    public function validateResourceCompatibility(AuthorizationEntity $authorization): void
295
    {
296
        $resourceType = $authorization->getResourceType();
297
        $permissionSet = $authorization->getCachedPermissions();
298
299
        foreach ($permissionSet as $permission) {
300
            if (!ResourceTypeUtil::resourceIsContainedInArray($resourceType, $permission->getTypes())) {
301
                //throw LOG.invalidResourceForAuthorization(resourceType, permission->getName());
302
            }
303
        }
304
    }
305
306
    // authorization checks on queries ////////////////////////////////
307
308
    public function configureQueryHistoricFinishedInstanceReport(ListQueryParameterObject $query, ResourceInterface $resource): void
309
    {
310
        $this->configureQuery($query);
311
312
        $compositePermissionCheck = (new PermissionCheckBuilder())
313
            ->conjunctive()
314
            ->atomicCheck($resource, "RES.KEY_", Permissions::read())
315
            ->atomicCheck($resource, "RES.KEY_", Permissions::readHistory())
316
            ->build();
317
318
        $query->getAuthCheck()->setPermissionChecks($compositePermissionCheck);
319
    }
320
321
    public function enableQueryAuthCheck(AuthorizationCheck $authCheck): void
322
    {
323
        $authGroupIds = $authCheck->getAuthGroupIds();
324
        $authUserId = $authCheck->getAuthUserId();
325
326
        $authCheck->setAuthorizationCheckEnabled(true);
327
        $authCheck->setAuthGroupIds($this->filterAuthenticatedGroupIds($authGroupIds));
328
        $authCheck->setRevokeAuthorizationCheckEnabled($this->isRevokeAuthCheckEnabled($authUserId, $authGroupIds));
329
    }
330
331
    public function configureQuery(
332
        $query,
333
        ?ResourceInterface $resource = null,
334
        ?string $queryParam = "RES.ID_",
335
        ?PermissionInterface $permission = null
336
    ): void {
337
        if ($query instanceof AbstractQuery) {
338
            if ($resource === null) {
339
                $authCheck = $query->getAuthCheck();
340
                $authCheck->clearPermissionChecks();
0 ignored issues
show
Bug introduced by
The method clearPermissionChecks() does not exist on Jabe\Impl\Db\AuthorizationCheck. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

340
                $authCheck->/** @scrutinizer ignore-call */ 
341
                            clearPermissionChecks();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
341
342
                if ($this->isAuthCheckExecuted()) {
343
                    $currentAuthentication = $this->getCurrentAuthentication();
344
                    $authCheck->setAuthUserId($currentAuthentication->getUserId());
345
                    $authCheck->setAuthGroupIds($currentAuthentication->getGroupIds());
0 ignored issues
show
Bug introduced by
It seems like $currentAuthentication->getGroupIds() can also be of type null; however, parameter $authGroupIds of Jabe\Impl\Db\AuthorizationCheck::setAuthGroupIds() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

345
                    $authCheck->setAuthGroupIds(/** @scrutinizer ignore-type */ $currentAuthentication->getGroupIds());
Loading history...
346
                    $this->enableQueryAuthCheck($authCheck);
347
                } else {
348
                    $authCheck->setAuthorizationCheckEnabled(false);
349
                    $authCheck->setAuthUserId(null);
0 ignored issues
show
Bug introduced by
null of type null is incompatible with the type string expected by parameter $authUserId of Jabe\Impl\Db\AuthorizationCheck::setAuthUserId(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

349
                    $authCheck->setAuthUserId(/** @scrutinizer ignore-type */ null);
Loading history...
350
                    $authCheck->setAuthGroupIds(null);
351
                }
352
            } else {
353
                $permission = $permission ?? Permissions::read();
354
                $this->configureQuery($query);
355
                $permissionCheck = (new PermissionCheckBuilder())
356
                    ->atomicCheck($resource, $queryParam, $permission)
357
                    ->build();
358
                $this->addPermissionCheck($query->getAuthCheck(), $permissionCheck);
359
            }
360
        } elseif ($query instanceof ListQueryParameterObject) {
361
            $authCheck = $query->getAuthCheck();
362
            $authCheck->clearPermissionChecks();
363
364
            if ($this->isAuthCheckExecuted()) {
365
                $currentAuthentication = $this->getCurrentAuthentication();
366
                $authCheck->setAuthUserId($currentAuthentication->getUserId());
367
                $authCheck->setAuthGroupIds($currentAuthentication->getGroupIds());
368
                $this->enableQueryAuthCheck($authCheck);
369
            } else {
370
                $authCheck->setAuthorizationCheckEnabled(false);
371
                $authCheck->setAuthUserId(null);
372
                $authCheck->setAuthGroupIds(null);
373
            }
374
        }
375
    }
376
377
    public function isPermissionDisabled(PermissionInterface $permission): bool
378
    {
379
        $disabledPermissions = $this->getCommandContext()->getProcessEngineConfiguration()->getDisabledPermissions();
380
        if (!empty($disabledPermissions)) {
381
            foreach ($disabledPermissions as $disabledPermission) {
382
                if ($permission->getName() == $disabledPermission) {
383
                    return true;
384
                }
385
            }
386
        }
387
        return false;
388
    }
389
390
    protected function addPermissionCheck(AuthorizationCheck $authCheck, CompositePermissionCheck $compositeCheck): void
391
    {
392
        $commandContext = $this->getCommandContext();
393
        if ($this->isAuthorizationEnabled() && $this->getCurrentAuthentication() !== null && $commandContext->isAuthorizationCheckEnabled()) {
394
            $authCheck->setPermissionChecks($compositeCheck);
395
        }
396
    }
397
398
    // delete authorizations //////////////////////////////////////////////////
399
400
    public function deleteAuthorizationsByResourceIds(
401
        ResourceInterface $resource,
402
        ?array $resourceIds = []
403
    ): void {
404
405
        if (empty($resourceIds)) {
406
            throw new \Exception("Resource ids cannot be empty");
407
        }
408
409
        foreach ($resourceIds as $resourceId) {
410
            $this->deleteAuthorizationsByResourceId($resource, $resourceId);
411
        }
412
    }
413
414
    public function deleteAuthorizationsByResourceId(ResourceInterface $resource, ?string $resourceId): void
415
    {
416
        if (empty($resourceId)) {
417
            throw new \Exception("Resource id cannot be null");
418
        }
419
420
        if ($this->isAuthorizationEnabled()) {
421
            $deleteParams = [];
422
            $deleteParams["resourceType"] = $resource->resourceType();
423
            $deleteParams["resourceId"] = $resourceId;
424
            $this->getDbEntityManager()->delete(AuthorizationEntity::class, "deleteAuthorizationsForResourceId", $deleteParams);
425
        }
426
    }
427
428
    public function deleteAuthorizationsByResourceIdAndUserId(ResourceInterface $resource, ?string $resourceId, string $userId): void
429
    {
430
        if (empty($resourceId)) {
431
            throw new \Exception("Resource id cannot be null");
432
        }
433
434
        if ($this->isAuthorizationEnabled()) {
435
            $deleteParams = [];
436
            $deleteParams["resourceType"] = $resource->resourceType();
437
            $deleteParams["resourceId"] = $resourceId;
438
            $deleteParams["userId"] = $userId;
439
            $this->getDbEntityManager()->delete(AuthorizationEntity::class, "deleteAuthorizationsForResourceId", $deleteParams);
440
        }
441
    }
442
443
    public function deleteAuthorizationsByResourceIdAndGroupId(ResourceInterface $resource, ?string $resourceId, string $groupId): void
444
    {
445
        if (empty($resourceId)) {
446
            throw new \Exception("Resource id cannot be null");
447
        }
448
449
        if ($this->isAuthorizationEnabled()) {
450
            $deleteParams = [];
451
            $deleteParams["resourceType"] = $resource->resourceType();
452
            $deleteParams["resourceId"] = $resourceId;
453
            $deleteParams["groupId"] = $groupId;
454
            $this->getDbEntityManager()->delete(AuthorizationEntity::class, "deleteAuthorizationsForResourceId", $deleteParams);
455
        }
456
    }
457
458
    // predefined authorization checks
459
460
    /**
461
     * Checks if the current authentication contains the group
462
     * Groups#ADMIN. The check is ignored if the authorization is
463
     * disabled or no authentication exists.
464
     *
465
     * @throws AuthorizationException
466
     */
467
    public function checkAdmin(): void
468
    {
469
        $currentAuthentication = $this->getCurrentAuthentication();
470
        $commandContext = Context::getCommandContext();
471
472
        if (
473
            $this->isAuthorizationEnabled() && $commandContext->isAuthorizationCheckEnabled()
474
            && $currentAuthentication !== null  && !$this->isAdmin($currentAuthentication)
475
        ) {
476
            //throw LOG.requiredCamundaAdminException();
477
        }
478
    }
479
480
    /**
481
     * @param authentication
482
     *          authentication to check, cannot be <code>null</code>
483
     * @return bool true if the given authentication contains the group
484
     *         Groups#CAMUNDA_ADMIN or the user
485
     */
486
    public function isAdmin(Authentication $authentication): bool
487
    {
488
        $groupIds = $authentication->getGroupIds();
489
        if (!empty($groupIds)) {
490
            $commandContext = Context::getCommandContext();
491
            $adminGroups = $commandContext->getProcessEngineConfiguration()->getAdminGroups();
0 ignored issues
show
Bug introduced by
The method getAdminGroups() does not exist on Jabe\Impl\Cfg\ProcessEngineConfigurationImpl. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

491
            $adminGroups = $commandContext->getProcessEngineConfiguration()->/** @scrutinizer ignore-call */ getAdminGroups();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
492
            foreach ($adminGroups as $adminGroup) {
493
                if (in_array($adminGroup, $groupIds)) {
494
                    return true;
495
                }
496
            }
497
        }
498
499
        $userId = $authentication->getUserId();
500
        if ($userId !== null) {
0 ignored issues
show
introduced by
The condition $userId !== null is always true.
Loading history...
501
            $commandContext = Context::getCommandContext();
502
            $adminUsers = $commandContext->getProcessEngineConfiguration()->getAdminUsers();
0 ignored issues
show
Bug introduced by
The method getAdminUsers() does not exist on Jabe\Impl\Cfg\ProcessEngineConfigurationImpl. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

502
            $adminUsers = $commandContext->getProcessEngineConfiguration()->/** @scrutinizer ignore-call */ getAdminUsers();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
503
            return !empty($adminUsers) && in_array($userId, $adminUsers);
504
        }
505
506
        return false;
507
    }
508
509
    /* QUERIES */
510
511
    // deployment query ////////////////////////////////////////
512
513
    public function configureDeploymentQuery(DeploymentQueryImpl $query): void
514
    {
515
        $this->configureQuery($query, Resources::deployment());
516
    }
517
518
    // process definition query ////////////////////////////////
519
520
    public function configureProcessDefinitionQuery(ProcessDefinitionQueryImpl $query): void
521
    {
522
        $this->configureQuery($query, Resources::processDefinition(), "RES.KEY_");
523
524
        if ($query->isStartablePermissionCheck()) {
525
            $authorizationCheck = $query->getAuthCheck();
526
527
            if (!$authorizationCheck->isRevokeAuthorizationCheckEnabled()) {
528
                $permCheck = (new PermissionCheckBuilder())
529
                    ->atomicCheck(Resources::processDefinition(), "RES.KEY_", Permissions::createInstance())
530
                    ->build();
531
532
                $query->addProcessDefinitionCreatePermissionCheck($permCheck);
533
            } else {
534
                $permissionCheck = (new PermissionCheckBuilder())
535
                    ->conjunctive()
536
                    ->atomicCheck(Resources::processDefinition(), "RES.KEY_", Permissions::read())
537
                    ->atomicCheck(Resources::processDefinition(), "RES.KEY_", Permissions::createInstance())
538
                    ->build();
539
                $this->addPermissionCheck($authorizationCheck, $permissionCheck);
540
            }
541
        }
542
    }
543
544
    // execution/process instance query ////////////////////////
545
546
    public function configureExecutionQuery(AbstractQuery $query): void
547
    {
548
        $this->configureQuery($query);
549
        $permissionCheck = (new PermissionCheckBuilder())
550
            ->disjunctive()
551
            ->atomicCheck(Resources::processInstance(), "RES.PROC_INST_ID_", Permissions::read())
552
            ->atomicCheck(Resources::processDefinition(), "P.KEY_", Permissions::readInstance())
553
            ->build();
554
        $this->addPermissionCheck($query->getAuthCheck(), $permissionCheck);
555
    }
556
557
    // task query //////////////////////////////////////////////
558
559
    public function configureTaskQuery(TaskQueryImpl $query): void
560
    {
561
        $this->configureQuery($query);
562
563
        if ($query->getAuthCheck()->isAuthorizationCheckEnabled()) {
564
            // necessary authorization check when the task is part of
565
            // a running process instance
566
567
            $permissionCheck = (new PermissionCheckBuilder())
568
                    ->disjunctive()
569
                    ->atomicCheck(Resources::task(), "RES.ID_", Permissions::read())
570
                    ->atomicCheck(Resources::processDefinition(), "D.KEY_", Permissions::readTask())
571
                    ->build();
572
            $this->addPermissionCheck($query->getAuthCheck(), $permissionCheck);
573
        }
574
    }
575
576
    // event subscription query //////////////////////////////
577
578
    public function configureEventSubscriptionQuery(EventSubscriptionQueryImpl $query): void
579
    {
580
        $this->configureQuery($query);
581
        $permissionCheck = (new PermissionCheckBuilder())
582
                ->disjunctive()
583
                ->atomicCheck(Resources::processInstance(), "RES.PROC_INST_ID_", Permissions::read())
584
                ->atomicCheck(Resources::processDefinition(), "PROCDEF.KEY_", Permissions::readInstance())
585
                ->build();
586
        $this->addPermissionCheck($query->getAuthCheck(), $permissionCheck);
587
    }
588
589
    public function configureConditionalEventSubscriptionQuery(ListQueryParameterObject $query): void
590
    {
591
        $this->configureQuery($query);
592
        $permissionCheck = (new PermissionCheckBuilder())
593
            ->atomicCheck(Resources::processDefinition(), "P.KEY_", Permissions::read())
594
            ->build();
595
        $this->addPermissionCheck($query->getAuthCheck(), $permissionCheck);
596
    }
597
598
    // incident query ///////////////////////////////////////
599
600
    public function configureIncidentQuery(IncidentQueryImpl $query): void
601
    {
602
        $this->configureQuery($query);
603
        $permissionCheck = (new PermissionCheckBuilder())
604
                ->disjunctive()
605
                ->atomicCheck(Resources::processInstance(), "RES.PROC_INST_ID_", Permissions::read())
606
                ->atomicCheck(Resources::processDefinition(), "PROCDEF.KEY_", Permissions::readInstance())
607
                ->build();
608
        $this->addPermissionCheck($query->getAuthCheck(), $permissionCheck);
609
    }
610
611
    // variable instance query /////////////////////////////
612
613
    protected function configureVariableInstanceQuery(VariableInstanceQueryImpl $query): void
614
    {
615
        $this->configureQuery($query);
616
617
        if ($query->getAuthCheck()->isAuthorizationCheckEnabled()) {
618
            $permissionCheck = null;
619
            if ($this->isEnsureSpecificVariablePermission()) {
620
                $permissionCheck = (new PermissionCheckBuilder())
621
                    ->disjunctive()
622
                    ->atomicCheck(Resources::processDefinition(), "PROCDEF.KEY_", ProcessDefinitionPermissions::readInstanceVariable())
623
                    ->atomicCheck(Resources::task(), "RES.TASK_ID_", TaskPermissions::readVariable())
624
                    ->build();
625
            } else {
626
                $permissionCheck = (new PermissionCheckBuilder())
627
                    ->disjunctive()
628
                    ->atomicCheck(Resources::processInstance(), "RES.PROC_INST_ID_", Permissions::read())
629
                    ->atomicCheck(Resources::processDefinition(), "PROCDEF.KEY_", Permissions::readInstance())
630
                    ->atomicCheck(Resources::task(), "RES.TASK_ID_", Permissions::read())
631
                    ->build();
632
            }
633
            $this->addPermissionCheck($query->getAuthCheck(), $permissionCheck);
634
        }
635
    }
636
637
    // job definition query ////////////////////////////////////////////////
638
639
    public function configureJobDefinitionQuery(JobDefinitionQueryImpl $query): void
640
    {
641
        $this->configureQuery($query, Resources::processDefinition(), "RES.PROC_DEF_KEY_");
642
    }
643
644
    // job query //////////////////////////////////////////////////////////
645
646
    public function configureJobQuery(JobQueryImpl $query): void
647
    {
648
        $this->configureQuery($query);
649
        $permissionCheck = (new PermissionCheckBuilder())
650
            ->disjunctive()
651
            ->atomicCheck(Resources::processInstance(), "RES.PROCESS_INSTANCE_ID_", Permissions::read())
652
            ->atomicCheck(Resources::processDefinition(), "RES.PROCESS_DEF_KEY_", Permissions::readInstance())
653
            ->build();
654
        $this->addPermissionCheck($query->getAuthCheck(), $permissionCheck);
655
    }
656
657
    /* HISTORY */
658
659
    // historic process instance query ///////////////////////////////////
660
661
    public function configureHistoricProcessInstanceQuery(HistoricProcessInstanceQueryImpl $query): void
662
    {
663
        $authCheck = $query->getAuthCheck();
664
665
        $isHistoricInstancePermissionsEnabled = $this->isHistoricInstancePermissionsEnabled();
666
        $authCheck->setHistoricInstancePermissionsEnabled($isHistoricInstancePermissionsEnabled);
667
668
        if (!$isHistoricInstancePermissionsEnabled) {
669
            $this->configureQuery($query, Resources::processDefinition(), "SELF.PROC_DEF_KEY_", Permissions::readHistory());
670
        } else {
671
            $this->configureQuery($query);
672
673
            $permissionCheck = (new PermissionCheckBuilder())
674
                ->disjunctive()
675
                ->atomicCheck(Resources::processDefinition(), "SELF.PROC_DEF_KEY_", Permissions::readHistory())
676
                ->atomicCheck(Resources::historicProcessInstance(), "SELF.ID_", HistoricProcessInstancePermissions::read())
677
                ->build();
678
679
            $this->addPermissionCheck($authCheck, $permissionCheck);
680
        }
681
    }
682
683
    // historic activity instance query /////////////////////////////////
684
685
    public function configureHistoricActivityInstanceQuery(HistoricActivityInstanceQueryImpl $query): void
686
    {
687
        $authCheck = $query->getAuthCheck();
688
689
        $isHistoricInstancePermissionsEnabled = $this->isHistoricInstancePermissionsEnabled();
690
        $authCheck->setHistoricInstancePermissionsEnabled($isHistoricInstancePermissionsEnabled);
691
692
        if (!$isHistoricInstancePermissionsEnabled) {
693
            $this->configureQuery($query, Resources::processDefinition(), "RES.PROC_DEF_KEY_", Permissions::readHistory());
694
        } else {
695
            $this->configureQuery($query);
696
697
            $permissionCheck = (new PermissionCheckBuilder())
698
                ->disjunctive()
699
                ->atomicCheck(Resources::processDefinition(), "RES.PROC_DEF_KEY_", Permissions::readHistory())
700
                ->atomicCheck(
701
                    Resources::historicProcessInstance(),
702
                    "RES.PROC_INST_ID_",
703
                    HistoricProcessInstancePermissions::read()
704
                )
705
                ->build();
706
            $this->addPermissionCheck($authCheck, $permissionCheck);
707
        }
708
    }
709
710
    // historic task instance query ////////////////////////////////////
711
712
    public function configureHistoricTaskInstanceQuery(HistoricTaskInstanceQueryImpl $query): void
713
    {
714
        $authCheck = $query->getAuthCheck();
715
716
        $isHistoricInstancePermissionsEnabled = $this->isHistoricInstancePermissionsEnabled();
717
        $authCheck->setHistoricInstancePermissionsEnabled($isHistoricInstancePermissionsEnabled);
718
719
        if (!$isHistoricInstancePermissionsEnabled) {
720
            $this->configureQuery($query, Resources::processDefinition(), "RES.PROC_DEF_KEY_", Permissions::readHistory());
721
        } else {
722
            $this->configureQuery($query);
723
724
            $permissionCheck = (new PermissionCheckBuilder())
725
                ->disjunctive()
726
                ->atomicCheck(Resources::processDefinition(), "RES.PROC_DEF_KEY_", Permissions::readHistory())
727
                ->atomicCheck(
728
                    Resources::historicProcessInstance(),
729
                    "RES.PROC_INST_ID_",
730
                    HistoricProcessInstancePermissions::read()
731
                )
732
                ->atomicCheck(Resources::historicTask(), "RES.ID_", HistoricTaskPermissions::read())
733
                ->build();
734
735
            $this->addPermissionCheck($query->getAuthCheck(), $permissionCheck);
736
        }
737
    }
738
739
    // historic variable instance query ////////////////////////////////
740
741
    public function configureHistoricVariableInstanceQuery(HistoricVariableInstanceQueryImpl $query): void
742
    {
743
        $this->configureHistoricVariableAndDetailQuery($query);
744
    }
745
746
    // historic detail query ////////////////////////////////
747
748
    public function configureHistoricDetailQuery(HistoricDetailQueryImpl $query): void
749
    {
750
        $this->configureHistoricVariableAndDetailQuery($query);
751
    }
752
753
    protected function configureHistoricVariableAndDetailQuery(AbstractQuery $query): void
754
    {
755
        $ensureSpecificVariablePermission = $this->isEnsureSpecificVariablePermission();
756
757
        $variablePermissions =
758
            AuthManagerUtil::getVariablePermissions($ensureSpecificVariablePermission);
759
760
        $processDefinitionPermission = $variablePermissions->getProcessDefinitionPermission();
761
762
        $authCheck = $query->getAuthCheck();
763
764
        $isHistoricInstancePermissionsEnabled = $this->isHistoricInstancePermissionsEnabled();
765
        $authCheck->setHistoricInstancePermissionsEnabled($isHistoricInstancePermissionsEnabled);
766
767
        if (!$isHistoricInstancePermissionsEnabled) {
768
            $this->configureQuery($query, Resources::processDefinition(), "RES.PROC_DEF_KEY_", $processDefinitionPermission);
769
        } else {
770
            $this->configureQuery($query);
771
772
            $historicTaskPermission = $variablePermissions->getHistoricTaskPermission();
773
774
            $permissionCheck = (new PermissionCheckBuilder())
775
                ->disjunctive()
776
                ->atomicCheck(Resources::processDefinition(), "RES.PROC_DEF_KEY_", $processDefinitionPermission)
777
                ->atomicCheck(
778
                    Resources::historicProcessInstance(),
779
                    "RES.PROC_INST_ID_",
780
                    HistoricProcessInstancePermissions::read()
781
                )
782
                ->atomicCheck(Resources::historicTask(), "TI.ID_", $historicTaskPermission)
783
                ->build();
784
785
            $this->addPermissionCheck($authCheck, $permissionCheck);
786
        }
787
    }
788
789
    // historic job log query ////////////////////////////////
790
791
    public function configureHistoricJobLogQuery(HistoricJobLogQueryImpl $query): void
792
    {
793
        $authCheck = $query->getAuthCheck();
794
795
        $isHistoricInstancePermissionsEnabled = $this->isHistoricInstancePermissionsEnabled();
796
        $authCheck->setHistoricInstancePermissionsEnabled($isHistoricInstancePermissionsEnabled);
797
798
        if (!$isHistoricInstancePermissionsEnabled) {
799
            $this->configureQuery($query, Resources::processDefinition(), "RES.PROCESS_DEF_KEY_", Permissions::readHistory());
800
        } else {
801
            $this->configureQuery($query);
802
            $permissionCheck = (new PermissionCheckBuilder())
803
                ->disjunctive()
804
                ->atomicCheck(Resources::processDefinition(), "RES.PROCESS_DEF_KEY_", Permissions::readHistory())
805
                ->atomicCheck(
806
                    Resources::historicProcessInstance(),
807
                    "RES.PROCESS_INSTANCE_ID_",
808
                    HistoricProcessInstancePermissions::read()
809
                )
810
                ->build();
811
            $this->addPermissionCheck($authCheck, $permissionCheck);
812
        }
813
    }
814
815
    // historic incident query ////////////////////////////////
816
817
    public function configureHistoricIncidentQuery(HistoricIncidentQueryImpl $query): void
818
    {
819
        $authCheck = $query->getAuthCheck();
820
821
        $isHistoricInstancePermissionsEnabled = $this->isHistoricInstancePermissionsEnabled();
822
        $authCheck->setHistoricInstancePermissionsEnabled($isHistoricInstancePermissionsEnabled);
823
824
        if (!$isHistoricInstancePermissionsEnabled) {
825
            $this->configureQuery($query, Resources::processDefinition(), "RES.PROC_DEF_KEY_", Permissions::readHistory());
826
        } else {
827
            $this->configureQuery($query);
828
            $permissionCheck = (new PermissionCheckBuilder())
829
                ->disjunctive()
830
                ->atomicCheck(Resources::processDefinition(), "RES.PROC_DEF_KEY_", Permissions::readHistory())
831
                ->atomicCheck(
832
                    Resources::historicProcessInstance(),
833
                    "RES.PROC_INST_ID_",
834
                    HistoricProcessInstancePermissions::read()
835
                )
836
                ->build();
837
            $this->addPermissionCheck($authCheck, $permissionCheck);
838
        }
839
    }
840
841
    //historic identity link query ////////////////////////////////
842
843
    public function configureHistoricIdentityLinkQuery(HistoricIdentityLinkLogQueryImpl $query): void
844
    {
845
        $authCheck = $query->getAuthCheck();
846
847
        $isHistoricInstancePermissionsEnabled = $this->isHistoricInstancePermissionsEnabled();
848
        $authCheck->setHistoricInstancePermissionsEnabled($isHistoricInstancePermissionsEnabled);
849
850
        if (!$isHistoricInstancePermissionsEnabled) {
851
            $this->configureQuery($query, Resources::processDefinition(), "RES.PROC_DEF_KEY_", Permissions::readHistory());
852
        } else {
853
            $this->configureQuery($query);
854
855
            $permissionCheck = (new PermissionCheckBuilder())
856
                ->disjunctive()
857
                ->atomicCheck(Resources::processDefinition(), "RES.PROC_DEF_KEY_", Permissions::readHistory())
858
                ->atomicCheck(
859
                    Resources::historicProcessInstance(),
860
                    "TI.PROC_INST_ID_",
861
                    HistoricProcessInstancePermissions::read()
862
                )
863
                ->atomicCheck(
864
                    Resources::historicTask(),
865
                    "RES.TASK_ID_",
866
                    HistoricTaskPermissions::read()
867
                )
868
                ->build();
869
870
            $this->addPermissionCheck($authCheck, $permissionCheck);
871
        }
872
    }
873
874
    public function configureHistoricDecisionInstanceQuery(HistoricDecisionInstanceQueryImpl $query): void
875
    {
876
        $this->configureQuery($query, Resources::decisionDefinition(), "RES.DEC_DEF_KEY_", Permissions::readHistory());
877
    }
878
879
    // historic external task log query /////////////////////////////////
880
881
    public function configureHistoricExternalTaskLogQuery(HistoricExternalTaskLogQueryImpl $query): void
882
    {
883
        $authCheck = $query->getAuthCheck();
884
885
        $isHistoricInstancePermissionsEnabled = $this->isHistoricInstancePermissionsEnabled();
886
        $authCheck->setHistoricInstancePermissionsEnabled($isHistoricInstancePermissionsEnabled);
887
888
        if (!$this->isHistoricInstancePermissionsEnabled) {
0 ignored issues
show
Bug Best Practice introduced by
The property isHistoricInstancePermissionsEnabled does not exist on Jabe\Impl\Persistence\Entity\AuthorizationManager. Did you maybe forget to declare it?
Loading history...
889
            $this->configureQuery($query, Resources::processDefinition(), "RES.PROC_DEF_KEY_", Permissions::readHistory());
890
        } else {
891
            $this->configureQuery($query);
892
893
            $permissionCheck = (new PermissionCheckBuilder())
894
                ->disjunctive()
895
                ->atomicCheck(Resources::processDefinition(), "RES.PROC_DEF_KEY_", Permissions::readHistory())
896
                ->atomicCheck(
897
                    Resources::historicProcessInstance(),
898
                    "RES.PROC_INST_ID_",
899
                    HistoricProcessInstancePermissions::read()
900
                )
901
                ->build();
902
            $this->addPermissionCheck($authCheck, $permissionCheck);
903
        }
904
    }
905
906
    // user operation log query ///////////////////////////////
907
    public function configureUserOperationLogQuery(UserOperationLogQueryImpl $query): void
908
    {
909
        $this->configureQuery($query);
910
        $permissionCheckBuilder = (new PermissionCheckBuilder())
911
            ->disjunctive()
912
            ->atomicCheck(Resources::processDefinition(), "RES.PROC_DEF_KEY_", Permissions::readHistory())
913
            ->atomicCheck(Resources::operationLogCategory(), "RES.CATEGORY_", Permissions::read());
914
915
        $authCheck = $query->getAuthCheck();
916
917
        $isHistoricInstancePermissionsEnabled = $this->isHistoricInstancePermissionsEnabled();
918
        $authCheck->setHistoricInstancePermissionsEnabled($isHistoricInstancePermissionsEnabled);
919
920
        if ($isHistoricInstancePermissionsEnabled) {
921
            $permissionCheckBuilder
922
                ->atomicCheck(
923
                    Resources::historicProcessInstance(),
924
                    "RES.PROC_INST_ID_",
925
                    HistoricProcessInstancePermissions::read()
926
                )
927
                ->atomicCheck(
928
                    Resources::historicTask(),
929
                    "RES.TASK_ID_",
930
                    HistoricTaskPermissions::read()
931
                );
932
        }
933
        $permissionCheck = $permissionCheckBuilder->build();
934
        $this->addPermissionCheck($authCheck, $permissionCheck);
935
    }
936
937
    // batch
938
939
    public function configureHistoricBatchQuery(HistoricBatchQueryImpl $query): void
940
    {
941
        $this->configureQuery($query, Resources::batch(), "RES.ID_", Permissions::readHistory());
942
    }
943
944
    /* STATISTICS QUERY */
945
    public function configureDeploymentStatisticsQuery(DeploymentStatisticsQueryImpl $query): void
946
    {
947
        $this->configureQuery($query, Resources::deployment(), "RES.ID_");
948
949
        $query->clearProcessInstancePermissionChecks();
0 ignored issues
show
Bug introduced by
The method clearProcessInstancePermissionChecks() does not exist on Jabe\Impl\DeploymentStatisticsQueryImpl. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

949
        $query->/** @scrutinizer ignore-call */ 
950
                clearProcessInstancePermissionChecks();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
950
        $query->clearJobPermissionChecks();
0 ignored issues
show
Bug introduced by
The method clearJobPermissionChecks() does not exist on Jabe\Impl\DeploymentStatisticsQueryImpl. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

950
        $query->/** @scrutinizer ignore-call */ 
951
                clearJobPermissionChecks();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
951
        $query->clearIncidentPermissionChecks();
0 ignored issues
show
Bug introduced by
The method clearIncidentPermissionChecks() does not exist on Jabe\Impl\DeploymentStatisticsQueryImpl. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

951
        $query->/** @scrutinizer ignore-call */ 
952
                clearIncidentPermissionChecks();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
952
953
        if ($query->getAuthCheck()->isAuthorizationCheckEnabled()) {
954
            $processInstancePermissionCheck = (new PermissionCheckBuilder())
955
                ->disjunctive()
956
                ->atomicCheck(Resources::processInstance(), "EXECUTION.PROC_INST_ID_", Permissions::read())
957
                ->atomicCheck(Resources::processDefinition(), "PROCDEF.KEY_", Permissions::readInstance())
958
                ->build();
959
960
            $query->addProcessInstancePermissionCheck($processInstancePermissionCheck->getAllPermissionChecks());
961
962
            if ($query->isFailedJobsToInclude()) {
963
                $jobPermissionCheck = (new PermissionCheckBuilder())
964
                    ->disjunctive()
965
                    ->atomicCheck(Resources::processInstance(), "JOB.PROCESS_INSTANCE_ID_", Permissions::read())
966
                    ->atomicCheck(Resources::processDefinition(), "JOB.PROCESS_DEF_KEY_", Permissions::readInstance())
967
                    ->build();
968
969
                $query->addJobPermissionCheck($jobPermissionCheck->getAllPermissionChecks());
970
            }
971
972
            if ($query->isIncidentsToInclude()) {
973
                $incidentPermissionCheck = (new PermissionCheckBuilder())
974
                    ->disjunctive()
975
                    ->atomicCheck(Resources::processInstance(), "INC.PROC_INST_ID_", Permissions::read())
976
                    ->atomicCheck(Resources::processDefinition(), "PROCDEF.KEY_", Permissions::readInstance())
977
                    ->build();
978
979
                $query->addIncidentPermissionCheck($incidentPermissionCheck->getAllPermissionChecks());
980
            }
981
        }
982
    }
983
984
    public function configureProcessDefinitionStatisticsQuery(ProcessDefinitionStatisticsQueryImpl $query): void
985
    {
986
        $this->configureQuery($query, Resources::processDefinition(), "RES.KEY_");
987
    }
988
989
    public function configureActivityStatisticsQuery(ActivityStatisticsQueryImpl $query): void
990
    {
991
        $this->configureQuery($query);
992
993
        $query->clearPermissionChecks();
0 ignored issues
show
Bug introduced by
The method clearPermissionChecks() does not exist on Jabe\Impl\ActivityStatisticsQueryImpl. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

993
        $query->/** @scrutinizer ignore-call */ 
994
                clearPermissionChecks();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
994
        $query->clearJobPermissionChecks();
0 ignored issues
show
Bug introduced by
The method clearJobPermissionChecks() does not exist on Jabe\Impl\ActivityStatisticsQueryImpl. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

994
        $query->/** @scrutinizer ignore-call */ 
995
                clearJobPermissionChecks();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
995
        $query->clearIncidentPermissionChecks();
0 ignored issues
show
Bug introduced by
The method clearIncidentPermissionChecks() does not exist on Jabe\Impl\ActivityStatisticsQueryImpl. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

995
        $query->/** @scrutinizer ignore-call */ 
996
                clearIncidentPermissionChecks();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
996
997
        if ($query->getAuthCheck()->isAuthorizationCheckEnabled()) {
998
            $processInstancePermissionCheck = (new PermissionCheckBuilder())
999
                ->disjunctive()
1000
                ->atomicCheck(Resources::processInstance(), "E.PROC_INST_ID_", Permissions::read())
1001
                ->atomicCheck(Resources::processDefinition(), "P.KEY_", Permissions::readInstance())
1002
                ->build();
1003
1004
            // the following is need in order to evaluate whether to perform authCheck or not
1005
            $query->getAuthCheck()->setPermissionChecks($processInstancePermissionCheck);
1006
            // the actual check
1007
            $query->addProcessInstancePermissionCheck($processInstancePermissionCheck->getAllPermissionChecks());
1008
1009
            if ($query->isFailedJobsToInclude()) {
1010
                $jobPermissionCheck = (new PermissionCheckBuilder())
1011
                    ->disjunctive()
1012
                    ->atomicCheck(Resources::processInstance(), "JOB.PROCESS_INSTANCE_ID_", Permissions::read())
1013
                    ->atomicCheck(Resources::processDefinition(), "JOB.PROCESS_DEF_KEY_", Permissions::readInstance())
1014
                    ->build();
1015
1016
                // the following is need in order to evaluate whether to perform authCheck or not
1017
                $query->getAuthCheck()->setPermissionChecks($jobPermissionCheck);
1018
                // the actual check
1019
                $query->addJobPermissionCheck($jobPermissionCheck->getAllPermissionChecks());
1020
            }
1021
1022
            if ($query->isIncidentsToInclude()) {
1023
                $incidentPermissionCheck = (new PermissionCheckBuilder())
1024
                    ->disjunctive()
1025
                    ->atomicCheck(Resources::processInstance(), "I.PROC_INST_ID_", Permissions::read())
1026
                    ->atomicCheck(Resources::processDefinition(), "PROCDEF.KEY_", Permissions::readInstance())
1027
                    ->build();
1028
1029
                // the following is need in order to evaluate whether to perform authCheck or not
1030
                $query->getAuthCheck()->setPermissionChecks($incidentPermissionCheck);
1031
                // the actual check
1032
                $query->addIncidentPermissionCheck($incidentPermissionCheck->getAllPermissionChecks());
1033
            }
1034
        }
1035
    }
1036
1037
    public function configureExternalTaskQuery(ExternalTaskQueryImpl $query): void
1038
    {
1039
        $this->configureQuery($query);
1040
        $permissionCheck = (new PermissionCheckBuilder())
1041
            ->disjunctive()
1042
            ->atomicCheck(Resources::processInstance(), "RES.PROC_INST_ID_", Permissions::read())
1043
            ->atomicCheck(Resources::processDefinition(), "RES.PROC_DEF_KEY_", Permissions::readInstance())
1044
            ->build();
1045
        $this->addPermissionCheck($query->getAuthCheck(), $permissionCheck);
1046
    }
1047
1048
    public function configureExternalTaskFetch(ListQueryParameterObject $parameter): void
1049
    {
1050
        $this->configureQuery($parameter);
1051
1052
        $permissionCheck = (new PermissionCheckBuilder())
1053
            ->conjunctive()
1054
            ->composite()
1055
            ->disjunctive()
1056
            ->atomicCheck(Resources::processInstance(), "RES.PROC_INST_ID_", Permissions::read())
1057
            ->atomicCheck(Resources::processDefinition(), "RES.PROC_DEF_KEY_", Permissions::readInstance())
1058
            ->done()
1059
            ->composite()
1060
            ->disjunctive()
1061
            ->atomicCheck(Resources::processInstance(), "RES.PROC_INST_ID_", Permissions::update())
1062
            ->atomicCheck(Resources::processDefinition(), "RES.PROC_DEF_KEY_", Permissions::updateInstance())
1063
            ->done()
1064
            ->build();
1065
1066
        $this->addPermissionCheck($parameter->getAuthCheck(), $permissionCheck);
1067
    }
1068
1069
    public function configureDecisionDefinitionQuery(DecisionDefinitionQueryImpl $query): void
1070
    {
1071
        $this->configureQuery($query, Resources::decisionDefinition(), "RES.KEY_");
1072
    }
1073
1074
    public function configureDecisionRequirementsDefinitionQuery(DecisionRequirementsDefinitionQueryImpl $query): void
1075
    {
1076
        $this->configureQuery($query, Resources::decisionRequirementsDefinition(), "RES.KEY_");
1077
    }
1078
1079
    public function configureBatchQuery(BatchQueryImpl $query): void
1080
    {
1081
        $this->configureQuery($query, Resources::batch(), "RES.ID_", Permissions::read());
1082
    }
1083
1084
    public function configureBatchStatisticsQuery(BatchStatisticsQueryImpl $query): void
1085
    {
1086
        $this->configureQuery($query, Resources::batch(), "RES.ID_", Permissions::read());
1087
    }
1088
1089
    public function filterAuthenticatedGroupIds(?array $authenticatedGroupIds = []): array
1090
    {
1091
        if (empty($authenticatedGroupIds)) {
1092
            return self::EMPTY_LIST;
1093
        } else {
1094
            if (empty($this->availableAuthorizedGroupIds)) {
1095
                $this->availableAuthorizedGroupIds = $this->getDbEntityManager()->selectList("selectAuthorizedGroupIds");
1096
            }
1097
            return $this->availableAuthorizedGroupIds;
1098
        }
1099
    }
1100
1101
    protected function isAuthCheckExecuted(): bool
1102
    {
1103
        $currentAuthentication = $this->getCurrentAuthentication();
1104
        $commandContext = Context::getCommandContext();
1105
        return $this->isAuthorizationEnabled()
1106
            && $commandContext->isAuthorizationCheckEnabled()
1107
            && $currentAuthentication !== null
1108
            && $currentAuthentication->getUserId() !== null;
1109
    }
1110
1111
    public function isEnsureSpecificVariablePermission(): bool
1112
    {
1113
        return Context::getProcessEngineConfiguration()->isEnforceSpecificVariablePermission();
1114
    }
1115
1116
    protected function isHistoricInstancePermissionsEnabled(): bool
1117
    {
1118
        return Context::getProcessEngineConfiguration()->isEnableHistoricInstancePermissions();
0 ignored issues
show
Bug introduced by
The method isEnableHistoricInstancePermissions() does not exist on Jabe\Impl\Cfg\ProcessEngineConfigurationImpl. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1118
        return Context::getProcessEngineConfiguration()->/** @scrutinizer ignore-call */ isEnableHistoricInstancePermissions();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1119
    }
1120
1121
    public function addRemovalTimeToAuthorizationsByRootProcessInstanceId(
1122
        string $rootProcessInstanceId,
1123
        string $removalTime
1124
    ): void {
1125
        $parameters = [];
1126
        $parameters["rootProcessInstanceId"] = $rootProcessInstanceId;
1127
        $parameters["removalTime"] = $removalTime;
1128
1129
        $this->getDbEntityManager()
1130
            ->updatePreserveOrder(
1131
                AuthorizationEntity::class,
1132
                "updateAuthorizationsByRootProcessInstanceId",
1133
                $parameters
1134
            );
1135
    }
1136
1137
    public function addRemovalTimeToAuthorizationsByProcessInstanceId(
1138
        string $processInstanceId,
1139
        string $removalTime
1140
    ): void {
1141
        $parameters = [];
1142
        $parameters["processInstanceId"] = $processInstanceId;
1143
        $parameters["removalTime"] = $removalTime;
1144
1145
        $this->getDbEntityManager()
1146
            ->updatePreserveOrder(
1147
                AuthorizationEntity::class,
1148
                "updateAuthorizationsByProcessInstanceId",
1149
                $parameters
1150
            );
1151
    }
1152
1153
    public function deleteAuthorizationsByRemovalTime(
1154
        string $removalTime,
1155
        int $minuteFrom,
1156
        int $minuteTo,
1157
        int $batchSize
1158
    ): DbOperation {
1159
        $parameters = [];
1160
        $parameters["removalTime"] = $removalTime;
1161
        if ($minuteTo - $minuteFrom + 1 < 60) {
1162
            $parameters["minuteFrom"] = $minuteFrom;
1163
            $parameters["minuteTo"] = $minuteTo;
1164
        }
1165
        $parameters["batchSize"] = $batchSize;
1166
1167
        return $this->getDbEntityManager()
1168
            ->deletePreserveOrder(
1169
                AuthorizationEntity::class,
1170
                "deleteAuthorizationsByRemovalTime",
1171
                new ListQueryParameterObject($parameters, 0, $batchSize)
1172
            );
1173
    }
1174
}
1175