Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…ikone into trunk
  • Loading branch information
esakemp committed Jul 10, 2019
2 parents 43795aa + ba11d52 commit 11a7fbd
Show file tree
Hide file tree
Showing 12 changed files with 81 additions and 43 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"docker:logs:backend": "npm run docker -- logs -f backend",
"docker:restart": "npm run docker -- restart",
"docker:restart:backend": "npm run docker -- restart backend",
"docker:obliterate": "docker stop $(docker ps -aq) ; docker rmi -f $(docker images -a -q) ; docker system prune",
"docker:obliterate": "docker stop $(docker ps -aq) ; docker rmi -f $(docker images -a -q) ; docker system prune -a",
"start": "npm run docker:up && npm run docker:logs"
},
"husky": {
Expand Down
22 changes: 12 additions & 10 deletions services/backend/oodikone2-backend/src/middleware/auth.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const jwt = require('jsonwebtoken')
const conf = require('../conf-backend')
const blacklist = require('../services/blacklist')
const { getAccessGroupCodesFor, getCodesFromElementDetails } = require('../services/userService')
const { ACCESS_TOKEN_HEADER_KEY } = require('../conf-backend')
const { hasRequiredGroup, parseHyGroups } = require('../util/utils')

Expand All @@ -15,9 +16,11 @@ const checkAuth = async (req, res, next) => {
if (err) {
res.status(403).json(err)
} else if (decoded.version !== TOKEN_VERSION) {
res.status(401).json({ error: 'Token needs to be refreshed - invalid version', reloadPage: true })
res.status(401).json({ error: 'Token needs to be refreshed - invalid version' })
} else if (decoded.mockedBy ? isShibboUser(decoded.mockedBy, uid) : isShibboUser(decoded.userId, uid)) {
req.decodedToken = decoded
req.roles = await getAccessGroupCodesFor(decoded.userId)
req.rights = await getCodesFromElementDetails(decoded.userId)
next()
} else {
res.status(403).json({ error: 'User shibboleth id and token id did not match' })
Expand All @@ -28,17 +31,17 @@ const checkAuth = async (req, res, next) => {
}
}

const roles = requiredRoles => (req, res, next) => {
if (req.decodedToken && req.decodedToken.roles != null) {
const roles = req.decodedToken.roles.map(r => r.group_code)
console.log(`Request has roles: ${roles}`)
const roles = requiredRoles => async (req, res, next) => {
if (req.decodedToken) {
const { roles } = req
console.log(`Request has roles: ${ roles }`)
if (requiredRoles.every(r => roles.indexOf(r) >= 0) || roles.includes('admin')) {
console.log(`authorized for ${requiredRoles}`)
console.log(`Authorized for ${ requiredRoles }`)
next()
return
}
}
console.log(`missing required roles ${requiredRoles}`)
console.log(`Missing required roles ${ requiredRoles }`)
res.status(403).json({ error: 'missing required roles' })
}

Expand All @@ -48,8 +51,7 @@ const checkRequiredGroup = async (req, res, next) => {
const tokenOutdated = req.decodedToken.enabled !== enabled
if (tokenOutdated) {
res.status(401).json({
error: 'Token needs to be refreshed - enabled doesnt match hy-group requirement',
reloadPage: true
error: 'Token needs to be refreshed - enabled doesnt match hy-group requirement'
})
} else if (!enabled) {
res.status(403).json({ error: 'User is not enabled' })
Expand All @@ -62,7 +64,7 @@ const checkUserBlacklisting = async (req, res, next) => {
const { userId, createdAt } = req.decodedToken
const isBlacklisted = await blacklist.isUserBlacklisted(userId, createdAt)
if (isBlacklisted) {
res.status(401).json({ error: 'Token needs to be refreshed - blacklisted', reloadPage: true })
res.status(401).json({ error: 'Token needs to be refreshed - blacklisted' })
} else {
next()
}
Expand Down
6 changes: 3 additions & 3 deletions services/backend/oodikone2-backend/src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ module.exports = (app, url) => {
app.use(url, providers)
app.use(url, faculties)
app.use(url, semesters)
app.use(url, tags)
app.use(`${url}/teachers`, auth.roles(['teachers']), teachers)
app.use(`${url}/users`, auth.roles(['users']), users)
app.use(`${url}/feedback`, feedback)
app.use(`${url}/usage`, auth.roles(['usage']), usage)
app.use(`${url}/oodilearn`, auth.roles(['oodilearn']), oodilearn)
app.use(`${url}/course-groups`, auth.roles(['coursegroups']), courseGroups)
app.use(`${url}/mandatory_courses`, mandatoryCourses),
app.use(`${url}/mandatory-course-labels`, mandatoryCourseLabels),
app.use(`${url}/mandatory_courses`, mandatoryCourses)
app.use(`${url}/mandatory-course-labels`, mandatoryCourseLabels)
app.use(`${url}/oodi`, auth.roles(['dev']), oodi)
app.use(url, auth.roles(['dev', 'admin']), task)
app.use(url, tags)
}
5 changes: 2 additions & 3 deletions services/backend/oodikone2-backend/src/routes/courseGroups.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
const router = require('express').Router()

const CourseGroupService = require('../services/courseGroups')

router.get('/programme/:programmeId/:force?', async (req, res) => {
const { programmeId, force } = req.params
const { rights, roles } = req.decodedToken
const { rights, roles } = req
const semesterCode = req.query.semester
if (rights.includes(programmeId) || (roles && roles.map(r => r.group_code).includes('admin'))) {
if (rights.includes(programmeId) || (roles && roles.includes('admin'))) {
const courseGroups = await CourseGroupService.getCourseGroupsWithTotals(
programmeId, semesterCode, force === 'force'
)
Expand Down
10 changes: 6 additions & 4 deletions services/backend/oodikone2-backend/src/routes/courses.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ router.get('/coursedisciplines', async (req, res) => {

router.get('/v2/courseyearlystats', async (req, res) => {
let results = []
const { rights, roles } = req.decodedToken
const admin = roles.map(r => r.group_code).includes('admin')
const { rights, roles } = req
const admin = roles.includes('admin')
if (!admin) {
if (rights.length <= 0) {
return res.status(403).json({ error: 'No programmes so no access to course stats' })
Expand All @@ -57,9 +57,11 @@ router.get('/v2/courseyearlystats', async (req, res) => {

router.get('/v3/courseyearlystats', async (req, res) => {
try {
const { rights, roles } = req.decodedToken
const admin = roles.map(r => r.group_code).includes('admin')
const { rights, roles } = req
const admin = roles.includes('admin')
if (!admin) {
// If user has rights to see at least one programme, then they are allowed
// to see all of them
if (rights.length <= 0) {
return res.status(403).json({ error: 'No programmes so no access to course stats' })
}
Expand Down
20 changes: 12 additions & 8 deletions services/backend/oodikone2-backend/src/routes/population.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ router.post('/v2/populationstatistics/coursesbycoursecode', async (req, res) =>
let studentnumberlist
const studentnumbers = await Student.findByCourseAndSemesters(coursecode, yearcode)

const { roles, userId } = req.decodedToken
if (roles && roles.map(r => r.group_code).includes('admin')) {
const { decodedToken: { userId }, roles } = req

if (roles && roles.includes('admin')) {
studentnumberlist = studentnumbers
} else {
const unitsUserCanAccess = await UserService.getUnitsFromElementDetails(userId)
Expand Down Expand Up @@ -76,8 +77,9 @@ router.get('/v3/populationstatistics', async (req, res) => {
let studyRights = null
try {
studyRights = JSON.parse(studyRightsJSON)
const { roles, rights } = req.decodedToken
if (!roles || !roles.map(r => r.group_code).includes('admin')) {
const { rights, roles } = req

if (!roles || !roles.includes('admin')) {
if (!rights.includes(studyRights.programme)) {
res.status(403).json([])
return
Expand Down Expand Up @@ -115,8 +117,10 @@ router.get('/v3/populationstatisticsbycourse', async (req, res) => {
console.log(coursecode, yearcode)
const studentnumbers = await Student.findByCourseAndSemesters(coursecode, yearcode)
console.log(studentnumbers)
const { roles, userId } = req.decodedToken
if (roles && roles.map(r => r.group_code).includes('admin')) {

const { decodedToken: { userId }, roles } = req

if (roles && roles.includes('admin')) {
studentnumberlist = studentnumbers
} else {
const unitsUserCanAccess = await UserService.getUnitsFromElementDetails(userId)
Expand Down Expand Up @@ -208,8 +212,8 @@ router.post('/updatedatabase', async (req, res) => {

router.get('/v3/populationstatistics/studyprogrammes', async (req, res) => {
try {
const { rights, roles } = req.decodedToken
if (roles && roles.map(r => r.group_code).includes('admin')) {
const { rights, roles } = req
if (roles && roles.includes('admin')) {
const studyrights = await StudyrightService.getAssociations()
res.json(studyrights)
} else {
Expand Down
13 changes: 7 additions & 6 deletions services/backend/oodikone2-backend/src/routes/students.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ const userService = require('../services/userService')
const Unit = require('../services/units')

router.get('/students', async (req, res) => {
const { roles, userId } = req.decodedToken
if (roles && roles.map(r => r.group_code).includes('admin')) {
const { roles } = req

if (roles && roles.includes('admin')) {
let results = []
if (req.query.searchTerm) {
results = await Student.bySearchTerm(req.query.searchTerm)
Expand All @@ -20,9 +21,10 @@ router.get('/students', async (req, res) => {
})

router.get('/students/:id', async (req, res) => {
const studentId = req.params.id
const { roles } = req.decodedToken
if (roles && roles.map(r => r.group_code).includes('admin')) {
const { id: studentId } = req.params
const { roles } = req

if (roles && roles.includes('admin')) {
const results = await Student.withId(studentId)
return res.json(results)
}
Expand All @@ -41,7 +43,6 @@ router.get('/students/:id', async (req, res) => {
} else {
res.json([]).end()
}

})

module.exports = router
5 changes: 3 additions & 2 deletions services/backend/oodikone2-backend/src/routes/teachers.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,15 @@ const mapToProviders = rights => rights.map((r) => {
})

router.get('/stats', async (req, res) => {
const { rights, roles } = req.decodedToken
const { rights, roles } = req

const { providers, semesterStart, semesterEnd } = req.query
if (!providers || !semesterStart) {
return res.status(422).send('Missing required query parameters.')
}
const providerRights = mapToProviders(rights)

if (!(providers.every(p => providerRights.includes(p)) || roles.map(r => r.group_code).includes('admin'))) {
if (!(providers.every(p => providerRights.includes(p)) || roles.includes('admin'))) {
return res.status(403).send('You do not have rights to see this data')
}
const result = await teachers.yearlyStatistics(providers, semesterStart, semesterEnd||semesterStart + 1)
Expand Down
12 changes: 12 additions & 0 deletions services/backend/oodikone2-backend/src/services/userService.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ const getUnitsFromElementDetails = async username => {
return elementDetails.map(element => UnitService.parseUnitFromElement(element))
}

const getCodesFromElementDetails = async uid => {
const elementDetails = await getUserElementDetails(uid)
return elementDetails.map(e => e.code)
}

const modifyAccess = async (body) => {
const response = await client.post('/modifyaccess', body)
return response.data
Expand All @@ -105,6 +110,11 @@ const getAccessGroups = async () => {
return response.data
}

const getAccessGroupCodesFor = async (user) => {
const response = await client.get(`/get_accessgroupcodes/${user}`)
return response.data
}

module.exports = {
ping,
byUsername,
Expand All @@ -120,7 +130,9 @@ module.exports = {
findAllEnabled,
modifyAccess,
getAccessGroups,
getAccessGroupCodesFor,
getUnitsFromElementDetails,
getCodesFromElementDetails,
getRolesFor,
setFaculties
}
4 changes: 0 additions & 4 deletions services/oodikone2-frontend/src/apiConnection/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,6 @@ export const handleRequest = store => next => async (action) => {
store.dispatch({ type: `${prefix}SUCCESS`, response: res.data, query })
} catch (e) {
// Something failed. Assume it's the token and try again.
if (e.response.data.reloadPage) {
setTimeout(() => { window.location.reload() }, 1000)
return
}
store.dispatch(loginAction(true, requestSettings))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ class StudentDetails extends Component {
history.push(`/coursestatistics?${searchString}`)
}

showPopulationStatistics = (studyprogramme, date) => {
const { history } = this.props
const year = moment(date).isBefore(moment(`${date.slice(0, 4)}-08-01`)) ? date.slice(0, 4) - 1 : date.slice(0, 4)
const months = Math.ceil(moment.duration(moment().diff(`${year}-08-01`)).asMonths())
history.push(`/populations?months=${months}&semesters=FALL&semesters=` +
`SPRING&studyRights=%7B"programme"%3A"${studyprogramme}"%7D&startYear=${year}&endYear=${year}`)
}

renderCreditsGraph = () => {
const { translate, student } = this.props
return (
Expand Down Expand Up @@ -106,6 +114,7 @@ class StudentDetails extends Component {
}))
const programmes = sortBy(studyright.studyrightElements, 'enddate').filter(e => e.element_detail.type === 20)
.map(programme => ({
code: programme.code,
startdate: programme.startdate,
enddate: programme.enddate,
name: getTextIn(programme.element_detail.name, language)
Expand Down Expand Up @@ -161,7 +170,9 @@ class StudentDetails extends Component {
</Table.Cell>
<Table.Cell>
{c.elements.programmes.filter(filterDuplicates).map(programme => (
<p key={programme.name}>{`${programme.name} (${reformatDate(programme.startdate, 'DD.MM.YYYY')} - ${reformatDate(programme.enddate, 'DD.MM.YYYY')})`}<br /> </p>
<p key={programme.name}>{`${programme.name} (${reformatDate(programme.startdate, 'DD.MM.YYYY')} - ${reformatDate(programme.enddate, 'DD.MM.YYYY')})`}
<Icon name="level up alternate" onClick={() => this.showPopulationStatistics(programme.code, programme.startdate)} /> <br />
</p>
))}
</Table.Cell>
<Table.Cell>
Expand Down
12 changes: 11 additions & 1 deletion services/oodikone2-userservice/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ app.get('/user/:uid', async (req, res) => {

app.get('/user/elementdetails/:username', async (req, res) => {
const username = req.params.username
const user = await byUsername(username)
const user = await User.byUsername(username)
const elementdetails = User.getUserElementDetails(user)

console.log(JSON.stringify(elementdetails))
Expand Down Expand Up @@ -156,4 +156,14 @@ app.get('/get_roles/:user', async (req, res) => {
}
})

app.get('/get_accessgroupcodes/:uid', async (req, res) => {
const { uid } = req.params
try {
const user = await User.byUsername(uid)
res.status(200).json(user.accessgroup.map(g => g.group_code))
} catch (e) {
res.status(400).json({ e })
}
})

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

0 comments on commit 11a7fbd

Please sign in to comment.