Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Page visibility configuration #1420

Merged
merged 2 commits into from
Dec 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions docs/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,25 @@ With authentication set up, by default no access is allowed to your dashboard wi

### Granular Access

You can use the following properties to make certain sections or items only visible to some users, or hide sections and items from guests.
You can use the following properties to make certain pages, sections or items only visible to some users, or hide pages, sections and items from guests.

- `hideForUsers` - Section or Item will be visible to all users, except for those specified in this list
- `showForUsers` - Section or Item will be hidden from all users, except for those specified in this list
- `hideForGuests` - Section or Item will be visible for logged in users, but not for guests
- `hideForUsers` - Page, Section or Item will be visible to all users, except for those specified in this list
- `showForUsers` - Page, Section or Item will be hidden from all users, except for those specified in this list
- `hideForGuests` - Page, Section or Item will be visible for logged in users, but not for guests

For Example:
```yaml
pages:
- name: Home Lab
path: home-lab.yml
displayData:
showForUsers: [admin]
- name: Intranet
path: intranet.yml
displayData:
hideForGuests: true
hideForUsers: [alicia, bob]
```

```yaml
- name: Code Analysis & Monitoring
Expand Down
28 changes: 27 additions & 1 deletion src/components/InteractiveEditor/EditMultiPages.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<div class="edit-multi-pages-inner" v-if="allowViewConfig">
<h3>{{ $t('interactive-editor.menu.edit-page-info-btn') }}</h3>
<FormSchema
:schema="schema"
:schema="customSchema"
v-model="formData"
@submit.prevent="saveToState"
class="multi-page-form"
Expand Down Expand Up @@ -49,6 +49,32 @@ export default {
pages() {
return this.$store.getters.pages;
},
/* Make a custom schema object, using fields from ConfigSchema */
customSchema() {
return {
type: 'array',
title: this.schema.title,
description: this.schema.description,
items: {
title: this.schema.items.title,
type: this.schema.items.type,
additionalProperties: this.schema.items.additionalProperties,
required: this.schema.items.required,
properties: {
name: this.schema.items.properties.name,
path: this.schema.items.properties.path,
displayData: {
title: 'Display (see documentation for more options)',
description: '',
type: 'object',
properties: {
hideForGuests: this.schema.items.properties.displayData.properties.hideForGuests,
},
},
},
},
};
},
allowViewConfig() {
return this.$store.getters.permissions.allowViewConfig;
},
Expand Down
10 changes: 6 additions & 4 deletions src/components/PageStrcture/Nav.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
<script>
import IconBurger from '@/assets/interface-icons/burger-menu.svg';
import { makePageSlug } from '@/utils/ConfigHelpers';
import { checkPageVisibility } from '@/utils/CheckPageVisibility';

export default {
name: 'Nav',
Expand All @@ -45,10 +46,11 @@ export default {
computed: {
/* Get links to sub-pages, and combine with nav-links */
allLinks() {
const subPages = this.$store.getters.pages.map((subPage) => ({
path: makePageSlug(subPage.name, 'home'),
title: subPage.name,
}));
const subPages = this.$store.getters.pages.filter((page) => checkPageVisibility(page))
.map((subPage) => ({
path: makePageSlug(subPage.name, 'home'),
title: subPage.name,
}));
const navLinks = this.links || [];
return [...navLinks, ...subPages];
},
Expand Down
18 changes: 18 additions & 0 deletions src/utils/CheckPageVisibility.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* A helper function that checks if a page is visible based on current users permissions
* Checks a page's displayData for hideForUsers, showForUsers and hideForGuests
* Returns a boolean that determines if the user has the required permissions
*/

// Import helper functions from auth, to get current user, and check if guest
import { getCurrentUser } from '@/utils/Auth';
import { isVisibleToUser } from '@/utils/IsVisibleToUser';

/* Putting it all together, the function to export */
export const checkPageVisibility = (page) => {
const currentUser = getCurrentUser(); // Get current user object
const displayData = page.displayData || {};
return isVisibleToUser(displayData, currentUser);
};

export default checkPageVisibility;
86 changes: 85 additions & 1 deletion src/utils/ConfigSchema.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"type": "array",
"description": "List of additional config files to load as extra pages",
"items": {
"title": "Pages",
"title": "Page",
"type": "object",
"required": ["name", "path"],
"additionalProperties": false,
Expand All @@ -24,6 +24,90 @@
"title": "Path",
"type": "string",
"description": "The file name, or path. If in public directory, use just `file-name.yml`"
},
"displayData": {
"title": "Display Data",
"type": "object",
"additionalProperties": false,
"description": "Optional meta data for customizing a page",
"properties": {
"hideForUsers": {
"title": "Hide for Users",
"type": "array",
"description": "Page will be visible to all users, except for those specified in this list",
"items": {
"type": "string",
"description": "Username for the user that will not be able to view this page"
}
},
"showForUsers": {
"title": "Show for Users",
"type": "array",
"description": "Page will be hidden from all users, except for those specified in this list",
"items": {
"type": "string",
"description": "Username for the user that will have access to this page"
}
},
"hideForGuests": {
"title": "Hide for Guests?",
"type": "boolean",
"default": false,
"description": "If set to true, page will be visible for logged in users, but not for guests"
},
"showForKeycloakUsers": {
"title": "Show for select Keycloak groups or roles",
"type": "object",
"description": "Configure the Keycloak groups or roles that will have access to this page",
"additionalProperties": false,
"properties": {
"groups": {
"title": "Show for Groups",
"type": "array",
"description": "Page will be hidden from all users except those with one or more of these groups",
"items": {
"type": "string",
"description": "Name of the group that will be able to view this page"
}
},
"roles": {
"title": "Show for Roles",
"type": "array",
"description": "Page will be hidden from all users except those with one or more of these roles",
"items": {
"type": "string",
"description": "Name of the role that will be able to view this page"
}
}
}
},
"hideForKeycloakUsers": {
"title": "Hide for select Keycloak groups or roles",
"type": "object",
"description": "Configure the Keycloak groups or roles that will not have access to this page",
"additionalProperties": false,
"properties": {
"groups": {
"title": "Hide for Groups",
"type": "array",
"description": "Page will be hidden from users with any of these groups",
"items": {
"type": "string",
"description": "name of the group that will not be able to view this page"
}
},
"roles": {
"title": "Hide for Roles",
"type": "array",
"description": "Page will be hidden from users with any of roles",
"items": {
"type": "string",
"description": "name of the role that will not be able to view this page"
}
}
}
}
}
}
}
}
Expand Down