From 04087b318af04e17a388124eb0abb243598ff97a Mon Sep 17 00:00:00 2001
From: SodhiA1 <38086281+SodhiA1@users.noreply.github.com>
Date: Wed, 1 Nov 2023 17:13:35 -0700
Subject: [PATCH 1/5] Ported SCHOOL_ADMIN role to permissions
---
backend/src/components/edx/exchange.js | 7 ---
backend/src/components/institute/institute.js | 55 +++++++------------
backend/src/routes/edx-router.js | 2 +-
backend/src/routes/institute.js | 18 +++---
backend/src/util/Permission.js | 9 ++-
.../components/institute/SchoolDetails.vue | 26 +++++----
.../src/components/institute/SchoolList.vue | 6 +-
.../components/institute/common/Details.vue | 21 +++----
.../institute/common/SchoolContacts.vue | 20 +++----
.../institute/common/SchoolMove.vue | 11 ++--
frontend/src/store/modules/auth.js | 12 ----
frontend/src/utils/constants/Permission.js | 16 +++++-
12 files changed, 96 insertions(+), 107 deletions(-)
diff --git a/backend/src/components/edx/exchange.js b/backend/src/components/edx/exchange.js
index 2fd71721c..b9d7d4971 100644
--- a/backend/src/components/edx/exchange.js
+++ b/backend/src/components/edx/exchange.js
@@ -1117,13 +1117,6 @@ async function getExchangeStats(req, res) {
async function createSchool(req, res) {
try {
- if (!req.session.roles.includes('SCHOOL_ADMIN')) {
- return res.status(HttpStatus.UNAUTHORIZED).json({
- status: HttpStatus.UNAUTHORIZED,
- message: 'You are not authorized to add or edit schools'
- });
- }
-
const {school, user} = req.body;
const isEmptyString = str => typeof str === 'string' && str.trim() === '';
diff --git a/backend/src/components/institute/institute.js b/backend/src/components/institute/institute.js
index 1e62f9232..6c990ed91 100644
--- a/backend/src/components/institute/institute.js
+++ b/backend/src/components/institute/institute.js
@@ -345,12 +345,6 @@ async function addSchool(req, res) {
try {
const token = getBackendToken(req);
- if(!hasSchoolAdminRole(req, req.body)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
- });
- }
-
const payload = {
createUser: utils.getUser(req).idir_username,
createDate: null,
@@ -433,9 +427,9 @@ async function addNewSchoolNote(req, res) {
const token = getBackendToken(req);
let school = cacheService.getSchoolBySchoolID(req.body.schoolId);
- if(!school || !hasSchoolAdminRole(req, school)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
+ if(!school){
+ return res.status(HttpStatus.NOT_FOUND).json({
+ message: 'School not found'
});
}
@@ -472,9 +466,9 @@ async function updateSchoolNote(req, res) {
try {
const token = getBackendToken(req);
let school = cacheService.getSchoolBySchoolID(req.body.schoolId);
- if (!school || !hasSchoolAdminRole(req, school)) {
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
+ if (!school) {
+ return res.status(HttpStatus.NOT_FOUND).json({
+ message: 'School not found'
});
}
const payload = {
@@ -494,9 +488,9 @@ async function deleteSchoolNote(req, res) {
try {
const token = getBackendToken(req);
let school = cacheService.getSchoolBySchoolID(req.params.schoolId);
- if(!school || !hasSchoolAdminRole(req, school)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
+ if(!school){
+ return res.status(HttpStatus.NOT_FOUND).json({
+ message: 'School not found'
});
}
await utils.deleteData(token, `${config.get('server:institute:instituteSchoolURL')}/${req.params.schoolId}/note/${req.params.noteId}`);
@@ -512,9 +506,9 @@ async function addSchoolContact(req, res) {
const token = getBackendToken(req);
let school = cacheService.getSchoolBySchoolID(req.body.schoolID);
- if(!school || !hasSchoolAdminRole(req, school)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
+ if(!school){
+ return res.status(HttpStatus.NOT_FOUND).json({
+ message: 'School not found'
});
}
@@ -554,9 +548,9 @@ async function updateSchoolContact(req, res) {
const token = getBackendToken(req);
let school = cacheService.getSchoolBySchoolID(req.body.schoolID);
- if(!school || !hasSchoolAdminRole(req, school)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
+ if(!school){
+ return res.status(HttpStatus.NOT_FOUND).json({
+ message: 'School not found'
});
}
@@ -587,9 +581,9 @@ async function deleteSchoolContact(req, res) {
const token = getBackendToken(req);
let school = cacheService.getSchoolBySchoolID(req.params.schoolId);
- if(!school || !hasSchoolAdminRole(req, school)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
+ if(!school){
+ return res.status(HttpStatus.NOT_FOUND).json({
+ message: 'School not found'
});
}
@@ -984,9 +978,9 @@ async function updateSchool(req, res) {
let school = cacheService.getSchoolBySchoolID(req.body.schoolId);
- if (!school || !hasSchoolAdminRole(req, school)) {
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
+ if (!school) {
+ return res.status(HttpStatus.NOT_FOUND).json({
+ message: 'School not found'
});
}
const payload = req.body;
@@ -1086,13 +1080,6 @@ async function getSchoolsPaginated(req, res){
async function moveSchool(req, res) {
try {
const token = getBackendToken(req);
-
- if(!hasSchoolAdminRole(req, req.body.toSchool)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
- });
- }
-
let school = cacheService.getSchoolBySchoolID(req.body.fromSchoolId);
if(!school || school.schoolCategoryCode === 'OFFSHORE') {
diff --git a/backend/src/routes/edx-router.js b/backend/src/routes/edx-router.js
index 105bc8dd1..b9b1bd6ac 100644
--- a/backend/src/routes/edx-router.js
+++ b/backend/src/routes/edx-router.js
@@ -92,6 +92,6 @@ router.post('/exchange/:secureExchangeID/documents', passport.authenticate('jwt'
router.get('/exchange/:secureExchangeID/documents/:documentId', auth.isValidExchangeUserToken, getExchangeDocumentById());
// Create School Saga
-router.post('/create-school', passport.authenticate('jwt', {session: false}, undefined), auth.isValidSchoolAdmin, createSchool);
+router.post('/create-school', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), createSchool);
module.exports = router;
diff --git a/backend/src/routes/institute.js b/backend/src/routes/institute.js
index 2544b0b3e..7fd062a05 100644
--- a/backend/src/routes/institute.js
+++ b/backend/src/routes/institute.js
@@ -49,33 +49,33 @@ router.post('/authority/contact', passport.authenticate('jwt', {session: false},
router.get('/school', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.VIEW_SCHOOL_PERMISSION), extendSession, getSchools);
-router.post('/school', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, addSchool);
+router.post('/school', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, addSchool);
router.get('/school/:schoolId/notes', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.VIEW_SCHOOL_PERMISSION), extendSession, getSchoolNotes);
-router.post('/school/note', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, addNewSchoolNote);
+router.post('/school/note', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, addNewSchoolNote);
-router.put('/school/note/:noteId', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, updateSchoolNote);
+router.put('/school/note/:noteId', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, updateSchoolNote);
-router.delete('/school/note/:schoolId/:noteId', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, deleteSchoolNote);
+router.delete('/school/note/:schoolId/:noteId', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, deleteSchoolNote);
-router.delete('/school/contact/:schoolId/:contactId', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, deleteSchoolContact);
+router.delete('/school/contact/:schoolId/:contactId', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, deleteSchoolContact);
-router.put('/school/contact/:contactId', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, updateSchoolContact);
+router.put('/school/contact/:contactId', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, updateSchoolContact);
-router.post('/school/contact', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, addSchoolContact);
+router.post('/school/contact', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, addSchoolContact);
router.get('/school/:id', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.VIEW_SCHOOL_PERMISSION), extendSession, getSchoolByID);
router.get('/school/mincode/:mincode', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.VIEW_SCHOOL_PERMISSION), extendSession, getSchoolByMincode);
-router.put('/school/:id', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, updateSchool);
+router.put('/school/:id', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, updateSchool);
router.get('/schoolsPaginated', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.VIEW_SCHOOL_PERMISSION), extendSession, getSchoolsPaginated);
router.get('/schoolHistoryPaginated', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.VIEW_SCHOOL_PERMISSION), extendSession, getSchoolHistoryPaginated);
-router.post('/school/moveSchool', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, moveSchool);
+router.post('/school/moveSchool', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, moveSchool);
router.get('/authoritiesPaginated', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.VIEW_AUTHORITY_PERMISSION), extendSession, getAuthoritiesPaginated);
diff --git a/backend/src/util/Permission.js b/backend/src/util/Permission.js
index 49fd64745..a8161d898 100644
--- a/backend/src/util/Permission.js
+++ b/backend/src/util/Permission.js
@@ -4,7 +4,14 @@ const PERMISSION = Object.freeze(
MANAGE_EDX_SCHOOL_USERS_PERMISSION: 'MANAGE_EDX_SCHOOL_USERS_PERMISSION',
VIEW_SCHOOL_PERMISSION: 'VIEW_SCHOOL_PERMISSION',
VIEW_DISTRICT_PERMISSION: 'VIEW_DISTRICT_PERMISSION',
- VIEW_AUTHORITY_PERMISSION: 'VIEW_AUTHORITY_PERMISSION'
+ VIEW_AUTHORITY_PERMISSION: 'VIEW_AUTHORITY_PERMISSION',
+ EDIT_SCHOOL_PERMISSION: 'EDIT_SCHOOL_PERMISSION',
+ EDIT_DISTRICT_PERMISSION: 'EDIT_DISTRICT_PERMISSION',
+ EDIT_AUTHORITY_PERMISSION: 'EDIT_AUTHORITY_PERMISSION',
+ EDIT_INDEPENDENT_SCHOOL_PERMISSION: 'EDIT_INDEPENDENT_SCHOOL_PERMISSION',
+ EDIT_OFFSHORE_SCHOOL_PERMISSION: 'EDIT_OFFSHORE_SCHOOL_PERMISSION',
+ EDIT_INDEPENDENT_AUTHORITY_PERMISSION: 'EDIT_INDEPENDENT_AUTHORITY_PERMISSION',
+ EDIT_OFFSHORE_AUTHORITY_PERMISSION: 'EDIT_OFFSHORE_AUTHORITY_PERMISSION'
}
);
diff --git a/frontend/src/components/institute/SchoolDetails.vue b/frontend/src/components/institute/SchoolDetails.vue
index 8617978e1..660067865 100644
--- a/frontend/src/components/institute/SchoolDetails.vue
+++ b/frontend/src/components/institute/SchoolDetails.vue
@@ -154,11 +154,15 @@
-
+
+Address
@@ -1175,6 +1175,10 @@ export default {
type: String,
required: true
},
+ hasAccess: {
+ type: Boolean,
+ required: true
+ },
},
data() {
return {
@@ -1211,7 +1215,7 @@ export default {
};
},
computed: {
- ...mapState(authStore, ['isAuthenticated', 'userInfo', 'SCHOOL_ADMIN_ROLE', 'INDEPENDENT_SCHOOLS_ADMIN_ROLE', 'OFFSHORE_SCHOOLS_ADMIN_ROLE']),
+ ...mapState(authStore, ['isAuthenticated', 'userInfo', 'INDEPENDENT_SCHOOLS_ADMIN_ROLE', 'OFFSHORE_SCHOOLS_ADMIN_ROLE']),
...mapState(instituteStore, ['facilityTypeCodes', 'schoolCategoryTypeCodes', 'activeSchoolCategoryTypeCodes', 'schoolOrganizationTypeCodes', 'schoolReportingRequirementTypeCodes', 'schoolNeighborhoodLearningCodes', 'gradeCodes', 'provinceCodes', 'countryCodes', 'schoolCategoryFacilityTypesMap', 'gradeOptions']),
...mapState(notificationsStore, ['notification']),
dataReady: function () {
@@ -1495,7 +1499,7 @@ export default {
this.$refs.schoolDetailsForm.validate();
},
showEditLinks(fieldValue) {
- return this.canEditSchoolDetails() && !fieldValue;
+ return this.hasAccess && !fieldValue;
},
cancelClicked() {
this.editing = false;
@@ -1573,15 +1577,6 @@ export default {
});
}
},
- canEditSchoolDetails() {
- if (this.school.schoolCategoryCode && this.independentArray.includes(this.school.schoolCategoryCode)) {
- return this.INDEPENDENT_SCHOOLS_ADMIN_ROLE || this.SCHOOL_ADMIN_ROLE;
- } else if(this.school.schoolCategoryCode && this.offshoreArray.includes(this.school.schoolCategoryCode)) {
- return this.OFFSHORE_SCHOOLS_ADMIN_ROLE || this.SCHOOL_ADMIN_ROLE;
- }
- return this.SCHOOL_ADMIN_ROLE;
- },
-
async clickSameAsAddressButton() {
await this.$nextTick();
await this.$refs.schoolDetailsForm.validate();
diff --git a/frontend/src/components/institute/common/SchoolContacts.vue b/frontend/src/components/institute/common/SchoolContacts.vue
index df5d1a519..b2928fedd 100644
--- a/frontend/src/components/institute/common/SchoolContacts.vue
+++ b/frontend/src/components/institute/common/SchoolContacts.vue
@@ -35,7 +35,7 @@
@@ -173,6 +173,10 @@ export default {
type: String,
required: true
},
+ hasAccess: {
+ type: Boolean,
+ required: true
+ },
},
data() {
return {
@@ -189,19 +193,11 @@ export default {
};
},
computed: {
- ...mapState(authStore, ['isAuthenticated', 'userInfo', 'INDEPENDENT_SCHOOLS_ADMIN_ROLE', 'SCHOOL_ADMIN_ROLE', 'OFFSHORE_SCHOOLS_ADMIN_ROLE']),
+ ...mapState(authStore, ['isAuthenticated', 'userInfo', 'INDEPENDENT_SCHOOLS_ADMIN_ROLE', 'OFFSHORE_SCHOOLS_ADMIN_ROLE']),
...mapState(instituteStore, ['schoolContactTypeCodes', 'independentAuthoritySchoolContacts', 'offshoreSchoolContacts', 'regularSchoolContactTypes']),
loading() {
return this.loadingCount !== 0;
- },
- canAddEditSchoolContact() {
- if (this.school.schoolCategoryCode && this.independentArray.includes(this.school.schoolCategoryCode)) {
- return (this.INDEPENDENT_SCHOOLS_ADMIN_ROLE || this.SCHOOL_ADMIN_ROLE) && this.isNotClosedAndNeverOpened();
- } else if(this.school.schoolCategoryCode && this.offshoreArray.includes(this.school.schoolCategoryCode)) {
- return (this.OFFSHORE_SCHOOLS_ADMIN_ROLE || this.SCHOOL_ADMIN_ROLE) && this.isNotClosedAndNeverOpened();
- }
- return this.SCHOOL_ADMIN_ROLE && this.isNotClosedAndNeverOpened();
- },
+ }
},
watch: {
async school(value) {
diff --git a/frontend/src/components/institute/common/SchoolMove.vue b/frontend/src/components/institute/common/SchoolMove.vue
index 75d3f2fc8..a80c88e3d 100644
--- a/frontend/src/components/institute/common/SchoolMove.vue
+++ b/frontend/src/components/institute/common/SchoolMove.vue
@@ -75,6 +75,7 @@ import {getStatusAuthorityOrSchool} from '@/utils/institute/status';
import {appStore} from '@/store/modules/app';
import {authStore} from '@/store/modules/auth';
import {instituteStore} from '@/store/modules/institute';
+import { PERMISSION, hasRequiredPermission } from '@/utils/constants/Permission';
export default {
name: 'SchoolMove',
@@ -110,7 +111,7 @@ export default {
};
},
computed: {
- ...mapState(authStore, ['isAuthenticated', 'userInfo', 'SCHOOL_ADMIN_ROLE', 'INDEPENDENT_SCHOOLS_ADMIN_ROLE']),
+ ...mapState(authStore, ['isAuthenticated', 'userInfo', 'INDEPENDENT_SCHOOLS_ADMIN_ROLE']),
...mapState(appStore, ['schoolMap', 'districtMap', 'independentAuthorityMap']),
},
watch: {
@@ -134,6 +135,7 @@ export default {
appStore().getCodes().then(() => this.getSchoolDetails());
},
methods: {
+ hasRequiredPermission,
...mapActions(instituteStore, ['schoolMovedNotification']),
getPageHeading() {
let school = this.schoolMap?.get(this.schoolID);
@@ -192,10 +194,9 @@ export default {
return formatDob(datetime.substring(0, 10), 'uuuu-MM-dd');
},
canEditSchoolDetails() {
- if (this.school.schoolCategoryCode && this.independentArray.includes(this.school.schoolCategoryCode)) {
- return this.INDEPENDENT_SCHOOLS_ADMIN_ROLE || this.SCHOOL_ADMIN_ROLE;
- }
- return this.SCHOOL_ADMIN_ROLE;
+ return this.hasRequiredPermission(this.userInfo, PERMISSION.EDIT_SCHOOL_PERMISSION) ||
+ (this.independentArray.includes(this.school?.schoolCategoryCode) &&
+ this.hasRequiredPermission(this.userInfo, PERMISSION.EDIT_INDEPENDENT_SCHOOL_PERMISSION));
},
isMoveSchoolAllowed() {
return this.school.status !== 'Closed' && this.school.status !== 'Never Opened' && this.school.schoolCategoryCode !== 'POST_SEC' && this.school.schoolCategoryCode !== 'OFFSHORE' && this.canEditSchoolDetails();
diff --git a/frontend/src/store/modules/auth.js b/frontend/src/store/modules/auth.js
index af6e29a24..ba58dde08 100644
--- a/frontend/src/store/modules/auth.js
+++ b/frontend/src/store/modules/auth.js
@@ -28,7 +28,6 @@ export const authStore = defineStore('auth', {
isValidExchangeUser: localStorage.getItem('isValidExchangeUser') !== null,
isValidPenTeamRoleUser: localStorage.getItem('isValidPenTeamRoleUser') !== null,
isValidDistrictAdmin: localStorage.getItem('isValidDistrictAdmin') !== null,
- isValidSchoolAdmin: localStorage.getItem('isValidSchoolAdmin') !== null,
isValidIndependentAuthorityAdmin: localStorage.getItem('isValidIndependentAuthorityAdmin') !== null,
isValidSchoolIndependentAdmin: localStorage.getItem('isValidSchoolIndependentAdmin') !== null,
isValidSchoolOffshoreAdmin: localStorage.getItem('isValidSchoolOffshoreAdmin') !== null,
@@ -64,7 +63,6 @@ export const authStore = defineStore('auth', {
EXCHANGE_ROLE: state => state.isValidExchangeUser,
PEN_TEAM_ROLE: state => state.isValidPenTeamRoleUser,
DISTRICT_ADMIN_ROLE: state => state.isValidDistrictAdmin,
- SCHOOL_ADMIN_ROLE: state => state.isValidSchoolAdmin,
INDEPENDENT_SCHOOLS_ADMIN_ROLE: state => state.isValidSchoolIndependentAdmin,
OFFSHORE_SCHOOLS_ADMIN_ROLE: state => state.isValidSchoolOffshoreAdmin,
INDEPENDENT_AUTHORITY_ADMIN_ROLE: state => state.isValidIndependentAuthorityAdmin,
@@ -251,15 +249,6 @@ export const authStore = defineStore('auth', {
localStorage.removeItem('isValidDistrictAdmin');
}
},
- async setIsValidSchoolAdmin(isValidSchoolAdmin) {
- if (isValidSchoolAdmin) {
- this.isValidSchoolAdmin = true;
- localStorage.setItem('isValidSchoolAdmin', 'true');
- } else {
- this.isValidSchoolAdmin = false;
- localStorage.removeItem('isValidSchoolAdmin');
- }
- },
async setIsValidSchoolIndependentAdmin(isValidSchoolIndependentAdmin) {
if (isValidSchoolIndependentAdmin) {
this.isValidSchoolIndependentAdmin = true;
@@ -361,7 +350,6 @@ export const authStore = defineStore('auth', {
await this.setExchangeUser(response.isValidExchangeUser);
await this.setIsValidPenTeamRoleUser(response.isValidPenTeamRoleUser);
await this.setIsValidDistrictAdmin(response.isValidDistrictAdmin);
- await this.setIsValidSchoolAdmin(response.isValidSchoolAdmin);
await this.setIsValidSchoolIndependentAdmin(response.isValidSchoolIndependentAdmin);
await this.setIsValidSchoolOffshoreAdmin(response.isValidSchoolOffshoreAdmin);
await this.setIsValidIndependentAuthorityAdmin(response.isValidIndependentAuthorityAdmin);
diff --git a/frontend/src/utils/constants/Permission.js b/frontend/src/utils/constants/Permission.js
index 3815e652f..95d11b95e 100644
--- a/frontend/src/utils/constants/Permission.js
+++ b/frontend/src/utils/constants/Permission.js
@@ -16,7 +16,21 @@ export const PERMISSION = Object.freeze(
VIEW_DISTRICT_PERMISSION: 'VIEW_DISTRICT_PERMISSION',
- VIEW_AUTHORITY_PERMISSION: 'VIEW_AUTHORITY_PERMISSION'
+ VIEW_AUTHORITY_PERMISSION: 'VIEW_AUTHORITY_PERMISSION',
+
+ EDIT_SCHOOL_PERMISSION: 'EDIT_SCHOOL_PERMISSION',
+
+ EDIT_DISTRICT_PERMISSION: 'EDIT_DISTRICT_PERMISSION',
+
+ EDIT_AUTHORITY_PERMISSION: 'EDIT_AUTHORITY_PERMISSION',
+
+ EDIT_INDEPENDENT_SCHOOL_PERMISSION: 'EDIT_INDEPENDENT_SCHOOL_PERMISSION',
+
+ EDIT_OFFSHORE_SCHOOL_PERMISSION: 'EDIT_OFFSHORE_SCHOOL_PERMISSION',
+
+ EDIT_INDEPENDENT_AUTHORITY_PERMISSION: 'EDIT_INDEPENDENT_AUTHORITY_PERMISSION',
+
+ EDIT_OFFSHORE_AUTHORITY_PERMISSION: 'EDIT_OFFSHORE_AUTHORITY_PERMISSION'
}
);
From af66fa33a31e0c59c70c2328b66276aaa2f0aa33 Mon Sep 17 00:00:00 2001
From: SodhiA1 <38086281+SodhiA1@users.noreply.github.com>
Date: Wed, 1 Nov 2023 17:36:51 -0700
Subject: [PATCH 2/5] removing dependency on SCHOOL_ADMIN role
---
backend/src/components/roles.js | 1 -
backend/src/components/sdc/sdc.js | 53 ++++++++-----------------------
backend/src/routes/sdc.js | 16 ++++++----
3 files changed, 22 insertions(+), 48 deletions(-)
diff --git a/backend/src/components/roles.js b/backend/src/components/roles.js
index 64e968085..85cb7e468 100644
--- a/backend/src/components/roles.js
+++ b/backend/src/components/roles.js
@@ -40,7 +40,6 @@ const roles = {
StaffAdministration: config.get('server:administration:roleAdmin'),
NominalRoll: config.get('server:nominalRoll:roleAdmin'),
District: 'DISTRICT_ADMIN',
- School: 'SCHOOL_ADMIN',
SchoolIndependent: 'INDEPENDENT_SCHOOLS_ADMIN',
IndependentAuthority: 'INDEPENDENT_AUTHORITY_ADMIN',
SchoolOffshore: 'OFFSHORE_SCHOOLS_ADMIN'
diff --git a/backend/src/components/sdc/sdc.js b/backend/src/components/sdc/sdc.js
index 07756307c..8e16820a6 100644
--- a/backend/src/components/sdc/sdc.js
+++ b/backend/src/components/sdc/sdc.js
@@ -9,15 +9,7 @@ async function getFundingGroupDataForSchool(req, res) {
try {
const accessToken = getBackendToken(req);
validateAccessToken(accessToken, res);
-
- let school = cacheService.getSchoolBySchoolID(req.params.schoolID);
-
- if(!hasSchoolAdminRole(req, school)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
- });
- }
-
+
const data = await getData(accessToken, `${config.get('sdc:fundingGroupDataURL')}/search/${req.params.schoolID}`);
return res.status(HttpStatus.OK).json(data);
} catch (e) {
@@ -29,16 +21,7 @@ async function getFundingGroupDataForSchool(req, res) {
async function getSnapshotFundingDataForSchool(req, res) {
try {
const accessToken = getBackendToken(req);
- validateAccessToken(accessToken, res);
-
- let school = cacheService.getSchoolBySchoolID(req.params.schoolID);
-
- if(!hasSchoolAdminRole(req, school)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
- });
- }
-
+ validateAccessToken(accessToken, res);
const data = await getData(accessToken, `${config.get('sdc:fundingGroupDataURL')}/snapshot/${req.params.schoolID}/${req.params.collectionID}`);
return res.status(HttpStatus.OK).json(data);
} catch (e) {
@@ -53,10 +36,9 @@ async function deleteFundingDataForSchool(req, res) {
validateAccessToken(accessToken, res);
let school = cacheService.getSchoolBySchoolID(req.params.schoolID);
-
- if(!hasSchoolAdminRole(req, school)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
+ if(!school){
+ return res.status(HttpStatus.NOT_FOUND).json({
+ message: 'School not found'
});
}
@@ -75,9 +57,9 @@ async function updateFundingDataForSchool(req, res) {
let school = cacheService.getSchoolBySchoolID(req.params.schoolID);
- if(!hasSchoolAdminRole(req, school)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
+ if(school?.schoolCategoryCode !== 'INDEPEND' && school?.schoolCategoryCode !== 'INDP_FNS') {
+ return res.status(HttpStatus.BAD_REQUEST).json({
+ message: 'Unable to update funding code for this school category'
});
}
@@ -100,10 +82,10 @@ async function addNewFundingForSchool(req, res) {
validateAccessToken(accessToken, res);
let school = cacheService.getSchoolBySchoolID(req.params.schoolID);
-
- if(!hasSchoolAdminRole(req, school)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
+
+ if(school?.schoolCategoryCode !== 'INDEPEND' && school?.schoolCategoryCode !== 'INDP_FNS') {
+ return res.status(HttpStatus.BAD_REQUEST).json({
+ message: 'Unable to add funding code for this school category'
});
}
@@ -122,16 +104,7 @@ async function addNewFundingForSchool(req, res) {
async function getAllCollectionsForSchool(req, res) {
try {
const accessToken = getBackendToken(req);
- validateAccessToken(accessToken, res);
-
- let school = cacheService.getSchoolBySchoolID(req.params.schoolID);
-
- if(!hasSchoolAdminRole(req, school)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
- });
- }
-
+ validateAccessToken(accessToken, res);
const data = await getData(accessToken, `${config.get('sdc:schoolCollectionURL')}/searchAll/${req.params.schoolID}`);
return res.status(HttpStatus.OK).json(data);
} catch (e) {
diff --git a/backend/src/routes/sdc.js b/backend/src/routes/sdc.js
index 64116e7ce..88b571fa8 100644
--- a/backend/src/routes/sdc.js
+++ b/backend/src/routes/sdc.js
@@ -2,20 +2,22 @@ const passport = require('passport');
const express = require('express');
const router = express.Router();
const utils = require('../components/utils');
+const perm = require('../util/Permission');
const extendSession = utils.extendSession();
const { getFundingGroupDataForSchool, deleteFundingDataForSchool, updateFundingDataForSchool,
getSnapshotFundingDataForSchool, addNewFundingForSchool, getAllCollectionsForSchool} = require('../components/sdc/sdc');
const auth = require('../components/auth');
const {getCachedSDCData} = require('../components/sdc/sdc-cache');
const constants = require('../util/constants');
+const PERMISSION = perm.PERMISSION;
-router.post('/funding-groups/:schoolID', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, addNewFundingForSchool);
-router.get('/funding-groups/:schoolID', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, getFundingGroupDataForSchool);
-router.delete('/funding-groups/:schoolID/funding/:schoolFundingGroupID', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, deleteFundingDataForSchool);
-router.put('/funding-groups/:schoolID/funding/:schoolFundingGroupID', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, updateFundingDataForSchool);
-router.get('/funding-groups/snapshot/:schoolID/:collectionID', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, getSnapshotFundingDataForSchool);
+router.post('/funding-groups/:schoolID', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, addNewFundingForSchool);
+router.get('/funding-groups/:schoolID', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, getFundingGroupDataForSchool);
+router.delete('/funding-groups/:schoolID/funding/:schoolFundingGroupID', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, deleteFundingDataForSchool);
+router.put('/funding-groups/:schoolID/funding/:schoolFundingGroupID', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, updateFundingDataForSchool);
+router.get('/funding-groups/snapshot/:schoolID/:collectionID', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, getSnapshotFundingDataForSchool);
-router.get('/funding-groups', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, getCachedSDCData(constants.CACHE_KEYS.SDC_FUNDING_GROUPS, 'sdc:fundingGroupsURL'));
-router.get('/sdcSchoolCollection/:schoolID', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, getAllCollectionsForSchool);
+router.get('/funding-groups', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, getCachedSDCData(constants.CACHE_KEYS.SDC_FUNDING_GROUPS, 'sdc:fundingGroupsURL'));
+router.get('/sdcSchoolCollection/:schoolID', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, getAllCollectionsForSchool);
module.exports = router;
From 246d961a5fedbef04064894d01e0ef683483d3ca Mon Sep 17 00:00:00 2001
From: SodhiA1 <38086281+SodhiA1@users.noreply.github.com>
Date: Thu, 2 Nov 2023 09:29:58 -0700
Subject: [PATCH 3/5] lint fixes
---
backend/src/components/institute/institute.js | 10 ----------
backend/src/components/sdc/sdc.js | 9 ---------
backend/src/routes/sdc.js | 1 -
3 files changed, 20 deletions(-)
diff --git a/backend/src/components/institute/institute.js b/backend/src/components/institute/institute.js
index 6c990ed91..165d68a51 100644
--- a/backend/src/components/institute/institute.js
+++ b/backend/src/components/institute/institute.js
@@ -842,16 +842,6 @@ function hasDistrictAdminRole(req){
return req.session.roles.includes('DISTRICT_ADMIN');
}
-function hasSchoolAdminRole(req, school){
- if(school.schoolCategoryCode === 'INDEPEND' || school.schoolCategoryCode === 'INDP_FNS'){
- return req.session.roles.includes('SCHOOL_ADMIN') || req.session.roles.includes('INDEPENDENT_SCHOOLS_ADMIN');
- } else if(school.schoolCategoryCode === 'OFFSHORE'){
- return req.session.roles.includes('SCHOOL_ADMIN') || req.session.roles.includes('OFFSHORE_SCHOOLS_ADMIN');
- }
-
- return req.session.roles.includes('SCHOOL_ADMIN');
-}
-
function hasAuthorityAdminRole(req, authority){
if(authority?.authorityTypeCode === 'INDEPENDNT') {
return req.session.roles.includes('INDEPENDENT_AUTHORITY_ADMIN') || req.session.roles.includes('INDEPENDENT_SCHOOLS_ADMIN');
diff --git a/backend/src/components/sdc/sdc.js b/backend/src/components/sdc/sdc.js
index 8e16820a6..994de54e0 100644
--- a/backend/src/components/sdc/sdc.js
+++ b/backend/src/components/sdc/sdc.js
@@ -113,15 +113,6 @@ async function getAllCollectionsForSchool(req, res) {
}
}
-function hasSchoolAdminRole(req, school){
- if(school.schoolCategoryCode === 'INDEPEND' || school.schoolCategoryCode === 'INDP_FNS'){
- return req.session.roles.includes('SCHOOL_ADMIN') || req.session.roles.includes('INDEPENDENT_SCHOOLS_ADMIN');
- }
-
- return req.session.roles.includes('SCHOOL_ADMIN');
-}
-
-
module.exports = {
getFundingGroupDataForSchool,
deleteFundingDataForSchool,
diff --git a/backend/src/routes/sdc.js b/backend/src/routes/sdc.js
index 88b571fa8..0542b7ed9 100644
--- a/backend/src/routes/sdc.js
+++ b/backend/src/routes/sdc.js
@@ -6,7 +6,6 @@ const perm = require('../util/Permission');
const extendSession = utils.extendSession();
const { getFundingGroupDataForSchool, deleteFundingDataForSchool, updateFundingDataForSchool,
getSnapshotFundingDataForSchool, addNewFundingForSchool, getAllCollectionsForSchool} = require('../components/sdc/sdc');
-const auth = require('../components/auth');
const {getCachedSDCData} = require('../components/sdc/sdc-cache');
const constants = require('../util/constants');
const PERMISSION = perm.PERMISSION;
From 84b4cb19b7593e90e1c554a057b71294f965335e Mon Sep 17 00:00:00 2001
From: SodhiA1 <38086281+SodhiA1@users.noreply.github.com>
Date: Thu, 2 Nov 2023 11:22:23 -0700
Subject: [PATCH 4/5] DISTRICT_ADMIN role
---
backend/src/components/institute/institute.js | 46 +++++++++----------
backend/src/components/roles.js | 1 -
backend/src/routes/institute.js | 14 +++---
.../components/institute/DistrictDetails.vue | 12 +++--
.../components/institute/district/Details.vue | 17 +++----
.../institute/district/DistrictContacts.vue | 13 +++---
frontend/src/store/modules/auth.js | 12 -----
tools/config/update-configmap.sh | 2 +-
8 files changed, 54 insertions(+), 63 deletions(-)
diff --git a/backend/src/components/institute/institute.js b/backend/src/components/institute/institute.js
index 165d68a51..5105f6ae3 100644
--- a/backend/src/components/institute/institute.js
+++ b/backend/src/components/institute/institute.js
@@ -60,9 +60,9 @@ async function addDistrictContact(req, res) {
const token = getBackendToken(req);
let district = cacheService.getDistrictJSONByDistrictId(req.body.districtID);
- if(!district || !hasDistrictAdminRole(req)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
+ if(!district){
+ return res.status(HttpStatus.NOT_FOUND).json({
+ message: 'District not found'
});
}
@@ -125,9 +125,9 @@ async function updateDistrict(req, res) {
let district = cacheService.getDistrictJSONByDistrictId(req.body.districtId);
- if (!district || !hasDistrictAdminRole(req)) {
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
+ if (!district) {
+ return res.status(HttpStatus.NOT_FOUND).json({
+ message: 'District not found'
});
}
const districtPayload = req.body;
@@ -158,9 +158,9 @@ async function updateDistrictContact(req, res) {
const token = getBackendToken(req);
let district = cacheService.getDistrictJSONByDistrictId(req.body.districtId);
- if(!district || !hasDistrictAdminRole(req)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
+ if(!district){
+ return res.status(HttpStatus.NOT_FOUND).json({
+ message: 'District not found'
});
}
@@ -188,9 +188,9 @@ async function deleteDistrictContact(req, res) {
const token = getBackendToken(req);
let district = cacheService.getDistrictJSONByDistrictId(req.params.districtId);
- if(!district || !hasDistrictAdminRole(req)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
+ if(!district){
+ return res.status(HttpStatus.NOT_FOUND).json({
+ message: 'District not found'
});
}
@@ -245,9 +245,9 @@ async function addNewDistrictNote(req, res) {
const token = getBackendToken(req);
let district = cacheService.getDistrictJSONByDistrictId(req.body.districtId);
- if(!district || !hasDistrictAdminRole(req)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
+ if(!district){
+ return res.status(HttpStatus.NOT_FOUND).json({
+ message: 'District not found'
});
}
const params = {
@@ -271,9 +271,9 @@ async function updateDistrictNote(req, res) {
try {
const token = getBackendToken(req);
let district = cacheService.getDistrictJSONByDistrictId(req.body.districtId);
- if(!district || !hasDistrictAdminRole(req)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
+ if(!district){
+ return res.status(HttpStatus.NOT_FOUND).json({
+ message: 'District not found'
});
}
const payload = {
@@ -293,9 +293,9 @@ async function deleteDistrictNote(req, res) {
try {
const token = getBackendToken(req);
let district = cacheService.getDistrictJSONByDistrictId(req.params.districtId);
- if(!district || !hasDistrictAdminRole(req)){
- return res.status(HttpStatus.UNAUTHORIZED).json({
- message: 'You do not have the required access for this function'
+ if(!district){
+ return res.status(HttpStatus.NOT_FOUND).json({
+ message: 'District not found'
});
}
await utils.deleteData(token, `${config.get('server:institute:instituteDistrictURL')}/${req.params.districtId}/note/${req.params.noteId}`);
@@ -838,10 +838,6 @@ async function updateAuthority(req, res) {
}
}
-function hasDistrictAdminRole(req){
- return req.session.roles.includes('DISTRICT_ADMIN');
-}
-
function hasAuthorityAdminRole(req, authority){
if(authority?.authorityTypeCode === 'INDEPENDNT') {
return req.session.roles.includes('INDEPENDENT_AUTHORITY_ADMIN') || req.session.roles.includes('INDEPENDENT_SCHOOLS_ADMIN');
diff --git a/backend/src/components/roles.js b/backend/src/components/roles.js
index 85cb7e468..163eabc20 100644
--- a/backend/src/components/roles.js
+++ b/backend/src/components/roles.js
@@ -39,7 +39,6 @@ const roles = {
//Help functions created in auth module: isValidStaffAdministrationAdmin
StaffAdministration: config.get('server:administration:roleAdmin'),
NominalRoll: config.get('server:nominalRoll:roleAdmin'),
- District: 'DISTRICT_ADMIN',
SchoolIndependent: 'INDEPENDENT_SCHOOLS_ADMIN',
IndependentAuthority: 'INDEPENDENT_AUTHORITY_ADMIN',
SchoolOffshore: 'OFFSHORE_SCHOOLS_ADMIN'
diff --git a/backend/src/routes/institute.js b/backend/src/routes/institute.js
index 7fd062a05..5ed545ccc 100644
--- a/backend/src/routes/institute.js
+++ b/backend/src/routes/institute.js
@@ -19,25 +19,25 @@ router.get('/district', passport.authenticate('jwt', {session: false}, undefined
router.get('/district/:districtId', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.VIEW_DISTRICT_PERMISSION), extendSession, getDistrictByDistrictID);
-router.put('/district/:districtId', passport.authenticate('jwt', {session: false}, undefined), auth.isValidDistrictAdmin, extendSession, updateDistrict);
+router.put('/district/:districtId', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_DISTRICT_PERMISSION), extendSession, updateDistrict);
router.get('/studentRegistrationContacts', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, getStudentRegistrationContacts);
router.get('/studentRegistrationContact/:mincode', passport.authenticate('jwt', {session: false}, undefined), extendSession, getStudentRegistrationContactByMincode);
-router.put('/district/contact/:contactId', passport.authenticate('jwt', {session: false}, undefined), auth.isValidDistrictAdmin, extendSession, updateDistrictContact);
+router.put('/district/contact/:contactId', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_DISTRICT_PERMISSION), extendSession, updateDistrictContact);
-router.delete('/district/contact/:districtId/:contactId', passport.authenticate('jwt', {session: false}, undefined), auth.isValidDistrictAdmin, extendSession, deleteDistrictContact);
+router.delete('/district/contact/:districtId/:contactId', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_DISTRICT_PERMISSION), extendSession, deleteDistrictContact);
router.get('/district/:districtId/notes', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.VIEW_DISTRICT_PERMISSION), extendSession, getDistrictNotes);
-router.post('/district/note', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, addNewDistrictNote);
+router.post('/district/note', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_DISTRICT_PERMISSION), extendSession, addNewDistrictNote);
-router.put('/district/note/:noteId', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, updateDistrictNote);
+router.put('/district/note/:noteId', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_DISTRICT_PERMISSION), extendSession, updateDistrictNote);
-router.delete('/district/note/:districtId/:noteId', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, deleteDistrictNote);
+router.delete('/district/note/:districtId/:noteId', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_DISTRICT_PERMISSION), extendSession, deleteDistrictNote);
-router.post('/district/contact', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, addDistrictContact);
+router.post('/district/contact', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_DISTRICT_PERMISSION), extendSession, addDistrictContact);
router.put('/authority/contact/:contactId', passport.authenticate('jwt', {session: false}, undefined), auth.isLoggedInUser, extendSession, updateAuthorityContact);
diff --git a/frontend/src/components/institute/DistrictDetails.vue b/frontend/src/components/institute/DistrictDetails.vue
index 33f91a62d..838546eb9 100644
--- a/frontend/src/components/institute/DistrictDetails.vue
+++ b/frontend/src/components/institute/DistrictDetails.vue
@@ -134,11 +134,15 @@
-
+
@@ -704,7 +704,11 @@ export default {
districtID: {
type: String,
required: true,
- }
+ },
+ hasAccess: {
+ type: Boolean,
+ required: true
+ },
},
data() {
return {
@@ -722,7 +726,7 @@ export default {
};
},
computed: {
- ...mapState(authStore, ['DISTRICT_ADMIN_ROLE', 'OFFSHORE_SCHOOLS_ADMIN_ROLE']),
+ ...mapState(authStore, ['OFFSHORE_SCHOOLS_ADMIN_ROLE']),
...mapState(instituteStore, ['provinceCodes', 'countryCodes']),
...mapState(edxStore, ['schoolSearchParams']),
notesLoading() {
@@ -771,7 +775,7 @@ export default {
this.setHasSamePhysicalFlag();
},
showEditLinks(fieldValue) {
- return this.canEditDistrictDetails() && !fieldValue;
+ return this.hasAccess && !fieldValue;
},
setHasSamePhysicalFlag() {
this.sameAsMailingCheckbox = this.hasSamePhysicalAddress;
@@ -802,9 +806,6 @@ export default {
return 'red';
}
},
- canEditDistrictDetails() {
- return this.DISTRICT_ADMIN_ROLE;
- },
addAddressesIfRequired(district) {
let addresses = district.addresses;
if (!this.hasMailingAddress()) {
diff --git a/frontend/src/components/institute/district/DistrictContacts.vue b/frontend/src/components/institute/district/DistrictContacts.vue
index 3a5fbd7c0..f9f15bae2 100644
--- a/frontend/src/components/institute/district/DistrictContacts.vue
+++ b/frontend/src/components/institute/district/DistrictContacts.vue
@@ -37,7 +37,7 @@
@@ -229,6 +229,10 @@ export default {
required: false,
default: undefined
},
+ hasAccess: {
+ type: Boolean,
+ required: true
+ },
},
data() {
return {
@@ -249,13 +253,10 @@ export default {
};
},
computed: {
- ...mapState(authStore, ['isAuthenticated', 'userInfo', 'DISTRICT_ADMIN_ROLE']),
+ ...mapState(authStore, ['isAuthenticated', 'userInfo']),
loading() {
return this.loadingCount !== 0;
},
- canEditDistrictContact() {
- return this.DISTRICT_ADMIN_ROLE && this.districtDetails.districtStatusCode === 'ACTIVE';
- },
filteredDistrictContactTypes() {
if (!this.isFiltered) {
return this.districtContactTypes;
diff --git a/frontend/src/store/modules/auth.js b/frontend/src/store/modules/auth.js
index ba58dde08..0907f6519 100644
--- a/frontend/src/store/modules/auth.js
+++ b/frontend/src/store/modules/auth.js
@@ -27,7 +27,6 @@ export const authStore = defineStore('auth', {
isValidPenRequestBatchAnalyticsUser: localStorage.getItem('isValidPenRequestBatchAnalyticsUser') !== null,
isValidExchangeUser: localStorage.getItem('isValidExchangeUser') !== null,
isValidPenTeamRoleUser: localStorage.getItem('isValidPenTeamRoleUser') !== null,
- isValidDistrictAdmin: localStorage.getItem('isValidDistrictAdmin') !== null,
isValidIndependentAuthorityAdmin: localStorage.getItem('isValidIndependentAuthorityAdmin') !== null,
isValidSchoolIndependentAdmin: localStorage.getItem('isValidSchoolIndependentAdmin') !== null,
isValidSchoolOffshoreAdmin: localStorage.getItem('isValidSchoolOffshoreAdmin') !== null,
@@ -62,7 +61,6 @@ export const authStore = defineStore('auth', {
HAS_STATS_ROLE: state => state.isValidGUMPAnalyticsUser || state.isValidPenRequestBatchAnalyticsUser,
EXCHANGE_ROLE: state => state.isValidExchangeUser,
PEN_TEAM_ROLE: state => state.isValidPenTeamRoleUser,
- DISTRICT_ADMIN_ROLE: state => state.isValidDistrictAdmin,
INDEPENDENT_SCHOOLS_ADMIN_ROLE: state => state.isValidSchoolIndependentAdmin,
OFFSHORE_SCHOOLS_ADMIN_ROLE: state => state.isValidSchoolOffshoreAdmin,
INDEPENDENT_AUTHORITY_ADMIN_ROLE: state => state.isValidIndependentAuthorityAdmin,
@@ -240,15 +238,6 @@ export const authStore = defineStore('auth', {
localStorage.removeItem('isValidPenTeamRoleUser');
}
},
- async setIsValidDistrictAdmin(isValidDistrictAdmin) {
- if (isValidDistrictAdmin) {
- this.isValidDistrictAdmin = true;
- localStorage.setItem('isValidDistrictAdmin', 'true');
- } else {
- this.isValidDistrictAdmin = false;
- localStorage.removeItem('isValidDistrictAdmin');
- }
- },
async setIsValidSchoolIndependentAdmin(isValidSchoolIndependentAdmin) {
if (isValidSchoolIndependentAdmin) {
this.isValidSchoolIndependentAdmin = true;
@@ -349,7 +338,6 @@ export const authStore = defineStore('auth', {
await this.setPenRequestBatchAnalytics(response.isValidPenRequestBatchAnalyticsUser);
await this.setExchangeUser(response.isValidExchangeUser);
await this.setIsValidPenTeamRoleUser(response.isValidPenTeamRoleUser);
- await this.setIsValidDistrictAdmin(response.isValidDistrictAdmin);
await this.setIsValidSchoolIndependentAdmin(response.isValidSchoolIndependentAdmin);
await this.setIsValidSchoolOffshoreAdmin(response.isValidSchoolOffshoreAdmin);
await this.setIsValidIndependentAuthorityAdmin(response.isValidIndependentAuthorityAdmin);
diff --git a/tools/config/update-configmap.sh b/tools/config/update-configmap.sh
index 68cfa1bb5..556d42bd2 100644
--- a/tools/config/update-configmap.sh
+++ b/tools/config/update-configmap.sh
@@ -434,7 +434,7 @@ BANNER_COLOR="$bannerColor"
WEB_SOCKET_URL="wss://$SERVER_FRONTEND/api/socket"
echo Creating config map $APP_NAME-backend-config-map
-oc create -n $PEN_NAMESPACE-$envValue configmap $APP_NAME-backend-config-map --from-literal=WEB_SOCKET_URL="$WEB_SOCKET_URL" --from-literal=BANNER_COLOR="$BANNER_COLOR" --from-literal=BANNER_ENVIRONMENT="$BANNER_ENVIRONMENT" --from-literal=TZ=$TZVALUE --from-literal=UI_PRIVATE_KEY="$UI_PRIVATE_KEY_VAL" --from-literal=SITEMINDER_LOGOUT_ENDPOINT="$siteMinderLogoutUrl" --from-literal=UI_PUBLIC_KEY="$UI_PUBLIC_KEY_VAL" --from-literal=ID=$APP_NAME-soam --from-literal=SECRET=$studentAdminClientSecret --from-literal=SERVER_FRONTEND=https://$SERVER_FRONTEND --from-literal=ISSUER=STUDENT_ADMIN_APPLICATION --from-literal=SOAM_PUBLIC_KEY="$formattedPublicKey" --from-literal=PEN_REQUEST_EMAIL_API_URL="http://student-profile-email-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/gmp" --from-literal=PEN_REQUEST_API_URL="http://pen-request-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/pen-request" --from-literal=DISCOVERY=https://$SOAM_KC/auth/realms/$SOAM_KC_REALM_ID/.well-known/openid-configuration --from-literal=KC_DOMAIN=https://$SOAM_KC/auth/realms/$SOAM_KC_REALM_ID --from-literal=PEN_DEMOGRAPHICS_URL="http://pen-demographics-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080" --from-literal=DIGITAL_ID_URL="http://digitalid-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/digital-id" --from-literal=STUDENT_API_URL="http://student-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/student" --from-literal=LOG_LEVEL=info --from-literal=IDIR_IDP_HINT=keycloak_bcdevexchange_idir --from-literal=REDIS_HOST=redis --from-literal=REDIS_PORT=6379 --from-literal=STUDENT_PROFILE_API_URL="http://student-profile-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/student-profile" --from-literal=SCHOOL_API_URL="http://school-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1" --from-literal=STUDENT_PROFILE_EMAIL_API_URL="http://student-profile-email-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/ump" --from-literal=PROFILE_REQUEST_SAGA_API_URL="http://student-profile-saga-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/student-profile-saga" --from-literal=NATS_URL="$NATS_URL" --from-literal=NATS_CLUSTER="$NATS_CLUSTER" --from-literal=UMP_ROLES="STUDENT_PROFILE_ADMIN,STUDENT_PROFILE_READ_ONLY" --from-literal=GMP_ROLES="STUDENT_ADMIN,STUDENT_ADMIN_READ_ONLY" --from-literal=STUDENT_SEARCH_ADMIN="STUDENT_SEARCH_ADMIN" --from-literal=STUDENT_SEARCH_ROLES="STUDENT_SEARCH_ADMIN,STUDENT_SEARCH_READ_ONLY" --from-literal=STUDENT_ADMIN_ADMINISTRATOR="STUDENT_ADMIN_ADMINISTRATOR" --from-literal=UMP_ROLE_ADMIN="STUDENT_PROFILE_ADMIN" --from-literal=GMP_ROLE_ADMIN="STUDENT_ADMIN" --from-literal=PEN_REQUEST_BATCH_ADMIN="PEN_REQUEST_BATCH_ADMIN" --from-literal=EDX_ADMIN="EDX_ADMIN" --from-literal=PEN_REQUEST_BATCH_API_URL="http://pen-reg-batch-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1" --from-literal=PEN_MATCH_API_URL="http://pen-match-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/pen-match" --from-literal=SESSION_MAX_AGE=$sessionMaxAge --from-literal=TOKEN_EXPIRES_IN=$tokenExpiresIn --from-literal=SCHEDULER_CRON_STALE_SAGA_RECORD_REDIS="0/30 * * * * *" --from-literal=MIN_TIME_BEFORE_SAGA_IS_STALE_IN_SECONDS=10 --from-literal=PEN_SERVICES_API_URL="http://pen-services-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/pen-services" --from-literal=PEN_TRAX_API_URL="http://pen-trax-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1" --from-literal=SLD_API_URL="http://sld-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1" --from-literal=QUEUE_GROUP_NAME="student-admin-node-queue-group" --from-literal=STAN_ENABLED="true" --from-literal=NODE_ENV="openshift" --from-literal=SCHEDULER_CRON_DOC_TYPE_MIGRATION="$SCHEDULER_CRON_DOC_TYPE_MIGRATION" --from-literal=ENABLE_PRR_STUDENT_DEMOGRAPHICS="$ENABLE_PRR_STUDENT_DEMOGRAPHICS" --from-literal=NOMINAL_ROLL="NOMINAL_ROLL_EDIT" --from-literal=MACRO_API_URL="http://macro-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/macro" --from-literal=NOMINAL_ROLL_API_URL="http://pen-nominal-roll-api-main.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/nominal-roll" --from-literal=STUDENT_ANALYTICS_STUDENT_PROFILE="STUDENT_ANALYTICS_STUDENT_PROFILE" --from-literal=STUDENT_ANALYTICS_BATCH="STUDENT_ANALYTICS_BATCH" --from-literal=NOMINAL_ROLL_ROLES="NOMINAL_ROLL,NOMINAL_ROLL_EDIT" --from-literal=EDX_API_URL="http://edx-api-master.$EDX_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/edx" --from-literal=SDC_API_URL="http://student-data-collection-api-master.$EDX_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/student-data-collection" --from-literal=INSTITUTE_API_URL="http://institute-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/institute" --from-literal=EDX_PEN_TEAM_ROLES="PEN_TEAM_ROLE" --from-literal=INSTITUTE_ROLES="SCHOOL_ADMIN,DISTRICT_ADMIN,INDEPENDENT_SCHOOLS_ADMIN,INDEPENDENT_AUTHORITY_ADMIN,OFFSHORE_SCHOOLS_ADMIN" --from-literal=DISABLE_SDC_FUNCTIONALITY=$disableSdcFunctionality --dry-run -o yaml | oc apply -f -
+oc create -n $PEN_NAMESPACE-$envValue configmap $APP_NAME-backend-config-map --from-literal=WEB_SOCKET_URL="$WEB_SOCKET_URL" --from-literal=BANNER_COLOR="$BANNER_COLOR" --from-literal=BANNER_ENVIRONMENT="$BANNER_ENVIRONMENT" --from-literal=TZ=$TZVALUE --from-literal=UI_PRIVATE_KEY="$UI_PRIVATE_KEY_VAL" --from-literal=SITEMINDER_LOGOUT_ENDPOINT="$siteMinderLogoutUrl" --from-literal=UI_PUBLIC_KEY="$UI_PUBLIC_KEY_VAL" --from-literal=ID=$APP_NAME-soam --from-literal=SECRET=$studentAdminClientSecret --from-literal=SERVER_FRONTEND=https://$SERVER_FRONTEND --from-literal=ISSUER=STUDENT_ADMIN_APPLICATION --from-literal=SOAM_PUBLIC_KEY="$formattedPublicKey" --from-literal=PEN_REQUEST_EMAIL_API_URL="http://student-profile-email-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/gmp" --from-literal=PEN_REQUEST_API_URL="http://pen-request-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/pen-request" --from-literal=DISCOVERY=https://$SOAM_KC/auth/realms/$SOAM_KC_REALM_ID/.well-known/openid-configuration --from-literal=KC_DOMAIN=https://$SOAM_KC/auth/realms/$SOAM_KC_REALM_ID --from-literal=PEN_DEMOGRAPHICS_URL="http://pen-demographics-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080" --from-literal=DIGITAL_ID_URL="http://digitalid-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/digital-id" --from-literal=STUDENT_API_URL="http://student-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/student" --from-literal=LOG_LEVEL=info --from-literal=IDIR_IDP_HINT=keycloak_bcdevexchange_idir --from-literal=REDIS_HOST=redis --from-literal=REDIS_PORT=6379 --from-literal=STUDENT_PROFILE_API_URL="http://student-profile-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/student-profile" --from-literal=SCHOOL_API_URL="http://school-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1" --from-literal=STUDENT_PROFILE_EMAIL_API_URL="http://student-profile-email-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/ump" --from-literal=PROFILE_REQUEST_SAGA_API_URL="http://student-profile-saga-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/student-profile-saga" --from-literal=NATS_URL="$NATS_URL" --from-literal=NATS_CLUSTER="$NATS_CLUSTER" --from-literal=UMP_ROLES="STUDENT_PROFILE_ADMIN,STUDENT_PROFILE_READ_ONLY" --from-literal=GMP_ROLES="STUDENT_ADMIN,STUDENT_ADMIN_READ_ONLY" --from-literal=STUDENT_SEARCH_ADMIN="STUDENT_SEARCH_ADMIN" --from-literal=STUDENT_SEARCH_ROLES="STUDENT_SEARCH_ADMIN,STUDENT_SEARCH_READ_ONLY" --from-literal=STUDENT_ADMIN_ADMINISTRATOR="STUDENT_ADMIN_ADMINISTRATOR" --from-literal=UMP_ROLE_ADMIN="STUDENT_PROFILE_ADMIN" --from-literal=GMP_ROLE_ADMIN="STUDENT_ADMIN" --from-literal=PEN_REQUEST_BATCH_ADMIN="PEN_REQUEST_BATCH_ADMIN" --from-literal=EDX_ADMIN="EDX_ADMIN" --from-literal=PEN_REQUEST_BATCH_API_URL="http://pen-reg-batch-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1" --from-literal=PEN_MATCH_API_URL="http://pen-match-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/pen-match" --from-literal=SESSION_MAX_AGE=$sessionMaxAge --from-literal=TOKEN_EXPIRES_IN=$tokenExpiresIn --from-literal=SCHEDULER_CRON_STALE_SAGA_RECORD_REDIS="0/30 * * * * *" --from-literal=MIN_TIME_BEFORE_SAGA_IS_STALE_IN_SECONDS=10 --from-literal=PEN_SERVICES_API_URL="http://pen-services-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/pen-services" --from-literal=PEN_TRAX_API_URL="http://pen-trax-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1" --from-literal=SLD_API_URL="http://sld-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1" --from-literal=QUEUE_GROUP_NAME="student-admin-node-queue-group" --from-literal=STAN_ENABLED="true" --from-literal=NODE_ENV="openshift" --from-literal=SCHEDULER_CRON_DOC_TYPE_MIGRATION="$SCHEDULER_CRON_DOC_TYPE_MIGRATION" --from-literal=ENABLE_PRR_STUDENT_DEMOGRAPHICS="$ENABLE_PRR_STUDENT_DEMOGRAPHICS" --from-literal=NOMINAL_ROLL="NOMINAL_ROLL_EDIT" --from-literal=MACRO_API_URL="http://macro-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/macro" --from-literal=NOMINAL_ROLL_API_URL="http://pen-nominal-roll-api-main.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/nominal-roll" --from-literal=STUDENT_ANALYTICS_STUDENT_PROFILE="STUDENT_ANALYTICS_STUDENT_PROFILE" --from-literal=STUDENT_ANALYTICS_BATCH="STUDENT_ANALYTICS_BATCH" --from-literal=NOMINAL_ROLL_ROLES="NOMINAL_ROLL,NOMINAL_ROLL_EDIT" --from-literal=EDX_API_URL="http://edx-api-master.$EDX_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/edx" --from-literal=SDC_API_URL="http://student-data-collection-api-master.$EDX_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/student-data-collection" --from-literal=INSTITUTE_API_URL="http://institute-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/institute" --from-literal=EDX_PEN_TEAM_ROLES="PEN_TEAM_ROLE" --from-literal=INSTITUTE_ROLES="INDEPENDENT_SCHOOLS_ADMIN,INDEPENDENT_AUTHORITY_ADMIN,OFFSHORE_SCHOOLS_ADMIN" --from-literal=DISABLE_SDC_FUNCTIONALITY=$disableSdcFunctionality --dry-run -o yaml | oc apply -f -
echo
echo Setting environment variables for $APP_NAME-backend-$SOAM_KC_REALM_ID application
oc -n $PEN_NAMESPACE-$envValue set env --from=configmap/$APP_NAME-backend-config-map dc/$APP_NAME-backend-$SOAM_KC_REALM_ID
From c8a777cf65923e49013ca56133491b9035bfde02 Mon Sep 17 00:00:00 2001
From: SodhiA1 <38086281+SodhiA1@users.noreply.github.com>
Date: Thu, 2 Nov 2023 11:44:37 -0700
Subject: [PATCH 5/5] Update sdc.js
---
backend/src/routes/sdc.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backend/src/routes/sdc.js b/backend/src/routes/sdc.js
index 0542b7ed9..0cf53ea22 100644
--- a/backend/src/routes/sdc.js
+++ b/backend/src/routes/sdc.js
@@ -16,7 +16,7 @@ router.delete('/funding-groups/:schoolID/funding/:schoolFundingGroupID', passpor
router.put('/funding-groups/:schoolID/funding/:schoolFundingGroupID', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, updateFundingDataForSchool);
router.get('/funding-groups/snapshot/:schoolID/:collectionID', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, getSnapshotFundingDataForSchool);
-router.get('/funding-groups', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, getCachedSDCData(constants.CACHE_KEYS.SDC_FUNDING_GROUPS, 'sdc:fundingGroupsURL'));
+router.get('/funding-groups', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.VIEW_SCHOOL_PERMISSION), extendSession, getCachedSDCData(constants.CACHE_KEYS.SDC_FUNDING_GROUPS, 'sdc:fundingGroupsURL'));
router.get('/sdcSchoolCollection/:schoolID', passport.authenticate('jwt', {session: false}, undefined), utils.checkUserHasPermission(PERMISSION.EDIT_SCHOOL_PERMISSION), extendSession, getAllCollectionsForSchool);
module.exports = router;