Skip to content

Commit

Permalink
feat: properly distinguish between inherited and unset permissions in…
Browse files Browse the repository at this point in the history
… ACL ui

Signed-off-by: Robin Appelman <robin@icewind.nl>
  • Loading branch information
icewind1991 committed Apr 2, 2024
1 parent 7d82233 commit 65df13f
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 21 deletions.
3 changes: 3 additions & 0 deletions src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@ class AclDavService {
inheritedAclsById[id] = acl
if (aclsById[id] == null) {
aclsById[id] = acl
} else {
aclsById[id].inheritedMask = acl.mask;

Check failure on line 232 in src/client.js

View workflow job for this annotation

GitHub Actions / NPM lint

Extra semicolon
aclsById[id].inheritedPermissions = acl.permissions;

Check failure on line 233 in src/client.js

View workflow job for this annotation

GitHub Actions / NPM lint

Extra semicolon
}
}
return {
Expand Down
20 changes: 13 additions & 7 deletions src/components/AclStateButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@
<component :is="icon" :class="{inherited: isInherited}" :size="16" />
</template>
<NcActionRadio name="state"
:checked="state === STATES.INHERIT_ALLOW || state === STATES.INHERIT_DENY"
:checked="state === STATES.INHERIT_ALLOW || state === STATES.INHERIT_DENY || state === STATES.INHERIT_DEFAULT"
:disabled="disabled"
@change="$emit('update', STATES.INHERIT_ALLOW)">
@change="$emit('update', STATES.INHERIT_DEFAULT)">
{{ t('groupfolders', 'Inherit permission') }}
</NcActionRadio>
<NcActionRadio name="state"
Expand All @@ -68,16 +68,18 @@
<script>
import Check from 'vue-material-design-icons/Check.vue'
import Cancel from 'vue-material-design-icons/Cancel.vue'
import Minus from 'vue-material-design-icons/Minus.vue'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
import NcActionRadio from '@nextcloud/vue/dist/Components/NcActionRadio.js'
import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip.js'
const STATES = {
export const STATES = {
INHERIT_DENY: 0,
INHERIT_ALLOW: 1,
SELF_DENY: 2,
SELF_ALLOW: 3,
INHERIT_DEFAULT: 2,
SELF_DENY: 3,
SELF_ALLOW: 4,
}
export default {
Expand Down Expand Up @@ -117,13 +119,15 @@ export default {
},
computed: {
isAllowed() {
return this.state & 1
return this.state === STATES.INHERIT_ALLOW || this.state === STATES.SELF_ALLOW || this.state === STATES.INHERIT_DEFAULT
},
isInherited() {
return (this.state & 2) === 0
return this.state === STATES.INHERIT_ALLOW || this.state === STATES.INHERIT_DENY || this.state === STATES.INHERIT_DEFAULT
},
icon() {
switch (this.state) {
case STATES.INHERIT_DEFAULT:
return Minus
case STATES.INHERIT_ALLOW:
case STATES.SELF_ALLOW:
return Check
Expand All @@ -133,6 +137,8 @@ export default {
},
label() {
switch (this.state) {
case STATES.INHERIT_DEFAULT:
return t('groupfolders', 'Unset')
case STATES.INHERIT_DENY:
return t('groupfolders', 'Denied (Inherited permission)')
case STATES.INHERIT_ALLOW:
Expand Down
36 changes: 22 additions & 14 deletions src/components/SharingSidebarView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -83,31 +83,31 @@
{{ getFullDisplayName(item.mappingDisplayName, item.mappingType) }}
</td>
<td class="state-column">
<AclStateButton :state="getState(OC.PERMISSION_READ, item.permissions, item.mask, item.inherited)"
<AclStateButton :state="getState(OC.PERMISSION_READ, item)"
:inherited="item.inherited"
:disabled="loading"
@update="changePermission(item, OC.PERMISSION_READ, $event)" />
</td>
<td class="state-column">
<AclStateButton :state="getState(OC.PERMISSION_UPDATE, item.permissions, item.mask, item.inherited)"
<AclStateButton :state="getState(OC.PERMISSION_UPDATE, item)"
:inherited="item.inherited"
:disabled="loading"
@update="changePermission(item, OC.PERMISSION_UPDATE, $event)" />
</td>
<td v-if="model.type === 'dir'" class="state-column">
<AclStateButton :state="getState(OC.PERMISSION_CREATE, item.permissions, item.mask, item.inherited)"
<AclStateButton :state="getState(OC.PERMISSION_CREATE, item)"
:inherited="item.inherited"
:disabled="loading"
@update="changePermission(item, OC.PERMISSION_CREATE, $event)" />
</td>
<td class="state-column">
<AclStateButton :state="getState(OC.PERMISSION_DELETE, item.permissions, item.mask, item.inherited)"
<AclStateButton :state="getState(OC.PERMISSION_DELETE, item)"
:inherited="item.inherited"
:disabled="loading"
@update="changePermission(item, OC.PERMISSION_DELETE, $event)" />
</td>
<td class="state-column">
<AclStateButton :state="getState(OC.PERMISSION_SHARE, item.permissions, item.mask, item.inherited)"
<AclStateButton :state="getState(OC.PERMISSION_SHARE, item)"
:inherited="item.inherited"
:disabled="loading"
@update="changePermission(item, OC.PERMISSION_SHARE, $event)" />
Expand Down Expand Up @@ -157,7 +157,7 @@
import Vue from 'vue'
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import AclStateButton from './AclStateButton.vue'
import AclStateButton, {STATES} from './AclStateButton.vue'

Check failure on line 160 in src/components/SharingSidebarView.vue

View workflow job for this annotation

GitHub Actions / NPM lint

A space is required after '{'

Check failure on line 160 in src/components/SharingSidebarView.vue

View workflow job for this annotation

GitHub Actions / NPM lint

A space is required before '}'
import Rule from './../model/Rule.js'
import BinaryTools from './../BinaryTools.js'
import client from './../client.js'
Expand Down Expand Up @@ -208,7 +208,7 @@ export default {
return this.aclCanManage
},
isNotInherited() {
return (permission, permissions, mask) => {
return (permission, mask) => {
return (permission & ~mask) === 0
}
},
Expand All @@ -218,10 +218,18 @@ export default {
}
},
getState() {
return (permission, permissions, mask, inherited) => {
const inheritance = (!inherited && this.isNotInherited(permission, permissions, mask)) << 1
const permitted = this.isAllowed(permission, permissions)
return inheritance | permitted
return (permission, item) => {
const permitted = this.isAllowed(permission, item.permissions)
if (this.isNotInherited(permission, item.mask)) {
return permitted ? STATES.SELF_ALLOW : STATES.SELF_DENY
} else {
const inheritPermitted = this.isAllowed(permission, item.inheritedPermissions)
if (this.isNotInherited(permission, item.inheritedMask)) {
return inheritPermitted ? STATES.INHERIT_ALLOW : STATES.INHERIT_DENY
} else {
return STATES.INHERIT_DEFAULT
}
}
}
},
},
Expand Down Expand Up @@ -328,13 +336,13 @@ export default {
},
changePermission(item, permission, $event) {
const index = this.list.indexOf(item)
const inherit = ($event < 2)
const allow = ($event & (0b01)) === 1
const inherit = $event === STATES.INHERIT_ALLOW || $event === STATES.INHERIT_DENY || $event === STATES.INHERIT_DEFAULT
const allow = $event === STATES.SELF_ALLOW
const bit = BinaryTools.firstHigh(permission)
item = item.clone()
if (inherit) {
item.mask = BinaryTools.clear(item.mask, bit)
// TODO check if: we can ignore permissions, since they are inherited
// we can ignore permissions, since they are inherited
} else {
item.mask = BinaryTools.set(item.mask, bit)
if (allow) {
Expand Down
2 changes: 2 additions & 0 deletions src/model/Rule.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export default class Rule {
this.mask = mask
this.permissions = permissions
this.inherited = inherited
this.inheritedMask = 0;

Check failure on line 41 in src/model/Rule.js

View workflow job for this annotation

GitHub Actions / NPM lint

Extra semicolon
this.inheritedPermissions = 31;

Check failure on line 42 in src/model/Rule.js

View workflow job for this annotation

GitHub Actions / NPM lint

Extra semicolon
}

getProperties() {
Expand Down

0 comments on commit 65df13f

Please sign in to comment.