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

M #~: hooks by individual resource

Signed-off-by: Jorge Lobo <jlobo@opennebula.io>
This commit is contained in:
Jorge Lobo 2021-06-21 11:55:06 +02:00
parent 329117a434
commit 411c229d49
No known key found for this signature in database
GPG Key ID: 9C21660F7B06905E
10 changed files with 117 additions and 52 deletions

View File

@ -27,7 +27,7 @@ export const TIME_HIDE_LOGO = 1500
export const _APPS = defaultApps
export const APPS = Object.keys(defaultApps)
export const APP_URL = defaultAppName ? `/${defaultAppName}` : ''
export const WEBSOCKET_URL = `${APP_URL}/websocket`
export const WEBSOCKET_URL = `${APP_URL}/provision`
export const STATIC_FILES_URL = `${APP_URL}/client/assets`
export const IMAGES_URL = `${STATIC_FILES_URL}/images`

View File

@ -170,7 +170,7 @@ const genJWT = (token, informationUser) => {
if (!global.users) {
global.users = {}
}
global.users[user] = token.token
global.users[user] = { token: token.token }
const rtn = { token: jwt, id }
if (userTemplate && userTemplate.SUNSTONE && userTemplate.SUNSTONE.LANG) {
rtn.language = userTemplate.SUNSTONE.LANG

View File

@ -29,6 +29,7 @@ const {
internalServerError
} = require('server/utils/constants/http-codes')
const { httpResponse, parsePostData, existsFile, createFile } = require('server/utils/server')
const { checkEmptyObject } = require('server/utils/general')
const { defaultFolderTmpProvision, defaultCommandProvision, defaultEmptyFunction, defaultErrorTemplate } = require('server/utils/constants/defaults')
const {
executeCommand,
@ -198,8 +199,6 @@ const getProvisionDefaults = (res = {}, next = defaultEmptyFunction, params = {}
let rtn = httpInternalError
const files = {}
const path = `${global.SHARE_CPI}`
const checkEmpty = (obj = {}) =>
Object.keys(obj).length === 0 && obj.constructor === Object
const endpoint = getEndpoint()
if (user && password) {
@ -279,7 +278,7 @@ const getProvisionDefaults = (res = {}, next = defaultEmptyFunction, params = {}
)
})
if (description && !checkEmpty(providers) && !checkEmpty(provisions)) {
if (description && !checkEmptyObject(providers) && !checkEmptyObject(provisions)) {
files[directory.filename] = {
description,
providers,

View File

@ -93,7 +93,10 @@ router.all(
[fromData.postBody]: req.body
}
if (routeFunction) {
// this execute functions
/*********************************************************
* This execute functions (routes)
*********************************************************/
const valRouteFunction = checkMethodRouteFunction(
routeFunction,
httpMethod
@ -112,7 +115,10 @@ router.all(
next()
}
} else {
// this execute a XMLRPC commands
/*********************************************************
* This execute a XMLRPC commands
*********************************************************/
const { method } = getParamsState()
const command = commandXML(
resource,

View File

@ -14,6 +14,8 @@
/* -------------------------------------------------------------------------- */
const { Map } = require('immutable')
const { env } = require('process')
const { global } = require('window-or-global')
const {
private: authenticated,
public: nonAuthenticated
@ -42,6 +44,18 @@ const getIdUserOpennebula = () => idUserOpennebula
const getUserOpennebula = () => userOpennebula
const getPassOpennebula = () => passOpennebula
const passUserValidation = (user = '', token = '') => {
if (user &&
token &&
global &&
global.users &&
global.users[user] &&
global.users[user].token &&
global.users[user].token === token) {
return true
}
}
const validateResourceAndSession = (req, res, next) => {
const { badRequest, unauthorized, serviceUnavailable } = httpCodes
let status = badRequest
@ -57,18 +71,29 @@ const validateResourceAndSession = (req, res, next) => {
userOpennebula = session.aud
passOpennebula = session.jti
if (env && (!env.NODE_ENV || env.NODE_ENV !== defaultWebpackMode)) {
if (
global &&
global.users &&
global.users[userOpennebula] &&
global.users[userOpennebula] === passOpennebula
) {
/*********************************************************
* Validate user in production mode
*********************************************************/
if (passUserValidation(userOpennebula, passOpennebula)) {
next()
return
}
} else {
next()
return
/*********************************************************
* Validate user in development mode
*********************************************************/
if (global && !global.users) {
global.users = {}
}
if (!global.users[userOpennebula]) {
global.users[userOpennebula] = { token: passOpennebula }
}
if (passUserValidation(userOpennebula, passOpennebula)) {
next()
return
}
}
}
status = unauthorized

View File

@ -14,11 +14,10 @@
/* -------------------------------------------------------------------------- */
const socketIO = require('socket.io')
const { messageTerminal } = require('server/utils/general')
const { messageTerminal, checkEmptyObject } = require('server/utils/general')
const {
defaultFilesWebsockets,
defaultConfigErrorMessage,
defaultEndpointWebsocket
defaultConfigErrorMessage
} = require('server/utils/constants/defaults')
// user config
@ -31,29 +30,35 @@ const websockets = (appServer = {}) => {
appServer.constructor.name &&
appServer.constructor.name === 'Server'
) {
const io = socketIO(
{
path: defaultEndpointWebsocket,
cors: {
origin: '*',
methods: ['GET', 'POST'],
credentials: true
}
}
).listen(appServer)
defaultFilesWebsockets.forEach(file => {
try {
// eslint-disable-next-line global-require
const fileInfo = require(`./${file}`)
if (fileInfo.main && typeof fileInfo.main === 'function') {
sockets.push(io)
fileInfo.main(io)
}
} catch (error) {
if (error instanceof Error) {
const config = defaultConfigErrorMessage
config.type = error.message
messageTerminal(config)
Object.entries(defaultFilesWebsockets).forEach(([filename = '', info = {}]) => {
if (filename && info && !checkEmptyObject(info)) {
const path = info && info.path
const methods = info && info.methods
if (path && methods) {
const io = socketIO(
{
path,
cors: {
origin: '*',
methods,
credentials: true
}
}
).listen(appServer)
try {
// eslint-disable-next-line global-require
const fileInfo = require(`./${filename}`)
if (fileInfo.main && typeof fileInfo.main === 'function') {
sockets.push(io)
fileInfo.main(io)
}
} catch (error) {
if (error instanceof Error) {
const config = defaultConfigErrorMessage
config.type = error.message
messageTerminal(config)
}
}
}
}
})

View File

@ -14,6 +14,7 @@
/* -------------------------------------------------------------------------- */
const appName = 'fireedge'
const prepend = `${appName ? `/${appName}/` : '/'}`
const apps = {
flow: {
name: 'flow',
@ -38,10 +39,16 @@ const defaults = {
color: 'red',
message: 'file not found: %s'
},
defaultFilesWebsockets: [
'hooks',
'provision'
],
defaultFilesWebsockets: {
hooks: {
path: `${prepend}hooks`,
methods: ['GET', 'POST']
},
provision: {
path: `${prepend}provision`,
methods: ['GET', 'POST']
}
},
defaultFilesRoutes: [
'2fa',
'auth',
@ -79,7 +86,6 @@ const defaults = {
defaultHideCredentials: true,
defaultHideCredentialReplacer: '****',
defaultOneFlowServer: `${protocol}://${defaultIp}:2474`,
defaultEndpointWebsocket: `${appName ? '/' + appName : ''}/websocket`,
defaultConfigFile: `${appName}-server.conf`,
defaultTypeLog: 'prod',
defaultWebpackMode: 'development',
@ -93,8 +99,8 @@ const defaults = {
defaultKeyFilename: `${appName}_key`,
defaultVmrcTokens: 'sunstone_vmrc_tokens/',
defaultBaseURL: '',
endpointVmrc: `${appName ? '/' + appName : ''}/vmrc`,
endpointGuacamole: `${appName ? '/' + appName : ''}/guacamole`,
endpointVmrc: `${prepend}vmrc`,
endpointGuacamole: `${prepend}guacamole`,
defaultNamespace: 'one.',
defaultMessageInvalidZone: 'Invalid Zone',
default2FAIssuer: `${appName}-UI`,

View File

@ -38,7 +38,11 @@ const addPrintf = (string = '', args = '') => {
return rtn
}
const checkEmptyObject = (obj = {}) =>
Object.keys(obj).length === 0 && obj.constructor === Object
module.exports = {
messageTerminal,
addPrintf
addPrintf,
checkEmptyObject
}

View File

@ -19,7 +19,7 @@ const { defaultTypeLog } = require('./constants/defaults')
const functionRoutes = require('../routes/api')
const { validateAuth } = require('./jwt')
const { httpResponse, getDataZone } = require('./server')
const { messageTerminal, addPrintf } = require('./general')
const { messageTerminal, addPrintf, checkEmptyObject } = require('./general')
const { getConfig } = require('./yml')
// user config
@ -145,5 +145,6 @@ module.exports = {
responseOpennebula,
getConfig,
httpResponse,
getDataZone
getDataZone,
checkEmptyObject
}

View File

@ -21,6 +21,7 @@ const xml2js = require('xml2js')
const { Map } = require('immutable')
const { sprintf } = require('sprintf-js')
const speakeasy = require('speakeasy')
const { global } = require('window-or-global')
const httpCodes = require('./constants/http-codes')
const commandsParams = require('./constants/commands')
const {
@ -29,12 +30,26 @@ const {
defaultMessageProblemOpennebula
} = require('./constants/defaults')
// regex for separate the commands .info
const regexInfoAction = /^(\w+).info$/
// user config
const { getConfig } = require('./yml')
const appConfig = getConfig()
const namespace = appConfig.namespace || defaultNamespace
const fillResourceforHookConection = (username = '', action = '', parameters = '') => {
let match
// parameters[0] is the resource ID
if (username && action && (match = action.match(regexInfoAction)) && match[1] && parameters[0] >= 0) {
if (global.users[username] && !global.users[username].resourcesHooks) {
global.users[username].resourcesHooks = {}
}
global.users[username].resourcesHooks[match[1]] = parameters[0]
}
}
const opennebulaConnect = (username = '', password = '', path = '') => {
let rtn = () => null
if (username && password && path) {
@ -94,6 +109,8 @@ const opennebulaConnect = (username = '', password = '', path = '') => {
errorData[0] &&
errorData[0].STRING
) {
// success
fillResourceforHookConection(username, action, parameters)
callback(undefined, errorData[0].STRING)
}
}
@ -111,10 +128,12 @@ const opennebulaConnect = (username = '', password = '', path = '') => {
callback(error, undefined) // error parse xml
return
}
// success
fillResourceforHookConection(username, action, parameters)
callback(
undefined,
error === null && result === null ? messageCall : result
) // success
)
}
)
return