Skip to content

Commit

Permalink
Merge pull request #153 from Ioannis/fix_table_related_permissions
Browse files Browse the repository at this point in the history
fix related permissions
  • Loading branch information
Ioannis authored Feb 12, 2024
2 parents c328425 + cd30ba9 commit 6c06000
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,19 @@ class SqlProvisionersTable extends Table {
'source' => 'People',
'source_table' => 'people',
'related' => [
'AdHocAttributes',
'Addresses',
'EmailAddresses',
'ExternalIdentities',
'GroupMembers',
'Identifiers',
'Names',
'PersonRoles',
'Pronouns',
'TelephoneNumbers',
'Urls'
'table' => [
'AdHocAttributes',
'Addresses',
'EmailAddresses',
'ExternalIdentities',
'GroupMembers',
'Identifiers',
'Names',
'PersonRoles',
'Pronouns',
'TelephoneNumbers',
'Urls'
],
]
],
'Groups' => [
Expand All @@ -80,7 +82,9 @@ class SqlProvisionersTable extends Table {
'source' => 'Groups',
'source_table' => 'groups',
'related' => [
'GroupMembers'
'table' => [
'GroupMembers'
],
]
]
];
Expand Down Expand Up @@ -114,15 +118,17 @@ class SqlProvisionersTable extends Table {
'source' => 'ExternalIdentities',
'source_table' => 'external_identities',
'related' => [
'AdHocAttributes',
'Addresses',
'EmailAddresses',
'ExternalIdentityRoles',
'Identifiers',
'Names',
'Pronouns',
'TelephoneNumbers',
'Urls'
'table' => [
'AdHocAttributes',
'Addresses',
'EmailAddresses',
'ExternalIdentityRoles',
'Identifiers',
'Names',
'Pronouns',
'TelephoneNumbers',
'Urls'
],
]
],
'ExternalIdentityRoles' => [
Expand All @@ -131,9 +137,11 @@ class SqlProvisionersTable extends Table {
'source' => 'ExternalIdentityRoles',
'source_table' => 'external_identity_roles',
'related' => [
'AdHocAttributes',
'Addresses',
'TelephoneNumbers'
'table' => [
'AdHocAttributes',
'Addresses',
'TelephoneNumbers'
],
]
],
'GroupMembers' => [
Expand Down Expand Up @@ -164,9 +172,11 @@ class SqlProvisionersTable extends Table {
'source' => 'PersonRoles',
'source_table' => 'person_roles',
'related' => [
'AdHocAttributes',
'Addresses',
'TelephoneNumbers'
'table' => [
'AdHocAttributes',
'Addresses',
'TelephoneNumbers'
],
]
],
'Pronouns' => [
Expand Down
87 changes: 82 additions & 5 deletions app/src/Controller/Component/RegistryAuthComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
use \Cake\Http\Exception\UnauthorizedException;
use \Cake\ORM\ResultSet;
use \Cake\ORM\TableRegistry;
use \Cake\Utility\Inflector;
use \App\Lib\Enum\AuthenticationEventEnum;
use \App\Lib\Enum\SuspendableStatusEnum;
use \App\Lib\Enum\TemplateableStatusEnum;
Expand Down Expand Up @@ -319,6 +320,9 @@ protected function calculatePermissions(?int $id=null): array {

// Is this user a CO Member?
$coMember = $this->isCoMember($controller->getCOID());

// Get the action
$reqAction = $controller->getRequest()->getParam('action');

// Is this record read only?
$readOnly = false;
Expand All @@ -333,8 +337,27 @@ protected function calculatePermissions(?int $id=null): array {
$readOnlyActions = ['view'];

// Pull the record so we can interrogate it

$obj = $table->get($id);

// XXX Get the record along with the contains
// We use findById() rather than get() so we can apply subsequent
// query modifications via traits
$query = $table->findById($id);

// QueryModificationTrait
$getActionMethod = "get{$reqAction}Contains";
if(method_exists($table, $getActionMethod)) {
$query = $query->contain($table->$getActionMethod());
}

try {
// Pull the current record
$obj = $query->firstOrFail();
}
catch(\Exception $e) {
// findById throws Cake\Datasource\Exception\RecordNotFoundException
$this->Flash->error($e->getMessage());
return $this->generateRedirect(null);
}

if(method_exists($obj, "isReadOnly")) {
$readOnly = $obj->isReadOnly();
Expand Down Expand Up @@ -375,9 +398,62 @@ protected function calculatePermissions(?int $id=null): array {

$ret[$action] = $ok;
}

if(!empty($permissions['related']['entity'])) {
foreach($permissions['related']['entity'] as $rtable) {
$RelatedTable = TableRegistry::getTableLocator()->get($rtable);
$rpermissions = $this->getTablePermissions($RelatedTable, $id);
$robj = $obj->get(Inflector::singularize(Inflector::underscore($rtable)));
$rreadOnlyActions = ['view'];

// Is this record read only?
$rreadOnly = false;

// Can this record be deleted?
$rcanDelete = true;

if($robj !== null && method_exists($robj, "isReadOnly")) {
$rreadOnly = $robj->isReadOnly();

if(!empty($rpermissions['readOnly'])) {
// Merge in controller specific actions permitted on read only entities
$rreadOnlyActions = array_merge($rreadOnlyActions, $rpermissions['readOnly']);
}
}

if($robj !== null && method_exists($robj, "canDelete")) {
$rcanDelete = $robj->canDelete();
}

foreach($rpermissions['entity'] as $action => $roles) {
$ok = false;

if((($action != 'delete' || $rcanDelete)
&&
!$rreadOnly) || in_array($action, $rreadOnlyActions)) {
if(is_array($roles)) {
// A list of roles authorized to perform this action, see if the
// current user has any
foreach($roles as $role) {
// eg: $role = "platformAdmin", which corresponds to the variables set, above
if($$role) {
$ok = true;
break;
}
}
} elseif($roles === true) {
// Any authenticated user is permitted
$ok = true;
}
}

$ret[$rtable][$action] = $ok;
}
}
}

if(!empty($permissions['related'])) {
foreach($permissions['related'] as $rtable) {
if(!empty($permissions['related']['table'])) {
foreach($permissions['related']['table'] as $rtable) {
$RelatedTable = TableRegistry::getTableLocator()->get($rtable);
$rpermissions = $this->getTablePermissions($RelatedTable, $id);

Expand All @@ -403,7 +479,8 @@ protected function calculatePermissions(?int $id=null): array {
}
}
}
} else {

} else { // No $id
// Permissions for actions that operate over tables

foreach($permissions['table'] as $action => $roles) {
Expand Down
5 changes: 4 additions & 1 deletion app/src/Model/Table/CosTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,10 @@ public function initialize(array $config): void {
],
// Related models whose permissions we'll need, typically for table views
'related' => [
'Dashboards'
'entity' => [],
'table' => [
'Dashboards'
]
]
]);
}
Expand Down
30 changes: 17 additions & 13 deletions app/src/Model/Table/ExternalIdentitiesTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public function initialize(array $config): void {
$this->hasMany('ExternalIdentityRoles')
->setDependent(true)
->setCascadeCallbacks(true);
$this->hasMany('ExtIdentitySourceRecords')
$this->hasOne('ExtIdentitySourceRecords')
->setDependent(true)
->setCascadeCallbacks(true);
$this->hasMany('HistoryRecords')
Expand Down Expand Up @@ -162,18 +162,22 @@ public function initialize(array $config): void {
],
// Related models whose permissions we'll need, typically for table views
'related' => [
'Names',
'Addresses',
'AdHocAttributes',
'EmailAddresses',
'ExternalIdentityRoles',
'ExtIdentitySourceRecords',
'HistoryRecords',
'Identifiers',
'JobHistoryRecords',
'Pronouns',
'TelephoneNumbers',
'Urls'
'entity' => [
'ExtIdentitySourceRecords',
],
'table' => [
'Names',
'Addresses',
'AdHocAttributes',
'EmailAddresses',
'ExternalIdentityRoles',
'HistoryRecords',
'Identifiers',
'JobHistoryRecords',
'Pronouns',
'TelephoneNumbers',
'Urls'
],
]
]);
}
Expand Down
15 changes: 9 additions & 6 deletions app/src/Model/Table/GroupsTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,16 +164,19 @@ public function initialize(array $config): void {
],
// Related models whose permissions we'll need, typically for table views
'related' => [
'entity' => [],
'table' => [
// XXX As a first pass, this (combined with the implementation in AppController::calculatePermissions)
// will render a link to group-members?group_id=X for all groups in the index view
// groups?co_id=2. This may or may not be right in the long term, eg for private
// groups. Maybe it's OK for now, since all groups are visible to all members of the CO.
'GroupMembers',
'GroupNestings',
'HistoryRecords',
'IdentifierAssignments',
'Identifiers',
'ProvisioningTargets'
'GroupMembers',
'GroupNestings',
'HistoryRecords',
'IdentifierAssignments',
'Identifiers',
'ProvisioningTargets'
],
]
]);
}
Expand Down
5 changes: 4 additions & 1 deletion app/src/Model/Table/IdentifiersTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,10 @@ public function initialize(array $config): void {
],
// Related models whose permissions we'll need, typically for table views
'related' => [
'AuthenticationEvents'
'entity' => [],
'table' => [
'AuthenticationEvents'
]
]
]);
}
Expand Down
5 changes: 4 additions & 1 deletion app/src/Model/Table/JobsTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,10 @@ public function initialize(array $config): void {
'readOnly' => ['cancel'],
// Related models whose permissions we'll need, typically for table views
'related' => [
'JobHistoryRecords'
'entity' => [],
'table' => [
'JobHistoryRecords'
]
]
]);
}
Expand Down
6 changes: 5 additions & 1 deletion app/src/Model/Table/NamesTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,11 @@ public function initialize(array $config): void {
$this->belongsTo('People');
$this->belongsTo('ExternalIdentities');
$this->belongsTo('Types');

$this->belongsTo('ExtIdentitySourceRecords')
->setClassName('ExtIdentitySourceRecords')
->setForeignKey('source_name_id')
->setProperty('source_name');

$this->setDisplayField('full_name');

$this->setPrimaryLink(['external_identity_id', 'person_id']);
Expand Down
29 changes: 16 additions & 13 deletions app/src/Model/Table/PeopleTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -207,18 +207,21 @@ public function initialize(array $config): void {
],
// Related models whose permissions we'll need, typically for table views
'related' => [
'Addresses',
'AdHocAttributes',
'Names',
'EmailAddresses',
'ExternalIdentities',
'HistoryRecords',
'IdentifierAssignments',
'Identifiers',
'PersonRoles',
'ProvisioningTargets',
'TelephoneNumbers',
'Urls'
'entity' => [],
'table' => [
'Addresses',
'AdHocAttributes',
'Names',
'EmailAddresses',
'ExternalIdentities',
'HistoryRecords',
'IdentifierAssignments',
'Identifiers',
'PersonRoles',
'ProvisioningTargets',
'TelephoneNumbers',
'Urls'
],
]
]);
}
Expand Down Expand Up @@ -660,7 +663,7 @@ public function validationDefault(Validator $validator): Validator {
'content' => ['rule' => 'isInteger']
]);
$validator->notEmptyString('co_id');

$validator->add('status', [
'content' => ['rule' => ['inList', StatusEnum::getConstValues()]]
]);
Expand Down
2 changes: 1 addition & 1 deletion app/templates/ExternalIdentities/fields-nav.inc
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ $topLinks = [
'link' => [
'controller' => 'ext_identity_source_records',
'action' => 'view',
$vv_obj->ext_identity_source_records[0]->id
$vv_obj->ext_identity_source_record->id
]
]
];
Expand Down
Loading

0 comments on commit 6c06000

Please sign in to comment.