1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-22 18:50:08 +03:00

M #-: Fix gen one tokens 6.0 (#1139)

Co-authored-by: Jorge Lobo <jlobo@opennebula.io>
This commit is contained in:
Jorge Miguel Lobo Escalona 2021-04-23 12:23:36 +02:00 committed by Ruben S. Montero
parent c708278936
commit 8c87780c32
No known key found for this signature in database
GPG Key ID: A0CEA6FA880A1D87
3 changed files with 117 additions and 67 deletions

View File

@ -14,7 +14,7 @@
/* -------------------------------------------------------------------------- */
const { Map } = require('immutable')
const {
authenticate,
login,
getUser,
getPass,
setUser,
@ -26,23 +26,23 @@ const {
setReq,
setRes,
setNodeConnect,
setDates,
getRelativeTime,
connectOpennebula,
updaterResponse
} = require('./functions')
const { internalServerError } = require('server/utils/constants/http-codes')
const {
httpMethod,
defaultMethodLogin
defaultMethodLogin,
defaultMethodUserInfo
} = require('server/utils/constants/defaults')
const {
paramsDefaultByCommandOpennebula,
responseOpennebula,
checkOpennebulaCommand
} = require('server/utils/opennebula')
const { from } = require('server/utils/constants/defaults')
const { POST } = httpMethod
const { POST, GET } = httpMethod
const auth = (req, res, next, connect) => {
if (req && res && connect) {
@ -85,17 +85,12 @@ const auth = (req, res, next, connect) => {
)
setNodeConnect(connect)
if (getUser() && getPass()) {
setDates()
const relativeTime = getRelativeTime()
const oneConnect = connectOpennebula()
const dataSourceWithExpirateDate = Map(req).toObject()
// add expire time unix for opennebula creation token
dataSourceWithExpirateDate[from.postBody].expire = relativeTime
oneConnect(
defaultMethodLogin,
getOpennebulaMethod(dataSourceWithExpirateDate),
defaultMethodUserInfo,
paramsDefaultByCommandOpennebula(defaultMethodUserInfo, GET),
(err, value) => {
responseOpennebula(updaterResponse, err, value, authenticate, next)
responseOpennebula(updaterResponse, err, value, login, next)
}
)
}

View File

@ -15,8 +15,10 @@
const { DateTime } = require('luxon')
const { Map } = require('immutable')
const {
from,
httpMethod,
defaultLimit,
defaultOpennebulaExpiration,
defaultOpennebulaMinimumExpiration,
defaultMethodLogin,
defaultMethodZones,
defaultMethodUserInfo,
@ -33,22 +35,22 @@ const { createToken } = require('server/utils/jwt')
const { httpResponse } = require('server/utils/server')
const {
responseOpennebula,
paramsDefaultByCommandOpennebula,
checkOpennebulaCommand,
check2Fa
} = require('server/utils/opennebula')
// eslint-disable-next-line node/no-deprecated-api
const { parse } = require('url')
const { global } = require('window-or-global')
const { global, Array } = require('window-or-global')
const appConfig = getConfig()
const namespace = appConfig.namespace || defaultNamespace
const { GET, POST } = httpMethod
const minimumExpirationTime = appConfig.minimun_opennebula_expiration || defaultOpennebulaMinimumExpiration
const { POST } = httpMethod
const getOpennebulaMethod = checkOpennebulaCommand(defaultMethodLogin, POST)
let opennebulaToken = ''
let user = ''
let pass = ''
let type = ''
@ -60,7 +62,7 @@ let res = {}
let nodeConnect = () => undefined
let now = ''
let nowUnix = ''
let nowWithDays = ''
let nowWithMinutes = ''
let relativeTime = ''
const dataSourceWithExpirateDate = () => Map(req).toObject()
@ -112,12 +114,11 @@ const setRes = newRes => {
}
const setDates = () => {
const limitToken = appConfig.limit_token || defaultLimit
const { min, max } = limitToken
const limitToken = appConfig.opennebula_expiration || defaultOpennebulaExpiration
now = DateTime.local()
nowUnix = now.toSeconds()
nowWithDays = now.plus({ days: extended ? max : min })
const diff = nowWithDays.diff(now, 'seconds')
nowWithMinutes = now.plus({ minutes: limitToken })
const diff = nowWithMinutes.diff(now, 'seconds')
relativeTime = diff.seconds
}
@ -136,6 +137,7 @@ const updaterResponse = code => {
}
const validate2faAuthentication = informationUser => {
let rtn = false
if (
informationUser.TEMPLATE &&
informationUser.TEMPLATE.SUNSTONE &&
@ -143,28 +145,31 @@ const validate2faAuthentication = informationUser => {
) {
if (tfatoken.length <= 0) {
updaterResponse(httpResponse(accepted))
next()
return
}
const secret = informationUser.TEMPLATE.SUNSTONE[default2FAOpennebulaVar]
if (!check2Fa(secret, tfatoken)) {
updaterResponse(httpResponse(unauthorized, '', 'invalid 2fa token'))
next()
} else {
const secret = informationUser.TEMPLATE.SUNSTONE[default2FAOpennebulaVar]
if (!check2Fa(secret, tfatoken)) {
updaterResponse(httpResponse(unauthorized, '', 'invalid 2fa token'))
} else {
rtn = true
}
}
} else {
// without 2FA login
rtn = true
}
return rtn
}
const genJWT = informationUser => {
if (informationUser && informationUser.ID && informationUser.PASSWORD) {
const genJWT = (token, informationUser) => {
if (token && informationUser && informationUser.ID && informationUser.PASSWORD) {
const { ID: id, TEMPLATE: userTemplate } = informationUser
const dataJWT = { id, user, token: opennebulaToken }
const jwt = createToken(dataJWT, nowUnix, nowWithDays.toSeconds())
const dataJWT = { id, user, token }
const jwt = createToken(dataJWT, nowUnix, nowWithMinutes.toSeconds())
if (jwt) {
if (!global.users) {
global.users = {}
}
global.users[user] = opennebulaToken
global.users[user] = token
const rtn = { token: jwt, id }
if (userTemplate && userTemplate.SUNSTONE && userTemplate.SUNSTONE.LANG) {
rtn.language = userTemplate.SUNSTONE.LANG
@ -216,42 +221,96 @@ const setZones = () => {
}
}
const userInfo = userData => {
if (user && opennebulaToken && userData && userData.USER) {
const informationUser = userData.USER
setZones()
validate2faAuthentication(informationUser)
genJWT(informationUser)
next()
} else {
const login = (userData) => {
let rtn = true
if (userData) {
const findTextError = `[${namespace + defaultMethodUserInfo}]`
if (userData.indexOf && userData.indexOf(findTextError) >= 0) {
updaterResponse(httpResponse(unauthorized))
}
if (userData.USER) {
setZones()
if (validate2faAuthentication(userData.USER)) {
rtn = false
checkOpennebulaToken(userData.USER)
}
}
}
if (rtn) {
next()
}
}
const authenticate = val => {
const findTextError = `[${namespace + defaultMethodLogin}]`
if (val) {
if (val.indexOf(findTextError) >= 0) {
updaterResponse(httpResponse(unauthorized))
const checkOpennebulaToken = userData => {
setDates()
if (userData && userData.LOGIN_TOKEN) {
const loginTokens = Array.isArray(userData.LOGIN_TOKEN) ? userData.LOGIN_TOKEN : [userData.LOGIN_TOKEN]
const token = getValidOpennebulaToken(loginTokens)
if (token) {
genJWT(token, userData)
next()
} else {
const oneConnect = connectOpennebula()
opennebulaToken = val
oneConnect(
defaultMethodUserInfo,
paramsDefaultByCommandOpennebula(defaultMethodUserInfo, GET),
(err, value) => {
responseOpennebula(updaterResponse, err, value, userInfo, next)
}
)
createOpennebulaToken(userData)
}
} else {
next()
createOpennebulaToken(userData)
}
}
const getValidOpennebulaToken = userDataTokens => {
let rtn
if (Array.isArray(userDataTokens)) {
const validToken = userDataTokens.find(token => {
now = DateTime.local()
nowUnix = now.toSeconds()
return (
token &&
token.TOKEN &&
token.EGID &&
token.EGID === '-1' &&
token.EXPIRATION_TIME &&
parseInt(token.EXPIRATION_TIME, 10) >= nowUnix + (parseInt(minimumExpirationTime, 10) * 60)
)
})
rtn = validToken && validToken.TOKEN
}
return rtn
}
const createOpennebulaToken = userData => {
const relativeTime = getRelativeTime()
const dataSourceWithExpirateDate = Map(req).toObject()
// add expire time unix for opennebula creation token
dataSourceWithExpirateDate[from.postBody].expire = relativeTime
dataSourceWithExpirateDate[from.postBody].token = ''
const oneConnect = connectOpennebula()
oneConnect(
defaultMethodLogin,
getOpennebulaMethod(dataSourceWithExpirateDate),
(err, value) => {
responseOpennebula(
updaterResponse,
err,
value,
token => authenticate(token, userData),
next)
}
)
}
const authenticate = (token, userData) => {
const findTextError = `[${namespace + defaultMethodLogin}]`
if (token && userData) {
if (token.indexOf(findTextError) < 0) {
genJWT(token, userData)
}
}
next()
}
const functionRoutes = {
authenticate,
login,
getUser,
getPass,
setType,
@ -264,9 +323,7 @@ const functionRoutes = {
setRes,
updaterResponse,
setNodeConnect,
connectOpennebula,
setDates,
getRelativeTime
connectOpennebula
}
module.exports = functionRoutes

View File

@ -29,10 +29,8 @@ const default2FAOpennebulaVar = 'TWO_FACTOR_AUTH_SECRET'
const defaultIp = 'localhost'
const protocol = 'http'
const defaults = {
defaultLimit: {
min: 14,
max: 30
},
defaultOpennebulaExpiration: 180,
defaultOpennebulaMinimumExpiration: 30,
defaultAppName: appName,
defaultConfigErrorMessage: {
color: 'red',