Commit 8e8bc732 authored by jackie / Andrea Ida Malkah Klaura's avatar jackie / Andrea Ida Malkah Klaura
Browse files

refactor OIDC auth to auth module in store

parent 496c8906
...@@ -12,10 +12,8 @@ ...@@ -12,10 +12,8 @@
<script> <script>
import 'bootstrap/dist/css/bootstrap.css' import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css' import 'bootstrap-vue/dist/bootstrap-vue.css'
import oidc from 'oidc-client'
import header from './components/Header.vue' import header from './components/Header.vue'
import footer from './components/Footer.vue' import footer from './components/Footer.vue'
import axios from 'axios'
export default { export default {
name: 'App', name: 'App',
...@@ -45,32 +43,11 @@ export default { ...@@ -45,32 +43,11 @@ export default {
{ slug: 'credits', title: 'Credits' }, { slug: 'credits', title: 'Credits' },
{ slug: 'debug', title: 'Debug' } { slug: 'debug', title: 'Debug' }
], ],
user: {
name: '',
email: '',
access_token: '',
expires_at: 0,
logged_in: false,
steeringUser: null
},
userOIDC: null,
oidcmgr: new oidc.UserManager({
userStore: new oidc.WebStorageStateStore(),
authority: process.env.VUE_APP_API_STEERING_OIDC_URI,
// the client id has to be a string, therefore we add the + ''
client_id: process.env.VUE_APP_OIDC_CLIENT_ID,
redirect_uri: process.env.VUE_APP_API_STEERING_OIDC_REDIRECT_URI,
silent_redirect_uri: 'http://localhost:8080/oidc_callback_silentRenew.html',
popup_redirect_uri: 'http://localhost:8080/oidc_callback_popupRenew.html',
accessTokenExpiringNotificationTime: process.env.VUE_APP_API_STEERING_OIDC_EXPIRE_NOTIFICATION,
response_type: 'id_token token',
scope: 'openid profile email',
post_logout_redirect_uri: process.env.VUE_APP_API_STEERING_OIDC_REDIRECT_URI_POSTLOGOUT,
loadUserInfo: true
})
} }
}, },
computed: { computed: {
userOIDC () { return this.$store.state.auth.userOIDC },
user () { return this.$store.state.auth.user },
modules: function () { modules: function () {
if (this.user.logged_in === true) { if (this.user.logged_in === true) {
if (this.user.steeringUser && this.user.steeringUser.is_superuser) { if (this.user.steeringUser && this.user.steeringUser.is_superuser) {
...@@ -84,103 +61,15 @@ export default { ...@@ -84,103 +61,15 @@ export default {
} }
}, },
mounted () { mounted () {
// TODO: remove oidc logging after thorough testing this.$store.dispatch('auth/oidcInit')
oidc.Log.logger = console
let self = this
this.oidcmgr.events.addAccessTokenExpiring(function () {
console.log('Debug info: starting silent access_token renewal')
self.oidcmgr.signinSilent().then(function (user) {
self.user.access_token = user.access_token
console.log(self.user.access_token)
}).catch(function (err) {
console.log(err)
alert('Your OpenID access token could not be renewed automatically.\n' +
'You will be logged out in ' + process.env.VUE_APP_API_STEERING_OIDC_EXPIRE_NOTIFICATION + ' seconds.')
})
})
this.oidcmgr.events.addAccessTokenExpired(function () {
// at this point where the app is just mounted, we cannot use the
// vue logger, because this.$log does not yet exist. therefore we log
// to the console, but only if the environment is set tu debug log level
if (process.env.VUE_APP_LOGLEVEL === 'debug') {
console.log("Debug info: OIDC token has expired. Logging out.")
}
self.signOut()
})
this.getOIDCUser()
}, },
methods: { methods: {
signIn () { signIn () {
this.oidcmgr.signinRedirect().catch(err => { this.$store.dispatch('auth/signinRedirect')
alert('Error: something went wrong when signing in. See console for details.')
this.$log.error(err)
})
}, },
signOut () { signOut () {
this.oidcmgr.signoutRedirect().then(resp => { this.$store.dispatch('auth/signoutRedirect')
this.user.logged_in = false
this.$log.debug('signed out', resp)
}).catch(err => {
this.$log.error(err)
alert('Error: something went wrong when logging out. See console for details.')
})
console.log('3')
}, },
getSteeringUser () {
axios.get(process.env.VUE_APP_API_STEERING + 'users/', {
withCredentials: true,
headers: { 'Authorization': 'Bearer ' + this.user.access_token }
}).then(response => {
if (response.data.length === 0) {
alert('No user profile data provided by steering backend!')
} else if (response.data.length === 1) {
this.user.steeringUser = response.data[0]
} else {
// in case we are a superuser, we get all users returned
// so we have to iterate through the user list to find out own profile
for (var u in response.data) {
if (response.data[u].username === this.user.name) {
this.user.steeringUser = response.data[u]
break
}
}
}
}).catch(error => {
this.$log.error(error.response.status + ' ' + error.response.statusText)
this.$log.error(error.response)
alert('Error: could not fetch user object from the steering backend. See console for details.')
})
},
getOIDCUser () {
let self = this
this.oidcmgr.getUser().then(function (user) {
if (user == null) {
self.user.logged_in = false
self.user.name = ''
self.user.email = ''
self.user.access_token = ''
} else {
// TODO: check user.expires_at
// if token already expired try to get a new one or mark the user as logged out
self.setUserProperties(user)
self.getSteeringUser()
}
}).catch(function (err) {
this.$log.error(err)
alert('Error: could not fetch OIDC user object. See console for details.')
})
},
setUserProperties (user) {
this.userOIDC = user
this.user.logged_in = true
this.user.name = user.profile.nickname
this.user.email = user.profile.email
this.user.access_token = user.access_token
// TODO: remove debug info after thorough testing
this.$log.debug(new Date(user.expires_at * 1000).toString())
this.$log.debug(new Date(user.expires_at * 1000).toUTCString())
this.$log.debug(user.access_token)
}
} }
} }
</script> </script>
......
...@@ -23,8 +23,11 @@ Vue.use(BootstrapVue) ...@@ -23,8 +23,11 @@ Vue.use(BootstrapVue)
Vue.config.productionTip = false Vue.config.productionTip = false
new Vue({ const app = new Vue({
router, router,
store, store,
render: h => h(App) render: h => h(App)
}).$mount('#app') })
store.$log = app.$log
app.$mount('#app')
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
import auth from './modules/auth'
import shows from './modules/shows' import shows from './modules/shows'
import files from './modules/files' import files from './modules/files'
import playlists from './modules/playlists' import playlists from './modules/playlists'
...@@ -32,6 +33,7 @@ const mutations = { ...@@ -32,6 +33,7 @@ const mutations = {
export default new Vuex.Store({ export default new Vuex.Store({
strict: debug, strict: debug,
modules: { modules: {
auth,
shows, shows,
files, files,
playlists, playlists,
......
import axios from 'axios'
import oidc from 'oidc-client'
const oidcmgr = new oidc.UserManager({
userStore: new oidc.WebStorageStateStore(),
authority: process.env.VUE_APP_API_STEERING_OIDC_URI,
// the client id has to be a string, therefore we add the + ''
client_id: process.env.VUE_APP_OIDC_CLIENT_ID,
redirect_uri: process.env.VUE_APP_API_STEERING_OIDC_REDIRECT_URI,
silent_redirect_uri: 'http://localhost:8080/oidc_callback_silentRenew.html',
popup_redirect_uri: 'http://localhost:8080/oidc_callback_popupRenew.html',
accessTokenExpiringNotificationTime: process.env.VUE_APP_API_STEERING_OIDC_EXPIRE_NOTIFICATION,
response_type: 'id_token token',
scope: 'openid profile email',
post_logout_redirect_uri: process.env.VUE_APP_API_STEERING_OIDC_REDIRECT_URI_POSTLOGOUT,
loadUserInfo: true
})
const state = {
items: [],
user: {
name: '',
email: '',
access_token: '',
expires_at: 0,
logged_in: false,
steeringUser: null
},
userOIDC: null,
}
const getters = {
items: state => state.items,
itemCount: state => state.items.length,
}
const mutations = {
addItem (state, item) {
state.items.push(item)
},
setUserProperties (state, user) {
state.userOIDC = user
state.user.logged_in = true
state.user.name = user.profile.nickname
state.user.email = user.profile.email
state.user.access_token = user.access_token
},
clearUserProperties (state) {
state.userOIDC = null
state.user.logged_in = false
state.user.name = ''
state.user.email = ''
state.user.access_token = ''
},
setSteeringUser (state, user) {
state.user.steeringUser = {...user}
},
setAccessToken (state, token) {
state.user.access_token = token
},
signOut (state) {
state.user.logged_in = false
},
}
const actions = {
addItem ({commit}, item) {
commit('addItem', item)
},
fetchSteeringUser (ctx) {
axios.get(process.env.VUE_APP_API_STEERING + 'users/', {
withCredentials: true,
headers: { 'Authorization': 'Bearer ' + ctx.state.user.access_token }
}).then(response => {
if (response.data.length === 0) {
alert('No user profile data provided by steering backend!')
} else if (response.data.length === 1) {
ctx.commit('setSteeringUser', response.data[0])
} else {
// in case we are a superuser, we get all users returned
// so we have to iterate through the user list to find out own profile
for (let u in response.data) {
if (response.data[u].username === ctx.state.user.name) {
ctx.commit('setSteeringUser', response.data[u])
break
}
}
}
}).catch(error => {
this.$log.error(error.response.status + ' ' + error.response.statusText)
this.$log.error(error.response)
alert('Error: could not fetch user object from the steering backend. See console for details.')
})
},
oidcInit (ctx) {
// TODO: remove oidc logging after thorough testing
oidc.Log.logger = console
this.$log.debug('Initializing oidc client')
oidcmgr.events.addAccessTokenExpiring(() => {
this.$log.debug('Starting silent access_token renewal')
oidcmgr.signinSilent().then(user => {
ctx.commit('setAccessToken', user.access_token)
this.$log.debug('Access token:', ctx.state.user.access_token)
}).catch(err => {
this.$log.error(err)
alert('Your OpenID access token could not be renewed automatically.\n' +
'You will be logged out in ' + process.env.VUE_APP_API_STEERING_OIDC_EXPIRE_NOTIFICATION + ' seconds.')
})
})
oidcmgr.events.addAccessTokenExpired(() => {
// at this point where the app is just mounted, we cannot use the
// vue logger, because this.$log does not yet exist. therefore we log
// to the console, but only if the environment is set tu debug log level
if (process.env.VUE_APP_LOGLEVEL === 'debug') {
this.$log.debug("OIDC token has expired. Logging out.")
}
ctx.commit('signOut')
})
oidcmgr.getUser().then(user => {
if (user == null) {
ctx.commit('clearUserProperties')
} else {
// TODO: check user.expires_at
// if token already expired try to get a new one or mark the user as logged out
ctx.commit('setUserProperties', user)
ctx.dispatch('fetchSteeringUser')
// TODO: remove debug info after thorough testing
this.$log.debug(new Date(user.expires_at * 1000).toString())
this.$log.debug(new Date(user.expires_at * 1000).toUTCString())
this.$log.debug(user.access_token)
}
}).catch(err => {
this.$log.debug(err)
alert('Error: could not fetch OIDC user object. See console for details.')
})
},
signinRedirect () {
oidcmgr.signinRedirect().catch(err => {
alert('Error: something went wrong when signing in. See console for details.')
this.$log.error(err)
})
},
signoutRedirect (ctx) {
oidcmgr.signoutRedirect().then(resp => {
ctx.commit('signOut')
this.$log.debug('signed out', resp)
}).catch(err => {
this.$log.error(err)
alert('Error: something went wrong when logging out. See console for details.')
})
}
}
export default {
namespaced: true,
state,
getters,
actions,
mutations,
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment