Skip to content

Commit

Permalink
Auth adjustments (#818)
Browse files Browse the repository at this point in the history
Use the API interface instead of fetch() to make the HTTP HEAD
request to determine whether the SSE are protected.
Fix custom auth header logic.
Change probe endpoint to /rest/sitemaps.

Signed-off-by: Yannick Schaus <[email protected]>
  • Loading branch information
ghys authored Jan 18, 2021
1 parent 90f49f4 commit cd659a7
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 22 deletions.
4 changes: 2 additions & 2 deletions bundles/org.openhab.ui/web/src/components/auth-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export default {
this.$oh.api.postPlain('/rest/auth/token?useCookie=true', payload, 'application/json', 'application/x-www-form-urlencoded').then((data) => {
const resp = JSON.parse(data)
localStorage.setItem('openhab.ui:refreshToken', resp.refresh_token)
return this.$oh.auth.setAccessToken(resp.access_token).then(() => {
return this.$oh.auth.setAccessToken(resp.access_token, this.$oh.api).then(() => {
// schedule the next token refresh when 95% of this token's lifetime has elapsed, i.e. 3 minutes before a 1-hour token is due to expire
setTimeout(this.refreshAccessToken, resp.expires_in * 950)
this.$store.commit('setUser', { user: resp.user })
Expand Down Expand Up @@ -73,7 +73,7 @@ export default {
this.$oh.auth.clearAccessToken()
this.$oh.api.postPlain('/rest/auth/token', payload, 'application/json', 'application/x-www-form-urlencoded').then((data) => {
const resp = JSON.parse(data)
return this.$oh.auth.setAccessToken(resp.access_token).then(() => {
return this.$oh.auth.setAccessToken(resp.access_token, this.$oh.api).then(() => {
// schedule the next token refresh when 95% of this token's lifetime has elapsed, i.e. 3 minutes before a 1-hour token is due to expire
setTimeout(this.refreshAccessToken, resp.expires_in * 950)
// also make sure to check the token and renew it when the app becomes visible again
Expand Down
8 changes: 7 additions & 1 deletion bundles/org.openhab.ui/web/src/js/openhab/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function wrapPromise (f7promise) {
Framework7.request.setup({
xhrFields: { withCredentials: true },
beforeSend (xhr) {
if (getAccessToken()) {
if (getAccessToken() && xhr.requestParameters.method !== 'HEAD') {
if (getTokenInCustomHeader()) {
xhr.setRequestHeader('X-OPENHAB-TOKEN', getAccessToken())
} else {
Expand Down Expand Up @@ -73,6 +73,12 @@ export default {
dataType: dataType || 'application/json'
}))
},
head (uri) {
return wrapPromise(Framework7.request.promise({
method: 'HEAD',
url: uri
}))
},
delete (uri, data) {
return wrapPromise(Framework7.request.promise({
method: 'DELETE',
Expand Down
29 changes: 12 additions & 17 deletions bundles/org.openhab.ui/web/src/js/openhab/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ let basicCredentials = null
/**
* The token is required for all requests, including SSE
*/
let requireToken = false
let requireToken

export function getAccessToken () { return accessToken }
export function getTokenInCustomHeader () { return tokenInCustomHeader }
export function getBasicCredentials () { return basicCredentials }
export function getRequireToken () { return requireToken }

if (document.cookie.indexOf('X-OPENHAB-AUTH-HEADER')) tokenInCustomHeader = true
if (document.cookie.indexOf('X-OPENHAB-AUTH-HEADER') >= 0) tokenInCustomHeader = true

export function authorize (setup) {
import('pkce-challenge').then((PkceChallenge) => {
Expand Down Expand Up @@ -74,7 +74,7 @@ export function setBasicCredentials (username, password) {

export function clearBasicCredentials () {
basicCredentials = null
tokenInCustomHeader = document.cookie.indexOf('X-OPENHAB-AUTH-HEADER')
tokenInCustomHeader = document.cookie.indexOf('X-OPENHAB-AUTH-HEADER') >= 0
}

export function storeBasicCredentials () {
Expand All @@ -83,23 +83,18 @@ export function storeBasicCredentials () {
}
}

export function setAccessToken (token) {
export function setAccessToken (token, api) {
accessToken = token
if (!token || !api || requireToken !== undefined) return

// determine whether the token is required for user operations
let headers = {}
if (getBasicCredentials()) {
const creds = getBasicCredentials()
headers.Authorization = 'Basic ' + btoa(creds.id + ':' + creds.password)
}
return fetch('rest/events', { method: 'HEAD', credentials: 'include', headers })
.then((resp) => {
if (resp.status === 401) {
requireToken = true
if (!token) authorize()
}
return Promise.resolve()
})
return api.head('/rest/sitemaps').then((resp) => {
requireToken = false
return Promise.resolve()
}).catch((err) => {
if (err === 'Unauthorized') requireToken = true
return Promise.resolve()
})
}

export function clearAccessToken () {
Expand Down
4 changes: 4 additions & 0 deletions bundles/org.openhab.ui/web/src/js/openhab/cordova/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ export default {
})
}
},
head (uri) {
// Not implemented
return Promise.resolve()
},
delete (uri, data) {
const fullUri = prepareRequest(uri)
if (fullUri) {
Expand Down
4 changes: 2 additions & 2 deletions bundles/org.openhab.ui/web/src/js/openhab/sse.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ function newSSEConnection (path, readyCallback, messageCallback, errorCallback)
const headers = {}
if (getAccessToken() && getRequireToken()) {
if (getTokenInCustomHeader()) {
headers['Authorization'] = 'Bearer ' + getAccessToken()
} else {
headers['X-OPENHAB-TOKEN'] = getAccessToken()
} else {
headers['Authorization'] = 'Bearer ' + getAccessToken()
}
}
if (getBasicCredentials()) {
Expand Down

0 comments on commit cd659a7

Please sign in to comment.