Skip to content

Commit

Permalink
Merge pull request #21 from Eseperio/multi-tenant-prefixed-relations
Browse files Browse the repository at this point in the history
Improve inheritance
  • Loading branch information
Eseperio committed Oct 25, 2023
2 parents 42fed8c + d1d7cee commit 0cd5485
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 74 deletions.
8 changes: 7 additions & 1 deletion src/actions/RemoveACL.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,21 @@ public function run()
$permModel = Yii::createObject(InodePermissionsForm::class);
$permModel->scenario = AccessControl::SCENARIO_DELETE;
$permModel->setAttributes(Yii::$app->request->post(), false);
$all = Yii::$app->request->post('all', false);
if ($permModel->validate()) {
try {
$realModel = AccessControl::find()->where([
'user_id' => $permModel->user_id,
'role' => $permModel->role,
'inode_id' => $permModel->inode_id
])->one();
if (!empty($realModel))

if (!empty($realModel)) {
if($all){
$realModel->removeSiblingsRecursive();
}
$realModel->delete();
}
} catch (\Throwable $e) {
throw $e;
}
Expand Down
7 changes: 5 additions & 2 deletions src/messages/es/filescatalog.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
'An error ocurred when trying to delete' => 'Ocurrió un error al intentar eliminar',
'An error ocurred while uploading the file/s' => 'Ocurrió un error al cargar el/los archivo/s',
'Apply to all children? This cannot be undone' => '¿Aplicar a todo el contenido de forma recursiva? Esto no se puede deshacer',
'Apply to children' => 'Aplicar a hijos',
'Apply to children' => 'Aplicar a descendientes',
'Author Name' => 'Nombre del autor',
'Back' => 'Atrás',
'Bulk access control' => 'Control de acceso en masa',
Expand Down Expand Up @@ -58,6 +58,7 @@
'Directories does not accept versioning' => 'Los directorios no permiten versiones',
'Directory' => 'Directorio',
'Download' => 'Descargar',
'Error saving file content: ' => 'Error al guardar el contenido del archivo: ',
'Everyone' => 'Todos',
'Expires At' => 'Fecha de caducidad',
'Extension' => 'Extensión',
Expand Down Expand Up @@ -103,6 +104,7 @@
'Read, Write and Delete' => 'Leer, escribir y borrar',
'Real path' => 'Ruta real',
'Recipient' => 'Destinatario',
'Remove here and in all descendants' => 'Quitar aquí y en todos los descendientes',
'Rename' => 'Renombrar',
'Role' => 'Rol',
'Root node can not be deleted' => 'El nodo principal no puede ser eliminado',
Expand Down Expand Up @@ -154,5 +156,6 @@
'or' => 'ó',
'tomorrow' => 'mañana',
'{user} has shared the file {filename} with you' => '{user} ha compartido el archivo {filename} contigo',
'Shared with {qty}' => '@@Compartido con {qty}@@',
'Remove' => 'Quitar',
'Shared with {qty}' => 'Compartido con {qty}',
];
130 changes: 92 additions & 38 deletions src/models/AccessControl.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ class AccessControl extends ActiveRecord

const SCENARIO_DELETE = 'delscen';

/**
* @var array buffer for descendant ids
*/
private $_descentantIds = [];

/**
* {@inheritdoc}
*/
Expand All @@ -78,35 +83,49 @@ public function copyPermissionToDescendants()
throw new InvalidConfigException('Permissions can only be copied from a stored record');
}
$inode = $this->inode;
$children = $inode->getDescendantsIds(null, true);
$data = [];
$delPk = ['OR'];
foreach ($children as $child) {
$delPk[] = [
'user_id' => $this->user_id,
'role' => $this->role,
'inode_id' => $child
];
$data[] = [
$this->user_id,
$this->role,
$child,
$this->crud_mask
];
$inode->childrenJoinLevels = 5;
$children = $this->getDescendantsIds($inode);

$this->removeSiblingsRecursive();
if (count($children) > 200) {
Yii::$app->db->enableLogging = false;
Yii::$app->db->enableProfiling = false;
Yii::debug('Disabled db logging for bulk insert of inode descendants permissions due to large amount of records', 'filescatalog');
}
$transaction = Yii::$app->db->beginTransaction();
try {
$batchSize = 1000;
$batchLoop = 0;// iterate children in batches
while (!empty($children)) {
$data = [];
$batch = array_splice($children, 0, $batchSize);
foreach ($batch as $child) {
$data[] = [
$this->user_id,
$this->role,
$child,
$this->crud_mask
];
}

if (count($delPk) > 1) {
self::deleteAll($delPk);
/** @var Connection $db */
$db = Yii::$app->get($this->module->db);
$db->createCommand()->batchInsert($this->module->inodeAccessControlTableName, [
'user_id',
'role',
'inode_id',
'crud_mask'
], $data)->execute();
$batchLoop++;
}
$transaction->commit();
} catch (\Throwable $e) {
$transaction->rollBack();
throw $e;
} finally {
Yii::$app->db->enableLogging = true;
Yii::$app->db->enableProfiling = true;
}

/** @var Connection $db */
$db = Yii::$app->get($this->module->db);
$db->createCommand()->batchInsert($this->module->inodeAccessControlTableName, [
'user_id',
'role',
'inode_id',
'crud_mask'
], $data)->execute();
}

/**
Expand All @@ -115,20 +134,41 @@ public function copyPermissionToDescendants()
*/
public function removeSiblingsRecursive()
{
$inode = $this->inode;
$children = $inode->getDescendantsIds(null, true);
$delPk = ['OR'];
foreach ($children as $child) {
$delPk[] = [
'user_id' => $this->user_id,
'role' => $this->role,
'inode_id' => $child
];
}
$transaction = Yii::$app->db->beginTransaction();

if(count($delPk)> 1){
self::deleteAll($delPk);
try {
$inode = $this->inode;
$children = $this->getDescendantsIds($inode);// disable logging if children is greater than 200
$totalRows = count($children);
if ($totalRows > 200) {
Yii::debug('Disabled db logging for bulk delete of inode descendants permissions', 'filescatalog');
Yii::$app->db->enableLogging = false;
Yii::$app->db->enableProfiling = false;
}
$batchSize = 1000;
$batchLoop = 0;
while (!empty($children)) {
$batch = array_splice($children, 0, $batchSize);
$delPk = [
'AND',
['user_id' => $this->user_id],
['role' => $this->role],
['inode_id' => $batch]
];
self::deleteAll($delPk);

$batchLoop++;
}
$transaction->commit();
} catch (\Throwable $e) {
$transaction->rollBack();
throw $e;
} finally {
Yii::$app->db->enableLogging = true;
Yii::$app->db->enableProfiling = true;
}


}

/**
Expand All @@ -137,6 +177,7 @@ public function removeSiblingsRecursive()
* @param $users
* @param null $mask
* @return bool|int
* @throws \Exception
*/
public static function grantAccessToUsers($files, $users, $mask = null)
{
Expand All @@ -149,6 +190,7 @@ public static function grantAccessToUsers($files, $users, $mask = null)
* @param $mask
* @param int $type
* @return bool|int the number of rows inserted
* @throws \Exception
*/
private static function setInodesAccessRules($files, $usersOrRoles, $mask = null, $type = self::TYPE_USER)
{
Expand Down Expand Up @@ -380,4 +422,16 @@ public function setCrud($crud): void
}
}
}

/**
* @param \eseperio\filescatalog\models\Inode|null $inode
* @return array
*/
private function getDescendantsIds(?Inode $inode): array
{
if (empty($this->_descentantIds)) {
$this->_descentantIds = $inode->getDescendantsIds(null, true);
}
return $this->_descentantIds;
}
}
1 change: 1 addition & 0 deletions src/models/InodeSearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public function getSearchQuery(array $params, $model = null, mixed $mode = self:
->withSymlinksReferences();
}

/* @var $query \app\modules\repository\models\InodeQuery */

$query->excludeVersions()
->onlyReadable();
Expand Down
5 changes: 5 additions & 0 deletions src/models/InodeShare.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ public function getAccessControl()
* @param $insert
* @param $changedAttributes
* @return void
* @throws \yii\base\InvalidConfigException
* @throws \yii\db\Exception
* @throws \yii\web\ServerErrorHttpException
*/
public function afterSave($insert, $changedAttributes)
{
Expand All @@ -71,6 +74,8 @@ public function afterSave($insert, $changedAttributes)
/**
* Delete granted permissions to children
* @return void
* @throws \Throwable
* @throws \yii\db\StaleObjectException
*/
public function afterDelete()
{
Expand Down
81 changes: 48 additions & 33 deletions src/views/default/partials/_acl.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,42 +123,57 @@
}
?>
</div>
<div class="col-sm-3">
<div class="col-sm-2">
<?= CrudStatus::widget(['model' => $item]) ?>
</div>
<div class="col-sm-3">
<?= Html::a(Yii::t('filescatalog', 'Apply to children'), ['inherit-acl'],
[
'class' => 'pull-right',
'data' => [
'method' => 'post',
'confirm' => Yii::t('filescatalog', 'Apply to all children? This cannot be undone'),
'params' => [
'inode_id' => $item->inode_id,
'role' => $item->role,
'user_id' => $item->user_id
]
],
]) ?>
</div>
<div class="col-sm-3">
<?= Html::a(Yii::t('filescatalog', 'Delete'), [
'remove-acl',
], [
'class' => 'pull-right',
'data' => [
'method' => 'post',
'confirm' => Yii::t('filescatalog', 'Confirm deletion'),
'params' => [
'inode_id' => $item->inode_id,
'role' => $item->role,
'user_id' => $item->user_id
]
],
]) ?>

<div class="col-sm-6">
<ul>
<li>
<?= Html::a(Yii::t('filescatalog', 'Apply to children'), ['inherit-acl'],
[
'data' => [
'method' => 'post',
'confirm' => Yii::t('filescatalog', 'Apply to all children? This cannot be undone'),
'params' => [
'inode_id' => $item->inode_id,
'role' => $item->role,
'user_id' => $item->user_id
]
],
]) ?>
</li>
<li> <?= Html::a(Yii::t('filescatalog', 'Remove'), [
'remove-acl',
], [
'data' => [
'method' => 'post',
'confirm' => Yii::t('filescatalog', 'Confirm deletion'),
'params' => [
'inode_id' => $item->inode_id,
'role' => $item->role,
'user_id' => $item->user_id
]
],
]) ?></li>
<li>
<?= Html::a(Yii::t('filescatalog', 'Remove here and in all descendants'), [
'remove-acl',
], [
'data' => [
'method' => 'post',
'confirm' => Yii::t('filescatalog', 'Confirm deletion'),
'params' => [
'inode_id' => $item->inode_id,
'role' => $item->role,
'user_id' => $item->user_id,
'all' => true
]
],
]) ?>
</li>
</ul>
</div>
</
>
</li>
<?php endforeach; ?>
</ul>
Expand Down

0 comments on commit 0cd5485

Please sign in to comment.