Skip to content

Commit

Permalink
feat: create new command to change all permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielfs7 committed Oct 19, 2023
1 parent 71152a3 commit ae04101
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 120 deletions.
94 changes: 94 additions & 0 deletions model/Command/ChangeAccessCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

/**
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2023 (original work) Open Assessment Technologies SA.
*/

declare(strict_types=1);

namespace oat\taoDacSimple\model\Command;

class ChangeAccessCommand
{
/**
* An array in the form ['resourceId' => ['userId1', 'userId2']]
*
* @var string[][]
*/
private array $removeAccessMap = [];

/**
* An array in the form ['resourceId' [ 'READ' => ['userId1', 'userId2']]]
*
* @var string[][][]
*/
private array $giveAccessMap = [];

public function __construct() {
}

public function revokeResourceForUser(string $resourceId, string $userId): void
{
$this->removeAccessMap[$resourceId] = $this->removeAccessMap[$resourceId] ?? [];
$this->removeAccessMap[$resourceId] = array_unique(array_merge($this->removeAccessMap[$resourceId], [$userId]));
}

public function cancelRevokeResourceForUser(string $resourceId, string $userId): void
{
$this->removeAccessMap[$resourceId] = $this->removeAccessMap[$resourceId] ?? [];

$key = array_search($userId, $this->removeAccessMap[$resourceId]);

if ($key === false) {
return;
}

unset($this->removeAccessMap[$resourceId][$key]);
}

public function getResourceIdsToRevoke(): array
{
return array_keys($this->removeAccessMap);
}

public function getUserIdsToRevoke(string $resourceId): array
{
return $this->removeAccessMap[$resourceId] ?? [];
}

public function grantResourceForUser(string $resourceId, string $permission, string $userId): void
{
$this->giveAccessMap[$resourceId] = $this->giveAccessMap[$resourceId] ?? [];
$this->giveAccessMap[$resourceId][$permission] = $this->giveAccessMap[$resourceId][$permission] ?? [];
$this->giveAccessMap[$resourceId][$permission] = array_unique(
array_merge(
$this->giveAccessMap[$resourceId][$permission],
[$userId]
)
);
}

public function getResourceIdsToGrant(): array
{
return array_keys($this->giveAccessMap);
}

public function getUserIdsToGrant(string $resourceId, string $permission): array
{
return $this->giveAccessMap[$resourceId][$permission] ?? [];
}
}
71 changes: 0 additions & 71 deletions model/Command/RevokeAccessCommand.php

This file was deleted.

94 changes: 45 additions & 49 deletions model/DataBaseAccess.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
use common_persistence_SqlPersistence;
use oat\oatbox\event\EventManager;
use oat\oatbox\service\ConfigurableService;
use oat\taoDacSimple\model\Command\RevokeAccessCommand;
use oat\taoDacSimple\model\Command\ChangeAccessCommand;
use oat\taoDacSimple\model\event\DacAddedEvent;
use oat\taoDacSimple\model\event\DacRemovedEvent;
use oat\generis\persistence\PersistenceManager;
Expand Down Expand Up @@ -185,67 +185,63 @@ public function changeResourcePermissions(array $resources): void
}
}

public function addReadAccess(array $addAccessList): bool
public function changeAccess(ChangeAccessCommand $command): bool
{
//@TODO Use proper object in the command instead of an array
if (empty($addAccessList)) {
return true;
}
$resourceIds = $command->getResourceIdsToGrant();

$values = [];
if (!empty($resourceIds)) {
$values = [];

try {
foreach ($addAccessList as $resourceId => $usersIds) {
foreach ($usersIds as $userId) {
$values[] = [
'user_id' => $userId,
'resource_id' => $resourceId,
'privilege' => PermissionProvider::PERMISSION_READ
];
try {
foreach ($resourceIds as $resourceId) {
foreach (PermissionProvider::ALLOWED_PERMISSIONS as $permission) {
$usersIds = $command->getUserIdsToGrant($resourceId, $permission);

foreach ($usersIds as $userId) {
$values[] = [
'user_id' => $userId,
'resource_id' => $resourceId,
'privilege' => $permission,
];
}
}
}
}

$this->insertPermissions($values);
$this->insertPermissions($values);
} catch (Throwable $exception) {
$this->logError('Error when adding permission access: ' . $exception->getMessage());

return true;
} catch (Throwable $exception) {
$this->logError('Error when adding READ access: ' . $exception->getMessage());

return false;
return false;
}
}
}

public function revokeAccess(RevokeAccessCommand $revokeAccess): bool
{
$resourceIds = $revokeAccess->getResourceIdsToRevoke();
$resourceIds = $command->getResourceIdsToRevoke();

if (empty($resourceIds)) {
return true;
}

$persistence = $this->getPersistence();
if (!empty($resourceIds)) {
$persistence = $this->getPersistence();

try {
$persistence->transactional(static function () use ($resourceIds, $revokeAccess, $persistence): void {
foreach ($resourceIds as $resourceId) {
$usersIds = $revokeAccess->getUserIdsToRevoke($resourceId);

$persistence->exec(
sprintf(
'DELETE FROM data_privileges WHERE resource_id = ? AND user_id IN (%s)',
implode(',', array_fill(0, count($usersIds), ' ? '))
),
array_merge([$resourceId], array_values($usersIds))
);
}
});
try {
$persistence->transactional(static function () use ($resourceIds, $command, $persistence): void {
foreach ($resourceIds as $resourceId) {
$usersIds = $command->getUserIdsToRevoke($resourceId);

return true;
} catch (Throwable $exception) {
$this->logError('Error when revoking access: ' . $exception->getMessage());
$persistence->exec(
sprintf(
'DELETE FROM data_privileges WHERE resource_id = ? AND user_id IN (%s)',
implode(',', array_fill(0, count($usersIds), ' ? '))
),
array_merge([$resourceId], array_values($usersIds))
);
}
});
} catch (Throwable $exception) {
$this->logError('Error when revoking access: ' . $exception->getMessage());

return false;
return false;
}
}

return true;
}

/**
Expand Down
5 changes: 5 additions & 0 deletions model/PermissionProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ class PermissionProvider extends ConfigurableService implements PermissionInterf
public const PERMISSION_GRANT = 'GRANT';
public const PERMISSION_READ = 'READ';
public const PERMISSION_WRITE = 'WRITE';
public const ALLOWED_PERMISSIONS = [
PermissionProvider::PERMISSION_READ,
PermissionProvider::PERMISSION_GRANT,
PermissionProvider::PERMISSION_WRITE,
];

/**
* (non-PHPdoc)
Expand Down

0 comments on commit ae04101

Please sign in to comment.