Skip to content

Commit

Permalink
fix related permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
Ioannis committed Feb 12, 2024
1 parent af1c76c commit c4a2643
Show file tree
Hide file tree
Showing 10 changed files with 184 additions and 74 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
21 changes: 20 additions & 1 deletion 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 @@ -159,6 +159,25 @@ public function initialize(array $config): void {
'table' => [
'add' => ['platformAdmin', 'coAdmin'],
'index' => ['platformAdmin', 'coAdmin']
],
// Related models whose permissions we'll need, typically for table views
'related' => [
'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
Loading

0 comments on commit c4a2643

Please sign in to comment.