Skip to content

Commit

Permalink
Backend work, frontend loader and disable action button.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ioannis committed Mar 7, 2024
1 parent d2fe650 commit 83727b0
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 65 deletions.
101 changes: 74 additions & 27 deletions Controller/GrouperGroupsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class GrouperGroupsController extends GrouperLiteWidgetAppController
public $helpers = array('Html', 'Form', 'Flash');

// Dynamic properties are deprecated, so we will define the property here
protected $userId = null;
private $userId = null;

public $uses = array(
'GrouperLiteWidget.GrouperGroup',
Expand Down Expand Up @@ -146,6 +146,14 @@ public function beforeRender() {
$this->set('vv_coid', $this->cur_co['Co']['id']);
}

/**
* @return null
*/
public function getUserId()
{
return $this->userId;
}

/**
* Perform a "keyword" search for CO People, sort of like the CO Dashboard
* cross controller search, but intended specifically for "people finder"
Expand Down Expand Up @@ -234,7 +242,7 @@ public function groupSubscribers(): void
/**
* Listing of all Grouper Groups owned/admin by User Or search those Grouper Groups
*/
public function groupOwnerApi() {
public function groupOwnerApi(): void {
//Set initial setting
$arguments = [
'userId' => $this->userId,
Expand All @@ -261,7 +269,7 @@ public function groupOwnerApi() {
CakeLog::write('error', __METHOD__ . "::{$errorHint}: " . var_export($e->getMessage(), true));
$this->restResponse(HttpStatusCodesEnum::HTTP_INTERNAL_SERVER_ERROR, ErrorsEnum::Exception);

$this->set('groupsowners', []);
$this->set('groupowners', []);
$this->Flash->set(_txt('pl.grouperlite.message.flash.owner-group-failed'), array('key' => 'error'));
return;
}
Expand All @@ -275,7 +283,7 @@ public function groupOwnerApi() {
* This includes self-joined Optin Groups, as well as required Groups User cannot leave
*
*/
public function groupMemberApi() {
public function groupMemberApi(): void {
//Set initial setting
$arguments = [
'userId' => $this->userId,
Expand Down Expand Up @@ -404,7 +412,7 @@ public function index(): void
* @return array|bool Permissions
* @since COmanage Registry v3.2.0
*/
function isAuthorized(): array|bool
public function isAuthorized(): array|bool
{
$roles = $this->Role->calculateCMRoles();
$cfg = $this->CoGrouperLiteWidget->getConfig();
Expand All @@ -420,32 +428,32 @@ function isAuthorized(): array|bool
&& is_array($identifiers)
&& isset($identifiers['Identifier']['identifier'])
) {
$this->userId = $identifiers['Identifier']['identifier'];
$this->setUserId($identifiers['Identifier']['identifier']);
}

// Determine what operations this user can perform
// Construct the permission set for this user, which will also be passed to the view.
//Note: Leaving in current format, in case need to restrict certain pages, can just remove true and add params.
$p = array();

$p['index'] = true;
$p['groupowner'] = true;
$p['groupownerapi'] = true;
$p['groupoptin'] = true;
$p['groupoptinapi'] = true;
$p['groupmember'] = true;
$p['groupmemberapi'] = true;
$p['getBaseConfig'] = true;
$p['groupSubscribers'] = true;
$p['addSubscriber'] = true;
$p['findSubscriber'] = true;
$p['usermanager'] = true;
$p['removeSubscriber'] = true;

$p['groupCreate'] = true;
$p['joinGroup'] = true;
$p['leaveGroup'] = true;
$p['groupcreatetemplate'] = true;
$p = [];

$p['index'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']);
$p['groupowner'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']);
$p['groupownerapi'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']);
$p['groupoptin'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']);
$p['groupoptinapi'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']);
$p['groupmember'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']);
$p['groupmemberapi'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']);
$p['getBaseConfig'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']);
$p['groupSubscribers'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']);
$p['addSubscriber'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']);
$p['findSubscriber'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']);
$p['usermanager'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']);
$p['usermanagerapi'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']);
$p['removeSubscriber'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']);

$p['groupCreate'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']);
$p['joinGroup'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']);
$p['leaveGroup'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']);
$p['groupcreatetemplate'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']);

$this->set('permissions', $p);

Expand Down Expand Up @@ -597,6 +605,14 @@ public function restResponse(int $status,
$this->response->send();
}

/**
* @param null $userId
*/
private function setUserId($userId): void
{
$this->userId = $userId;
}

/**
* UserManager vue route for rendering
*
Expand All @@ -607,6 +623,37 @@ public function userManager(): void
$this->render('index');
}

/**
* Display all Groups for the user i manage
*/
public function userManagerApi(): void
{
//Set initial setting
$cfg = $this->CoGrouperLiteWidget->getConfig();

if (!isset($this->request->query['memberid'])) {
$this->restResponse(HttpStatusCodesEnum::HTTP_BAD_REQUEST, ErrorsEnum::Exception);
}

$memberId = urldecode($this->request->query['memberid']);

try {
$groupsimanage = $this->GrouperGroup->getManagedUsers($this->userId,
$memberId,
$cfg);
} catch (Exception $e) {
CakeLog::write('error', __METHOD__ . '::get Managed Users: ' . var_export($e->getMessage(), true));
$this->restResponse(HttpStatusCodesEnum::HTTP_INTERNAL_SERVER_ERROR, ErrorsEnum::Exception);

$this->set('groupsimanage', []);
return;
}

$this->set(compact('groupsimanage'));
$this->set('_serialize', 'groupsimanage');

}

/**
* Override the default sanity check performed in AppController
*
Expand Down
1 change: 1 addition & 0 deletions Lib/lang.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
'pl.grouperlite.action.view-members' => 'View members',
'pl.grouperlite.action.grouper' => 'Grouper',
'pl.grouperlite.action.members' => 'Members',
'pl.grouperlite.action.memberships' => 'Memberships',
'pl.grouperlite.action.close' => 'Close',
'pl.grouperlite.action.clear' => 'Clear',
'pl.grouperlite.action.add-user' => 'Add',
Expand Down
49 changes: 49 additions & 0 deletions Model/GrouperGroup.php
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,55 @@ public function getOwnedGroups(string $userId, array $cfg): array
return $this->removeDuplicates($resultsAdmin, $resultsUpdate);
}

/**
* Return all Grouper Groups that
* - the User(me) has a role of owner/admin
* - the User(member User) is a member
*
* @param string $userId
* @param string $memberId
* @param array $cfg
*
* @return array
* @throws GrouperLiteWidgetException
* @since COmanage Registry v4.4.0
*/
public function getManagedUsers(string $managerId, string $memberId, array $cfg): array {
if(empty($managerId) || empty($memberId)) {
return false;
}

$this->initApi($cfg);

try {
$resultsManagerAdmin = $this->grouperAPI->getUserMemberships($managerId, $managerId, GrouperGroupTypeEnum::ADMIN);
$resultsManagerUpdate = $this->grouperAPI->getUserMemberships($managerId, $managerId, GrouperGroupTypeEnum::UPDATE);
} catch (Exception $e) {
CakeLog::write('error', __METHOD__ . ': An error occurred');
throw $e;
}

$managerGroupSet = $this->removeDuplicates($resultsManagerAdmin, $resultsManagerUpdate);

try {
// Groups the user is a member of
$membersGroup = $this->grouperAPI->getUserGroups($memberId, $memberId);
} catch (Exception $e) {
CakeLog::write('error', __METHOD__ . ': An error occurred');
throw $e;
}

// Extract the names of the Groups the member-user is a member of
$memberGroupNames = Hash::extract($membersGroup, '{n}.name');
// Return the groups the user can join and is not a member of
return array_values( // Restart indexing from 0(zero) on the final array
array_filter( // Return the groups the member-user is a member
$managerGroupSet,
static fn($value) => in_array($value['name'], $memberGroupNames)
)
);
}

/**
* Potential use was for creating adhoc group by a user, not associated to WG.
*
Expand Down
2 changes: 2 additions & 0 deletions View/GrouperGroups/index.ctp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
removeSubscriberSuccess: "<?= _txt('pl.grouperlite.message.flash.remove-subscriber-success') ?>",
getSubscriberError: "<?= _txt('pl.grouperlite.message.flash.group-detail-members-failed') ?>",
peoplePickerPlaceHolder: "<?= _txt('op.grm.add.placeholder') ?>",
memberships: "<?= _txt('pl.grouperlite.action.memberships') ?>",
noaccess: "<?= _txt('pl.grouperlite.members.noaccess') ?>",
empty: "<?= _txt('pl.grouperlite.members.empty') ?>",
join: "<?= _txt('pl.grouperlite.action.join') ?>",
Expand Down Expand Up @@ -129,6 +130,7 @@
add: "<?= $this->webroot ?>grouper_lite_widget/grouper_groups/addSubscriber/co:<?= $vv_coid ?>/glid:<?= $vv_config['CoGrouperLiteWidget']['id'] ?>",
group: "<?= $this->webroot ?>grouper_lite_widget/grouper_groups/groupSubscribers/co:<?= $vv_coid ?>/glid:<?= $vv_config['CoGrouperLiteWidget']['id'] ?>",
memberships: "<?= $this->webroot ?>grouper_lite_widget/grouper_groups/groupmemberapi/co:<?= $vv_coid ?>/glid:<?= $vv_config['CoGrouperLiteWidget']['id'] ?>",
managing: "<?= $this->webroot ?>grouper_lite_widget/grouper_groups/usermanagerapi/co:<?= $vv_coid ?>/glid:<?= $vv_config['CoGrouperLiteWidget']['id'] ?>",
optin: "<?= $this->webroot ?>grouper_lite_widget/grouper_groups/groupoptinapi/co:<?= $vv_coid ?>/glid:<?= $vv_config['CoGrouperLiteWidget']['id'] ?>",
owner: "<?= $this->webroot ?>grouper_lite_widget/grouper_groups/groupownerapi/co:<?= $vv_coid ?>/glid:<?= $vv_config['CoGrouperLiteWidget']['id'] ?>",
},
Expand Down
10 changes: 5 additions & 5 deletions webroot/js/autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

export default {
props: {
group: {
type: String,
default: ""
},
action: {
type: String,
default: "addUser"
},
icon: {
type: String,
default: 'add'
},
activeBtn: {
type: Boolean,
default: true
}
},
inject: ['txt', 'api'],
Expand Down Expand Up @@ -86,7 +86,7 @@ export default {
class=" btn btn-grouper btn-primary px-4 border-0"
type="button"
@click="performAction()"
:disabled="true">
:disabled="activeBtn">
<em class="material-icons lg" aria-hidden="true">{{ this.icon }}</em>
<span class="ml-2">{{ btnTxt }}</span>
</button>
Expand Down
2 changes: 1 addition & 1 deletion webroot/js/members.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export default {
<div class="d-flex mb-4">
<form id="add-user-form" class="add-user-form w-100">
<label class="sr-only" for="addUser">{{ txt.search }}</label>
<autocomplete @addUser="(item) => addSubscriber(item)" />
<autocomplete @addUser="(item) => addSubscriber(item)" :activeBtn="loading"/>
</form>
</div>
</div>
Expand Down
50 changes: 18 additions & 32 deletions webroot/js/page/UserManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,31 @@ export default {
Pagination,
GroupsTable,
Members,
Autocomplete
Autocomplete,
Loader
},
data() {
return {
loading: false,
result: [],
}
},
inject: ['api', 'txt'],
methods: {
showSubscribers(group) {
this.$refs.members.show(group);
},
async findUserMemberships(user) {
async findManagedUsers(user) {
const { identifier: id, label } = user;
this.loading = true;
const { displayExtension, name } = this.group;
const formData = new FormData();
formData.append("userId", id);
formData.append("group", name);
const resp = await fetch(`${this.api.add}?group=${name}&userId=${id}`, {
method: "POST",
const resp = await fetch(`${this.api.managing}?memberid=${id}`, {
headers: {
"Accept": "application/json",
},
body: formData
method: "GET"
});
if (resp.ok) {
await this.loadGroupSubscribers(this.group);
generateFlash(`${label} ${this.txt.findUserMembershipsSuccess} ${(displayExtension)}`, 'success');
this.result = await resp.json();
console.log('result', this.result)
generateFlash(`${id} has ${this.result.length} ${this.txt.memberships}`, 'success');
} else {
generateFlash(`${this.txt.findUserMembershipsError}`, 'error');
let errorResponse = await resp.json();
generateFlash(`${errorResponse.message}`, 'error');
}
Expand All @@ -47,24 +46,11 @@ export default {
}
},
template: /*html*/`
<autocomplete @searchUserMemberships="(item) => findUserMemberships(item)"
<autocomplete @findManagedUsers="(item) => findManagedUsers(item)"
icon="search"
action="searchUserMemberships"
action="findManagedUsers"
:activeBtn="loading"
/>
<!-- <groups :api-path="api.owner">-->
<!-- <template v-slot:searchResult="searchResult">-->
<!-- <pagination :records="searchResult.groups">-->
<!-- <template v-slot:paginated="paginated">-->
<!-- <page-count :first="paginated.start" :last="paginated.end" :total="paginated.total"></page-count>-->
<!-- <groups-table-->
<!-- :groups="paginated.records"-->
<!-- :columns="['name', 'description', 'action']"-->
<!-- :members="true"-->
<!-- @show-subscribers="showSubscribers"></groups-table>-->
<!-- </template>-->
<!-- </pagination>-->
<!-- </template> -->
<!-- </groups>-->
<!-- <members ref="members" :add="true" :remove="true"></members>-->
<loader :active="loading"></loader>
`
}

0 comments on commit 83727b0

Please sign in to comment.