Redefine API to provider access. (#199)

* Migrate login, get session, change role, logout.

* Convert menu.
pull/3759/head
EdwinBetanc0urt 2019-12-10 10:11:44 -04:00 committed by Yamel Senih
parent 206539251b
commit 79698ad562
8 changed files with 232 additions and 293 deletions

View File

@ -13,59 +13,25 @@ function Instance() {
// Make login by UserName and password, this function can return user data for show
export function login(loginValues) {
if (loginValues.role !== undefined && loginValues.role.trim() !== '') {
return Instance.call(this).requestLogin(
loginValues.userName,
loginValues.password,
loginValues.role,
null,
loginValues.language
)
if (loginValues.role && loginValues.role.trim() !== '') {
return Instance.call(this).requestLogin({
userName: loginValues.userName,
userPass: loginValues.password,
role: loginValues.role,
language: getLanguage() || 'en_US'
})
} else {
return Instance.call(this).requestLoginDefault(
loginValues.userName,
loginValues.password,
loginValues.language
)
return Instance.call(this).requestLoginDefault({
userName: loginValues.userName,
userPass: loginValues.password,
language: getLanguage() || 'en_US'
})
}
}
// Get User Info from session Uuid or token
export function getInfo(token) {
return Instance.call(this).requestUserInfoFromSession(token)
.then(session => {
var roles = []
var rolesList = session.getRolesList().map(itemRol => {
roles.push(itemRol.getName())
return {
id: itemRol.getId(),
uuid: itemRol.getUuid(),
name: itemRol.getName(),
description: itemRol.getDescription(),
clientId: itemRol.getClientid(),
clientName: itemRol.getClientname(),
organizationList: itemRol.getOrganizationsList()
}
})
// TODO: Add user.id, user.level in request
const user = session.getUserinfo()
const response = {
id: user.getId(),
uuid: user.getUuid(),
name: user.getName(),
comments: user.getComments(),
description: user.getDescription(),
// TODO: Add from ADempiere
avatar: 'https://avatars1.githubusercontent.com/u/1263359?s=200&v=4',
roles: roles, // rol list names, used from app (src/permission.js, src/utils/permission.js)
rolesList: rolesList,
responseGrpc: session
}
return response
}).catch(error => {
console.log(error)
})
}
/**
@ -78,7 +44,7 @@ export function getSessionInfo(sessionUuid) {
// Logout from server
export function logout(sessionUuid) {
return Instance.call(this).requestLogout(sessionUuid)
return Instance.call(this).requestLogOut(sessionUuid)
}
// Get User menu from server

View File

@ -1,13 +1,11 @@
import { getMenu } from '@/api/user'
import { getToken } from '@/utils/auth'
import { convertAction } from '@/utils/ADempiere/dictionaryUtils'
/* Layout */
import Layout from '@/layout'
// Get Menu from server
export function loadMainMenu() {
return getMenu(getToken()).then(menu => {
const asyncRouterMap = [
const staticRoutes = [
{
path: '*',
redirect: '/404',
@ -16,14 +14,24 @@ export function loadMainMenu() {
{
path: '/ProcessActivity',
component: Layout,
meta: { title: 'ProcessActivity', icon: 'tree-table', noCache: true, breadcrumb: false },
meta: {
title: 'ProcessActivity',
icon: 'tree-table',
noCache: true,
breadcrumb: false
},
redirect: '/ProcessActivity/index',
children: [
{
path: 'index',
component: () => import('@/views/ADempiere/ProcessActivity'),
name: 'ProcessActivity',
meta: { title: 'ProcessActivity', icon: 'tree-table', noCache: true, isIndex: true }
meta: {
title: 'ProcessActivity',
icon: 'tree-table',
noCache: true,
isIndex: true
}
}
]
},
@ -43,70 +51,71 @@ export function loadMainMenu() {
}
]
}
]
menu.getChildsList().forEach(menu => {
]
// Get Menu from server
export function loadMainMenu() {
return getMenu(getToken()).then(menu => {
const asyncRoutesMap = []
menu.childsList.forEach(menu => {
const optionMenu = getRouteFromMenuItem(menu)
if (menu.getIssummary()) {
menu.getChildsList().forEach((menu, index) => {
optionMenu.children.push(getChildFromAction(menu, index = 0))
optionMenu.children[0].meta.childs.push(getChildFromAction(menu, index = 0))
optionMenu.meta.childs.push(getChildFromAction(menu, index = 0))
if (menu.isSummary) {
menu.childsList.forEach(menu => {
const childsSumaryConverted = getChildFromAction(menu, 0)
optionMenu.children.push(childsSumaryConverted)
optionMenu.children[0].meta.childs.push(childsSumaryConverted)
optionMenu.meta.childs.push(childsSumaryConverted)
})
} else {
optionMenu.children.push(getChildFromAction(menu))
optionMenu.meta.childs.push(getChildFromAction(menu))
const childsConverted = getChildFromAction(menu)
optionMenu.children.push(childsConverted)
optionMenu.meta.childs.push(childsConverted)
}
asyncRouterMap.push(optionMenu)
asyncRoutesMap.push(optionMenu)
})
return asyncRouterMap
return staticRoutes.concat(asyncRoutesMap)
}).catch(error => {
console.log('Error with Login: ' + error)
console.warn(`Error getting menu: ${error.message}. Code: ${error.code}`)
})
}
// Get Only Child
function getChildFromAction(menu, index) {
const action = menu.getAction()
var actionAttributes = convertAction(action)
var routeIdentifier = actionAttributes.name + '/' + menu.getId()
let selectedComponent
if (action === 'W') {
selectedComponent = () => import('@/views/ADempiere/Window')
routeIdentifier = actionAttributes.name + '/' + menu.getId()
} else if (action === 'S') {
selectedComponent = () => import('@/views/ADempiere/Browser')
} else if (action === 'P' || action === 'R') {
selectedComponent = () => import('@/views/ADempiere/Process')
} else if (action === 'B' || action === 'F' || action === 'T' || action === 'X') {
selectedComponent = () => import('@/views/ADempiere/Unsupported')
} else {
selectedComponent = () => import('@/views/ADempiere/Summary')
routeIdentifier = '/' + menu.getId()
const action = menu.action
const actionAttributes = convertAction(action)
let routeIdentifier = actionAttributes.name + '/' + menu.id
if (menu.isSummary) {
routeIdentifier = '/' + menu.id
}
var option = {
const option = {
path: routeIdentifier,
component: selectedComponent,
name: menu.getUuid(),
component: actionAttributes.component,
name: menu.uuid,
hidden: index > 0,
meta: {
isIndex: actionAttributes.isIndex,
title: menu.getName(),
description: menu.getDescription(),
uuid: menu.getReferenceuuid(),
title: menu.name,
description: menu.description,
uuid: menu.referenceUuid,
tabUuid: '',
type: actionAttributes.name,
parentUuid: menu.getParentuuid(),
parentUuid: menu.parentUuid,
icon: actionAttributes.icon,
alwaysShow: true,
noCache: false,
childs: []
}
}
if (option.meta.type === 'summary') {
if (actionAttributes.isIndex || actionAttributes.name === 'summary') {
option['children'] = []
menu.getChildsList().forEach((child, index) => {
option.children.push(getChildFromAction(child, index = 1))
option.meta.childs.push(getChildFromAction(child, index = 1))
menu.childsList.forEach(child => {
const menuConverted = getChildFromAction(child, 1)
option.children.push(menuConverted)
option.meta.childs.push(menuConverted)
})
}
return option
@ -114,93 +123,38 @@ function getChildFromAction(menu, index) {
// Convert menu item from server to Route
function getRouteFromMenuItem(menu) {
const action = menu.getAction()
var actionAttributes = convertAction(action)
var optionMenu = []
optionMenu = {
path: '/' + menu.getId(),
redirect: '/' + menu.getId() + '/index',
const action = menu.action
const actionAttributes = convertAction(action)
const optionMenu = {
path: '/' + menu.id,
redirect: '/' + menu.id + '/index',
component: Layout,
name: menu.getUuid(),
name: menu.uuid,
meta: {
title: menu.getName(),
description: menu.getDescription(),
title: menu.name,
description: menu.description,
type: actionAttributes.name,
icon: actionAttributes.icon,
noCache: true,
childs: []
},
children: [
{
children: [{
path: 'index',
component: () => import('@/views/ADempiere/Summary'),
name: menu.getUuid() + '-index',
component: actionAttributes.component,
name: menu.uuid + '-index',
hidden: true,
meta: {
isIndex: actionAttributes.isIndex,
parentUuid: menu.getUuid(),
title: menu.getName(),
description: menu.getDescription(),
parentUuid: menu.uuid,
title: menu.name,
description: menu.description,
type: actionAttributes.name,
icon: actionAttributes.icon,
noCache: true,
breadcrumb: false,
childs: []
}
}
]
}]
}
return optionMenu
}
// Convert action to action name for route
function convertAction(action) {
var actionAttributes = {
name: '',
icon: '',
hidden: false,
isIndex: false
}
switch (action) {
case 'B':
actionAttributes.name = 'workbech'
actionAttributes.icon = 'peoples'
break
case 'F':
actionAttributes.name = 'workflow'
actionAttributes.icon = 'example'
break
case 'P':
actionAttributes.name = 'process'
actionAttributes.icon = 'component'
break
case 'R':
actionAttributes.name = 'report'
actionAttributes.icon = 'skill'
break
case 'S':
actionAttributes.name = 'browser'
actionAttributes.icon = 'search'
break
case 'T':
actionAttributes.name = 'task'
actionAttributes.icon = 'size'
break
case 'W':
actionAttributes.name = 'window'
actionAttributes.icon = 'tab'
break
case 'X':
actionAttributes.name = 'form'
actionAttributes.icon = 'form'
break
default:
actionAttributes.name = 'summary'
actionAttributes.icon = 'nested'
// actionAttributes.hidden = true
actionAttributes.isIndex = true
break
}
return actionAttributes
}

View File

@ -7,6 +7,13 @@ const context = {
context: {}
},
mutations: {
/**
* Set context in state
* @param {string} payload.parentUuid
* @param {string} payload.containerUuid
* @param {string} payload.columnName
* @param {mixed} payload.value
*/
setContext(state, payload) {
var key = ''
if (payload.parentUuid && !isEmptyValue(payload.value)) {
@ -41,6 +48,25 @@ const context = {
commit('setContext', itemToSetter)
})
},
setMultipleContextObject: ({ commit }, valuesToSetter) => {
Object.keys(valuesToSetter).forEach(key => {
commit('setContext', {
columnName: key,
value: valuesToSetter[key]
})
})
},
setMultipleContextMap: ({ commit }, valuesToSetter) => {
return new Promise(resolve => {
valuesToSetter.forEach((value, key) => {
commit('setContext', {
columnName: key,
value: value
})
})
resolve()
})
},
setInitialContext: ({ commit }, otherContext = {}) => {
commit('setInitialContext', otherContext)
}

View File

@ -1,8 +1,7 @@
import { login, logout, getInfo, getSessionInfo, changeRole } from '@/api/user'
import { convertRoleFromGRPC } from '@/utils/ADempiere'
import { getToken, setToken, removeToken, getCurrentRole, setCurrentRole, removeCurrentRole } from '@/utils/auth'
import router, { resetRouter } from '@/router'
import { showMessage, convertMapToArrayPairs } from '@/utils/ADempiere'
import { showMessage } from '@/utils/ADempiere/notification'
const state = {
token: getToken(),
@ -56,22 +55,18 @@ const actions = {
const { userName, password } = userInfo
return new Promise((resolve, reject) => {
login({ userName: userName.trim(), password: password })
.then(response => {
var data = {
id: response.getId(),
token: response.getUuid(),
name: response.getUserinfo().getName(),
avatar: 'https://avatars1.githubusercontent.com/u/1263359?s=200&v=4',
currentRole: convertRoleFromGRPC(response.getRole()),
isProcessed: response.getProcessed()
}
.then(logInResponse => {
const { uuid: token } = logInResponse
commit('SET_TOKEN', data.token)
commit('SET_ROL', data.currentRole)
logInResponse.avatar = 'https://avatars1.githubusercontent.com/u/1263359?s=200&v=4'
logInResponse.name = logInResponse.userInfo.name
setToken(data.token)
setCurrentRole(data.currentRole.uuid)
resolve(data)
commit('SET_TOKEN', token)
commit('SET_ROL', logInResponse.role)
setToken(token)
setCurrentRole(logInResponse.role.uuid)
resolve(logInResponse)
}).catch(error => {
reject(error)
})
@ -83,45 +78,36 @@ const actions = {
sessionUuid = getToken()
}
return getSessionInfo(sessionUuid)
.then(response => {
.then(responseGetInfo => {
commit('setIsSession', true)
commit('setSessionInfo', {
id: response.getId(),
uuid: response.getUuid(),
name: response.getName(),
isProcessed: response.getProcessed()
id: responseGetInfo.id,
uuid: responseGetInfo.uuid,
name: responseGetInfo.name,
processed: responseGetInfo.processed
})
const userInfo = response.getUserinfo()
commit('SET_NAME', userInfo.getName())
commit('SET_INTRODUCTION', userInfo.getDescription())
commit('SET_USER_UUID', userInfo.getUuid())
const userInfo = responseGetInfo.userInfo
commit('SET_NAME', responseGetInfo.name)
commit('SET_INTRODUCTION', userInfo.description)
commit('SET_USER_UUID', responseGetInfo.uuid)
var defaultContext = convertMapToArrayPairs({
toConvert: response.getDefaultcontextMap()
})
// TODO: return request #Date as long data type Date (5)
// join column names without duplicating it
defaultContext = Array.from(new Set([
...defaultContext,
...[{
columnName: '#Date',
value: new Date()
}]
]))
// TODO: return 'Y' or 'N' string values as data type Booelan (4)
// TODO: return #Date as long data type Date (5)
responseGetInfo.defaultContextMap.set('#Date', new Date())
// set multiple context
dispatch('setMultipleContext', defaultContext, {
dispatch('setMultipleContextMap', responseGetInfo.defaultContextMap, {
root: true
})
const sessionResponse = {
name: response.getName(),
defaultContext: defaultContext
name: responseGetInfo.name,
defaultContext: responseGetInfo.defaultContextMap
}
return sessionResponse
})
.catch(error => {
console.warn('Error gettin context', error.message)
console.warn(`Error getting context session ${error.message}`)
})
.finally(() => {
dispatch('getUserInfoValue', sessionUuid)
@ -133,25 +119,37 @@ const actions = {
sessionUuid = getToken()
}
return new Promise((resolve, reject) => {
getInfo(sessionUuid).then(response => {
if (!response) {
getInfo(sessionUuid).then(responseGetInfo => {
if (!responseGetInfo) {
reject('Verification failed, please Login again.')
}
// roles must be a non-empty array
if (!response.rolesList || response.rolesList.length <= 0) {
if (!responseGetInfo.rolesList || responseGetInfo.rolesList.length <= 0) {
reject('getInfo: roles must be a non-null array!')
}
var rol = response.rolesList.find(itemRol => {
const rol = responseGetInfo.rolesList.find(itemRol => {
return itemRol.uuid === getCurrentRole()
})
const rolesName = responseGetInfo.rolesList.map(rolItem => {
return rolItem.name
})
commit('SET_ROLES_LIST', response.rolesList)
commit('SET_ROLES', response.roles)
commit('SET_ROLES_LIST', responseGetInfo.rolesList)
commit('SET_ROLES', rolesName)
commit('SET_ROL', rol)
commit('SET_AVATAR', response.avatar)
resolve(response)
// TODO: Add support from ADempiere
const avatar = 'https://avatars1.githubusercontent.com/u/1263359?s=200&v=4'
commit('SET_AVATAR', avatar)
resolve({
...responseGetInfo,
avatar: avatar,
roles: rolesName
})
}).catch(error => {
console.warn(`Error getting user info value ${error.message}`)
reject(error)
})
})
@ -170,7 +168,7 @@ const actions = {
root: true
})
// dispatch('tagsView/delAllViews', null, {root:true})
// dispatch('tagsView/delAllViews', null, { root:true })
removeToken()
removeCurrentRole()
resetRouter()
@ -190,31 +188,25 @@ const actions = {
})
},
// dynamically modify permissions
changeRoles({ commit, state, dispatch }, roleUuid) {
/**
* @param {string} attributes.sessionUuid
* @param {string} attributes.roleUuid
* @param {string} attributes.organizationUuid
* @param {string} attributes.warehouseUuid
*/
changeRoles({ commit, dispatch }, roleUuid) {
return changeRole({
sessionUuid: getToken(),
roleUuid: roleUuid,
organizationUuid: null,
warehouseUuid: null
})
.then(response => {
var rol = convertRoleFromGRPC(response.getRole())
commit('SET_ROL', rol)
setCurrentRole(rol.uuid)
commit('SET_TOKEN', response.getUuid())
setToken(response.getUuid())
.then(changeRoleResponse => {
const { role } = changeRoleResponse
commit('SET_ROL', role)
setCurrentRole(role.uuid)
commit('SET_TOKEN', changeRoleResponse.uuid)
setToken(changeRoleResponse.uuid)
// Update user info and context associated with session
dispatch('getInfo', response.getUuid())
dispatch('getInfo', changeRoleResponse.uuid)
.then(() => {
var route = router.app._route
var selectedTag = {
const route = router.app._route
const selectedTag = {
fullPath: route.fullPath,
hash: route.hash,
matched: route.matched,
@ -235,8 +227,8 @@ const actions = {
})
return {
...rol,
sessionUuid: response.getUuid()
...role,
sessionUuid: changeRoleResponse.uuid
}
})
.catch(error => {
@ -244,7 +236,7 @@ const actions = {
message: error.message,
type: 'error'
})
console.warn('Error change role:' + error.message + '. Code: ' + error.code)
console.warn(`Error change role: ${error.message}. Code: ${error.code}`)
})
// return new Promise(async resolve => {
// const token = role

View File

@ -443,51 +443,59 @@ export function fieldIsDisplayed(field) {
return field.isActive && isDisplayedView
}
// Convert action to action name for route
export function convertAction(action) {
var actionAttributes = {
const actionAttributes = {
name: '',
icon: '',
hidden: false,
isIndex: false
isIndex: false,
component: () => import('@/views/ADempiere/Unsupported')
}
switch (action) {
case 'B':
actionAttributes.name = 'Workbench'
actionAttributes.name = 'workbech'
actionAttributes.icon = 'peoples'
break
case 'F':
actionAttributes.name = 'Workflow'
actionAttributes.name = 'workflow'
actionAttributes.icon = 'example'
break
case 'P':
actionAttributes.name = 'Process'
actionAttributes.name = 'process'
actionAttributes.icon = 'component'
actionAttributes.component = () => import('@/views/ADempiere/Process')
break
case 'R':
actionAttributes.name = 'Report'
actionAttributes.name = 'report'
actionAttributes.icon = 'skill'
actionAttributes.component = () => import('@/views/ADempiere/Process')
break
case 'S':
actionAttributes.name = 'SmartBrowser'
actionAttributes.name = 'browser'
actionAttributes.icon = 'search'
actionAttributes.component = () => import('@/views/ADempiere/Browser')
break
case 'T':
actionAttributes.name = 'Task'
actionAttributes.name = 'task'
actionAttributes.icon = 'size'
break
case 'W':
actionAttributes.name = 'Window'
actionAttributes.name = 'window'
actionAttributes.icon = 'tab'
actionAttributes.component = () => import('@/views/ADempiere/Window')
break
case 'X':
actionAttributes.name = 'Form'
actionAttributes.name = 'form'
actionAttributes.icon = 'form'
break
default:
actionAttributes.name = 'summary'
actionAttributes.icon = 'nested'
// actionAttributes.hidden = true
actionAttributes.isIndex = true
actionAttributes.component = () => import('@/views/ADempiere/Summary')
break
}
return actionAttributes

View File

@ -1,17 +1,7 @@
export function convertRoleFromGRPC(roleGRPC) {
return {
id: roleGRPC.getId(),
uuid: roleGRPC.getUuid(),
name: roleGRPC.getName(),
desctiption: roleGRPC.getDescription(),
clientId: roleGRPC.getClientid(),
clientName: roleGRPC.getClientname(),
organizationsList: roleGRPC.getOrganizationsList()
}
}
export { default } from '@/utils/ADempiere/evaluator.js'
export * from '@/utils/ADempiere/auth.js'
export * from '@/utils/ADempiere/auth.js'
export * from '@/utils/ADempiere/notification.js'
export * from '@/utils/ADempiere/valueUtils.js'
export * from '@/utils/ADempiere/contextUtils.js'

View File

@ -22,6 +22,8 @@ export function isEmptyValue(value) {
return Boolean(!value.trim().length)
} else if (typeof value === 'function' || typeof value === 'number' || typeof value === 'boolean' || Object.prototype.toString.call(value) === '[object Date]') {
return false
} else if (Object.prototype.toString.call(value) === '[object Map]' && value.size === 0) {
return true
} else if (Array.isArray(value)) {
return Boolean(!value.length)
} else if (typeof value === 'object') {

View File

@ -182,7 +182,6 @@ export default {
this.$store.dispatch('user/login', this.loginForm)
.then(() => {
this.$router.push({ path: this.redirect || '/' })
// this.loading = false
})
.catch(error => {
if (error.code === 13) {
@ -190,6 +189,8 @@ export default {
} else {
this.$message.error(this.$t('login.unexpectedError'))
}
})
.finally(() => {
this.loading = false
})
} else {