Skip to content

Commit c97089a

Browse files
authored
Merge branch 'Internet2:main' into CO-2677
2 parents 52c1f62 + 9628024 commit c97089a

64 files changed

Lines changed: 2677 additions & 226 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

app/AvailablePlugin/DuplicateCheckEnroller/Controller/DuplicateCheckEnrollerCoPetitionsController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ protected function execute_plugin_start($id, $onFinish) {
7070
$this->set('vv_duplicate_account', $duplicate_account);
7171
$this->set('vv_petition_id', $id);
7272

73-
$remote_user = getenv($duplicate_account['DuplicateCheckEnroller']['env_remote_user']);
73+
$remote_user = getenv($duplicate_account['DuplicateCheckEnroller']['env_remote_user'] ?? IdentifierEnum::ePPN);
7474

7575
if(empty($remote_user)) {
7676
throw new RuntimeException(_txt('er.duplicate_check_enrollers.remote_user.notfound'));

app/AvailablePlugin/DuplicateCheckEnroller/Lib/lang.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545
// Fields
4646
'fd.duplicate_check_enrollers.env_remote_user' => 'Enviromental Variable',
47-
'fd.duplicate_check_enrollers.env_remote_user.desc' => 'Enviromental Variable used to save the REMOTE USER',
47+
'fd.duplicate_check_enrollers.env_remote_user.desc' => 'Enviromental Variable used to save the REMOTE USER, defaults to ePPN type',
4848
'fd.duplicate_check_enrollers.identifier_type' => 'Identifier Type',
4949
'fd.duplicate_check_enrollers.identifier_type.desc' => 'Identifier Type to query for (e.g. ePPN)',
5050
'fd.duplicate_check_enrollers.redirect_url' => 'Redirect URL',

app/AvailablePlugin/EligibilityWidget/Controller/CoEligibilityWidgetsController.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,18 +188,22 @@ public function assign($id) {
188188
$this->layout = 'ajax';
189189

190190
if (empty($this->request->params['pass'][0])) {
191+
$this->log(__METHOD__ . "::message " . _txt('pl.er.eligibilitywidget.param.notfound', array(_txt('ct.eligibility_widget.1') . ' Id')), LOG_ERROR);
191192
throw new BadRequestException(_txt('pl.er.eligibilitywidget.param.notfound', array(_txt('ct.eligibility_widget.1') . ' Id')));
192193
}
193194
if (empty($this->request->data['cou_id'])) {
195+
$this->log(__METHOD__ . "::message " . _txt('pl.er.eligibilitywidget.param.notfound', array('cou_id')), LOG_ERROR);
194196
throw new BadRequestException(_txt('pl.er.eligibilitywidget.param.notfound', array('cou_id')));
195197
}
196198
if(empty($this->request->data['co_person_id'])) {
199+
$this->log(__METHOD__ . "::message " . _txt('pl.er.eligibilitywidget.param.notfound', array('co_person_id')), LOG_ERROR);
197200
throw new BadRequestException(_txt('pl.er.eligibilitywidget.param.notfound', array('co_person_id')));
198201
}
199202

200203
// I need to verify that the CO Person is part of the CO
201204
$copersonid = $this->request->data['co_person_id'];
202205
if(!$this->Role->isCoPerson($copersonid, $this->cur_co["Co"]["id"])) {
206+
$this->log(__METHOD__ . "::message " . _txt('er.cop.nf', array($copersonid)), LOG_ERROR);
203207
throw new NotFoundException(_txt('er.cop.nf', array($copersonid)));
204208
}
205209

@@ -217,6 +221,7 @@ public function assign($id) {
217221
$this->CoPersonRole->save($copr);
218222

219223
if(!$this->CoPersonRole->save($copr)) {
224+
$this->log(__METHOD__ . "::message " . _txt('er.db.save'), LOG_ERROR);
220225
throw new InternalErrorException(_txt('er.db.save'));
221226
}
222227

@@ -292,19 +297,23 @@ public function eligibility($id) {
292297
$this->layout = 'ajax';
293298

294299
if (empty($this->request->params['pass'][0])) {
300+
$this->log(__METHOD__ . "::message " . _txt('pl.er.eligibilitywidget.param.notfound', array(_txt('ct.eligibility_widget.1') . ' Id')), LOG_ERROR);
295301
throw new BadRequestException(_txt('pl.er.eligibilitywidget.param.notfound', array(_txt('ct.eligibility_widget.1') . ' Id')));
296302
}
297303

298304
if (empty($this->request->data['ois_id'])) {
305+
$this->log(__METHOD__ . "::message " . _txt('pl.er.eligibilitywidget.param.notfound', array('ois_id')), LOG_ERROR);
299306
throw new BadRequestException(_txt('pl.er.eligibilitywidget.param.notfound', array('ois_id')));
300307
}
301308
if(empty($this->request->data['co_person_id'])) {
309+
$this->log(__METHOD__ . "::message " . _txt('pl.er.eligibilitywidget.param.notfound', array('co_person_id')), LOG_ERROR);
302310
throw new BadRequestException(_txt('pl.er.eligibilitywidget.param.notfound', array('co_person_id')));
303311
}
304312

305313
// I need to verify that the CO Person is part of the CO
306314
$copersonid = $this->request->data['co_person_id'];
307315
if(!$this->Role->isCoPerson($copersonid, $this->cur_co["Co"]["id"])) {
316+
$this->log(__METHOD__ . "::message " . _txt('er.cop.nf', array($copersonid)), LOG_ERROR);
308317
throw new NotFoundException(_txt('er.cop.nf', array($copersonid)));
309318
}
310319

@@ -313,6 +322,7 @@ public function eligibility($id) {
313322
$this->cur_co["Co"]["id"],
314323
$this->request->data['co_person_id']);
315324
} catch(Exception $e) {
325+
$this->log(__METHOD__ . "::message " .$e->getMessage(), LOG_ERROR);
316326
// Double quotes are not JSON accepted
317327
throw new BadRequestException(str_replace('"', "", $e->getMessage()));
318328
}
@@ -343,9 +353,11 @@ public function personroles($id) {
343353
$this->layout = 'ajax';
344354

345355
if (empty($this->request->params['pass'][0])) {
356+
$this->log(__METHOD__ . "::message " . _txt('pl.er.eligibilitywidget.param.notfound', array(_txt('ct.eligibility_widget.1') . ' Id')), LOG_ERROR);
346357
throw new BadRequestException(_txt('pl.er.eligibilitywidget.param.notfound', array(_txt('ct.eligibility_widget.1') . ' Id')));
347358
}
348359
if(empty($this->request->query["copersonid"])) {
360+
$this->log(__METHOD__ . "::message " . _txt('pl.er.eligibilitywidget.param.notfound', array('copersonid')), LOG_ERROR);
349361
throw new BadRequestException(_txt('pl.er.eligibilitywidget.param.notfound', array('copersonid')));
350362
}
351363

@@ -369,6 +381,7 @@ public function personroles($id) {
369381

370382
$roles = $this->CoPersonRole->find('all', $args);
371383
} catch(Exception $e) {
384+
$this->log(__METHOD__ . "::message " .$e->getMessage(), LOG_ERROR);
372385
// Double quotes are not JSON accepted
373386
throw new BadRequestException(str_replace('"', "", $e->getMessage()));
374387
}
@@ -393,12 +406,14 @@ public function sync($id) {
393406
$this->layout = 'ajax';
394407

395408
if(empty($this->request->query["copersonrole"])) {
409+
$this->log(__METHOD__ . "::message " . _txt('pl.er.eligibilitywidget.param.specify'), LOG_ERROR);
396410
throw new InvalidArgumentException(_txt('pl.er.eligibilitywidget.param.specify'));
397411
}
398412

399413
try{
400414
$data = $this->CoEligibilityWidget->syncEligibility($this->request->query["copersonrole"]);
401415
} catch(Exception $e) {
416+
$this->log(__METHOD__ . "::message " .$e->getMessage(), LOG_ERROR);
402417
throw new BadRequestException(str_replace('"', "", $e->getMessage()));
403418
}
404419

app/AvailablePlugin/EligibilityWidget/Model/CoEligibilityWidget.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ public function allPersonOrgIdentityFromSource($coId, $coPersonId) {
130130
$args['conditions']['CoOrgIdentityLink.co_person_id'] = $coPersonId;
131131
$args['conditions'][] = 'PipelineCoPersonRole.source_org_identity_id IS NOT NULL';
132132
$args['conditions']['OrgIdentity.co_id'] = $coId;
133+
$args['contain'] = false;
133134

134135
$OrgIdentity = ClassRegistry::init('OrgIdentity');
135136
$org_identities = $OrgIdentity->find('all', $args);
@@ -180,7 +181,6 @@ public function checkEligibility($oidId, $coId, $coPersonId) {
180181
throw new InvalidArgumentException(_txt('pl.er.eligibilitywidget.ois.inappropriate'));
181182
}
182183

183-
$ret = array();
184184
foreach($emailAddresses as $ea) {
185185
if (!empty($ea['EmailAddress']['mail'])) {
186186
try {
@@ -307,7 +307,9 @@ public function personCouMembership($copersonid,
307307
$args['joins'][0]['table'] = 'cous';
308308
$args['joins'][0]['alias'] = 'Cou';
309309
$args['joins'][0]['type'] = 'INNER';
310-
$args['joins'][0]['conditions'][0] = 'CoPersonRole.cou_id=Cou.id';
310+
$args['joins'][0]['conditions'][] = 'CoPersonRole.cou_id=Cou.id';
311+
$args['joins'][0]['conditions'][] = 'Cou.deleted IS NOT TRUE';
312+
$args['joins'][0]['conditions'][] = 'Cou.cou_id IS NULL';
311313
$args['conditions']['CoPersonRole.co_person_id'] = $copersonid;
312314
$args['conditions'][] = 'CoPersonRole.deleted IS NOT true';
313315
$args['conditions'][] = 'CoPersonRole.co_person_role_id IS NULL';

app/AvailablePlugin/SqlSource/Lib/lang.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,9 @@
4242
SqlSourceTableModeEnum::Relational => 'Relational Tables'
4343
),
4444

45-
/*
4645
// Error messages
47-
'er.sqlsource.placeholder' => 'Placeholder',
48-
*/
49-
46+
'er.sqlsource.source_table' => 'Source Table Name must consist only of alphanumeric characters, dots, dashes, and underscores',
47+
5048
// Plugin texts
5149
'pl.sqlsource.source_table' => 'Source Table',
5250
'pl.sqlsource.table_mode' => 'Table Mode',

app/AvailablePlugin/SqlSource/Model/SqlSource.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,11 @@ class SqlSource extends AppModel {
6767
// We need to constrain the table name here not just for SQL conformance
6868
// but because SqlSourceBackend will construct raw SQL queries using the
6969
// source_table name.
70-
'rule' => '/^[a-zA-Z0-9\-\.]+$/',
70+
// Commit with PMO 1156
71+
'rule' => '/^[a-zA-Z0-9_\-\.]+$/',
7172
'required' => true,
72-
'allowEmpty' => false
73+
'allowEmpty' => false,
74+
'message' => 'Source Table Name must consist only of alphanumeric characters, dots, dashes, and underscores'
7375
),
7476
'server_id' => array(
7577
'content' => array(

app/AvailablePlugin/SqlSource/Model/SqlSourceBackend.php

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,21 +85,27 @@ protected function getAdHocAttributes() {
8585
);
8686

8787
// Introspect the inbound attributes
88-
$SourceRecord = $this->getRecordModel();
89-
90-
$columnTypes = $SourceRecord->getColumnTypes();
88+
try {
89+
$SourceRecord = $this->getRecordModel();
90+
91+
$columnTypes = $SourceRecord->getColumnTypes();
92+
}
93+
catch(MissingTableException $e) {
94+
// If there is no AdHocAttribute table just return an empty array
95+
return array();
96+
}
9197

9298
return array_diff(array_keys($columnTypes), $standardAttrs);
9399
} else {
94100
// In Relational mode, we pull the unique tags
95101

96-
$AdHoc = $this->getRecordModel('AdHocAttribute');
97-
98-
$args = array();
99-
$args['fields'] = 'DISTINCT '.$AdHoc->alias.'.tag';
100-
$args['contain'] = false;
101-
102102
try {
103+
$AdHoc = $this->getRecordModel('AdHocAttribute');
104+
105+
$args = array();
106+
$args['fields'] = 'DISTINCT '.$AdHoc->alias.'.tag';
107+
$args['contain'] = false;
108+
103109
// find('list') would make more sense but because of the nature of our
104110
// query doesn't work so well
105111
$tags = $AdHoc->find('all', $args);
@@ -204,6 +210,14 @@ protected function getChangeListFromArchive() {
204210
// and in Full Mode OrgIdentitySource::syncOrgIdentitySource will separately
205211
// calculate the list of new IDs. Note order is important, if $archiveTableName
206212
// and $sourceTableName are swapped, the query will generate INSERTs but not DELETEs.
213+
214+
// Note that because we can't return new rows here bootstrapping an existing
215+
// instannce gets a bit complicated. Basically we won't be able to detect any
216+
// changes until the archive tables are populated, and we need an external event
217+
// to make that happen. In FULL mode, a new record will trigger a call to updateCache(),
218+
// but that might happen after several updates get ignored. In UPDATE mode
219+
// new records won't get processed so we never have the cache updated. The
220+
// solution (for now) is for the deployer to prepopulate the tables.
207221
$diffQuery = "SELECT * FROM " . $archiveTableName . " EXCEPT
208222
SELECT * FROM " . $sourceTableName;
209223

@@ -226,7 +240,7 @@ protected function getChangeListFromArchive() {
226240
}
227241

228242
// We perform an array_unique here once rather than after each merge
229-
return !empty($changedSorids) ? array_unique($changedSorids) : false;
243+
return !empty($changedSorids) ? array_unique($changedSorids) : array();
230244
}
231245

232246
/**

app/Config/Schema/schema.xml

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -450,10 +450,19 @@
450450
<field name="remote_ip" type="C" size="80" />
451451
<field name="created" type="T" />
452452
<field name="modified" type="T" />
453-
453+
<field name="api_user_id" type="I">
454+
<constraint>REFERENCES cm_api_users(id)</constraint>
455+
</field>
456+
<field name="revision" type="I" />
457+
<field name="deleted" type="L" />
458+
<field name="actor_identifier" type="C" size="256" />
459+
454460
<index name="api_users_i1">
455461
<col>username</col>
456-
<unique />
462+
</index>
463+
464+
<index name="api_users_i2">
465+
<col>api_user_id</col>
457466
</index>
458467
</table>
459468

@@ -1254,7 +1263,36 @@
12541263
<col>source_label</col>
12551264
</index>
12561265
</table>
1257-
1266+
1267+
<table name="co_provisioning_targets">
1268+
<field name="id" type="I">
1269+
<key />
1270+
<autoincrement />
1271+
</field>
1272+
<field name="co_id" type="I">
1273+
<notnull />
1274+
<constraint>REFERENCES cm_cos(id)</constraint>
1275+
</field>
1276+
<field name="description" type="C" size="256" />
1277+
<field name="plugin" type="C" size="32" />
1278+
<field name="provision_co_group_id" type="I">
1279+
<constraint>REFERENCES cm_co_groups(id)</constraint>
1280+
</field>
1281+
<field name="skip_org_identity_source_id" type="I">
1282+
<constraint>REFERENCES cm_org_identity_sources(id)</constraint>
1283+
</field>
1284+
<field name="status" type="C" size="2" />
1285+
<field name="retry_interval" type="I" />
1286+
<field name="max_retry" type="I" />
1287+
<field name="ordr" type="I" />
1288+
<field name="created" type="T" />
1289+
<field name="modified" type="T" />
1290+
1291+
<index name="co_provisioning_targets_i1">
1292+
<col>co_id</col>
1293+
</index>
1294+
</table>
1295+
12581296
<table name="co_provisioning_counts">
12591297
<field name="id" type="I">
12601298
<key />
@@ -1288,35 +1326,6 @@
12881326
</index>
12891327
</table>
12901328

1291-
<table name="co_provisioning_targets">
1292-
<field name="id" type="I">
1293-
<key />
1294-
<autoincrement />
1295-
</field>
1296-
<field name="co_id" type="I">
1297-
<notnull />
1298-
<constraint>REFERENCES cm_cos(id)</constraint>
1299-
</field>
1300-
<field name="description" type="C" size="256" />
1301-
<field name="plugin" type="C" size="32" />
1302-
<field name="provision_co_group_id" type="I">
1303-
<constraint>REFERENCES cm_co_groups(id)</constraint>
1304-
</field>
1305-
<field name="skip_org_identity_source_id" type="I">
1306-
<constraint>REFERENCES cm_org_identity_sources(id)</constraint>
1307-
</field>
1308-
<field name="status" type="C" size="2" />
1309-
<field name="retry_interval" type="I" />
1310-
<field name="max_retry" type="I" />
1311-
<field name="ordr" type="I" />
1312-
<field name="created" type="T" />
1313-
<field name="modified" type="T" />
1314-
1315-
<index name="co_provisioning_targets_i1">
1316-
<col>co_id</col>
1317-
</index>
1318-
</table>
1319-
13201329
<table name="identifiers">
13211330
<field name="id" type="I">
13221331
<key />

app/Config/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4.2.1
1+
4.3.0

app/Controller/CoPeopleController.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,14 @@ public function beforeRender() {
237237
$args['contain'] = false;
238238

239239
$this->set('vv_vetting_step_count', $this->Co->VettingStep->find('count', $args));
240+
241+
// Calculate COU node path from root in case the role COU has a parent id.
242+
foreach($this->viewVars["co_people"][0]["CoPersonRole"] as $idx => $prole) {
243+
if(isset($prole['Cou']['id'])) {
244+
// Add the path to parent node under the COU record
245+
$this->viewVars["co_people"][0]["CoPersonRole"][$idx]["Cou"]["path"] = $this->constructTreeParentPath($prole['Cou']['id']);
246+
}
247+
}
240248
}
241249

242250
parent::beforeRender();
@@ -474,7 +482,29 @@ public function compare($id) {
474482
$this->view($id);
475483
}
476484
}
477-
485+
486+
/**
487+
* Create path from parent
488+
*
489+
* @param int $nodeId The ID of the node
490+
* @return string The path
491+
*
492+
* @since COmanage Registry v4.3.0
493+
*/
494+
public function constructTreeParentPath($nodeId) {
495+
if(empty($nodeId)) return "";
496+
if(!$this->CoPerson->CoPersonRole->Cou->Behaviors->enabled('Tree')) {
497+
return "";
498+
}
499+
500+
$parents = $this->CoPerson->CoPersonRole->Cou->getPath($nodeId);
501+
502+
if(empty($parents)) return "";
503+
504+
$parent_names = Hash::extract($parents, '{n}.Cou.name');
505+
return implode(" / ", $parent_names);
506+
}
507+
478508
/**
479509
* Expunge (delete with intelligent clean up) a CO Person.
480510
* - precondition: <id> must exist

0 commit comments

Comments
 (0)