Skip to content

CFM-31_Enrollment_Flows_enable_people_picker_for_self_service #324

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/config/schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,7 @@
"plugin": {},
"ordr": {},
"actor_type": { "type": "string", "size": 2 },
"enable_person_find": { "type": "boolean" },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know on the dev call we decided to move this configuration to EnrollmentFlowStep, but on further reflection I wonder if it should actually be specific to the AttributeCollector? I don't think any other plugin is likely to use this setting...

"approver_group_id": { "type": "integer", "foreignkey": { "table": "groups", "column": "id" }},
"message_template_id": {},
"redirect_on_handoff": { "type": "string", "size": 256 },
Expand Down
6 changes: 6 additions & 0 deletions app/resources/locales/en_US/field.po
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,12 @@ msgstr "Limit Global Search Scope"
msgid "CoSettings.search_global_limited_models.desc"
msgstr "If true, Global Search will only search Names, Email Addresses, and Identifiers. This may result in faster searches for larger deployments."

msgid "EnrollmentFlowSteps.enable_person_find"
msgstr "Enable People Picker for Self Service"

msgid "EnrollmentFlowSteps.enable_person_find.desc"
msgstr "Enable people picker for self-service enrollments, see <a href=\"https://spaces.at.internet2.edu/display/COmanage/COmanage+Registry+PE+Technical+Manual\">Registry Technical Manual</a> for privacy considerations"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll need a deep link to the specific page (and preferably anchor) with the discussion of privacy consideration. This probably belongs in the Attribute Collector documentation.


msgid "EnrollmentFlowSteps.actor_type"
msgstr "Actor Type"

Expand Down
56 changes: 53 additions & 3 deletions app/src/Controller/ApiV2Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@

namespace App\Controller;

use Cake\Controller\Controller;
use InvalidArgumentException;
use App\Lib\Enum\EnrollmentAuthzEnum;
use Cake\Chronos\Chronos;
use Cake\Controller\Controller;
use Cake\Event\EventInterface;
use Cake\Http\Exception\BadRequestException;
use Cake\Log\Log;
use Cake\ORM\TableRegistry;
use Cake\Utility\Inflector;

use InvalidArgumentException;
use \App\Lib\Enum\ProvisioningContextEnum;
use \App\Lib\Enum\SuspendableStatusEnum;

Expand Down Expand Up @@ -410,4 +411,53 @@ public function view($id = null) {
public function pick() {
$this->dispatchIndex(mode: 'picker');
}

/**
* Indicate whether this Controller will handle some or all authnz.
*
* @param EventInterface $event Cake event, ie: from beforeFilter
* @return string "no", "open", "authz", "yes", or "notauth"
* @since COmanage Registry v5.2.0
*/
public function willHandleAuth(\Cake\Event\EventInterface $event): string
{
$request = $this->getRequest();
$reqAction = $request->getParam('action');
$session = $request->getSession();
$mode = 'no';

$auth = $session->read('Auth');

// Calculate people picker permissions on the fly for an enrollment flow/petition
if(
$this->name == 'People'
&& $reqAction == 'pick'
&& !empty($request->getQuery('petition_id'))
) {
$petitionId = (int)$request->getQuery('petition_id');
// We need to check if this is part of an Enrollment Flow
$Petitions = TableRegistry::getTableLocator()->get('Petitions');

// Pull the Petition to find its CO
$petition = $Petitions->get($petitionId, ['contain' => ['EnrollmentFlows' => ['EnrollmentFlowSteps']]]);

// We need to check the Petitioner Authorization.
$hasAuthorizedUser = false;
if ($petition->enrollment_flow->authz_type == EnrollmentAuthzEnum::AuthUser) {
$hasAuthorizedUser = !empty($auth['external']['user']);
} else {
// This will be the no authorization use case.
$hasAuthorizedUser = true;
}

foreach ($petition->enrollment_flow->enrollment_flow_steps as $step) {
if ($step->plugin == 'CoreEnroller.AttributeCollectors') {
$mode = $hasAuthorizedUser && $step->enable_person_find ? 'yes' : 'no';
}
}
}

// Apply standard behavior
return $mode;
}
}
8 changes: 4 additions & 4 deletions app/src/Controller/Component/RegistryAuthComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ protected function calculatePermission(string $action, ?int $id=null): bool {
* Obtain the permission set for this request.
*
* @since COmanage Registry v5.0.0
* @param int $id Subject ID, if applicable
* @param int|null $id Subject ID, if applicable
* @return array Array of actions and authorized roles
*/

Expand Down Expand Up @@ -719,8 +719,8 @@ public function getPersonID(int $coId): ?int {
* Obtain the set of permissions as provided by the table.
*
* @since COmanage Registry v5.0.0
* @param table $table Cake Table
* @param int $id Entity ID, if applicable
* @param table $table Cake Table
* @param int|null $id Entity ID, if applicable
* @return array Table permissions
*/

Expand Down Expand Up @@ -857,7 +857,7 @@ public function isAuthenticatedUser(): bool {
* Determine if the current user is a CO Administrator.
*
* @since COmanage Registry v5.0.0
* @param int $coId CO ID
* @param int|null $coId CO ID
* @return bool True if the current user is a CO Administrator
*/

Expand Down
1 change: 1 addition & 0 deletions app/src/Controller/PeopleController.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
namespace App\Controller;

// XXX not doing anything with Log yet
use Cake\Event\EventInterface;
use Cake\Log\Log;
use Cake\ORM\TableRegistry;
use http\QueryString;
Expand Down
32 changes: 32 additions & 0 deletions app/src/View/Helper/FieldHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
use App\Lib\Enum\DateTypeEnum;
use App\Lib\Util\StringUtilities;
use Cake\I18n\FrozenTime;
use Cake\ORM\Table;
use Cake\ORM\TableRegistry;
use Cake\Utility\Inflector;
use Cake\View\Helper;
use DOMDocument;
Expand Down Expand Up @@ -548,6 +550,36 @@ public function getReqFields(): array
return $this->reqFields;
}

/**
* Get reference to the Table Object
*
* @param string $tableName
*
* @return Table
* @since COmanage Registry v5.2.0
*/
public function getTable(string $tableName): Table
{
return TableRegistry::getTableLocator()->get($tableName);
}

/**
* Get attribute collectors configuration for a specific enrollment flow step
*
* @param int $stepId The ID of the enrollment flow step
* @return array The attribute collectors configuration array containing enrollment attributes
* @since COmanage Registry v5.2.0
*/
public function getAttributeCollectorsForStep(int $stepId): array
{
$AttributeCollectors = $this->getTable('CoreEnroller.AttributeCollectors');
return $AttributeCollectors->find()
->where(['enrollment_flow_step_id' => $stepId])
->contain(['EnrollmentAttributes'])
->first()
->toArray();
}

/**
* For the records that have a value like co_x.value, and we want to handle
* the value separate from the field
Expand Down
2 changes: 1 addition & 1 deletion app/src/View/Helper/PetitionHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public function populateAutoViewVars(): void
{
// XXX Find the co id
foreach (
$this->enrollmentAttributesTable->calculateAutoViewVars($this->petition?->enrollment_flow?->co_id,$this->entity) as $vvar => $value
$this->enrollmentAttributesTable->calculateAutoViewVars($this->petition?->enrollment_flow?->co_id, $this->entity) as $vvar => $value
) {
$this->getView()->set($vvar, $value);
}
Expand Down
52 changes: 26 additions & 26 deletions app/templates/CoSettings/fields.inc
Original file line number Diff line number Diff line change
Expand Up @@ -96,32 +96,32 @@ if($vv_action == 'edit') {
'fieldName' => 'search_global_limited_models'
]]);

print $this->element('form/listItem', [
'arguments' => [
'fieldName' => 'person_picker_display_fields',
'labelIsTextOnly' => true,
'groupedControls' => [
// each key is the fieldName of the control we are going to create
'person_picker_email_address_type_id' => [
'fieldOptions' => [
'label' => __d('field', 'mail'),
'empty' => '(' . __d('operation', 'all') . ')',
// 'all' => '(' . __d('operation', 'all') . ')'
],
],
'person_picker_identifier_type_id' => [
'fieldOptions' => [
'label' => __d('field', 'identifier'),
'empty' => '(' . __d('operation', 'all') . ')',
// 'all' => '(' . __d('operation', 'all') . ')',
],
],
'person_picker_display_types' => [
'singleRowItem' => true,
'fieldLabel' => __d('field', 'CoSettings.person_picker_display_types')
]
],
]]);
// print $this->element('form/listItem', [
// 'arguments' => [
// 'fieldName' => 'person_picker_display_fields',
// 'labelIsTextOnly' => true,
// 'groupedControls' => [
// // each key is the fieldName of the control we are going to create
// 'person_picker_email_address_type_id' => [
// 'fieldOptions' => [
// 'label' => __d('field', 'mail'),
// 'empty' => '(' . __d('operation', 'all') . ')',
//// 'all' => '(' . __d('operation', 'all') . ')'
// ],
// ],
// 'person_picker_identifier_type_id' => [
// 'fieldOptions' => [
// 'label' => __d('field', 'identifier'),
// 'empty' => '(' . __d('operation', 'all') . ')',
//// 'all' => '(' . __d('operation', 'all') . ')',
// ],
// ],
// 'person_picker_display_types' => [
// 'singleRowItem' => true,
// 'fieldLabel' => __d('field', 'CoSettings.person_picker_display_types')
// ]
// ],
// ]]);
Comment on lines -99 to +124
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we removing these configurations from CO Settings? If so, we should remove them from schema.json and the model code as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we are. I will make the extra changes.


print $this->element('form/listItem', [
'arguments' => [
Expand Down
16 changes: 16 additions & 0 deletions app/templates/EnrollmentFlowSteps/fields.inc
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,22 @@ if($vv_action == 'add' || $vv_action == 'edit') {
]]);
}

// The people picker enable checkbox is only useful for the attribute collection plugin.
if ($vv_obj->plugin === 'CoreEnroller.AttributeCollectors') {
$attributeCollectorConfig = $this->Field->getAttributeCollectorsForStep( $vv_obj->id);
$sponsorAttribute = array_filter(
$attributeCollectorConfig["enrollment_attributes"],
fn($enrollmentAttribute) => $enrollmentAttribute['attribute'] == 'sponsor_person_id'
);
print $this->element('form/listItem', [
'arguments' => [
'fieldName' => 'enable_person_find',
'fieldOptions' => [
'readonly' => empty($sponsorAttribute)
]
]]);
}

print $this->element('form/listItem', [
'arguments' => [
'fieldName' => 'actor_type',
Expand Down