comanage-dev - [comanage-dev] r629 - in registry/trunk/app: Config/Schema Controller Controller/Component Lib Model View/CoEnrollmentFlows View/CoPetitions
Subject: COmanage Developers List
List archive
[comanage-dev] r629 - in registry/trunk/app: Config/Schema Controller Controller/Component Lib Model View/CoEnrollmentFlows View/CoPetitions
Chronological Thread
- From:
- To:
- Subject: [comanage-dev] r629 - in registry/trunk/app: Config/Schema Controller Controller/Component Lib Model View/CoEnrollmentFlows View/CoPetitions
- Date: Sun, 17 Nov 2013 11:18:48 -0500
Author: benno
Date: 2013-11-17 11:18:48 -0500 (Sun, 17 Nov 2013)
New Revision: 629
Modified:
registry/trunk/app/Config/Schema/schema.xml
registry/trunk/app/Controller/AppController.php
registry/trunk/app/Controller/CoPetitionsController.php
registry/trunk/app/Controller/Component/RoleComponent.php
registry/trunk/app/Lib/lang.php
registry/trunk/app/Model/CoEnrollmentFlow.php
registry/trunk/app/Model/CoGroup.php
registry/trunk/app/View/CoEnrollmentFlows/fields.inc
registry/trunk/app/View/CoPetitions/index.ctp
Log:
Improve petition approver configuration (CO-511)
Modified: registry/trunk/app/Config/Schema/schema.xml
===================================================================
--- registry/trunk/app/Config/Schema/schema.xml 2013-11-07 14:53:10 UTC (rev
628)
+++ registry/trunk/app/Config/Schema/schema.xml 2013-11-17 16:18:48 UTC (rev
629)
@@ -549,6 +549,9 @@
</field>
<field name="match_policy" type="C" size="2" />
<field name="approval_required" type="L" />
+ <field name="approver_co_group_id" type="I">
+ <constraint>REFERENCES cm_co_groups(id)</constraint>
+ </field>
<field name="verify_email" type="L" />
<field name="require_authn" type="L" />
<field name="early_provisioning_exec" type="C" size="128" />
Modified: registry/trunk/app/Controller/AppController.php
===================================================================
--- registry/trunk/app/Controller/AppController.php 2013-11-07 14:53:10
UTC (rev 628)
+++ registry/trunk/app/Controller/AppController.php 2013-11-17 16:18:48
UTC (rev 629)
@@ -1097,8 +1097,12 @@
// Select from available enrollment flows?
$p['menu']['createpetition'] = $roles['user'];
- // Manage any CO (or COU) population?
- $p['menu']['petitions'] = $roles['admin'] || $roles['subadmin'];
+ // Review / approve petitions?
+ // XXX this isn't exactly the right check, but then neither are most of
the others (CO-731)
+ $p['menu']['petitions'] = $roles['admin']
+ // XXX A side effect of this current logic is that the link only appears
when the person is viewing
+ // another link with the CO specified in it (otherwise copersonid isn't
set)
+ || ($roles['copersonid'] &&
$this->Role->isApprover($roles['copersonid']));
// Manage CO extended attributes?
$p['menu']['extattrs'] = $roles['admin'];
Modified: registry/trunk/app/Controller/CoPetitionsController.php
===================================================================
--- registry/trunk/app/Controller/CoPetitionsController.php 2013-11-07
14:53:10 UTC (rev 628)
+++ registry/trunk/app/Controller/CoPetitionsController.php 2013-11-17
16:18:48 UTC (rev 629)
@@ -416,8 +416,11 @@
$p['add'] = ($roles['cmadmin'] || $flowAuthorized);
// Approve a CO Petition?
- $p['approve'] = ($roles['cmadmin']
- || ($flowAuthorized && ($roles['coadmin'] ||
$roles['couadmin'])));
+ if($this->enrollmentFlowID() != -1) {
+ $p['approve'] = $roles['cmadmin'] ||
$this->Role->isApproverForFlow($roles['copersonid'],
$this->enrollmentFlowID());
+ } else {
+ $p['approve'] = $roles['cmadmin'] ||
$this->Role->isApprover($roles['copersonid']);
+ }
$p['deny'] = $p['approve'];
// Delete an existing CO Petition?
@@ -440,7 +443,7 @@
|| $p['match_policy'] ==
EnrollmentMatchPolicyEnum::Automatic));
// View all existing CO Petitions?
- $p['index'] = ($roles['cmadmin'] || $roles['coadmin'] ||
$roles['couadmin']);
+ $p['index'] = ($roles['cmadmin'] || $roles['coadmin'] ||
$roles['couadmin'] || $this->Role->isApprover($roles['copersonid']));
// Search all existing CO Petitions?
$p['search'] = $p['index'];
@@ -450,25 +453,25 @@
|| ($flowAuthorized && ($roles['coadmin'] ||
$roles['couadmin'])));
// View an existing CO Petition? We allow the usual suspects to view a
Petition, even
- // if they don't have permission to edit it.
- $p['view'] = ($roles['cmadmin'] || $roles['coadmin'] ||
$roles['couadmin']);
+ // if they don't have permission to edit it. Also approvers need to be
able to see the Petition.
+ $p['view'] = ($roles['cmadmin'] || $roles['coadmin'] ||
$roles['couadmin'] || $p['approve']);
if($this->action == 'index' && $p['index']) {
- // Assume the person also has permission to perform various other
actions
- // for purposes of rendering the view, though these assumptions are
probably too generous.
+ // These permissions may not be exactly right, but they only apply
when rendering
+ // the index view
$p['add'] = true; // This is really permission to run
co_enrollment_flows/select
$p['delete'] = ($roles['cmadmin'] || $roles['coadmin']);
- $p['edit'] = true;
- $p['resend'] = true;
- $p['view'] = true;
+ $p['edit'] = $p['delete']; // For now, delete and edit are restricted
+ $p['resend'] = ($roles['cmadmin'] || $roles['coadmin'] ||
$roles['couadmin']);
+ $p['view'] = true; // Approvers will have the petitions they can see
filtered by the controller
}
$this->set('permissions', $p);
return $p[$this->action];
}
- /**
+ /**
* Determine the conditions for pagination of the index view, when
rendered via the UI.
*
* @since COmanage Registry v0.8.3
@@ -489,7 +492,19 @@
$searchterm = $this->params['named']['Search.status'];
$pagcond['CoPetition.status'] = $searchterm;
}
- return($pagcond);
+
+ // Potentially filter by enrollment flow ID. Our assumption is that if
we make it
+ // here the person has authorization to see at least some Petitions.
Either they
+ // are a CO or COU admin (in which case the following list will be
empty) or they
+ // are an approver by group (in which case the following list will not
be empty).
+
+ $efs =
$this->Role->approverFor($this->Session->read('Auth.User.co_person_id'));
+
+ if(!empty($efs)) {
+ $pagcond['CoPetition.co_enrollment_flow_id'] = $efs;
+ }
+
+ return $pagcond;
}
/**
Modified: registry/trunk/app/Controller/Component/RoleComponent.php
===================================================================
--- registry/trunk/app/Controller/Component/RoleComponent.php 2013-11-07
14:53:10 UTC (rev 628)
+++ registry/trunk/app/Controller/Component/RoleComponent.php 2013-11-17
16:18:48 UTC (rev 629)
@@ -29,6 +29,40 @@
private $cache = array();
/**
+ * Determine what CO Enrollment Flows a CO Person may approve. Note this
function
+ * will only return enrollment flows where the CO Person is an approver by
way
+ * of group membership. CO/COU Admins will return empty lists.
+ *
+ * @since COmanage Registry v0.8.3
+ * @param Integer CO Person ID
+ * @return Array List CO Enrollment Flow IDs
+ * @throws InvalidArgumentException
+ */
+
+ public function approverFor($coPersonId) {
+ if(!$coPersonId) {
+ return array();
+ }
+
+ // Use a join to pull enrollment flows where $coPersonId is in the
approver group
+
+ $CoEnrollmentFlow = ClassRegistry::init('CoEnrollmentFlow');
+
+ $args['fields'][] = 'CoEnrollmentFlow.id';
+ $args['joins'][0]['table'] = 'co_group_members';
+ $args['joins'][0]['alias'] = 'CoGroupMember';
+ $args['joins'][0]['type'] = 'INNER';
+ $args['joins'][0]['conditions'][0] =
'CoEnrollmentFlow.approver_co_group_id=CoGroupMember.co_group_id';
+ $args['conditions']['CoGroupMember.co_person_id'] = $coPersonId;
+ $args['contain'] = false;
+
+ $efs = $CoEnrollmentFlow->find('list', $args);
+
+ // find() will return id => id with only one field specified, so just
pull the keys
+ return array_keys($efs);
+ }
+
+ /**
* Cached CO ID lookup.
*
* @since COmanage Registry v0.8
@@ -587,6 +621,150 @@
}
/**
+ * Determine if a CO Person has the ability to approve petitions for any
enrollment flow.
+ *
+ * @since COmanage Registry v0.8.3
+ * @param Integer CO Person ID
+ * @return Boolean True if the CO Person is an approver for any enrollment
flow, false otherwise
+ */
+
+ public function isApprover($coPersonId) {
+ // First check the cache
+
+ if(isset($this->cache['coperson'][$coPersonId]['co_ef']['approver'])) {
+ return $this->cache['coperson'][$coPersonId]['co_ef']['approver'];
+ }
+
+ $ret = false;
+
+ // Make sure we have a CO Person ID
+
+ if(!$coPersonId) {
+ throw new InvalidArgumentException(_txt('er.cop.unk'));
+ }
+
+ // Find the person's CO
+
+ try {
+ $coId = $this->cachedCoIdLookup($coPersonId);
+ }
+ catch(InvalidArgumentException $e) {
+ throw new InvalidArgumentException($e->getMessage());
+ }
+
+ // A person is an approver if
+ // (1) they are a CO Admin or COU Admin (note they may not actually have
the ability to approve anything)
+ // (2) they are a member of any group that is an approver group for any
enrollment flow in the CO
+
+ if($this->isCoOrCouAdmin($coPersonId, $coId)) {
+ $ret = true;
+ } else {
+ // Pull groups associated with enrollment flows in $coID
+
+ $args = array();
+ $args['conditions']['CoEnrollmentFlow.co_id'] = $coId;
+ $args['conditions']['CoEnrollmentFlow.status'] = StatusEnum::Active;
+ $args['conditions'][] = 'CoEnrollmentFlow.approver_co_group_id IS NOT
NULL';
+ $args['fields'][] = 'DISTINCT (approver_co_group_id)';
+ $args['contain'] = false;
+
+ $CoEnrollmentFlow = ClassRegistry::init('CoEnrollmentFlow');
+
+ $groups = $CoEnrollmentFlow->find('first', $args);
+
+ foreach($groups as $g) {
+ if(!empty($g['approver_co_group_id'])) {
+ if($this->isCoGroupMember($coPersonId,
$g['approver_co_group_id'])) {
+ // Person is member of this group, so is an approver for at
least one group
+ $ret = true;
+ break;
+ }
+ }
+ }
+ }
+
+ // Update the cache
+ $this->cache['coperson'][$coPersonId]['co_ef']['approver'] = $ret;
+
+ return $ret;
+ }
+
+ /**
+ * Determine if a CO Person has the ability to approve petitions for the
specified enrollment flow.
+ *
+ * @since COmanage Registry v0.8.3
+ * @param Integer CO Person ID
+ * @param Integer CO Enrollment Flow ID
+ * @return Boolean True if the CO Person is an approver for any enrollment
flow, false otherwise
+ * @throws InvalidArgumentException
+ */
+
+ public function isApproverForFlow($coPersonId, $coEfId) {
+ // First check the cache
+
+
if(isset($this->cache['coperson'][$coPersonId]['co_ef'][$coEfId]['approver']))
{
+ return
$this->cache['coperson'][$coPersonId]['co_ef'][$coEfId]['approver'];
+ }
+
+ $ret = false;
+
+ // Make sure we have a CO Person ID
+
+ if(!$coPersonId) {
+ throw new InvalidArgumentException(_txt('er.cop.unk'));
+ }
+
+ // Try to find the enrollment flow
+
+ $args = array();
+ $args['conditions']['CoEnrollmentFlow.id'] = $coEfId;
+ $args['conditions']['CoEnrollmentFlow.status'] = StatusEnum::Active;
+ $args['contain'] = false;
+
+ $CoEnrollmentFlow = ClassRegistry::init('CoEnrollmentFlow');
+
+ $coEF = $CoEnrollmentFlow->find('first', $args);
+
+ if(empty($coEF)) {
+ throw new InvalidArgumentException(_txt('er.coef.unk'));
+ }
+
+ if($coEF['CoEnrollmentFlow']['approval_required']) {
+ if(!empty($coEF['CoEnrollmentFlow']['approver_co_group_id'])) {
+ // $coPersonId must be a member of this group
+
+ if($this->isCoGroupMember($coPersonId,
$coEF['CoEnrollmentFlow']['authz_co_group_id'])) {
+ $ret = true;
+ }
+ } else {
+ // If no group is defined, then we use the following logic:
+ // (1) $coPersonId is a CO admin
+
+ if($this->isCoAdmin($coPersonId,
$coEF['CoEnrollmentFlow']['co_id'])) {
+ $ret = true;
+ }
+
+ if(!empty($coEF['CoEnrollmentFlow']['authz_cou_id'])) {
+ // (2) authz_cou_id is specified and $coPersonId is a COU admin
for that COU
+
+ $ret = $this->isCouAdmin($coPersonId,
$coEF['CoEnrollmentFlow']['authz_cou_id']);
+ } else {
+ // (3) No authz_cou_id is specified and $coPersonId is a COU admin
+
+ $ret = $this->isCouAdmin($coPersonId);
+ }
+ }
+ } else {
+ // No approval required
+ }
+
+ // Update the cache
+ $this->cache['coperson'][$coPersonId]['co_ef'][$coEfId]['approver'] =
$ret;
+
+ return $ret;
+ }
+
+ /**
* Determine if a CO Person is a CO Administrator.
*
* @since COmanage Registry v0.7
Modified: registry/trunk/app/Lib/lang.php
===================================================================
--- registry/trunk/app/Lib/lang.php 2013-11-07 14:53:10 UTC (rev 628)
+++ registry/trunk/app/Lib/lang.php 2013-11-17 16:18:48 UTC (rev 629)
@@ -504,7 +504,8 @@
'fd.ef.asub' => 'Subject For Approval Email',
'fd.ef.asub.desc' => 'Subject line for email message sent after Petition
is approved.',
'fd.ef.appr' => 'Require Approval For Enrollment',
- 'fd.ef.appr.desc' => 'If administrator approval is required, a member of
the appropriate <tt>admin.approvers</tt> group must approve the enrollment',
+ 'fd.ef.appr.desc' => 'If administrator approval is required, a Petition
must be approved before the Enrollee becomes active.',
+ 'fd.ef.appr.gr' => 'Members of this Group are authorized approvers (or
else CO/COU admins by default)',
'fd.ef.authn' => 'Require Authentication',
'fd.ef.authn.desc' => 'Require enrollee to authenticate in order to
complete their enrollment',
'fd.ef.authz' => 'Enrollment Authorization',
Modified: registry/trunk/app/Model/CoEnrollmentFlow.php
===================================================================
--- registry/trunk/app/Model/CoEnrollmentFlow.php 2013-11-07 14:53:10
UTC (rev 628)
+++ registry/trunk/app/Model/CoEnrollmentFlow.php 2013-11-17 16:18:48
UTC (rev 629)
@@ -37,6 +37,11 @@
// Association rules from this model to other models
public $belongsTo = array(
+ "Co",
+ "CoEnrollmentFlowApproverCoGroup" => array(
+ 'className' => 'CoGroup',
+ 'foreignKey' => 'approver_co_group_id'
+ ),
"CoEnrollmentFlowAuthzCoGroup" => array(
'className' => 'CoGroup',
'foreignKey' => 'authz_co_group_id'
@@ -44,8 +49,7 @@
"CoEnrollmentFlowAuthzCou" => array(
'className' => 'Cou',
'foreignKey' => 'authz_cou_id'
- ),
- "Co"
+ )
);
public $hasMany = array(
@@ -59,7 +63,8 @@
public $displayField = "name";
// Default ordering for find operations
- public $order = array("CoEnrollmentFlow.name");
+// XXX Toss? CO-296
+// public $order = array("CoEnrollmentFlow.name");
// Validation rules for table elements
public $validate = array(
@@ -103,6 +108,11 @@
'approval_required' => array(
'rule' => array('boolean')
),
+ 'approver_co_group_id' => array(
+ 'rule' => 'numeric',
+ 'required' => false,
+ 'allowEmpty' => true
+ ),
'verify_email' => array(
'rule' => array('boolean')
),
Modified: registry/trunk/app/Model/CoGroup.php
===================================================================
--- registry/trunk/app/Model/CoGroup.php 2013-11-07 14:53:10 UTC (rev
628)
+++ registry/trunk/app/Model/CoGroup.php 2013-11-17 16:18:48 UTC (rev
629)
@@ -33,6 +33,10 @@
public $hasMany = array(
// A CoGroup has zero or more members
"CoGroupMember" => array('dependent' => true),
+ "CoEnrollmentFlowApproverCoGroup" => array(
+ 'className' => 'CoEnrollmentFlow',
+ 'foreignKey' => 'approver_co_group_id'
+ ),
"CoEnrollmentFlowAuthzCoGroup" => array(
'className' => 'CoEnrollmentFlow',
'foreignKey' => 'authz_co_group_id'
Modified: registry/trunk/app/View/CoEnrollmentFlows/fields.inc
===================================================================
--- registry/trunk/app/View/CoEnrollmentFlows/fields.inc 2013-11-07
14:53:10 UTC (rev 628)
+++ registry/trunk/app/View/CoEnrollmentFlows/fields.inc 2013-11-17
16:18:48 UTC (rev 629)
@@ -60,6 +60,20 @@
<script type="text/javascript">
<!-- JS specific to these fields -->
+ function approver_update_gadgets() {
+ // Hide and show accordingly. Reset sub-popups to prevent superfluous
data from
+ // being saved. (ie: we don't need a group ID if approval is not
required)
+
+ var approval =
document.getElementById('CoEnrollmentFlowApprovalRequired').checked;
+
+ if(approval) {
+ document.getElementById('approvergroupdiv').style.display = "block";
+ } else {
+ document.getElementById('approvergroupdiv').style.display = "none";
+ document.getElementById('CoEnrollmentFlowApproverCoGroupId').value =
"";
+ }
+ }
+
function authz_update_gadgets() {
// Hide and show accordingly. Reset sub-popups to prevent superfluous
data from
// being saved. (ie: we don't need a group ID if not setting authz to
'CG')
@@ -98,6 +112,7 @@
}
function js_local_onload() {
+ approver_update_gadgets();
authz_update_gadgets();
fields_update_gadgets();
}
@@ -245,8 +260,33 @@
</td>
<td>
<?php print ($e
- ? $this->Form->input('approval_required')
+ ? $this->Form->input('approval_required',
array('onClick' => 'approver_update_gadgets()'))
:
Sanitize::html($co_enrollment_flows[0]['CoEnrollmentFlow']['approval_required']));
?>
+ <div id="approvergroupdiv" style="display:none">
+ <?php
+ if(!empty($co_groups)) {
+ $attrs = array();
+ $attrs['value'] =
(isset($co_enrollment_flows[0]['CoEnrollmentFlow']['approver_co_group_id'])
+ ?
$co_enrollment_flows[0]['CoEnrollmentFlow']['approver_co_group_id']
+ : null);
+ $attrs['empty'] = true;
+
+ if($e) {
+ print $this->Form->select('approver_co_group_id',
+ $co_groups,
+ $attrs);
+
+ if($this->Form->isFieldError('approver_co_group_id')) {
+ print $this->Form->error('approver_co_group_id');
+ }
+
+ print '<br /><font class="desc">' . _txt('fd.ef.appr.gr') .
'</font>';
+ } else {
+ print $co_groups[
$co_enrollment_flows[0]['CoEnrollmentFlow']['approver_co_group_id'] ];
+ }
+ }
+ ?>
+ </div>
</td>
</tr>
<tr class="line2">
Modified: registry/trunk/app/View/CoPetitions/index.ctp
===================================================================
--- registry/trunk/app/View/CoPetitions/index.ctp 2013-11-07 14:53:10
UTC (rev 628)
+++ registry/trunk/app/View/CoPetitions/index.ctp 2013-11-17 16:18:48
UTC (rev 629)
@@ -2,7 +2,7 @@
/**
* COmanage Registry CO Petition Index View
*
- * Copyright (C) 2012 University Corporation for Advanced Internet
Development, Inc.
+ * Copyright (C) 2012-13 University Corporation for Advanced Internet
Development, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with
* the License. You may obtain a copy of the License at
@@ -14,7 +14,7 @@
* KIND, either express or implied. See the License for the specific
language governing
* permissions and limitations under the License.
*
- * @copyright Copyright (C) 2012 University Corporation for Advanced
Internet Development, Inc.
+ * @copyright Copyright (C) 2012-13 University Corporation for Advanced
Internet Development, Inc.
* @link http://www.internet2.edu/comanage COmanage Project
* @package registry
* @since COmanage Registry v0.5
@@ -59,7 +59,7 @@
$params = array('title' => $cur_co['Co']['name'] . " Petitions"); // XXX
I18N
print $this->element("pageTitle", $params);
-
+
if($permissions['add']) {
print $this->Html->link(_txt('op.enroll'),
array('controller' => 'co_enrollment_flows',
'action' => 'select', 'co' => $cur_co['Co']['id']),
- [comanage-dev] r629 - in registry/trunk/app: Config/Schema Controller Controller/Component Lib Model View/CoEnrollmentFlows View/CoPetitions, svnlog, 11/17/2013
Archive powered by MHonArc 2.6.16.