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

B #5703: Fix FireEdge routes (#1708)

(cherry picked from commit 7e1ac044e318b1562cce8c21a489ae136a7fa458)
This commit is contained in:
Jorge Miguel Lobo Escalona 2022-01-20 14:17:06 +01:00 committed by Tino Vazquez
parent 364105a498
commit 0424a1daa4
No known key found for this signature in database
GPG Key ID: 14201E424D02047E
49 changed files with 1371 additions and 1374 deletions

View File

@ -28,7 +28,7 @@ export const applicationService = {
*/
getApplication: async ({ id }) => {
const res = await RestClient.request({
url: `/api/${SERVICE}/list/${id}`,
url: `/api/${SERVICE}/${id}`,
})
if (!res?.id || res?.id !== httpCodes.ok.id) throw res
@ -44,7 +44,7 @@ export const applicationService = {
*/
getApplications: async () => {
const res = await RestClient.request({
url: `/api/${SERVICE}/list`,
url: `/api/${SERVICE}`,
})
if (!res?.id || res?.id !== httpCodes.ok.id) throw res

View File

@ -30,7 +30,7 @@ export const applicationTemplateService = {
*/
getApplicationTemplate: ({ id }) => {
const res = RestClient.request({
url: `/api/${SERVICE_TEMPLATE}/list/${id}`,
url: `/api/${SERVICE_TEMPLATE}/${id}`,
})
if (!res?.id || res?.id !== httpCodes.ok.id) throw res
@ -44,7 +44,7 @@ export const applicationTemplateService = {
*/
getApplicationsTemplates: async () => {
const res = await RestClient.request({
url: `/api/${SERVICE_TEMPLATE}/list`,
url: `/api/${SERVICE_TEMPLATE}`,
})
if (!res?.id || res?.id !== httpCodes.ok.id) throw res
@ -64,7 +64,7 @@ export const applicationTemplateService = {
const res = await RestClient.request({
data,
method: POST,
url: `/api/${SERVICE_TEMPLATE}/create`,
url: `/api/${SERVICE_TEMPLATE}`,
})
if (!res?.id || res?.id !== httpCodes.ok.id) throw res
@ -85,7 +85,7 @@ export const applicationTemplateService = {
const res = RestClient.request({
data,
method: PUT,
url: `/api/${SERVICE_TEMPLATE}/update/${id}`,
url: `/api/${SERVICE_TEMPLATE}/${id}`,
})
if (!res?.id || res?.id !== httpCodes.ok.id) throw res

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
import { PROVIDER } from 'server/routes/api/provision/string-routes'
import { PROVIDER } from 'server/routes/api/oneprovision/string-routes'
import { httpCodes, defaults } from 'server/utils/constants'
import { RestClient } from 'client/utils'
@ -30,7 +30,7 @@ export const providerService = {
*/
getProvider: async ({ id }) => {
const res = await RestClient.request({
url: `/api/${PROVIDER}/list/${id}`,
url: `/api/${PROVIDER}/${id}`,
})
if (!res?.id || res?.id !== httpCodes.ok.id) throw res
@ -46,7 +46,7 @@ export const providerService = {
*/
getProviders: async () => {
const res = await RestClient.request({
url: `/api/${PROVIDER}/list`,
url: `/api/${PROVIDER}`,
})
if (!res?.id || res?.id !== httpCodes.ok.id) throw res
@ -86,7 +86,7 @@ export const providerService = {
const res = await RestClient.request({
data,
method: POST,
url: `/api/${PROVIDER}/create`,
url: `/api/${PROVIDER}`,
})
if (!res?.id || res?.id !== httpCodes.ok.id) throw res
@ -107,7 +107,7 @@ export const providerService = {
const res = await RestClient.request({
data,
method: PUT,
url: `/api/${PROVIDER}/update/${id}`,
url: `/api/${PROVIDER}/${id}`,
})
if (!res?.id || res?.id !== httpCodes.ok.id) throw res
@ -126,7 +126,7 @@ export const providerService = {
deleteProvider: async ({ id }) => {
const res = await RestClient.request({
method: DELETE,
url: `/api/${PROVIDER}/delete/${id}`,
url: `/api/${PROVIDER}/${id}`,
})
if (!res?.id || res?.id !== httpCodes.ok.id) throw res

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
import { PROVISION } from 'server/routes/api/provision/string-routes'
import { PROVISION } from 'server/routes/api/oneprovision/string-routes'
import { httpCodes, defaults } from 'server/utils/constants'
import { RestClient } from 'client/utils'
@ -63,7 +63,7 @@ export const provisionService = {
*/
getProvision: async ({ id }) => {
const res = await RestClient.request({
url: `/api/${PROVISION}/list/${id}`,
url: `/api/${PROVISION}/${id}`,
})
if (!res?.id || res?.id !== httpCodes.ok.id) throw res
@ -79,7 +79,7 @@ export const provisionService = {
*/
getProvisions: async () => {
const res = await RestClient.request({
url: `/api/${PROVISION}/list`,
url: `/api/${PROVISION}`,
})
if (!res?.id || res?.id !== httpCodes.ok.id) throw res
@ -99,7 +99,7 @@ export const provisionService = {
const res = await RestClient.request({
data,
method: POST,
url: `/api/${PROVISION}/create`,
url: `/api/${PROVISION}`,
})
if (!res?.id || res?.id !== httpCodes.ok.id) {
@ -146,7 +146,7 @@ export const provisionService = {
deleteProvision: async ({ id, ...data }) => {
const res = await RestClient.request({
method: DELETE,
url: `/api/${PROVISION}/delete/${id}`,
url: `/api/${PROVISION}/${id}`,
data,
})

View File

@ -15,8 +15,8 @@
* ------------------------------------------------------------------------- */
const { setApiRoutes } = require('server/utils/server')
const { routes: tfaRoutes } = require('./tfa')
const { TFA } = require('./string-routes')
const { routes: tfaRoutes } = require('server/routes/api/2fa/routes')
const { TFA } = require('server/routes/api/2fa/string-routes')
const functionRoutes = {
private: setApiRoutes(tfaRoutes, TFA),

View File

@ -18,7 +18,7 @@ const {
httpMethod,
from: fromData,
} = require('server/utils/constants/defaults')
const { setup, qr, del } = require('./tfa-functions')
const { setup, qr, del } = require('server/routes/api/2fa/functions')
const { POST, DELETE, GET } = httpMethod
const routes = {

View File

@ -1,134 +0,0 @@
/* ------------------------------------------------------------------------- *
* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may *
* not use this file except in compliance with the License. You may obtain *
* a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
const { Map } = require('immutable')
const {
login,
setUser,
setPass,
setType,
setTfaToken,
setRemember,
setNext,
setRes,
setNodeConnect,
connectOpennebula,
updaterResponse,
} = require('./functions')
const {
internalServerError,
unauthorized,
} = require('server/utils/constants/http-codes')
const { Actions } = require('server/utils/constants/commands/user')
const {
httpMethod,
defaultEmptyFunction,
} = require('server/utils/constants/defaults')
const { GET } = httpMethod
const {
getDefaultParamsOfOpennebulaCommand,
} = require('server/utils/opennebula')
const { writeInLogger } = require('server/utils/logger')
/**
* Login user.
*
* @param {error} err - run if no have user data
* @param {string} value - opennebula information
* @param {Function} success - success
* @param {Function} error - error
*/
const loginUser = (
err = '',
value = '',
success = defaultEmptyFunction,
error = defaultEmptyFunction
) => {
if (value && value.USER && !err) {
success(value)
} else {
error()
}
}
/**
* Fireedge user auth.
*
* @param {object} res - http response
* @param {Function} next - express stepper
* @param {object} params - params of http request
* @param {object} userData - user of http request
* @param {Function} oneConnection - function of xmlrpc
*/
const auth = (
res = {},
next = defaultEmptyFunction,
params = {},
userData = {},
oneConnection = defaultEmptyFunction
) => {
const { user, token, type, token2fa, remember } = params
setRes(res)
setNext(next)
setNodeConnect(oneConnection)
updaterResponse(new Map(internalServerError).toObject())
if (user && token) {
const oneConnect = connectOpennebula(user, token)
/**
* Run if have information.
*
* @param {object} oneValue - opennebula value
*/
const success = (oneValue) => {
setUser(user || '')
setPass(token || '')
setType(type || '')
setTfaToken(token2fa || '')
setRemember(remember || false)
login(oneValue)
}
/**
* Run if no have information.
*/
const error = () => {
updaterResponse(new Map(unauthorized).toObject())
writeInLogger(unauthorized)
next()
}
oneConnect(
Actions.USER_INFO,
getDefaultParamsOfOpennebulaCommand(Actions.USER_INFO, GET),
(err, value) => {
loginUser(err, value, success, error)
},
false
)
} else {
next()
}
}
const authApi = {
auth,
}
module.exports = authApi

View File

@ -14,611 +14,121 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
const { DateTime } = require('luxon')
// eslint-disable-next-line node/no-deprecated-api
const { parse } = require('url')
const { global, Array } = require('window-or-global')
const { Actions: ActionUsers } = require('server/utils/constants/commands/user')
const { Actions: ActionZones } = require('server/utils/constants/commands/zone')
const { Map } = require('immutable')
const {
httpMethod,
defaultSessionExpiration,
default2FAOpennebulaVar,
defaultNamespace,
defaultEmptyFunction,
defaultSessionLimitExpiration,
defaultRememberSessionExpiration,
} = require('server/utils/constants/defaults')
const { getFireedgeConfig } = require('server/utils/yml')
const {
ok,
unauthorized,
accepted,
internalServerError,
} = require('server/utils/constants/http-codes')
const { createJWT, check2Fa } = require('server/utils/jwt')
const {
httpResponse,
encrypt,
getSunstoneAuth,
} = require('server/utils/server')
const {
responseOpennebula,
getDefaultParamsOfOpennebulaCommand,
} = require('server/utils/opennebula')
const appConfig = getFireedgeConfig()
const namespace = appConfig.namespace || defaultNamespace
const { GET } = httpMethod
let user = ''
let key = ''
let iv = ''
let pass = ''
let type = ''
let tfatoken = ''
let remember = false
let next = defaultEmptyFunction
let req = {}
let res = {}
let nodeConnect = defaultEmptyFunction
let now = ''
let nowUnix = ''
let expireTime = ''
let relativeTime = ''
let limitToken = defaultSessionExpiration
let limitExpirationReuseToken = defaultSessionLimitExpiration
/**
* Get key opennebula.
*
* @returns {string} get key
*/
const getKey = () => key
/**
* Get initialization vector.
*
* @returns {string} get initialization vector
*/
const getIV = () => iv
/**
* Get user opennebula.
*
* @returns {string} user opennebula
*/
const getUser = () => user
/**
* Get user password opennebula.
*
* @returns {string} get password user opennebula
*/
const getPass = () => pass
/**
* Get relative time.
*
* @returns {string} date
*/
const getRelativeTime = () => relativeTime
/**
* Opennebula encode-decode key.
*
* @param {string} newKey - new key
* @returns {string} get key
*/
const setKey = (newKey) => {
key = newKey
return key
}
/**
* Initialization vector (encrypt).
*
* @param {string} newIV - //16 characters
* @returns {string} get IV
*/
const setIV = (newIV) => {
iv = newIV
return iv
}
/**
* Username opennebula.
*
* @param {string} newUser - new user data
* @returns {string} get user
*/
const setUser = (newUser) => {
user = newUser
return user
}
/**
* User password opennebula.
*
* @param {string} newPass - set new opennebula password user
* @returns {string} password user
*/
const setPass = (newPass) => {
pass = newPass
return pass
}
/**
* Type app.
*
* @param {string} newtype - new type (application)
* @returns {string} get type
*/
const setType = (newtype) => {
type = newtype
return type
}
/**
* Set 2FA token.
*
* @param {string} newTfaToken - new TFA token
* @returns {string} get TFA token
*/
const setTfaToken = (newTfaToken) => {
tfatoken = newTfaToken
return tfatoken
}
/**
* Set remember.
*
* @param {boolean} newRemember - new remember
* @returns {boolean} remember
*/
const setRemember = (newRemember) => {
remember = newRemember
return remember
}
/**
* Set express stepper.
*
* @param {Function} newNext - new stepper
* @returns {Function} http response
*/
const setNext = (newNext = defaultEmptyFunction) => {
next = newNext
return next
}
/**
* Set http resquest.
*
* @param {object} newReq - new request
* @returns {object} http resquest
*/
const setReq = (newReq = {}) => {
req = newReq
return req
}
/**
* Set xlmrpc connection function.
*
* @param {Function} newConnect - new connect opennebula
* @returns {Function} xmlrpc function
*/
const setNodeConnect = (newConnect = defaultEmptyFunction) => {
nodeConnect = newConnect
return nodeConnect
}
/**
* Set http response.
*
* @param {object} newRes - new response
* @returns {object} http response
*/
const setRes = (newRes = {}) => {
res = newRes
return res
}
/**
* Set dates.
*/
const setDates = () => {
limitToken = remember
? appConfig.session__remember_expiration || defaultRememberSessionExpiration
: appConfig.session_expiration || defaultSessionExpiration
limitExpirationReuseToken =
parseInt(appConfig.session_reuse_token_time, 10) ||
defaultSessionLimitExpiration
now = DateTime.local()
nowUnix = now.toSeconds()
expireTime = now.plus({ minutes: limitToken })
const diff = expireTime.diff(now, 'seconds')
relativeTime = diff.seconds
}
/**
* Connect to function xmlrpc.
*
* @param {string} usr - user
* @param {string} pss - password
* @returns {Function} xmlrpc function
*/
const connectOpennebula = (usr = '', pss = '') => {
const connectUser = usr || user
const connectPass = pss || pass
return nodeConnect(connectUser, connectPass)
}
/**
* Updater http request.
*
* @param {string} code - http code
*/
const updaterResponse = (code) => {
if (
'id' in code &&
'message' in code &&
res &&
res.locals &&
res.locals.httpCode
) {
res.locals.httpCode = code
}
}
/**
* Validate 2FA.
*
* @param {object} informationUser - user data
* @returns {boolean} return if data is valid
*/
const validate2faAuthentication = (informationUser) => {
let rtn = false
if (
informationUser.TEMPLATE &&
informationUser.TEMPLATE.SUNSTONE &&
informationUser.TEMPLATE.SUNSTONE[default2FAOpennebulaVar]
) {
/*********************************************************
* Validate 2FA
*********************************************************/
if (tfatoken.length <= 0) {
updaterResponse(httpResponse(accepted))
} else {
const secret = informationUser.TEMPLATE.SUNSTONE[default2FAOpennebulaVar]
if (!check2Fa(secret, tfatoken)) {
updaterResponse(httpResponse(unauthorized, '', 'invalid 2fa token'))
} else {
rtn = true
}
}
} else {
/*********************************************************
* Without 2FA
*********************************************************/
rtn = true
}
return rtn
}
/**
* Generate a JWT.
*
* @param {string} token - opennebula token
* @param {object} informationUser - user data
*/
const genJWT = (token, informationUser) => {
if (
token &&
token.token &&
token.time &&
informationUser &&
informationUser.ID &&
informationUser.NAME
) {
const { ID: id, TEMPLATE: userTemplate, NAME: username } = informationUser
const dataJWT = { id, user: username, token: token.token }
const expire = token.time || expireTime.toSeconds()
const jwt = createJWT(dataJWT, nowUnix, expire)
if (jwt) {
const rtn = { token: jwt, id }
if (userTemplate && userTemplate.SUNSTONE && userTemplate.SUNSTONE.LANG) {
rtn.language = userTemplate.SUNSTONE.LANG
}
updaterResponse(httpResponse(ok, rtn))
}
}
}
/**
* Get created user tokens.
*
* @param {string} username - username
* @returns {object} - user token
*/
const getCreatedTokenOpennebula = (username = '') => {
if (
global &&
global.users &&
username &&
global.users[username] &&
global.users[username].tokens
) {
let acc = { token: '', time: 0 }
global.users[username].tokens.forEach((curr = {}, index = 0) => {
const currentTime = parseInt(curr.time, 10)
// this delete expired tokens of global.users[username]
if (currentTime < nowUnix) {
delete global.users[username].tokens[index]
}
// this select a valid token
if (
DateTime.fromSeconds(currentTime).minus({
minutes: limitExpirationReuseToken,
}) >= now &&
currentTime >= acc.time
) {
acc = { token: curr.token, time: curr.time }
}
})
if (acc.token && acc.time) {
return acc
}
}
}
/**
* Get zones.
*/
const setZones = () => {
if (global && !global.zones) {
const oneConnect = connectOpennebula()
oneConnect(
ActionZones.ZONEPOOL_INFO,
getDefaultParamsOfOpennebulaCommand(ActionZones.ZONEPOOL_INFO, GET),
(err, value) => {
// res, err, value, response, next
responseOpennebula(
() => undefined,
err,
value,
(zonesOpennebula) => {
if (
zonesOpennebula &&
zonesOpennebula.ZONE_POOL &&
zonesOpennebula.ZONE_POOL.ZONE
) {
const oneZones = !Array.isArray(zonesOpennebula.ZONE_POOL.ZONE)
? [zonesOpennebula.ZONE_POOL.ZONE]
: zonesOpennebula.ZONE_POOL.ZONE
global.zones = oneZones.map((oneZone) => {
const rpc =
(oneZone && oneZone.TEMPLATE && oneZone.TEMPLATE.ENDPOINT) ||
''
const parsedURL = rpc && parse(rpc)
const parsedHost = parsedURL.hostname || ''
return {
id: oneZone.ID || '',
name: oneZone.NAME || '',
rpc: rpc,
zeromq: `tcp://${parsedHost}:2101`,
}
})
}
},
next
)
},
false
)
}
}
/**
* Create token server admin.
*
* @param {string} serverAdmin - serveradmin name
* @param {string} username - user name
* @returns {string} data encrypted serveradmin
*/
const createTokenServerAdmin = (serverAdmin = '', username = '') => {
let rtn
const keyGet = getKey()
const ivGet = getIV()
if (serverAdmin && username && key && iv) {
const expire = parseInt(expireTime.toSeconds(), 10)
rtn = {
token: encrypt(`${serverAdmin}:${username}:${expire}`, keyGet, ivGet),
time: expire,
}
}
return rtn
}
/**
* Wrap user with serveradmin.
*
* @param {object} serverAdminData - opennebula serveradmin data
* @param {object} userData - opennebula user data
*/
const wrapUserWithServerAdmin = (serverAdminData = {}, userData = {}) => {
let serverAdminName = ''
let serverAdminPassword = ''
let userName = ''
if (
getRelativeTime() &&
serverAdminData &&
serverAdminData.USER &&
(serverAdminName = serverAdminData.USER.NAME) &&
(serverAdminPassword = serverAdminData.USER.PASSWORD) &&
userData &&
(userName = userData.NAME) &&
userData.ID &&
userData.TEMPLATE
) {
/*********************************************************
* equals what is placed in:
* src/authm_mad/remotes/server_cipher/server_cipher_auth.rb:44
*********************************************************/
setKey(serverAdminPassword.substring(0, 32))
setIV(serverAdminPassword.substring(0, 16))
const JWTusername = `${serverAdminName}:${userName}`
let tokenWithServerAdmin
let setGlobalNewToken = false
const validToken = getCreatedTokenOpennebula(JWTusername)
if (validToken) {
tokenWithServerAdmin = validToken
} else {
setGlobalNewToken = true
tokenWithServerAdmin = createTokenServerAdmin(serverAdminName, userName)
}
if (tokenWithServerAdmin) {
genJWT(tokenWithServerAdmin, {
NAME: JWTusername,
ID: userData.ID,
TEMPLATE: userData.TEMPLATE,
})
// set global state
if (setGlobalNewToken) {
if (!global.users) {
global.users = {}
}
if (!global.users[JWTusername]) {
global.users[JWTusername] = { tokens: [] }
}
global.users[JWTusername].tokens.push({
token: tokenWithServerAdmin.token,
time: parseInt(expireTime.toSeconds(), 10),
})
}
next()
}
} else {
updaterResponse(httpResponse(internalServerError))
next()
}
}
/**
* Get server admin and wrap user.
*
* @param {object} userData - opennebula user data
*/
const getServerAdminAndWrapUser = (userData = {}) => {
const serverAdminData = getSunstoneAuth()
if (
serverAdminData &&
serverAdminData.username &&
serverAdminData.key &&
serverAdminData.iv
) {
setKey(serverAdminData.key)
setIV(serverAdminData.iv)
const tokenWithServerAdmin = createTokenServerAdmin(
serverAdminData.username,
serverAdminData.username
)
if (tokenWithServerAdmin.token) {
const oneConnect = connectOpennebula(
`${serverAdminData.username}:${serverAdminData.username}`,
tokenWithServerAdmin.token
)
oneConnect(
ActionUsers.USER_INFO,
getDefaultParamsOfOpennebulaCommand(ActionUsers.USER_INFO, GET),
(err, value) => {
responseOpennebula(
updaterResponse,
err,
value,
(serverAdmin = {}) =>
wrapUserWithServerAdmin(serverAdmin, userData),
next
)
},
false
)
}
}
}
/**
* Login route function.
*
* @param {object} userData - opennebula user data
*/
const login = (userData) => {
let rtn = false
if (userData) {
const findTextError = `[${namespace}.${ActionUsers.USER_INFO}]`
if (userData.indexOf && userData.indexOf(findTextError) >= 0) {
updaterResponse(httpResponse(unauthorized))
} else {
rtn = true
}
if (userData.USER) {
setZones()
if (validate2faAuthentication(userData.USER)) {
rtn = false
setDates()
getServerAdminAndWrapUser(userData.USER)
}
}
}
if (rtn) {
next()
}
}
const functionRoutes = {
login,
getUser,
getPass,
setType,
setUser,
setPass,
setType,
setTfaToken,
setRemember,
setNext,
setReq,
setRes,
updaterResponse,
setNodeConnect,
connectOpennebula,
getCreatedTokenOpennebula,
updaterResponse,
} = require('server/routes/api/auth/utils')
const {
internalServerError,
unauthorized,
} = require('server/utils/constants/http-codes')
const { Actions } = require('server/utils/constants/commands/user')
const {
httpMethod,
defaultEmptyFunction,
} = require('server/utils/constants/defaults')
const { GET } = httpMethod
const {
getDefaultParamsOfOpennebulaCommand,
} = require('server/utils/opennebula')
const { writeInLogger } = require('server/utils/logger')
/**
* Login user.
*
* @param {error} err - run if no have user data
* @param {string} value - opennebula information
* @param {Function} success - success
* @param {Function} error - error
*/
const loginUser = (
err = '',
value = '',
success = defaultEmptyFunction,
error = defaultEmptyFunction
) => {
if (value && value.USER && !err) {
success(value)
} else {
error()
}
}
module.exports = functionRoutes
/**
* Fireedge user auth.
*
* @param {object} res - http response
* @param {Function} next - express stepper
* @param {object} params - params of http request
* @param {object} userData - user of http request
* @param {Function} oneConnection - function of xmlrpc
*/
const auth = (
res = {},
next = defaultEmptyFunction,
params = {},
userData = {},
oneConnection = defaultEmptyFunction
) => {
const { user, token, type, token2fa, remember } = params
setRes(res)
setNext(next)
setNodeConnect(oneConnection)
updaterResponse(new Map(internalServerError).toObject())
if (user && token) {
const oneConnect = connectOpennebula(user, token)
/**
* Run if have information.
*
* @param {object} oneValue - opennebula value
*/
const success = (oneValue) => {
setUser(user || '')
setPass(token || '')
setType(type || '')
setTfaToken(token2fa || '')
setRemember(remember || false)
login(oneValue)
}
/**
* Run if no have information.
*/
const error = () => {
updaterResponse(new Map(unauthorized).toObject())
writeInLogger(unauthorized)
next()
}
oneConnect(
Actions.USER_INFO,
getDefaultParamsOfOpennebulaCommand(Actions.USER_INFO, GET),
(err, value) => {
loginUser(err, value, success, error)
},
false
)
} else {
next()
}
}
const authApi = {
auth,
}
module.exports = authApi

View File

@ -15,8 +15,8 @@
* ------------------------------------------------------------------------- */
const { setApiRoutes } = require('server/utils/server')
const { routes: authRoutes } = require('./auth')
const { AUTH } = require('./string-routes')
const { routes: authRoutes } = require('server/routes/api/auth/routes')
const { AUTH } = require('server/routes/api/auth/string-routes')
const functionRoutes = {
private: [],

View File

@ -18,7 +18,7 @@ const {
httpMethod,
from: fromData,
} = require('server/utils/constants/defaults')
const { auth } = require('./auth-functions')
const { auth } = require('server/routes/api/auth/functions')
const { POST } = httpMethod
const routes = {

View File

@ -0,0 +1,624 @@
/* ------------------------------------------------------------------------- *
* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may *
* not use this file except in compliance with the License. You may obtain *
* a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
const { DateTime } = require('luxon')
// eslint-disable-next-line node/no-deprecated-api
const { parse } = require('url')
const { global, Array } = require('window-or-global')
const { Actions: ActionUsers } = require('server/utils/constants/commands/user')
const { Actions: ActionZones } = require('server/utils/constants/commands/zone')
const {
httpMethod,
defaultSessionExpiration,
default2FAOpennebulaVar,
defaultNamespace,
defaultEmptyFunction,
defaultSessionLimitExpiration,
defaultRememberSessionExpiration,
} = require('server/utils/constants/defaults')
const { getFireedgeConfig } = require('server/utils/yml')
const {
ok,
unauthorized,
accepted,
internalServerError,
} = require('server/utils/constants/http-codes')
const { createJWT, check2Fa } = require('server/utils/jwt')
const {
httpResponse,
encrypt,
getSunstoneAuth,
} = require('server/utils/server')
const {
responseOpennebula,
getDefaultParamsOfOpennebulaCommand,
} = require('server/utils/opennebula')
const appConfig = getFireedgeConfig()
const namespace = appConfig.namespace || defaultNamespace
const { GET } = httpMethod
let user = ''
let key = ''
let iv = ''
let pass = ''
let type = ''
let tfatoken = ''
let remember = false
let next = defaultEmptyFunction
let req = {}
let res = {}
let nodeConnect = defaultEmptyFunction
let now = ''
let nowUnix = ''
let expireTime = ''
let relativeTime = ''
let limitToken = defaultSessionExpiration
let limitExpirationReuseToken = defaultSessionLimitExpiration
/**
* Get key opennebula.
*
* @returns {string} get key
*/
const getKey = () => key
/**
* Get initialization vector.
*
* @returns {string} get initialization vector
*/
const getIV = () => iv
/**
* Get user opennebula.
*
* @returns {string} user opennebula
*/
const getUser = () => user
/**
* Get user password opennebula.
*
* @returns {string} get password user opennebula
*/
const getPass = () => pass
/**
* Get relative time.
*
* @returns {string} date
*/
const getRelativeTime = () => relativeTime
/**
* Opennebula encode-decode key.
*
* @param {string} newKey - new key
* @returns {string} get key
*/
const setKey = (newKey) => {
key = newKey
return key
}
/**
* Initialization vector (encrypt).
*
* @param {string} newIV - //16 characters
* @returns {string} get IV
*/
const setIV = (newIV) => {
iv = newIV
return iv
}
/**
* Username opennebula.
*
* @param {string} newUser - new user data
* @returns {string} get user
*/
const setUser = (newUser) => {
user = newUser
return user
}
/**
* User password opennebula.
*
* @param {string} newPass - set new opennebula password user
* @returns {string} password user
*/
const setPass = (newPass) => {
pass = newPass
return pass
}
/**
* Type app.
*
* @param {string} newtype - new type (application)
* @returns {string} get type
*/
const setType = (newtype) => {
type = newtype
return type
}
/**
* Set 2FA token.
*
* @param {string} newTfaToken - new TFA token
* @returns {string} get TFA token
*/
const setTfaToken = (newTfaToken) => {
tfatoken = newTfaToken
return tfatoken
}
/**
* Set remember.
*
* @param {boolean} newRemember - new remember
* @returns {boolean} remember
*/
const setRemember = (newRemember) => {
remember = newRemember
return remember
}
/**
* Set express stepper.
*
* @param {Function} newNext - new stepper
* @returns {Function} http response
*/
const setNext = (newNext = defaultEmptyFunction) => {
next = newNext
return next
}
/**
* Set http resquest.
*
* @param {object} newReq - new request
* @returns {object} http resquest
*/
const setReq = (newReq = {}) => {
req = newReq
return req
}
/**
* Set xlmrpc connection function.
*
* @param {Function} newConnect - new connect opennebula
* @returns {Function} xmlrpc function
*/
const setNodeConnect = (newConnect = defaultEmptyFunction) => {
nodeConnect = newConnect
return nodeConnect
}
/**
* Set http response.
*
* @param {object} newRes - new response
* @returns {object} http response
*/
const setRes = (newRes = {}) => {
res = newRes
return res
}
/**
* Set dates.
*/
const setDates = () => {
limitToken = remember
? appConfig.session__remember_expiration || defaultRememberSessionExpiration
: appConfig.session_expiration || defaultSessionExpiration
limitExpirationReuseToken =
parseInt(appConfig.session_reuse_token_time, 10) ||
defaultSessionLimitExpiration
now = DateTime.local()
nowUnix = now.toSeconds()
expireTime = now.plus({ minutes: limitToken })
const diff = expireTime.diff(now, 'seconds')
relativeTime = diff.seconds
}
/**
* Connect to function xmlrpc.
*
* @param {string} usr - user
* @param {string} pss - password
* @returns {Function} xmlrpc function
*/
const connectOpennebula = (usr = '', pss = '') => {
const connectUser = usr || user
const connectPass = pss || pass
return nodeConnect(connectUser, connectPass)
}
/**
* Updater http request.
*
* @param {string} code - http code
*/
const updaterResponse = (code) => {
if (
'id' in code &&
'message' in code &&
res &&
res.locals &&
res.locals.httpCode
) {
res.locals.httpCode = code
}
}
/**
* Validate 2FA.
*
* @param {object} informationUser - user data
* @returns {boolean} return if data is valid
*/
const validate2faAuthentication = (informationUser) => {
let rtn = false
if (
informationUser.TEMPLATE &&
informationUser.TEMPLATE.SUNSTONE &&
informationUser.TEMPLATE.SUNSTONE[default2FAOpennebulaVar]
) {
/*********************************************************
* Validate 2FA
*********************************************************/
if (tfatoken.length <= 0) {
updaterResponse(httpResponse(accepted))
} else {
const secret = informationUser.TEMPLATE.SUNSTONE[default2FAOpennebulaVar]
if (!check2Fa(secret, tfatoken)) {
updaterResponse(httpResponse(unauthorized, '', 'invalid 2fa token'))
} else {
rtn = true
}
}
} else {
/*********************************************************
* Without 2FA
*********************************************************/
rtn = true
}
return rtn
}
/**
* Generate a JWT.
*
* @param {string} token - opennebula token
* @param {object} informationUser - user data
*/
const genJWT = (token, informationUser) => {
if (
token &&
token.token &&
token.time &&
informationUser &&
informationUser.ID &&
informationUser.NAME
) {
const { ID: id, TEMPLATE: userTemplate, NAME: username } = informationUser
const dataJWT = { id, user: username, token: token.token }
const expire = token.time || expireTime.toSeconds()
const jwt = createJWT(dataJWT, nowUnix, expire)
if (jwt) {
const rtn = { token: jwt, id }
if (userTemplate && userTemplate.SUNSTONE && userTemplate.SUNSTONE.LANG) {
rtn.language = userTemplate.SUNSTONE.LANG
}
updaterResponse(httpResponse(ok, rtn))
}
}
}
/**
* Get created user tokens.
*
* @param {string} username - username
* @returns {object} - user token
*/
const getCreatedTokenOpennebula = (username = '') => {
if (
global &&
global.users &&
username &&
global.users[username] &&
global.users[username].tokens
) {
let acc = { token: '', time: 0 }
global.users[username].tokens.forEach((curr = {}, index = 0) => {
const currentTime = parseInt(curr.time, 10)
// this delete expired tokens of global.users[username]
if (currentTime < nowUnix) {
delete global.users[username].tokens[index]
}
// this select a valid token
if (
DateTime.fromSeconds(currentTime).minus({
minutes: limitExpirationReuseToken,
}) >= now &&
currentTime >= acc.time
) {
acc = { token: curr.token, time: curr.time }
}
})
if (acc.token && acc.time) {
return acc
}
}
}
/**
* Get zones.
*/
const setZones = () => {
if (global && !global.zones) {
const oneConnect = connectOpennebula()
oneConnect(
ActionZones.ZONEPOOL_INFO,
getDefaultParamsOfOpennebulaCommand(ActionZones.ZONEPOOL_INFO, GET),
(err, value) => {
// res, err, value, response, next
responseOpennebula(
() => undefined,
err,
value,
(zonesOpennebula) => {
if (
zonesOpennebula &&
zonesOpennebula.ZONE_POOL &&
zonesOpennebula.ZONE_POOL.ZONE
) {
const oneZones = !Array.isArray(zonesOpennebula.ZONE_POOL.ZONE)
? [zonesOpennebula.ZONE_POOL.ZONE]
: zonesOpennebula.ZONE_POOL.ZONE
global.zones = oneZones.map((oneZone) => {
const rpc =
(oneZone && oneZone.TEMPLATE && oneZone.TEMPLATE.ENDPOINT) ||
''
const parsedURL = rpc && parse(rpc)
const parsedHost = parsedURL.hostname || ''
return {
id: oneZone.ID || '',
name: oneZone.NAME || '',
rpc: rpc,
zeromq: `tcp://${parsedHost}:2101`,
}
})
}
},
next
)
},
false
)
}
}
/**
* Create token server admin.
*
* @param {string} serverAdmin - serveradmin name
* @param {string} username - user name
* @returns {string} data encrypted serveradmin
*/
const createTokenServerAdmin = (serverAdmin = '', username = '') => {
let rtn
const keyGet = getKey()
const ivGet = getIV()
if (serverAdmin && username && key && iv) {
const expire = parseInt(expireTime.toSeconds(), 10)
rtn = {
token: encrypt(`${serverAdmin}:${username}:${expire}`, keyGet, ivGet),
time: expire,
}
}
return rtn
}
/**
* Wrap user with serveradmin.
*
* @param {object} serverAdminData - opennebula serveradmin data
* @param {object} userData - opennebula user data
*/
const wrapUserWithServerAdmin = (serverAdminData = {}, userData = {}) => {
let serverAdminName = ''
let serverAdminPassword = ''
let userName = ''
if (
getRelativeTime() &&
serverAdminData &&
serverAdminData.USER &&
(serverAdminName = serverAdminData.USER.NAME) &&
(serverAdminPassword = serverAdminData.USER.PASSWORD) &&
userData &&
(userName = userData.NAME) &&
userData.ID &&
userData.TEMPLATE
) {
/*********************************************************
* equals what is placed in:
* src/authm_mad/remotes/server_cipher/server_cipher_auth.rb:44
*********************************************************/
setKey(serverAdminPassword.substring(0, 32))
setIV(serverAdminPassword.substring(0, 16))
const JWTusername = `${serverAdminName}:${userName}`
let tokenWithServerAdmin
let setGlobalNewToken = false
const validToken = getCreatedTokenOpennebula(JWTusername)
if (validToken) {
tokenWithServerAdmin = validToken
} else {
setGlobalNewToken = true
tokenWithServerAdmin = createTokenServerAdmin(serverAdminName, userName)
}
if (tokenWithServerAdmin) {
genJWT(tokenWithServerAdmin, {
NAME: JWTusername,
ID: userData.ID,
TEMPLATE: userData.TEMPLATE,
})
// set global state
if (setGlobalNewToken) {
if (!global.users) {
global.users = {}
}
if (!global.users[JWTusername]) {
global.users[JWTusername] = { tokens: [] }
}
global.users[JWTusername].tokens.push({
token: tokenWithServerAdmin.token,
time: parseInt(expireTime.toSeconds(), 10),
})
}
next()
}
} else {
updaterResponse(httpResponse(internalServerError))
next()
}
}
/**
* Get server admin and wrap user.
*
* @param {object} userData - opennebula user data
*/
const getServerAdminAndWrapUser = (userData = {}) => {
const serverAdminData = getSunstoneAuth()
if (
serverAdminData &&
serverAdminData.username &&
serverAdminData.key &&
serverAdminData.iv
) {
setKey(serverAdminData.key)
setIV(serverAdminData.iv)
const tokenWithServerAdmin = createTokenServerAdmin(
serverAdminData.username,
serverAdminData.username
)
if (tokenWithServerAdmin.token) {
const oneConnect = connectOpennebula(
`${serverAdminData.username}:${serverAdminData.username}`,
tokenWithServerAdmin.token
)
oneConnect(
ActionUsers.USER_INFO,
getDefaultParamsOfOpennebulaCommand(ActionUsers.USER_INFO, GET),
(err, value) => {
responseOpennebula(
updaterResponse,
err,
value,
(serverAdmin = {}) =>
wrapUserWithServerAdmin(serverAdmin, userData),
next
)
},
false
)
}
}
}
/**
* Login route function.
*
* @param {object} userData - opennebula user data
*/
const login = (userData) => {
let rtn = false
if (userData) {
const findTextError = `[${namespace}.${ActionUsers.USER_INFO}]`
if (userData.indexOf && userData.indexOf(findTextError) >= 0) {
updaterResponse(httpResponse(unauthorized))
} else {
rtn = true
}
if (userData.USER) {
setZones()
if (validate2faAuthentication(userData.USER)) {
rtn = false
setDates()
getServerAdminAndWrapUser(userData.USER)
}
}
}
if (rtn) {
next()
}
}
const functionRoutes = {
login,
getUser,
getPass,
setType,
setUser,
setPass,
setTfaToken,
setRemember,
setNext,
setReq,
setRes,
updaterResponse,
setNodeConnect,
connectOpennebula,
getCreatedTokenOpennebula,
}
module.exports = functionRoutes

View File

@ -18,8 +18,8 @@ const { setApiRoutes } = require('server/utils/server')
const {
privateRoutes: filePrivateRoutes,
publicRoutes: filePublicRoutes,
} = require('./files')
const { FILES } = require('./string-routes')
} = require('server/routes/api/files/routes')
const { FILES } = require('server/routes/api/files/string-routes')
const functionRoutes = {
private: setApiRoutes(filePrivateRoutes, FILES),

View File

@ -18,7 +18,13 @@ const {
from: fromData,
httpMethod,
} = require('server/utils/constants/defaults')
const { show, list, upload, update, deleteFile } = require('./functions')
const {
show,
list,
upload,
update,
deleteFile,
} = require('server/routes/api/files/functions')
const { GET, POST, PUT, DELETE } = httpMethod
const publicRoutes = {

View File

@ -14,35 +14,37 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
const { readdirSync } = require('fs-extra')
const { resolve } = require('path')
const { messageTerminal } = require('server/utils/general')
const { getRouteForOpennebulaCommand } = require('server/utils/opennebula')
const {
defaultFilesRoutes,
defaultConfigErrorMessage,
} = require('server/utils/constants/defaults')
const { defaultConfigErrorMessage } = require('server/utils/constants/defaults')
const filesDataPrivate = []
const filesDataPublic = []
defaultFilesRoutes.forEach((file) => {
try {
// eslint-disable-next-line global-require
const fileInfo = require(`./${file}`)
readdirSync(resolve(__dirname), { withFileTypes: true })
.filter((dirent) => dirent.isDirectory())
.forEach((file) => {
try {
const { name } = file
// eslint-disable-next-line global-require
const fileInfo = require(`./${name}`)
if (fileInfo.private && fileInfo.private.length) {
filesDataPrivate.push(...fileInfo.private)
if (fileInfo.private && fileInfo.private.length) {
filesDataPrivate.push(...fileInfo.private)
}
if (fileInfo.public && fileInfo.public.length) {
filesDataPublic.push(...fileInfo.public)
}
} catch (error) {
if (error instanceof Error && error.code === 'MODULE_NOT_FOUND') {
const config = defaultConfigErrorMessage
config.error = error.message
messageTerminal(config)
}
}
if (fileInfo.public && fileInfo.public.length) {
filesDataPublic.push(...fileInfo.public)
}
} catch (error) {
if (error instanceof Error && error.code === 'MODULE_NOT_FOUND') {
const config = defaultConfigErrorMessage
config.error = error.message
messageTerminal(config)
}
}
})
})
const opennebulaActions = getRouteForOpennebulaCommand()
const routes = {

View File

@ -15,7 +15,9 @@
* ------------------------------------------------------------------------- */
const { setApiRoutes } = require('server/utils/server')
const { routes: marketappRoutes } = require('./marketapp')
const {
routes: marketappRoutes,
} = require('server/routes/api/marketapp/routes')
const { MARKETAPP } = require('./string-routes')
const functionRoutes = {

View File

@ -18,7 +18,11 @@ const {
httpMethod,
from: fromData,
} = require('server/utils/constants/defaults')
const { exportApp, importMarket, getDockerTags } = require('./functions')
const {
exportApp,
importMarket,
getDockerTags,
} = require('server/routes/api/marketapp/functions')
const { POST, GET } = httpMethod
const routes = {

View File

@ -16,7 +16,7 @@
const { setApiRoutes } = require('server/utils/server')
const { routes: serviceRoutes } = require('./service')
const { routes: serviceTemplateRoutes } = require('./service_template')
const { routes: serviceTemplateRoutes } = require('./template')
const { SERVICE, SERVICE_TEMPLATE } = require('./string-routes')

View File

@ -15,8 +15,11 @@
* ------------------------------------------------------------------------- */
const { Validator } = require('jsonschema')
const { action } = require('./schemas')
const { oneFlowConnection } = require('./functions')
const { action } = require('server/routes/api/oneflow/schemas')
const {
oneFlowConnection,
returnSchemaError,
} = require('server/routes/api/oneflow/utils')
const {
httpMethod,
defaultEmptyFunction,
@ -27,7 +30,6 @@ const {
internalServerError,
methodNotAllowed,
} = require('server/utils/constants/http-codes')
const { returnSchemaError } = require('./functions')
const { generateNewResourceTemplate } = require('server/utils/opennebula')
const { Actions: ActionVM } = require('server/utils/constants/commands/vm')
const { GET, POST, DELETE } = httpMethod
@ -312,7 +314,7 @@ const serviceAddRoleAction = (
path: '/service/{0}/role/{1}',
user,
password,
request: [role, id],
request: [id, role],
post: postAction,
}
oneFlowConnection(

View File

@ -27,15 +27,15 @@ const {
serviceAddSchedAction,
serviceUpdateSchedAction,
serviceDeleteSchedAction,
} = require('./service-functions')
} = require('server/routes/api/oneflow/service/functions')
const { GET, POST, DELETE, PUT } = httpMethod
const routes = {
[GET]: {
list: {
null: {
action: service,
params: {
id: { from: fromData.resource, name: 'id' },
id: { from: fromData.resource, name: 'method' },
},
},
},
@ -54,11 +54,11 @@ const routes = {
action: { from: fromData.postBody },
},
},
'role-action': {
role_action: {
action: serviceAddRoleAction,
params: {
role: { from: fromData.resource, name: 'id' },
id: { from: fromData.resource, name: 'id2' },
id: { from: fromData.resource, name: 'id' },
role: { from: fromData.resource, name: 'id2' },
action: { from: fromData.postBody },
},
},
@ -81,15 +81,15 @@ const routes = {
},
},
[DELETE]: {
delete: {
null: {
action: serviceDelete,
params: { id: { from: fromData.resource, name: 'id', front: true } },
params: { id: { from: fromData.resource, name: 'method' } },
},
sched_action: {
action: serviceDeleteSchedAction,
params: {
id: { from: fromData.resource, name: 'id' },
id_sched: { from: fromData.resource, name: 'id2' },
id: { from: fromData.resource, name: 'method' },
id_sched: { from: fromData.resource, name: 'id' },
},
},
},

View File

@ -15,8 +15,11 @@
* ------------------------------------------------------------------------- */
const { Validator } = require('jsonschema')
const { role, service, action } = require('./schemas')
const { oneFlowConection } = require('./functions')
const { role, service, action } = require('server/routes/api/oneflow/schemas')
const {
oneFlowConection,
returnSchemaError,
} = require('server/routes/api/oneflow/utils')
const {
httpMethod,
defaultEmptyFunction,
@ -27,7 +30,6 @@ const {
internalServerError,
methodNotAllowed,
} = require('server/utils/constants/http-codes')
const { returnSchemaError } = require('./functions')
const { GET, POST, DELETE, PUT } = httpMethod
/**

View File

@ -24,47 +24,47 @@ const {
serviceTemplateCreate,
serviceTemplateUpdate,
serviceTemplateAction,
} = require('./service_template-functions')
} = require('server/routes/api/oneflow/template/functions')
const { GET, POST, DELETE, PUT } = httpMethod
const routes = {
[GET]: {
list: {
null: {
action: serviceTemplate,
params: {
id: { from: fromData.resource, name: 'id', front: true },
id: { from: fromData.resource, name: 'method' },
},
},
},
[POST]: {
create: {
null: {
action: serviceTemplateCreate,
params: {
template: { from: fromData.postBody, front: true },
template: { from: fromData.postBody },
},
},
action: {
action: serviceTemplateAction,
params: {
id: { from: fromData.resource, name: 'id', front: true },
template: { from: fromData.postBody, front: true },
id: { from: fromData.resource, name: 'id' },
template: { from: fromData.postBody },
},
},
},
[PUT]: {
update: {
null: {
action: serviceTemplateUpdate,
params: {
id: { from: fromData.resource, name: 'id', front: true },
template: { from: fromData.postBody, front: true },
id: { from: fromData.resource, name: 'method' },
template: { from: fromData.postBody },
},
},
},
[DELETE]: {
delete: {
null: {
action: serviceTemplateDelete,
params: {
id: { from: fromData.resource, name: 'id', front: true },
id: { from: fromData.resource, name: 'method' },
},
},
},

View File

@ -15,11 +15,21 @@
* ------------------------------------------------------------------------- */
const { setApiRoutes } = require('server/utils/server')
const { routes: provisionRoutes } = require('./provision')
const { routes: provisionTemplateRoutes } = require('./provision_template')
const { routes: providerRoutes } = require('./provider')
const {
routes: provisionRoutes,
} = require('server/routes/api/oneprovision/provision')
const {
routes: provisionTemplateRoutes,
} = require('server/routes/api/oneprovision/template')
const {
routes: providerRoutes,
} = require('server/routes/api/oneprovision/provider')
const { PROVIDER, PROVISION, PROVISION_TEMPLATE } = require('./string-routes')
const {
PROVIDER,
PROVISION,
PROVISION_TEMPLATE,
} = require('server/routes/api/oneprovision/string-routes')
/**
* Add routes.

View File

@ -39,7 +39,7 @@ const {
createYMLContent,
getEndpoint,
getSpecificConfig,
} = require('./functions')
} = require('server/routes/api/oneprovision/utils')
const httpInternalError = httpResponse(internalServerError, '', '')

View File

@ -14,7 +14,10 @@
* limitations under the License. *
* ------------------------------------------------------------------------- */
const { from: fromData } = require('server/utils/constants/defaults')
const {
from: fromData,
httpMethod,
} = require('server/utils/constants/defaults')
const {
getListProviders,
getConnectionProviders,
@ -22,23 +25,22 @@ const {
updateProviders,
deleteProvider,
getProviderConfig,
} = require('./provider-functions')
const { httpMethod } = require('server/utils/constants/defaults')
} = require('server/routes/api/oneprovision/provider/functions')
const { GET, POST, PUT, DELETE } = httpMethod
const routes = {
[GET]: {
list: {
null: {
action: getListProviders,
params: {
id: { from: fromData.resource, name: 'id', front: true },
id: { from: fromData.resource, name: 'method' },
},
},
connection: {
action: getConnectionProviders,
params: {
id: { from: fromData.resource, name: 'id', front: true },
id: { from: fromData.resource, name: 'id' },
},
},
config: {
@ -47,27 +49,27 @@ const routes = {
},
},
[POST]: {
create: {
null: {
action: createProviders,
params: {
resource: { from: fromData.postBody, front: true },
resource: { from: fromData.postBody },
},
},
},
[PUT]: {
update: {
null: {
action: updateProviders,
params: {
resource: { from: fromData.postBody, front: true },
id: { from: fromData.resource, name: 'id', front: true },
resource: { from: fromData.postBody },
id: { from: fromData.resource, name: 'method' },
},
},
},
[DELETE]: {
delete: {
null: {
action: deleteProvider,
params: {
id: { from: fromData.resource, name: 'id', front: true },
id: { from: fromData.resource, name: 'method' },
},
},
},

View File

@ -58,8 +58,8 @@ const {
getEndpoint,
addOptionalCreateCommand,
getSpecificConfig,
} = require('./functions')
const { provision } = require('./schemas')
} = require('server/routes/api/oneprovision/utils')
const { provision } = require('server/routes/api/oneprovision/schemas')
const httpInternalError = httpResponse(internalServerError, '', '')

View File

@ -31,63 +31,63 @@ const {
configureHost,
validate,
getProvisionDefaults,
} = require('./provision-functions')
} = require('server/routes/api/oneprovision/provision/functions')
const { GET, POST, DELETE, PUT } = httpMethod
const routes = {
[GET]: {
list: {
null: {
action: getListProvisions,
params: {
id: { from: fromData.resource, name: 'id', front: true },
id: { from: fromData.resource, name: 'method' },
},
},
cluster: {
action: getListResourceProvision,
params: {
resource: { from: fromData.resource, name: 'method' },
resource: { from: fromData.resource, name: 'id' },
},
},
datastore: {
action: getListResourceProvision,
params: {
resource: { from: fromData.resource, name: 'method' },
resource: { from: fromData.resource, name: 'id' },
},
},
host: {
action: getListResourceProvision,
params: {
resource: { from: fromData.resource, name: 'method' },
resource: { from: fromData.resource, name: 'id' },
},
},
image: {
action: getListResourceProvision,
params: {
resource: { from: fromData.resource, name: 'method' },
resource: { from: fromData.resource, name: 'id' },
},
},
network: {
action: getListResourceProvision,
params: {
resource: { from: fromData.resource, name: 'method' },
resource: { from: fromData.resource, name: 'id' },
},
},
template: {
action: getListResourceProvision,
params: {
resource: { from: fromData.resource, name: 'method' },
resource: { from: fromData.resource, name: 'id' },
},
},
vntemplate: {
action: getListResourceProvision,
params: {
resource: { from: fromData.resource, name: 'method' },
resource: { from: fromData.resource, name: 'id' },
},
},
log: {
action: getLogProvisions,
params: {
id: { from: fromData.resource, name: 'id', front: true },
id: { from: fromData.resource, name: 'id' },
},
},
defaults: {
@ -96,17 +96,17 @@ const routes = {
},
},
[POST]: {
create: {
null: {
action: createProvision,
params: {
resource: { from: fromData.postBody, front: true },
resource: { from: fromData.postBody },
},
websocket: true,
},
validate: {
action: validate,
params: {
resource: { from: fromData.postBody, front: true },
resource: { from: fromData.postBody },
},
},
host: {
@ -114,39 +114,39 @@ const routes = {
action: hostCommand,
params: {
action: { from: fromData.resource, name: 'id' },
id: { from: fromData.resource, name: 'id2', front: true },
id: { from: fromData.resource, name: 'id2' },
},
},
reboot: {
action: hostCommand,
params: {
action: { from: fromData.resource, name: 'id' },
id: { from: fromData.resource, name: 'id2', front: true },
id: { from: fromData.resource, name: 'id2' },
},
},
resume: {
action: hostCommand,
params: {
action: { from: fromData.resource, name: 'id' },
id: { from: fromData.resource, name: 'id2', front: true },
id: { from: fromData.resource, name: 'id2' },
},
},
ssh: {
action: hostCommandSSH,
params: {
action: { from: fromData.resource, name: 'id' },
id: { from: fromData.resource, name: 'id2', front: true },
command: { from: fromData.postBody, name: 'command', front: true },
id: { from: fromData.resource, name: 'id2' },
command: { from: fromData.postBody, name: 'command' },
},
},
},
},
[DELETE]: {
delete: {
null: {
action: deleteProvision,
params: {
id: { from: fromData.resource, name: 'id', front: true },
cleanup: { from: fromData.postBody, name: 'cleanup', front: true },
id: { from: fromData.resource, name: 'method' },
cleanup: { from: fromData.postBody, name: 'cleanup' },
},
websocket: true,
},
@ -154,56 +154,56 @@ const routes = {
action: deleteResource,
params: {
resource: { from: fromData.resource, name: 'method' },
id: { from: fromData.resource, name: 'id', front: true },
id: { from: fromData.resource, name: 'id' },
},
},
flowtemplate: {
action: deleteResource,
params: {
resource: { from: fromData.resource, name: 'method' },
id: { from: fromData.resource, name: 'id', front: true },
id: { from: fromData.resource, name: 'id' },
},
},
host: {
action: deleteResource,
params: {
resource: { from: fromData.resource, name: 'method' },
id: { from: fromData.resource, name: 'id', front: true },
id: { from: fromData.resource, name: 'id' },
},
},
image: {
action: deleteResource,
params: {
resource: { from: fromData.resource, name: 'method' },
id: { from: fromData.resource, name: 'id', front: true },
id: { from: fromData.resource, name: 'id' },
},
},
network: {
action: deleteResource,
params: {
resource: { from: fromData.resource, name: 'method' },
id: { from: fromData.resource, name: 'id', front: true },
id: { from: fromData.resource, name: 'id' },
},
},
vntemplate: {
action: deleteResource,
params: {
resource: { from: fromData.resource, name: 'method' },
id: { from: fromData.resource, name: 'id', front: true },
id: { from: fromData.resource, name: 'id' },
},
},
template: {
action: deleteResource,
params: {
resource: { from: fromData.resource, name: 'method' },
id: { from: fromData.resource, name: 'id', front: true },
id: { from: fromData.resource, name: 'id' },
},
},
cluster: {
action: deleteResource,
params: {
resource: { from: fromData.resource, name: 'method' },
id: { from: fromData.resource, name: 'id', front: true },
id: { from: fromData.resource, name: 'id' },
},
},
},

View File

@ -32,8 +32,8 @@ const {
createTemporalFile,
getEndpoint,
getSpecificConfig,
} = require('./functions')
const { provider } = require('./schemas')
} = require('server/routes/api/oneprovision/utils')
const { provider } = require('server/routes/api/oneprovision/schemas')
const httpInternalError = httpResponse(internalServerError, '', '')

View File

@ -21,48 +21,48 @@ const {
instantiateProvisionTemplate,
updateProvisionTemplate,
deleteProvisionTemplate,
} = require('./provision_template-functions')
} = require('server/routes/api/oneprovision/template/functions')
const { httpMethod } = require('server/utils/constants/defaults')
const { GET, POST, PUT, DELETE } = httpMethod
const routes = {
[GET]: {
list: {
null: {
action: getListProvisionTemplates,
params: {
id: { from: fromData.resource, name: 'id', front: true },
id: { from: fromData.resource, name: 'method' },
},
},
},
[POST]: {
create: {
null: {
action: createProvisionTemplate,
params: {
resource: { from: fromData.postBody, front: true },
resource: { from: fromData.postBody },
},
},
instantiate: {
action: instantiateProvisionTemplate,
params: {
id: { from: fromData.resource, name: 'id', front: true },
id: { from: fromData.resource, name: 'id' },
},
},
},
[PUT]: {
update: {
null: {
action: updateProvisionTemplate,
params: {
resource: { from: fromData.postBody, front: true },
id: { from: fromData.resource, name: 'id', front: true },
resource: { from: fromData.postBody },
id: { from: fromData.resource, name: 'method' },
},
},
},
[DELETE]: {
delete: {
null: {
action: deleteProvisionTemplate,
params: {
id: { from: fromData.resource, name: 'id', front: true },
id: { from: fromData.resource, name: 'method' },
},
},
},

View File

@ -15,7 +15,7 @@
* ------------------------------------------------------------------------- */
const { setApiRoutes } = require('server/utils/server')
const { routes: sunstoneRoutes } = require('./sunstone')
const { routes: sunstoneRoutes } = require('./routes')
const { SUNSTONE } = require('./string-routes')

View File

@ -15,7 +15,7 @@
* ------------------------------------------------------------------------- */
const { httpMethod } = require('server/utils/constants/defaults')
const { getConfig, getViews } = require('./sunstone-functions')
const { getConfig, getViews } = require('server/routes/api/sunstone/functions')
const { GET } = httpMethod
const routes = {

View File

@ -29,7 +29,7 @@ const {
consoleParseToString,
consoleParseToJSON,
} = require('server/utils/opennebula')
const { resources } = require('./command-flags')
const { resources } = require('server/routes/api/vcenter/command-flags')
const { getSunstoneConfig } = require('server/utils/yml')

View File

@ -15,8 +15,8 @@
* ------------------------------------------------------------------------- */
const { setApiRoutes } = require('server/utils/server')
const { routes: vcenterRoutes } = require('./vcenter')
const { VCENTER } = require('./string-routes')
const { routes: vcenterRoutes } = require('server/routes/api/vcenter/routes')
const { VCENTER } = require('server/routes/api/vcenter/string-routes')
const functionRoutes = {
private: setApiRoutes(vcenterRoutes, VCENTER),

View File

@ -24,7 +24,7 @@ const {
listAll,
cleartags,
hosts,
} = require('./functions')
} = require('server/routes/api/vcenter/functions')
const { POST, GET } = httpMethod
const routes = {
@ -82,12 +82,12 @@ const routes = {
},
},
[GET]: {
list: {
null: {
action: list,
params: {
vobject: {
from: fromData.resource,
name: 'id',
name: 'method',
},
host: {
from: fromData.query,

View File

@ -15,8 +15,8 @@
* ------------------------------------------------------------------------- */
const { setApiRoutes } = require('server/utils/server')
const { routes: vmRoutes } = require('./vm')
const { VM } = require('./string-routes')
const { routes: vmRoutes } = require('server/routes/api/vm/routes')
const { VM } = require('server/routes/api/vm/string-routes')
const functionRoutes = {
private: setApiRoutes(vmRoutes, VM),

View File

@ -18,7 +18,7 @@ const {
httpMethod,
from: fromData,
} = require('server/utils/constants/defaults')
const { saveAsTemplate } = require('./functions')
const { saveAsTemplate } = require('server/routes/api/vm/functions')
const { POST } = httpMethod
const routes = {

View File

@ -13,35 +13,422 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
const { global } = require('window-or-global')
const { env } = require('process')
const zendesk = require('node-zendesk')
const { getSunstoneConfig } = require('server/utils/yml')
const {
defaultEmptyFunction,
defaultSeverities,
defaultWebpackMode,
} = require('server/utils/constants/defaults')
const { httpResponse } = require('server/utils/server')
const { getSession } = require('server/routes/api/zendesk/utils')
const {
ok,
internalServerError,
badRequest,
unauthorized,
} = require('server/utils/constants/http-codes')
const formatCreate = ({
subject = '',
body = '',
version = '',
severity = '',
}) => {
let rtn
if (subject && body && version && severity) {
rtn = {
request: {
subject,
comment: {
body,
},
custom_fields: [
{ id: 391130, value: version }, // version
{ id: 391197, value: severity }, // severity
],
can_be_solved_by_me: false,
tags: [severity],
},
}
}
return rtn
}
const formatComment = ({ body = '', solved = '', attachments = [] }) => {
let rtn
if (body) {
rtn = {
request: {
comment: {
body,
public: true,
},
},
}
if (solved) {
rtn.solved = 'true'
}
if (attachments && Array.isArray(attachments) && attachments.length > 0) {
rtn.request.comment.uploads = attachments.filter((att) => att)
}
}
return rtn
}
const parseBufferError = (err) => {
let rtn = ''
let errorJson = {}
if (err && err.result) {
try {
errorJson = JSON.parse(err.result.toString())
} catch {}
if (errorJson && errorJson.error) {
rtn = errorJson.error.title ? `${errorJson.error.title}: ` : ''
rtn += errorJson.error.message ? errorJson.error.message : ''
}
}
return rtn
}
const httpBadRequest = httpResponse(badRequest, '', '')
/**
* Get data fireedge session.
* Login on Zendesk.
*
* @param {string} username - username
* @param {string} token - pass
* @returns {object} user session
* @param {object} response - http response
* @param {Function} next - express stepper
* @param {object} params - params of http request
* @param {string} params.user - zendesk user
* @param {string} params.pass - zendesk.pass
* @param {object} userData - user of http request
* @param {string} userData.user - username
* @param {string} userData.password - user password
*/
const getSession = (username = '', token = '') => {
if (
username &&
token &&
global &&
global.users &&
username &&
global.users[username] &&
global.users[username].tokens
) {
const session = global.users[username].tokens.find(
(curr = {}, index = 0) => curr.token && curr.token === token
)
const login = (
response = {},
next = defaultEmptyFunction,
params = {},
userData = {}
) => {
const sunstoneConfig = getSunstoneConfig()
const remoteUri = sunstoneConfig.support_url || ''
const { user, password } = userData
const { user: zendeskUser, pass } = params
if (remoteUri && zendeskUser && pass && user && password) {
const zendeskData = {
username: zendeskUser,
password: pass,
remoteUri,
debug: env.NODE_ENV === defaultWebpackMode,
}
const session = getSession(userData.user, userData.password)
/** ZENDESK AUTH */
const zendeskClient = zendesk.createClient(zendeskData)
zendeskClient.users.auth((err, res, result) => {
let method = ok
let data = result
if (err) {
if (session.zendesk) {
delete session.zendesk
}
method = internalServerError
data = parseBufferError(err)
}
if (result && result.authenticity_token) {
const zendeskUserData = {
...zendeskData,
id: result.id,
}
session.zendesk = zendeskUserData
}
return session
response.locals.httpCode = httpResponse(method, data)
next()
})
} else {
response.locals.httpCode = httpBadRequest
next()
}
}
const functions = {
getSession,
/**
* List on Zendesk.
*
* @param {object} response - http response
* @param {Function} next - express stepper
* @param {object} params - params of http request
* @param {object} userData - user of http request
* @param {string} userData.user - username
* @param {string} userData.password - user password
*/
const list = (
response = {},
next = defaultEmptyFunction,
params = {},
userData = {}
) => {
const { user, password } = userData
if (user && password) {
const session = getSession(user, password)
if (session.zendesk && session.zendesk.id) {
/** LIST ZENDESK */
const zendeskClient = zendesk.createClient(session.zendesk)
zendeskClient.requests.getRequest(
{ status: 'open,pending' },
(err, req, result) => {
let method = ok
let data = ''
if (err) {
method = internalServerError
data = parseBufferError(err)
} else if (result) {
let pendings = 0
let opens = 0
const tickets = Array.isArray(result) ? result : result
tickets.forEach((ticket) => {
if (ticket && ticket.status) {
switch (ticket.status) {
case 'pending':
pendings += 1
break
default:
opens += 1
break
}
}
})
data = {
tickets: result,
pendings,
opens,
}
}
response.locals.httpCode = httpResponse(method, data)
next()
}
)
} else {
response.locals.httpCode = httpResponse(unauthorized)
next()
}
} else {
response.locals.httpCode = httpBadRequest
next()
}
}
module.exports = functions
/**
* Get Comments on ticket.
*
* @param {object} response - http response
* @param {Function} next - express stepper
* @param {object} params - params of http request
* @param {number} params.id - comment id
* @param {object} userData - user of http request
* @param {string} userData.user - username
* @param {string} userData.password - user password
*/
const comments = (
response = {},
next = defaultEmptyFunction,
params = {},
userData = {}
) => {
const { id } = params
const { user, password } = userData
if (Number.isInteger(parseInt(id, 10)) && user && password) {
const session = getSession(user, password)
if (session.zendesk) {
/** GET COMMENTS ON TICKET ZENDESK */
const zendeskClient = zendesk.createClient(session.zendesk)
zendeskClient.requests.listComments(params.id, (err, req, result) => {
let method = ok
let data = ''
if (err) {
method = internalServerError
data = parseBufferError(err)
} else if (result) {
data = result
}
response.locals.httpCode = httpResponse(method, data)
next()
})
} else {
response.locals.httpCode = httpResponse(unauthorized)
next()
}
} else {
response.locals.httpCode = httpBadRequest
next()
}
}
/**
* Create ticket.
*
* @param {object} response - http response
* @param {Function} next - express stepper
* @param {object} params - params of http request
* @param {string} params.subject - subject
* @param {string} params.body - body
* @param {string} params.version - version
* @param {string} params.severity - severity
* @param {object} userData - user of http request
* @param {string} userData.user - username
* @param {string} userData.password - user password
*/
const create = (
response = {},
next = defaultEmptyFunction,
params = {},
userData = {}
) => {
const { subject, body, version, severity } = params
const { user, password } = userData
if (
subject &&
body &&
version &&
severity &&
defaultSeverities.includes(severity) &&
user &&
password
) {
const session = getSession(user, password)
if (session.zendesk && session.zendesk.id) {
/** CREATE TICKET ZENDESK */
const zendeskClient = zendesk.createClient(session.zendesk)
const ticket = formatCreate(params)
zendeskClient.requests.create(ticket, (err, req, result) => {
let method = ok
let data = ''
if (err) {
method = internalServerError
data = parseBufferError(err)
} else if (result) {
data = result
}
response.locals.httpCode = httpResponse(method, data)
next()
})
} else {
response.locals.httpCode = httpResponse(unauthorized)
next()
}
} else {
response.locals.httpCode = httpBadRequest
next()
}
}
/**
* Update Ticket.
*
* @param {object} response - http response
* @param {Function} next - express stepper
* @param {object} params - params of http request
* @param {string} params.id - ticket id
* @param {string} params.body - ticket body
* @param {object[]} params.attachments - files
* @param {string} params.attachments.originalname - original name
* @param {string} params.attachments.path - path file
* @param {object} userData - user of http request
* @param {string} userData.user - username
* @param {string} userData.password - user password
*/
const update = (
response = {},
next = defaultEmptyFunction,
params = {},
userData = {}
) => {
const { id, body, attachments } = params
const { user, password } = userData
if (Number.isInteger(parseInt(id, 10)) && body && user && password) {
const session = getSession(userData.user, userData.password)
if (session.zendesk && session.zendesk.id) {
const zendeskClient = zendesk.createClient(session.zendesk)
const sendRequest = (requestParams = {}) => {
/** UPDATE TICKET ZENDESK */
const ticket = formatComment(requestParams)
zendeskClient.requests.update(id, ticket, (err, req, result) => {
let method = ok
let data = ''
if (err) {
method = internalServerError
data = parseBufferError(err)
} else if (result) {
data = result
}
response.locals.httpCode = httpResponse(method, data)
next()
})
}
/** UPLOAD FILES */
let uploadedAttachments
if (
attachments &&
zendeskClient.attachments &&
typeof zendeskClient.attachments.upload === 'function'
) {
attachments.forEach((att = {}) => {
if (att && att.originalname && att.path) {
zendeskClient.attachments.upload(
att.path,
{
filename: att.originalname,
},
(err, req, result) => {
const token =
(result && result.upload && result.upload.token) || ''
if (uploadedAttachments) {
uploadedAttachments.push(token)
} else {
uploadedAttachments = [token]
}
if (
!err &&
token &&
uploadedAttachments.length === attachments.length
) {
sendRequest({ ...params, attachments: uploadedAttachments })
}
}
)
}
})
} else {
sendRequest({ ...params, attachments })
}
} else {
response.locals.httpCode = httpResponse(unauthorized)
next()
}
} else {
response.locals.httpCode = httpBadRequest
next()
}
}
const functionRoutes = {
login,
list,
comments,
create,
update,
}
module.exports = functionRoutes

View File

@ -15,8 +15,8 @@
* ------------------------------------------------------------------------- */
const { setApiRoutes } = require('server/utils/server')
const { routes: zendeskRoutes } = require('./zendesk')
const { ZENDESK } = require('./string-routes')
const { routes: zendeskRoutes } = require('server/routes/api/zendesk/routes')
const { ZENDESK } = require('server/routes/api/zendesk/string-routes')
const functionRoutes = {
private: setApiRoutes(zendeskRoutes, ZENDESK),

View File

@ -18,7 +18,13 @@ const {
httpMethod,
from: fromData,
} = require('server/utils/constants/defaults')
const { login, list, comments, create, update } = require('./zendesk-functions')
const {
login,
list,
comments,
create,
update,
} = require('server/routes/api/zendesk/functions')
const { POST, GET, PUT } = httpMethod
const routes = {
@ -36,7 +42,7 @@ const routes = {
},
},
},
create: {
null: {
action: create,
params: {
subject: {
@ -59,12 +65,12 @@ const routes = {
},
},
[PUT]: {
update: {
null: {
action: update,
params: {
id: {
from: fromData.resource,
name: 'id',
name: 'method',
},
body: {
from: fromData.postBody,
@ -82,7 +88,7 @@ const routes = {
},
},
[GET]: {
list: {
null: {
action: list,
params: {},
},

View File

@ -13,14 +13,35 @@
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
const { global } = require('window-or-global')
const privateRoutes = []
/**
* Get data fireedge session.
*
* @param {string} username - username
* @param {string} token - pass
* @returns {object} user session
*/
const getSession = (username = '', token = '') => {
if (
username &&
token &&
global &&
global.users &&
username &&
global.users[username] &&
global.users[username].tokens
) {
const session = global.users[username].tokens.find(
(curr = {}, index = 0) => curr.token && curr.token === token
)
const publicRoutes = []
const functionRoutes = {
private: privateRoutes,
public: publicRoutes,
return session
}
}
module.exports = functionRoutes
const functions = {
getSession,
}
module.exports = functions

View File

@ -1,434 +0,0 @@
/* ------------------------------------------------------------------------- *
* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may *
* not use this file except in compliance with the License. You may obtain *
* a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
const { env } = require('process')
const zendesk = require('node-zendesk')
const { getSunstoneConfig } = require('server/utils/yml')
const {
defaultEmptyFunction,
defaultSeverities,
defaultWebpackMode,
} = require('server/utils/constants/defaults')
const { httpResponse } = require('server/utils/server')
const { getSession } = require('./functions')
const {
ok,
internalServerError,
badRequest,
unauthorized,
} = require('server/utils/constants/http-codes')
const formatCreate = ({
subject = '',
body = '',
version = '',
severity = '',
}) => {
let rtn
if (subject && body && version && severity) {
rtn = {
request: {
subject,
comment: {
body,
},
custom_fields: [
{ id: 391130, value: version }, // version
{ id: 391197, value: severity }, // severity
],
can_be_solved_by_me: false,
tags: [severity],
},
}
}
return rtn
}
const formatComment = ({ body = '', solved = '', attachments = [] }) => {
let rtn
if (body) {
rtn = {
request: {
comment: {
body,
public: true,
},
},
}
if (solved) {
rtn.solved = 'true'
}
if (attachments && Array.isArray(attachments) && attachments.length > 0) {
rtn.request.comment.uploads = attachments.filter((att) => att)
}
}
return rtn
}
const parseBufferError = (err) => {
let rtn = ''
let errorJson = {}
if (err && err.result) {
try {
errorJson = JSON.parse(err.result.toString())
} catch {}
if (errorJson && errorJson.error) {
rtn = errorJson.error.title ? `${errorJson.error.title}: ` : ''
rtn += errorJson.error.message ? errorJson.error.message : ''
}
}
return rtn
}
const httpBadRequest = httpResponse(badRequest, '', '')
/**
* Login on Zendesk.
*
* @param {object} response - http response
* @param {Function} next - express stepper
* @param {object} params - params of http request
* @param {string} params.user - zendesk user
* @param {string} params.pass - zendesk.pass
* @param {object} userData - user of http request
* @param {string} userData.user - username
* @param {string} userData.password - user password
*/
const login = (
response = {},
next = defaultEmptyFunction,
params = {},
userData = {}
) => {
const sunstoneConfig = getSunstoneConfig()
const remoteUri = sunstoneConfig.support_url || ''
const { user, password } = userData
const { user: zendeskUser, pass } = params
if (remoteUri && zendeskUser && pass && user && password) {
const zendeskData = {
username: zendeskUser,
password: pass,
remoteUri,
debug: env.NODE_ENV === defaultWebpackMode,
}
const session = getSession(userData.user, userData.password)
/** ZENDESK AUTH */
const zendeskClient = zendesk.createClient(zendeskData)
zendeskClient.users.auth((err, res, result) => {
let method = ok
let data = result
if (err) {
if (session.zendesk) {
delete session.zendesk
}
method = internalServerError
data = parseBufferError(err)
}
if (result && result.authenticity_token) {
const zendeskUserData = {
...zendeskData,
id: result.id,
}
session.zendesk = zendeskUserData
}
response.locals.httpCode = httpResponse(method, data)
next()
})
} else {
response.locals.httpCode = httpBadRequest
next()
}
}
/**
* List on Zendesk.
*
* @param {object} response - http response
* @param {Function} next - express stepper
* @param {object} params - params of http request
* @param {object} userData - user of http request
* @param {string} userData.user - username
* @param {string} userData.password - user password
*/
const list = (
response = {},
next = defaultEmptyFunction,
params = {},
userData = {}
) => {
const { user, password } = userData
if (user && password) {
const session = getSession(user, password)
if (session.zendesk && session.zendesk.id) {
/** LIST ZENDESK */
const zendeskClient = zendesk.createClient(session.zendesk)
zendeskClient.requests.getRequest(
{ status: 'open,pending' },
(err, req, result) => {
let method = ok
let data = ''
if (err) {
method = internalServerError
data = parseBufferError(err)
} else if (result) {
let pendings = 0
let opens = 0
const tickets = Array.isArray(result) ? result : result
tickets.forEach((ticket) => {
if (ticket && ticket.status) {
switch (ticket.status) {
case 'pending':
pendings += 1
break
default:
opens += 1
break
}
}
})
data = {
tickets: result,
pendings,
opens,
}
}
response.locals.httpCode = httpResponse(method, data)
next()
}
)
} else {
response.locals.httpCode = httpResponse(unauthorized)
next()
}
} else {
response.locals.httpCode = httpBadRequest
next()
}
}
/**
* Get Comments on ticket.
*
* @param {object} response - http response
* @param {Function} next - express stepper
* @param {object} params - params of http request
* @param {number} params.id - comment id
* @param {object} userData - user of http request
* @param {string} userData.user - username
* @param {string} userData.password - user password
*/
const comments = (
response = {},
next = defaultEmptyFunction,
params = {},
userData = {}
) => {
const { id } = params
const { user, password } = userData
if (Number.isInteger(parseInt(id, 10)) && user && password) {
const session = getSession(user, password)
if (session.zendesk) {
/** GET COMMENTS ON TICKET ZENDESK */
const zendeskClient = zendesk.createClient(session.zendesk)
zendeskClient.requests.listComments(params.id, (err, req, result) => {
let method = ok
let data = ''
if (err) {
method = internalServerError
data = parseBufferError(err)
} else if (result) {
data = result
}
response.locals.httpCode = httpResponse(method, data)
next()
})
} else {
response.locals.httpCode = httpResponse(unauthorized)
next()
}
} else {
response.locals.httpCode = httpBadRequest
next()
}
}
/**
* Create ticket.
*
* @param {object} response - http response
* @param {Function} next - express stepper
* @param {object} params - params of http request
* @param {string} params.subject - subject
* @param {string} params.body - body
* @param {string} params.version - version
* @param {string} params.severity - severity
* @param {object} userData - user of http request
* @param {string} userData.user - username
* @param {string} userData.password - user password
*/
const create = (
response = {},
next = defaultEmptyFunction,
params = {},
userData = {}
) => {
const { subject, body, version, severity } = params
const { user, password } = userData
if (
subject &&
body &&
version &&
severity &&
defaultSeverities.includes(severity) &&
user &&
password
) {
const session = getSession(user, password)
if (session.zendesk && session.zendesk.id) {
/** CREATE TICKET ZENDESK */
const zendeskClient = zendesk.createClient(session.zendesk)
const ticket = formatCreate(params)
zendeskClient.requests.create(ticket, (err, req, result) => {
let method = ok
let data = ''
if (err) {
method = internalServerError
data = parseBufferError(err)
} else if (result) {
data = result
}
response.locals.httpCode = httpResponse(method, data)
next()
})
} else {
response.locals.httpCode = httpResponse(unauthorized)
next()
}
} else {
response.locals.httpCode = httpBadRequest
next()
}
}
/**
* Update Ticket.
*
* @param {object} response - http response
* @param {Function} next - express stepper
* @param {object} params - params of http request
* @param {string} params.id - ticket id
* @param {string} params.body - ticket body
* @param {object[]} params.attachments - files
* @param {string} params.attachments.originalname - original name
* @param {string} params.attachments.path - path file
* @param {object} userData - user of http request
* @param {string} userData.user - username
* @param {string} userData.password - user password
*/
const update = (
response = {},
next = defaultEmptyFunction,
params = {},
userData = {}
) => {
const { id, body, attachments } = params
const { user, password } = userData
if (Number.isInteger(parseInt(id, 10)) && body && user && password) {
const session = getSession(userData.user, userData.password)
if (session.zendesk && session.zendesk.id) {
const zendeskClient = zendesk.createClient(session.zendesk)
const sendRequest = (requestParams = {}) => {
/** UPDATE TICKET ZENDESK */
const ticket = formatComment(requestParams)
zendeskClient.requests.update(id, ticket, (err, req, result) => {
let method = ok
let data = ''
if (err) {
method = internalServerError
data = parseBufferError(err)
} else if (result) {
data = result
}
response.locals.httpCode = httpResponse(method, data)
next()
})
}
/** UPLOAD FILES */
let uploadedAttachments
if (
attachments &&
zendeskClient.attachments &&
typeof zendeskClient.attachments.upload === 'function'
) {
attachments.forEach((att = {}) => {
if (att && att.originalname && att.path) {
zendeskClient.attachments.upload(
att.path,
{
filename: att.originalname,
},
(err, req, result) => {
const token =
(result && result.upload && result.upload.token) || ''
if (uploadedAttachments) {
uploadedAttachments.push(token)
} else {
uploadedAttachments = [token]
}
if (
!err &&
token &&
uploadedAttachments.length === attachments.length
) {
sendRequest({ ...params, attachments: uploadedAttachments })
}
}
)
}
})
} else {
sendRequest({ ...params, attachments })
}
} else {
response.locals.httpCode = httpResponse(unauthorized)
next()
}
} else {
response.locals.httpCode = httpBadRequest
next()
}
}
const functionRoutes = {
login,
list,
comments,
create,
update,
}
module.exports = functionRoutes

View File

@ -16,7 +16,7 @@
const { middlewareValidateAuthWebsocket } = require('server/utils/server')
const { messageTerminal } = require('server/utils/general')
const { subscriber } = require('server/routes/api/provision/functions')
const { subscriber } = require('server/routes/api/oneprovision/utils')
/**
* Object http error.

View File

@ -67,19 +67,6 @@ const defaults = {
methods: ['GET', 'POST'],
},
},
defaultFilesRoutes: [
'2fa',
'auth',
'files',
'marketapp',
'oneflow',
'support',
'vcenter',
'vm',
'zendesk',
appNameProvision,
appNameSunstone,
],
defaultApps: apps,
httpMethod: {
GET: 'GET',

View File

@ -188,16 +188,16 @@ const addFunctionAsRoute = (
if (req && req.serverDataSource && res && next && routes) {
const serverDataSource = req.serverDataSource
const resources = Object.keys(serverDataSource[fromData.resource])
const route =
let route =
routes[
`${serverDataSource[fromData.resource][resources[index]]}`.toLowerCase()
]
if (
fromData &&
fromData.resource &&
serverDataSource[fromData.resource] &&
route
) {
if (!route && index === 0 && routes.null) {
route = routes.null
}
if (route) {
if (Object.keys(route).length > 0 && route.constructor === Object) {
if (
route.action &&