diff --git a/Controller/GrouperGroupsController.php b/Controller/GrouperGroupsController.php index 03d74ed..f50c289 100644 --- a/Controller/GrouperGroupsController.php +++ b/Controller/GrouperGroupsController.php @@ -248,10 +248,15 @@ public function findSubscriber(): void } /** + * @param bool $self By passes the actAsIdentifier condition + * * @return null|string */ - public function getUserId(): ?string + public function getUserId(bool $self = false): ?string { + if($self) { + return $this->userId; + } // XXX We are anot acting as but we are impersonating an other user. As a result // both the actor and the user need to have the same identifier return $this->actAsIdentifier ?? $this->userId; @@ -508,11 +513,14 @@ public function isAuthorized(): array|bool $isActAsEligibilityGroupmember = false; if(!empty($eligibleGroup)) { - $isActAsEligibilityGroupmember = $this->GrouperGroup->isGroupMember($this->getUserId(), $eligibleGroup, $cfg); + $isActAsEligibilityGroupmember = $this->GrouperGroup->isGroupMember($this->getUserId(self: true), + $eligibleGroup, $cfg); } // Determine what operations this user can perform // Construct the permission set for this user, which will also be passed to the view. + + // XXX In ActAs mode not edit actions are allowed $p = []; $p['index'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']); @@ -524,16 +532,16 @@ public function isAuthorized(): array|bool $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['addSubscriber'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']) && !$isActAsEligibilityGroupmember; $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['removeSubscriber'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']) && !$isActAsEligibilityGroupmember; - $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']); + $p['groupCreate'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']) && !$isActAsEligibilityGroupmember; + $p['joinGroup'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']) && !$isActAsEligibilityGroupmember; + $p['leaveGroup'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']) && !$isActAsEligibilityGroupmember; + $p['groupcreatetemplate'] = ($roles['cmadmin'] || $roles['coadmin'] || $roles['comember']) && !$isActAsEligibilityGroupmember; $p['actAsAction'] = $isActAsEligibilityGroupmember; $this->set('permissions', $p); diff --git a/View/Elements/ActAsPeopleAutocomplete.ctp b/View/Elements/ActAsPeopleAutocomplete.ctp index ed71650..ed73ecb 100644 --- a/View/Elements/ActAsPeopleAutocomplete.ctp +++ b/View/Elements/ActAsPeopleAutocomplete.ctp @@ -165,7 +165,6 @@ $suffix = Configure::read('debug') > 0 ? '?time=' . time() : ''; ` }); diff --git a/View/Elements/ActionSideBar.ctp b/View/Elements/ActionSideBar.ctp index 339bcfb..588fe63 100644 --- a/View/Elements/ActionSideBar.ctp +++ b/View/Elements/ActionSideBar.ctp @@ -24,6 +24,7 @@ element('ActAsPeopleAutocomplete', compact('vv_config', 'vv_coid', + 'vv_act_as_people', 'vv_is_user_owner', 'htmlId') )?> diff --git a/webroot/css/co-grouper-base.css b/webroot/css/co-grouper-base.css index d2e2e5b..a1aab2e 100644 --- a/webroot/css/co-grouper-base.css +++ b/webroot/css/co-grouper-base.css @@ -22,6 +22,16 @@ font-size: 0.8rem; } +button:disabled, +input[type=button]:disabled, +input[type=button][disabled], +button[disabled]{ + background:#999 !important; + color:#ffffff !important; + border: none !important; + cursor: not-allowed; +} + #content .material-icons.lg { font-size: 1.2rem; } diff --git a/webroot/js/autocomplete.js b/webroot/js/autocomplete.js index 3baf2b4..da2e95e 100644 --- a/webroot/js/autocomplete.js +++ b/webroot/js/autocomplete.js @@ -10,7 +10,7 @@ export default { type: String, default: 'add' }, - forceDisableBtn: { + forceDisable: { type: Boolean, default: false }, @@ -23,7 +23,7 @@ export default { default: '' } }, - inject: ['txt', 'api', 'all'], + inject: ['txt', 'api', 'other'], data() { return { search: '', @@ -45,7 +45,7 @@ export default { enableBtnFunc() { // The minimum length that i start search is 3. So we only enable the button when // the input text value has at least three characters - return this.enableBtn && !this.forceDisableBtn + return this.enableBtn && !this.forceDisable }, }, computed: { @@ -62,6 +62,9 @@ export default { this.url = `${this.api.find}?co=${this.api.co}&mode=${this.api.mode}&page=${this.page}&limit=${this.limit}` input.autocomplete({ source: ( request, response ) => { + if(this.forceDisable) { + return ["Not allowed"] + } $(`#autocomplete-search-container-${this.action} .co-loading-mini`).show(); $.ajax({ url: this.url, @@ -117,6 +120,7 @@ export default { name="display" class="form-control" v-model="search" + :disabled="this.forceDisable" :placeholder="txt.peoplePickerPlaceHolder"/> diff --git a/webroot/js/groups-table.js b/webroot/js/groups-table.js index 1449197..f9f9304 100644 --- a/webroot/js/groups-table.js +++ b/webroot/js/groups-table.js @@ -11,6 +11,7 @@ export default { return status === 'T' ? 'Enabled' : 'Disabled' } }, + inject: ['txt', 'api', 'other'], created() {}, template: /*html*/` @@ -38,7 +39,7 @@ export default { v-if="$attrs.onJoinGroup" @click="$emit('joinGroup', group)" class="btn btn-sm btn-block text-nowrap m-1 btn-success" type="button" - :disabled="group.loading"> + :disabled="group.loading || this.other.hasActAs"> {{ txt.join }}   @@ -47,7 +48,7 @@ export default { v-if="$attrs.onLeaveGroup" @click="$emit('leaveGroup', group)" class="btn btn-sm btn-block text-nowrap m-1 btn-danger" type="button" - :disabled="group.loading"> + :disabled="group.loading || this.other.hasActAs"> {{ txt.leave }} @@ -57,6 +58,7 @@ export default { class="btn btn-grouper btn-block btn-primary btn-sm m-1 text-nowrap members-btn" @click="$emit('showSubscribers', group)" :data-id="encodeURIComponent(group.name)" + :disabled="this.other.hasActAs" :data-name="group.displayExtension">{{ txt.members }} @@ -64,7 +66,7 @@ export default { v-if="$attrs.onRemoveUser" class="btn btn-sm btn-block text-nowrap m-1 btn-danger" type="button" @click="$emit('removeUser', group)" - :disabled="group.loading" + :disabled="group.loading || this.other.hasActAs" :data-id="encodeURIComponent(group.name)" :data-name="group.displayExtension"> {{ txt.remove }} diff --git a/webroot/js/members.js b/webroot/js/members.js index cd15a2f..ac71a1c 100644 --- a/webroot/js/members.js +++ b/webroot/js/members.js @@ -34,7 +34,7 @@ export default { remove: Boolean, default: false }, - inject: ['txt', 'api'], + inject: ['txt', 'api', 'other'], components: { Loader, Autocomplete @@ -163,7 +163,8 @@ export default {
- +
@@ -182,7 +183,9 @@ export default { {{ subscriber.id }} diff --git a/webroot/js/nested-table.js b/webroot/js/nested-table.js index eff276b..a60ff9a 100644 --- a/webroot/js/nested-table.js +++ b/webroot/js/nested-table.js @@ -39,7 +39,10 @@ export default {
-
-