Skip to content

Commit 544b415

Browse files
committed
Acually täsä the iam rights logic
1 parent 664864e commit 544b415

File tree

2 files changed

+471
-0
lines changed

2 files changed

+471
-0
lines changed

src/auth/IAMRights.ts

Lines changed: 335 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,335 @@
1+
import {
2+
isSuperAdminIam,
3+
isAdminIam,
4+
isOpenUniIam,
5+
isHyOneIam,
6+
isJoryIam,
7+
isKosuIam,
8+
isUniversityWideIam,
9+
isDoctoralIam,
10+
iamToOrganisationCode,
11+
isEmployeeIam,
12+
iamToDoctoralSchool,
13+
kosuIamToFaculties,
14+
opetusVaradekaani,
15+
isStudyLeaderGroup,
16+
isKatselmusViewer,
17+
dekaaniIamToFaculty
18+
} from './IAMConfig'
19+
import { FACULTIES } from '../organisation/faculties'
20+
import { mapToDegreeCode } from './common'
21+
import { OrganisationAccess } from '../types'
22+
import { Programme } from '../organisation/types'
23+
24+
type AccessSpecialGroupFunction = (hyGroups: string[]) => { access?: { [programmeCode: string]: OrganisationAccess }, specialGroup?: { [key: string]: boolean } }
25+
26+
/**
27+
* Return given access to all programmes where predicate is true
28+
* (all if no predicate defined)
29+
*/
30+
const getAllProgrammeAccess = (accessLevel: OrganisationAccess, where?: (program: Programme) => boolean): { [key: string]: OrganisationAccess } => {
31+
const access = {}
32+
FACULTIES.forEach((faculty) => {
33+
faculty.programmes.forEach((program) => {
34+
if (where?.(program) === false) return
35+
access[program.key] = { ...accessLevel }
36+
})
37+
})
38+
return access
39+
}
40+
41+
/**
42+
* Grant super-admin rights if the user has correct iams (eg. grp-toska)
43+
*/
44+
const getSuperAdmin: AccessSpecialGroupFunction = (hyGroups) => {
45+
const isToska = hyGroups.some(isSuperAdminIam)
46+
if (isToska) {
47+
return { specialGroup: { superAdmin: true } }
48+
}
49+
return {}
50+
}
51+
52+
/**
53+
* NOT USED
54+
* Grant admin rights if the user has correct iams (eg. grp-ospa)
55+
* @returns admin special group
56+
*/
57+
const getAdmin: AccessSpecialGroupFunction = (hyGroups) => {
58+
const isOspa = hyGroups.some(isAdminIam)
59+
if (isOspa) {
60+
return { specialGroup: { admin: true } }
61+
}
62+
return {}
63+
}
64+
65+
/**
66+
* Needed for Oodikone
67+
* Grant open uni rights if the user has correct iams (eg. hy-ypa-opa-dojo)
68+
* @returns openUni special group
69+
*/
70+
const getOpenUni: AccessSpecialGroupFunction = (hyGroups) => {
71+
const isOpenUni = hyGroups.some(isOpenUniIam)
72+
if (isOpenUni) {
73+
return { specialGroup: { openUni: true } }
74+
}
75+
return {}
76+
}
77+
78+
/**
79+
* Needed for Oodikone
80+
* Grant teachers rights if the user has correct iams (eg. hy-one)
81+
* @returns hyOne special group
82+
*/
83+
const getHyOne: AccessSpecialGroupFunction = (hyGroups) => {
84+
const isHyIam = hyGroups.some(isHyOneIam)
85+
if (isHyIam) {
86+
return { specialGroup: { hyOne: true } }
87+
}
88+
return {}
89+
}
90+
91+
/**
92+
* Needed for Oodikone
93+
* Grant jory special group if the user has jory iams (eg. hy-ttdk-tuk-jory)
94+
* @returns jory special group
95+
*/
96+
const getJory: AccessSpecialGroupFunction = (hyGroups) => {
97+
const isJory = hyGroups.some(isJoryIam)
98+
if (isJory) {
99+
return { specialGroup: { jory: true } }
100+
}
101+
return {}
102+
}
103+
104+
/**
105+
* Needed for Oodikone
106+
* Grant kosu special group if the user has kosu iams (eg. hy-ypa-opa-kosu-kumpula)
107+
* @returns kosu special group
108+
*/
109+
const getKosu: AccessSpecialGroupFunction = (hyGroups) => {
110+
const isKosu = hyGroups.some(isKosuIam)
111+
if (isKosu) {
112+
return { specialGroup: { kosu: true } }
113+
}
114+
return {}
115+
}
116+
117+
/**
118+
* Needed for Oodikone
119+
* Grant katselmusViewer special group, which means that the user can see oodikone's
120+
* evaluationoverview which is linked in tilannekuvalomake
121+
* @returns katselmusViewer special group
122+
*/
123+
const getKatselmusViewer: AccessSpecialGroupFunction = (hyGroups) => {
124+
const katselmusViewer = hyGroups.some(isKatselmusViewer)
125+
126+
if (katselmusViewer) {
127+
return { specialGroup: { katselmusViewer: true } }
128+
}
129+
return {}
130+
}
131+
132+
/**
133+
* Get special groups based on IAM-groups
134+
*/
135+
const getSpecialGroups: AccessSpecialGroupFunction = (hyGroups) => {
136+
let specialGroup = {}
137+
138+
;[
139+
getAdmin,
140+
getSuperAdmin,
141+
getOpenUni,
142+
getHyOne,
143+
getJory,
144+
getKosu,
145+
getKatselmusViewer,
146+
]
147+
.map((f) => f(hyGroups))
148+
.forEach(({ specialGroup: newSpecialGroup }) => {
149+
specialGroup = { ...specialGroup, ...newSpecialGroup }
150+
})
151+
152+
return { specialGroup }
153+
}
154+
155+
/**
156+
* Grant reading rights to all programmes if user has uni wide IAM (eg. hy-rehtoraatti)
157+
* @returns read access to ALL programmes
158+
*/
159+
const getUniversityReadingRights: AccessSpecialGroupFunction = (hyGroups) => {
160+
const hasUniversityReadingRights = hyGroups.some(isUniversityWideIam)
161+
if (!hasUniversityReadingRights) {
162+
return {}
163+
}
164+
165+
const access = getAllProgrammeAccess({
166+
read: true,
167+
write: false,
168+
admin: false,
169+
})
170+
const specialGroup = { allProgrammes: true }
171+
172+
return { access, specialGroup }
173+
}
174+
175+
/**
176+
* Grant reading rights to programmes of faculties if user is kosu or dekaanaatti of some faculties
177+
*/
178+
const getFacultyReadingRights: AccessSpecialGroupFunction = (hyGroups) => {
179+
// faculty codes from kosu iam
180+
const facultyCodes = hyGroups
181+
.flatMap(kosuIamToFaculties)
182+
// faculty codes from dekanaatti iam
183+
.concat(hyGroups.map(dekaaniIamToFaculty))
184+
.filter(Boolean)
185+
const access = {}
186+
facultyCodes.forEach((fc) => {
187+
const faculty = FACULTIES.find((faculty) => faculty.code === fc)
188+
const programmeCodes = faculty.programmes.map((p) => p.key)
189+
programmeCodes.forEach((code) => {
190+
access[code] = { read: true, write: false, admin: false }
191+
})
192+
})
193+
return { access, specialGroup: {} }
194+
}
195+
196+
/**
197+
* Grant admin rights to faculty programmes if user is opetusvaradekaani of that faculty
198+
*/
199+
const getFacultyAdminRights: AccessSpecialGroupFunction = (hyGroups) => {
200+
if (!hyGroups.includes(opetusVaradekaani)) return {}
201+
const facultyCodes = hyGroups.map(dekaaniIamToFaculty).filter(Boolean)
202+
203+
const access = {}
204+
facultyCodes.forEach((fc) => {
205+
const faculty = FACULTIES.find((faculty) => faculty.code === fc)
206+
const programmeCodes = faculty.programmes.map((p) => p.key)
207+
programmeCodes.forEach((code) => {
208+
access[code] = { read: true, write: true, admin: true }
209+
})
210+
})
211+
return { access, specialGroup: {} }
212+
}
213+
214+
/**
215+
* Grant reading rights to all doctoral programmes if the user belongs to doctoral IAM
216+
* @returns read access to ALL doctoral programs
217+
*/
218+
const getDoctoralAccess: AccessSpecialGroupFunction = (hyGroups) => {
219+
const hasDoctoralReadingRights = hyGroups.some(isDoctoralIam)
220+
if (!hasDoctoralReadingRights) return {}
221+
const access = getAllProgrammeAccess(
222+
{ read: true, write: false, admin: false },
223+
(program) => program.level === 'doctoral',
224+
)
225+
const specialGroup = { doctoral: true }
226+
227+
return { access, specialGroup }
228+
}
229+
230+
/**
231+
* Grants reading rights to all doctoral programmes that belong to user's
232+
* doctoral school IAMs
233+
* @returns read access to doctoral programs
234+
*/
235+
const getDoctoralSchoolAccess: AccessSpecialGroupFunction = (hyGroups) => {
236+
const doctoralProgrammeCodes = hyGroups.flatMap(iamToDoctoralSchool)
237+
const access = {}
238+
doctoralProgrammeCodes.forEach((code) => {
239+
if (!code) return
240+
access[code] = { read: true }
241+
})
242+
return { access }
243+
}
244+
245+
/**
246+
* Grant admin access if the user belongs to studyprogramme's manager group and is a study program leader
247+
*/
248+
const getProgrammeAdminAccess: AccessSpecialGroupFunction = (hyGroups) => {
249+
const orgCodes = hyGroups
250+
.filter((iam) => isStudyLeaderGroup(iam, hyGroups))
251+
.map((iam) => iamToOrganisationCode(iam))
252+
.filter(Boolean)
253+
254+
const degreeCodes = orgCodes.flatMap((codes) => codes.map(mapToDegreeCode))
255+
256+
if (!(degreeCodes?.length > 0)) {
257+
return {
258+
access: {},
259+
}
260+
}
261+
262+
const access = {}
263+
degreeCodes.forEach((code) => {
264+
access[code] = { read: true, write: true, admin: true }
265+
})
266+
return { access }
267+
}
268+
269+
/**
270+
* UPDATE: nobody gets this. Kept here for documentation and consistency with other Toska software
271+
* Grant write and read access if the user belongs to employees group and studyprogramme's manager group
272+
* @param {string[]} hyGroups
273+
*/
274+
// eslint-disable-next-line no-unused-vars
275+
const getProgrammeWriteAccess: AccessSpecialGroupFunction = (hyGroups) => {
276+
if (!hyGroups.some(isEmployeeIam)) return {}
277+
const orgCodes = hyGroups
278+
.map((iam) => iamToOrganisationCode(iam))
279+
.filter(Boolean)
280+
const degreeCodes = orgCodes.flatMap((codes) => codes.map(mapToDegreeCode))
281+
const access = {}
282+
degreeCodes.forEach((code) => {
283+
if (!code) return
284+
access[code] = { read: true, write: true, admin: false }
285+
})
286+
287+
return { access }
288+
}
289+
290+
/**
291+
* Grant read access if the user belongs to studyprogramme's manager group
292+
*/
293+
const getProgrammeReadAccess: AccessSpecialGroupFunction = (hyGroups) => {
294+
const orgCodes = hyGroups
295+
.map((iam) => iamToOrganisationCode(iam))
296+
.filter(Boolean)
297+
const degreeCodes = orgCodes.flatMap((codes) => codes.map(mapToDegreeCode))
298+
const access = {}
299+
degreeCodes.forEach((code) => {
300+
if (!code) return
301+
access[code] = { read: true, write: false, admin: false }
302+
})
303+
304+
return { access }
305+
}
306+
307+
/**
308+
* Gets access rights and special groups,
309+
* based on IAM-groups in IAM header string
310+
*/
311+
const getIAMRights: AccessSpecialGroupFunction = (hyGroups) => {
312+
let access = {}
313+
let specialGroup = {}
314+
315+
;[
316+
getUniversityReadingRights,
317+
getFacultyReadingRights,
318+
getDoctoralAccess,
319+
getDoctoralSchoolAccess,
320+
getProgrammeReadAccess,
321+
// getProgrammeWriteAccess,
322+
getProgrammeAdminAccess,
323+
getFacultyAdminRights,
324+
getSpecialGroups,
325+
]
326+
.map((f) => f(hyGroups))
327+
.forEach((accessInfo) => {
328+
access = { ...access, ...accessInfo.access }
329+
specialGroup = { ...specialGroup, ...accessInfo.specialGroup }
330+
})
331+
332+
return { access, specialGroup }
333+
}
334+
335+
export default getIAMRights

0 commit comments

Comments
 (0)