diff --git a/.travis.yml b/.travis.yml
index b4d533f4a5..6899dfd5cc 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -34,6 +34,7 @@ jobs:
- time npm run test_services
- time CYPRESS_baseUrl=http://localhost:1337/staging/ npm run cypress:record
- docker ps -a
+ - if [[ $(docker ps --all | grep -Eo '(Exited|Restarting) \([0-9]+\)' | grep -Eo '[0-9]+' | awk '{ sum += $1 } END { print sum }') != '0' ]]; then echo 'Some process had nonzero exit code'; exit 1; fi
deploy: # deploy is always skipped for PR
provider: script
skip_cleanup: true
@@ -54,10 +55,11 @@ jobs:
- time npm run test_services
- time CYPRESS_baseUrl=http://localhost:1337/ npm run cypress:record
- docker ps -a
+ - if [[ $(docker ps --all | grep -Eo '(Exited|Restarting) \([0-9]+\)' | grep -Eo '[0-9]+' | awk '{ sum += $1 } END { print sum }') != '0' ]]; then echo 'Some process had nonzero exit code'; exit 1; fi
deploy: # deploy is always skipped for PR
provider: script
skip_cleanup: true
- script: "docker-compose -f docker-compose.lateste2e.production.yml push && curl -X POST -H 'Content-type: application/json' --data \"{\\\"text\\\":\\\"${TRAVIS_TAG} release waiting for manual deployment!\\\"}\" ${SLACKBOT_URL}"
+ script: "docker-compose -f docker-compose.lateste2e.production.yml push && curl -X POST -H 'Content-type: application/json' --data \"{\\\"text\\\":\\\"${TRAVIS_TAG} release started auto deployment!\\\"}\" ${SLACKBOT_URL}"
on:
tags: true
diff --git a/cypress/integration/Users.js b/cypress/integration/Users.js
new file mode 100644
index 0000000000..15e8d45e99
--- /dev/null
+++ b/cypress/integration/Users.js
@@ -0,0 +1,39 @@
+
+describe('Users tests', () => {
+ beforeEach(() => {
+ cy.server({
+ onAnyRequest: function (route, proxy) {
+ if (Cypress.config().baseUrl.includes("http://localhost:1337/")) {
+ proxy.xhr.setRequestHeader('uid', 'admink')
+ proxy.xhr.setRequestHeader('shib-session-id', 'mock-shibboleth')
+ proxy.xhr.setRequestHeader('hygroupcn', 'grp-oodikone-users')
+ proxy.xhr.setRequestHeader('edupersonaffiliation', 'asdasd')
+ }
+ }
+ })
+ console.log(Cypress.config().baseUrl)
+ cy.visit(Cypress.config().baseUrl)
+ cy.reload()
+ cy.contains("Users").click()
+ cy.contains("Enable or disable access to Oodikone")
+ })
+
+ it("Admin mocking normal user shows only the mocked user's programmes", () => {
+ cy.contains("mocking").should('not.exist')
+ cy.contains("tr", "Normaalikäyttäjä").within(($row) => {
+ cy.contains('button', 'Edit').click()
+ })
+ cy.contains("Access rights").siblings().within(($row) => {
+ cy.get("div[role='listitem']").should('have.length', 1).contains("Tietojenkäsittelytieteen kandiohjelma")
+ })
+
+ cy.get('i.spy').click()
+ cy.contains("mocking as normk")
+ cy.contains("Study programme").click().siblings().contains("Search by class").click()
+ cy.contains("label", "Study programme")
+ cy.contains("label", "Study programme").siblings().within(($row) => {
+ cy.get("div[role='option']").should('have.length', 1).contains("Tietojenkäsittelytieteen kandiohjelma")
+ })
+ })
+
+})
diff --git a/package.json b/package.json
index 0ac6ceecb9..9d6a044dff 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,7 @@
"scripts": {
"cypress:open": "CYPRESS_baseUrl=http://localhost:8081 cypress open",
"cypress:run": "CYPRESS_baseUrl=http://localhost:8081 cypress run --config video=false -P ./",
- "cypress:record": "cypress run --config videoUploadOnPasses=false -P ./",
+ "cypress:record": "cypress run --config videoUploadOnPasses=false --record -P ./",
"concurrently": "concurrently",
"test": "./run_all_tests.sh",
"test_services": "./run_service_tests.sh"
diff --git a/scripts.sh b/scripts.sh
index a781775ce0..77fbe13c06 100644
--- a/scripts.sh
+++ b/scripts.sh
@@ -57,7 +57,7 @@ get_anon_oodikone() {
}
unpack_oodikone_server_backup() {
- bunzip2 -d -v ./$BACKUP_DIR/*.bz2
+ bunzip2 --force --decompress --verbose ./$BACKUP_DIR/*.bz2
}
restore_psql_from_backup () {
diff --git a/services/backend/oodikone2-backend/src/routes.js b/services/backend/oodikone2-backend/src/routes.js
index f3294bdf0e..6f416c840a 100644
--- a/services/backend/oodikone2-backend/src/routes.js
+++ b/services/backend/oodikone2-backend/src/routes.js
@@ -4,6 +4,7 @@ const courses = require('./routes/courses')
const students = require('./routes/students')
const population = require('./routes/population')
const login = require('./routes/login')
+const superlogin = require('./routes/superlogin')
const language = require('./routes/language')
const users = require('./routes/users')
const elementdetails = require('./routes/elementdetails')
@@ -25,6 +26,7 @@ module.exports = (app, url) => {
app.use(url, login)
app.use(url, ping)
app.use(auth.checkAuth, auth.checkRequiredGroup, auth.checkUserBlacklisting, accessLogger)
+ app.use(`${url}/superlogin`, auth.roles(['admin']), superlogin)
app.use(url, elementdetails)
app.use(url, courses)
app.use(url, students)
diff --git a/services/backend/oodikone2-backend/src/routes/elementdetails.js b/services/backend/oodikone2-backend/src/routes/elementdetails.js
index b4545ac281..3bc2c75a7b 100644
--- a/services/backend/oodikone2-backend/src/routes/elementdetails.js
+++ b/services/backend/oodikone2-backend/src/routes/elementdetails.js
@@ -21,7 +21,7 @@ router.get('/v2/studyprogrammes/:id/mandatory_courses', async (req, res) => {
const codes = await MandatoryCourses.byStudyprogramme(req.params.id)
res.json(codes)
} else {
- res.status(422)
+ res.status(422).end()
}
})
@@ -30,7 +30,7 @@ router.get('/v2/studyprogrammes/ping', async (req, res) => {
const result = await ping()
res.json(result)
} catch (e) {
- res.status(500)
+ res.status(500).end()
}
})
@@ -54,7 +54,7 @@ router.get('/v2/studyprogrammes/:id/productivity', async (req, res) => {
}
return res.json(data)
} else {
- res.status(422)
+ res.status(422).end()
}
})
@@ -118,7 +118,7 @@ router.get('/v2/studyprogrammes/:id/throughput', async (req, res) => {
}
return res.json({ ...data, thesis: await thesisPromise })
} else {
- res.status(422)
+ res.status(422).end()
}
})
@@ -162,7 +162,7 @@ router.get('/v2/studyprogrammes/:id/thesis', async (req, res) => {
const thesis = await findProgrammeTheses(id)
res.json(thesis)
} else {
- res.status(422)
+ res.status(422).end()
}
})
@@ -173,7 +173,7 @@ router.post('/v2/studyprogrammes/:id/thesis', async (req, res) => {
const thesis = await createThesisCourse(id, course, thesisType)
res.status(201).json(thesis)
} else {
- res.status(422)
+ res.status(422).end()
}
})
@@ -183,8 +183,8 @@ router.delete('/v2/studyprogrammes/:id/thesis/:course', async (req, res) => {
const deleted = await deleteThesisCourse(id, course)
res.status(204).json(deleted)
} else {
- res.status(422)
+ res.status(422).end()
}
})
-module.exports = router
\ No newline at end of file
+module.exports = router
diff --git a/services/backend/oodikone2-backend/src/routes/login.js b/services/backend/oodikone2-backend/src/routes/login.js
index 3f03d8f30b..faf1464d39 100644
--- a/services/backend/oodikone2-backend/src/routes/login.js
+++ b/services/backend/oodikone2-backend/src/routes/login.js
@@ -27,7 +27,7 @@ router.post('/login', async (req, res) => {
const mail = req.headers.mail || ''
const hyGroups = parseHyGroups(req.headers['hygroupcn'])
const affiliations = parseHyGroups(req.headers['edupersonaffiliation'])
-
+
console.log(uid, 'trying to login, referring to userservice.')
let { token, isNew } = await userService.login(uid, full_name, hyGroups, affiliations, mail)
isNew && sendEmail(uid)
@@ -44,26 +44,6 @@ router.post('/login', async (req, res) => {
}
})
-router.post('/superlogin/:uid', async (req, res) => {
- try {
- const asUser = req.params.uid
- const uid = req.headers['uid']
- if (req.headers['shib-session-id'] && uid) {
- console.log('super')
- const token = await userService.superlogin(uid, asUser)
- res.status(200).json({ token })
- } else {
- res.status(401).json({
- message: `Not enough headers login, uid:
- ${req.headers.uid} session-id ${req.headers['shib-session-id']}`
- }).end()
- }
- } catch (err) {
- console.log(err)
- res.status(401).json({ message: 'problem with login', err })
- }
-})
-
router.delete('/logout', async (req, res) => {
try {
const logoutUrl = req.headers.shib_logout_url
diff --git a/services/backend/oodikone2-backend/src/routes/population.js b/services/backend/oodikone2-backend/src/routes/population.js
index 9a6d6ac4c3..0364145e5d 100644
--- a/services/backend/oodikone2-backend/src/routes/population.js
+++ b/services/backend/oodikone2-backend/src/routes/population.js
@@ -62,7 +62,7 @@ router.get('/v3/populationstatistics', async (req, res) => {
if (result.error) {
console.log(result.error)
- res.status(400)
+ res.status(400).end()
return
}
diff --git a/services/backend/oodikone2-backend/src/routes/superlogin.js b/services/backend/oodikone2-backend/src/routes/superlogin.js
new file mode 100644
index 0000000000..574a314cc2
--- /dev/null
+++ b/services/backend/oodikone2-backend/src/routes/superlogin.js
@@ -0,0 +1,24 @@
+const router = require('express').Router()
+const userService = require('../services/userService')
+
+router.post('/:uid', async (req, res) => {
+ try {
+ const asUser = req.params.uid
+ const uid = req.decodedToken.mockedBy == null ? req.headers['uid'] : req.decodedToken.mockedBy
+ if (req.headers['shib-session-id'] && uid) {
+ console.log('super')
+ const token = await userService.superlogin(uid, asUser)
+ res.status(200).json({ token })
+ } else {
+ res.status(401).json({
+ message: `Not enough headers login, uid:
+ ${req.headers.uid} session-id ${req.headers['shib-session-id']}`
+ }).end()
+ }
+ } catch (err) {
+ console.log(err.message)
+ res.status(401).json({ message: 'problem with login', err: err.message })
+ }
+})
+
+module.exports = router
diff --git a/services/oodikone2-frontend/src/apiConnection/index.js b/services/oodikone2-frontend/src/apiConnection/index.js
index ac8ee96dc2..74a8d4a6a8 100644
--- a/services/oodikone2-frontend/src/apiConnection/index.js
+++ b/services/oodikone2-frontend/src/apiConnection/index.js
@@ -72,19 +72,6 @@ export const login = async () => {
return response.data.token
}
-export const superLogin = async (uid) => {
- let options = null
- if (isDevEnv) {
- options = devOptions
- }
- if (isTestEnv) {
- options = testOptions
- }
- const response = await getAxios().post(`/superlogin/${uid}`, null, options)
- console.log(`Setting new token ${response.data.token}`)
- await setToken(response.data.token)
-}
-
export const returnToSelf = async () => {
const token = await login()
await setToken(token)
@@ -115,6 +102,12 @@ export const callApi = async (url, method = 'get', data, params, timeout = 0) =>
}
}
+export const superLogin = async (uid) => {
+ const response = await callApi(`/superlogin/${uid}`, 'post')
+ console.log(`Setting new token ${response.data.token}`)
+ await setToken(response.data.token)
+}
+
export const callController = (route, prefix, data, method = 'get', query, params) => {
const requestSettings = {
route,
diff --git a/services/oodikone2-frontend/src/components/EnableUsers/index.jsx b/services/oodikone2-frontend/src/components/EnableUsers/index.jsx
index c60f610f03..f0b0c76ba9 100644
--- a/services/oodikone2-frontend/src/components/EnableUsers/index.jsx
+++ b/services/oodikone2-frontend/src/components/EnableUsers/index.jsx
@@ -158,11 +158,8 @@ class EnableUsers extends Component {
title: '',
getRowVal: user => (
-
),
diff --git a/services/oodikone2-frontend/src/components/UserPage/index.jsx b/services/oodikone2-frontend/src/components/UserPage/index.jsx
index 8aa8b061a5..c294515663 100644
--- a/services/oodikone2-frontend/src/components/UserPage/index.jsx
+++ b/services/oodikone2-frontend/src/components/UserPage/index.jsx
@@ -153,7 +153,7 @@ class UserPage extends Component {
{ this.props.isAdmin && user.is_enabled && (
}
+ trigger={ this.showAs(user.username)} />}
/>
)}
{user.full_name}
diff --git a/services/oodikone2-frontend/src/redux/students.js b/services/oodikone2-frontend/src/redux/students.js
index edb0180e4f..68f86b2269 100644
--- a/services/oodikone2-frontend/src/redux/students.js
+++ b/services/oodikone2-frontend/src/redux/students.js
@@ -3,7 +3,7 @@ import { callController } from '../apiConnection'
export const findStudents = (searchStr) => {
const route = `/students/?searchTerm=${searchStr}`
const prefix = 'FIND_STUDENTS_'
- return callController(route, prefix)
+ return callController(route, prefix, undefined, undefined, searchStr)
}
export const getStudent = (studentNumber) => {
@@ -31,6 +31,7 @@ const reducer = (state = { data: [] }, action) => {
return {
pending: true,
selected: state.selected,
+ lastSearch: action.requestSettings.query,
data: state.data
}
case 'FIND_STUDENTS_FAILURE':
@@ -45,7 +46,9 @@ const reducer = (state = { data: [] }, action) => {
pending: false,
error: false,
selected: state.selected,
- data: [...state.data.filter(student => student.fetched), ...action.response]
+ data: state.lastSearch === action.query ?
+ [...state.data.filter(student => student.fetched), ...action.response] :
+ state.data
}
case 'GET_STUDENT_SUCCESS':
return {
diff --git a/services/oodikone2-usageservice/src/middlewares/secret.js b/services/oodikone2-usageservice/src/middlewares/secret.js
index 9d49d71a7c..760ea6446a 100644
--- a/services/oodikone2-usageservice/src/middlewares/secret.js
+++ b/services/oodikone2-usageservice/src/middlewares/secret.js
@@ -1,5 +1,5 @@
const { SECRET } = require('../conf-usageservice')
-const checkSecret = (req, res, next) => req.headers.secret == SECRET ? next() : res.status(403)
+const checkSecret = (req, res, next) => req.headers.secret == SECRET ? next() : res.status(403).end()
module.exports = checkSecret
diff --git a/services/oodikone2-userservice/index.js b/services/oodikone2-userservice/index.js
index 7ae2c2319a..437aea3943 100644
--- a/services/oodikone2-userservice/index.js
+++ b/services/oodikone2-userservice/index.js
@@ -84,7 +84,7 @@ app.post('/superlogin', async (req, res) => {
if (token) {
res.status(200).json(token)
}
- res.status(400)
+ res.status(400).end()
})
app.put('/user/:uid', async (req, res) => {
@@ -138,7 +138,7 @@ app.get('/access_groups', async (req, res) => {
const groups = await AccessGroup.findAll()
res.status(200).json(groups)
} catch (e) {
- res.status(400)
+ res.status(400).end()
}
})
diff --git a/services/oodikone2-userservice/src/middlewares/secret.js b/services/oodikone2-userservice/src/middlewares/secret.js
index 799528ab51..6c6a9bf8f8 100644
--- a/services/oodikone2-userservice/src/middlewares/secret.js
+++ b/services/oodikone2-userservice/src/middlewares/secret.js
@@ -1,5 +1,5 @@
-const checkSecret = (req, res, next) => req.headers.secret == process.env.SECRET ? next() : res.status(403)
+const checkSecret = (req, res, next) => req.headers.secret == process.env.SECRET ? next() : res.status(403).end()
-module.exports =
+module.exports =
checkSecret
diff --git a/services/oodikone2-userservice/src/services/users.js b/services/oodikone2-userservice/src/services/users.js
index 0423e0849f..97484a06f7 100644
--- a/services/oodikone2-userservice/src/services/users.js
+++ b/services/oodikone2-userservice/src/services/users.js
@@ -108,7 +108,7 @@ const login = async (uid, full_name, hyGroups, affiliations, mail) => {
}
const superlogin = async (uid, asUser) => {
const user = await byUsername(uid)
- if (user.accessgroup.map(r => r.group_code).includes('admin')) {
+ if (user && user.accessgroup.map(r => r.group_code).includes('admin')) {
const token = await generateToken(asUser, uid)
return token
}