Skip to content

Commit

Permalink
#1380 - User Roles Phase 1 (#1470)
Browse files Browse the repository at this point in the history
* WIP

* Added emulator

* Update package-lock.json

* switching wording

Co-authored-by: Tom Gillespy <HalcyonJAC@judicialappointments.digital>
Co-authored-by: warrensearle <warren.searle@judicialappointments.digital>
  • Loading branch information
3 people authored Dec 10, 2021
1 parent b4757ec commit 3f61a48
Show file tree
Hide file tree
Showing 9 changed files with 771 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ Describe the steps required to test & verify this change
## Additional context
Include screen grabs, video demo, notes etc.

## Related permissions
Have permissions been considered for this functionality?
- No permission changes required
- Permissions have been added / updated. Details:

---
PREVIEW:DEVELOP
_can be OFF, DEVELOP or STAGING_
7 changes: 6 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,18 @@
Candidates
</RouterLink>
</li>

<li
v-if="authorisedToPerformAction"
class="govuk-header__navigation-item"
>
<RouterLink
:to="{ name: 'users' }"
class="govuk-header__link"
>
Users
</RouterLink>
</li>
<li class="govuk-header__navigation-item">
<a
v-if="$route.name !== 'sign-in'"
Expand Down
215 changes: 215 additions & 0 deletions src/components/ModalViews/UserRolePermissions.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
<template>
<div>
<div class="modal__title govuk-!-padding-2 govuk-heading-m">
Permissions
</div>
<div
v-if="!roleId"
class="modal__content govuk-!-margin-6"
>
<TextField
:id="`user_role_id`"
v-model="roleName"
label="User role name"
type="text"
/>
<ActionButton
class="govuk-!-margin-right-1"
type="primary"
@click="createUserRole"
>
Save
</ActionButton>
<button
class="govuk-button govuk-button--secondary govuk-!-margin-right-3"
@click="closeModal"
>
Cancel
</button>
</div>
<div
v-if="roleId"
class="modal__content govuk-!-margin-6"
>
<div class="govuk-grid-row">
<div
v-for="(permissionGroup, index) in permissions"
:key="index"
class="govuk-grid-column-one-quarter"
>
<h2 class="govuk-!-margin-top-0 govuk-!-margin-bottom-0">
{{ permissionGroup.group }}
</h2>
<Table
ref="exercisesTable"
data-key="value"
:data="permissionGroup.permissions"
:page-size="50"
:columns="tableColumns"
multi-select
:selection.sync="permissionGroup.enabledPermissions"
>
<template #row="{row}">
<TableCell :title="tableColumns[0].title">
{{ row.label }}
</TableCell>
</template>
</Table>
</div>
</div>
<div class="govuk-grid-row">
<ActionButton
type="primary"
class="govuk-button govuk-!-margin-right-3"
@click="saveUserRole()"
>
Save
</ActionButton>
<button
class="govuk-button govuk-button--secondary govuk-!-margin-right-3"
@click="closeModal"
>
Close
</button>
</div>
</div>
</div>
</template>

<script>
import { functions } from '@/firebase';
import TextField from '@jac-uk/jac-kit/draftComponents/Form/TextField';
//import Checkbox from '@jac-uk/jac-kit/draftComponents/Form/Checkbox';
import ActionButton from '@jac-uk/jac-kit/draftComponents/ActionButton';
import Table from '@jac-uk/jac-kit/components/Table/Table';
import TableCell from '@jac-uk/jac-kit/components/Table/TableCell';
export default {
name: 'UserRolePermissions',
components: {
//Checkbox,
Table,
TableCell,
TextField,
ActionButton,
},
props: {
roleId: {
type: String,
required: false,
default: null,
},
permissions: {
type: Array,
required: false,
default: () => [
{
group: 'Database',
enabledPermissions: [],
permissions: [
{
label: 'Can create',
value: 'canCreate',
},
{
label: 'Can update',
value: 'canUpdate',
},
{
label: 'Can delete',
value: 'canDelete',
},
],
},
{
group: 'Users',
enabledPermissions: [],
permissions: [
{
label: 'Can enable users',
value: 'canEnableUsers',
},
{
label: 'Can change user role',
value: 'canChangeUserRole',
},
{
label: 'Can edit role permissions',
value: 'canEditRolePermissions',
},
],
},
{
group: 'Exercises',
enabledPermissions: [],
permissions: [
{
label: 'Can approve exercise',
value: 'canApproveExercise',
},
{
label: 'Can add notes to exercise',
value: 'canAddNotesToExercise',
},
{
label: 'Can reset exercise',
value: 'canResetExercise',
},
{
label: 'Can amend after launch',
value: 'canAmendAfterLaunch',
},
],
},
{
group: 'Candidates',
enabledPermissions: [],
permissions: [
{
label: 'Can view all candidates',
value: 'canViewAllCandidates',
},
{
label: 'Can add notes to candidates',
value: 'canAddNotesToCandidates',
},
],
},
],
},
},
data() {
return {
roleName: null,
tableColumns: [
{ title: '' },
],
};
},
methods: {
closeModal() {
this.$emit('close');
},
async createUserRole() {
//TODO: enforce unique role name
const response = await functions.httpsCallable('adminCreateUserRole')({ roleName: this.roleName });
this.roleId = response.data.id;
},
async saveUserRole() {
const response = await functions.httpsCallable('adminUpdateUserRole')({ roleId: this.roleId, permissions: this.permissions });
return response;
},
},
};
</script>

<style>
.govuk-table__header .govuk-checkboxes__item {
display: none;
}
.wide .modal {
width: 90%;
}
</style>
22 changes: 20 additions & 2 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import App from '@/App';
import router from '@/router';
import store from '@/store';
import * as filters from '@jac-uk/jac-kit/filters/filters';
import { auth, functions } from '@/firebase';
import * as localFilters from '@/filters';
import { auth } from '@/firebase';

import CKEditor from '@ckeditor/ckeditor5-vue';
import * as Sentry from '@sentry/browser';
import * as Integrations from '@sentry/integrations';
Expand Down Expand Up @@ -38,10 +39,27 @@ Object.keys(localFilters)
});

let vueInstance = false;
auth().onAuthStateChanged( (user) => {
auth().onAuthStateChanged((user) => {
// check if user is a new user.
// TODO: check if there is a better way of doing this
// TODO: the logic for this actually sits on SignIn.vue but the redirect on line 44 still occurs without the next 3 lines
// TODO: and a check within auth.js
if (user && user.metadata.lastSignInTime === user.metadata.creationTime) {
user.isNewUser = true;
}

// Bind Firebase auth state to the vuex auth state store
store.dispatch('auth/setCurrentUser', user);
if (store.getters['auth/isSignedIn']) {
user.getIdTokenResult()
.then(async (idTokenResult) => {
if (idTokenResult.claims && idTokenResult.claims.r) {
await functions.httpsCallable('adminSyncUserRolePermissions')();
}
})
.catch((error) => {
console.log(error);
});
if (window.location.pathname == '/sign-in') {
router.push('/');
}
Expand Down
13 changes: 13 additions & 0 deletions src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ import PageNotFound from '@/views/Errors/PageNotFound';

import Sandbox from '@/views/Sandbox';

// Users
import Users from '@/views/Users/Users';

Vue.use(Router);

const router = new Router({
Expand Down Expand Up @@ -145,6 +148,15 @@ const router = new Router({
title: 'Events',
},
},
{
path: '/users',
name: 'users',
component: Users,
meta: {
requiresAuth: true,
title: 'Users',
},
},
{
path: '/notifications',
name: 'notifications',
Expand Down Expand Up @@ -1263,6 +1275,7 @@ const router = new Router({
meta: {
title: 'Sign In',
},

beforeEnter: (to, from, next) => {
const isSignedIn = store.getters['auth/isSignedIn'];
if (isSignedIn) {
Expand Down
3 changes: 2 additions & 1 deletion src/store/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ const module = {
},
actions: {
setCurrentUser({ state, commit }, user) {
if (user === null) {
if (user === null || (user && user.isNewUser)) {
commit('setCurrentUser', null);
} else {
if (state.authError) { commit('setAuthError', null); }
let allOk = false;

if (user.email.indexOf('@judicialappointments.gov.uk') > 0) {
allOk = true;
} else if ([
Expand Down
Loading

0 comments on commit 3f61a48

Please sign in to comment.