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;