diff --git a/src/fireedge/src/client/constants/index.js b/src/fireedge/src/client/constants/index.js index 15e96c7daa..d304ccd920 100644 --- a/src/fireedge/src/client/constants/index.js +++ b/src/fireedge/src/client/constants/index.js @@ -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` diff --git a/src/fireedge/src/server/routes/api/auth/functions.js b/src/fireedge/src/server/routes/api/auth/functions.js index f70eabb7fa..5cf959cf6f 100644 --- a/src/fireedge/src/server/routes/api/auth/functions.js +++ b/src/fireedge/src/server/routes/api/auth/functions.js @@ -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 diff --git a/src/fireedge/src/server/routes/api/provision/provision-functions.js b/src/fireedge/src/server/routes/api/provision/provision-functions.js index 3c6cf9a22c..3ccb0c98b9 100644 --- a/src/fireedge/src/server/routes/api/provision/provision-functions.js +++ b/src/fireedge/src/server/routes/api/provision/provision-functions.js @@ -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, diff --git a/src/fireedge/src/server/routes/entrypoints/Api.js b/src/fireedge/src/server/routes/entrypoints/Api.js index 682767d861..19966837de 100644 --- a/src/fireedge/src/server/routes/entrypoints/Api.js +++ b/src/fireedge/src/server/routes/entrypoints/Api.js @@ -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, diff --git a/src/fireedge/src/server/routes/entrypoints/middlewares/api/index.js b/src/fireedge/src/server/routes/entrypoints/middlewares/api/index.js index 0445d7565b..5cf1a9f5c8 100644 --- a/src/fireedge/src/server/routes/entrypoints/middlewares/api/index.js +++ b/src/fireedge/src/server/routes/entrypoints/middlewares/api/index.js @@ -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 diff --git a/src/fireedge/src/server/routes/websockets/index.js b/src/fireedge/src/server/routes/websockets/index.js index 0e5ba5a1bd..313a679113 100644 --- a/src/fireedge/src/server/routes/websockets/index.js +++ b/src/fireedge/src/server/routes/websockets/index.js @@ -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) + } + } } } }) diff --git a/src/fireedge/src/server/utils/constants/defaults.js b/src/fireedge/src/server/utils/constants/defaults.js index c34faa4f33..33770cc518 100644 --- a/src/fireedge/src/server/utils/constants/defaults.js +++ b/src/fireedge/src/server/utils/constants/defaults.js @@ -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`, diff --git a/src/fireedge/src/server/utils/general.js b/src/fireedge/src/server/utils/general.js index ed529cfe51..084cf779f3 100644 --- a/src/fireedge/src/server/utils/general.js +++ b/src/fireedge/src/server/utils/general.js @@ -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 } diff --git a/src/fireedge/src/server/utils/index.js b/src/fireedge/src/server/utils/index.js index f8035a2325..e409e52fb1 100644 --- a/src/fireedge/src/server/utils/index.js +++ b/src/fireedge/src/server/utils/index.js @@ -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 } diff --git a/src/fireedge/src/server/utils/opennebula.js b/src/fireedge/src/server/utils/opennebula.js index efb80d82ed..bedce24def 100644 --- a/src/fireedge/src/server/utils/opennebula.js +++ b/src/fireedge/src/server/utils/opennebula.js @@ -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