/**
* @namespace Services
* @category Services
* @module rights-service
* */
import store from '../store'
import envService from '@/services/env-service.js'
import { getQueryStringValue } from '@/utils/querystring'
const R = require('ramda')
export const rightsTable = {
location_access: 'GEOV3_LOCALISATION_ACCESS',
location_history_mode: 'GEOV3_LOCALISATION_HISTO_ACCESS',
location_history: 'GEOV3_LOCALISATION_HISTO_VIEW_ROUTES_DONE',
location_circuit: 'GEOV3_LOCALISATION_HISTO_VIEW_ROUTE_SECTIONS',
location_circuit_filter_ignored:
'GEOV3_LOCALISATION_HISTO_VIEW_IGNORED_ROUTE_SECTIO',
location_messages: 'GEOV3_MESSAGES_VIEW_LIST',
location_messages_can_send: 'GEOV3_MESSAGES_SENDED',
location_alerts: 'GEOV3_ALERTS_ACCESS',
location_events: 'GEOV3_EVENTS_ACCESS',
location_chrono: 'GEOV3_LOCALISATION_HISTO_TACHO_SEARCH',
location_identification: 'GEOV3_IDENTIFICATION_ACCESS',
location_position_analysis: 'GEOV3_LOCALISATION_HISTO_VIEW_ROUTES_DONE',
location_search_realtime_driver: 'GEOV3_LOCALISATION_REALTIME_DRIVER_SEARCH',
location_search_realtime_circuit:
'GEOV3_LOCALISATION_REALTIME_CIRCUIT_SEARCH',
location_search_realtime_vehicle:
'GEOV3_LOCALISATION_REALTIME_VEHICULE_SEARCH',
location_search_history_driver: 'GEOV3_LOCALISATION_HISTO_DRIVER_SEARCH',
location_search_history_circuit: 'GEOV3_LOCALISATION_HISTO_CIRCUIT_SEARCH',
location_search_history_vehicle: 'GEOV3_LOCALISATION_HISTO_VEHICLE_SEARCH',
identification_access: 'GEOV3_IDENTIFICATION_ACCESS',
identification_search_circuit: 'GEOV3_IDENTIFICATION_CIRCUIT_SEARCH',
identification_search_vehicle: 'GEOV3_IDENTIFICATION_VEHICLE_SEARCH',
common_login_as_access: 'acceuilselectclient',
common_login_as_user: 'seconnecter',
geocoding_access: 'GEOV3_MAP_SEARCH_ACCESS',
geocoding_address: 'GEOV3_MAP_SEARCH_LOCATE_ADDRESS',
geocoding_address_natural: 'GEOV3_MAP_SEARCH_NATURAL_GEOCODING',
geocoding_address_reverse: 'GEOV3_MAP_SEARCH_REVERSE_GEOCODING',
geocoding_routing: 'GEOV3_MAP_SEARCH_ROUTING',
ecoconduite_access: 'GEOV3_ECOCONDUITE_ACCESS',
circuit_access: 'GEOV3_CIRCUIT_ACCESS',
dashboard_access: 'GEOV3_DASHBOARD_ACCESS',
objects_access: 'GEOV3_OBJECTS_ACCESS',
zones_access: 'GEOV3_ZONES_ACCESS',
diagnostics_access: 'GEOV3_DIAGNOSTIC_ACCESS',
alerts_access: 'GEOV3_ALERTS_ACCESS',
help_access: 'GEOV3_HELP_ACCESS',
events_access: 'GEOV3_EVENTS_ACCESS',
events_search_vehicle: 'GEOV3_EVENTS_VEHICLE_SEARCH',
events_search_circuit: 'GEOV3_EVENTS_CIRCUIT_SEARCH',
diagnostics_chart_chrono: 'GEOV3_LOCALISATION_HISTO_TACHO_SEARCH',
map_predefined_view_list: 'GEOV3_MAPPREDEFINEDVIEW_ACCESS',
map_predefined_view_create: 'GEOV3_MAPPREDEFINEDVIEW_CREATE',
map_predefined_view_edit: 'GEOV3_MAPPREDEFINEDVIEW_EDIT',
map_predefined_view_remove: 'GEOV3_MAPPREDEFINEDVIEW_REMOVE',
nearby_vehicles_feature: 'GEOV3_MAP_SEARCH_NEARBY_VEHICLES',
nearby_vehicles_map_menu_context: 'GEOV3_MAP_MENU_NEARBY_VEHICLES',
map_menu_access: 'GEOV3_MAP_MENU_ACCESS',
}
/**
* Given a list of vue routes (vue-router), returns the first route available for the current user (based access rights loaded on memory)
*
* Note: Routes are sorted by meta.weight ASC. (i.g Location could have priority over Ecoconduite)
* Note: Login route is skip
* Note: Routes with meta.allowRedirect=false are skip
* @todo Add unit-test (router.spec.js)
* @todo Parameter should be a list of non-vue-object routes
* @todo Use a sort polyfill (sort behaves differently in firefox)
* @returns
*/
export function getFirstGrantedRouteFromVueRoutes(vueRoutes) {
return (
vueRoutes
.filter(
(r) =>
r.name !== 'login_as' &&
!(r.meta && r.meta.isTestingRoute === true) &&
(r.meta || {}).allowRedirect !== false &&
!['login_screen', 'login_as'].includes(r.name)
)
.sort((a, b) => {
return (a.meta || { weight: 999 }).weight <
(b.meta || { weight: 999 }).weight
? 1
: -1
})
.find(
(r) =>
((r.meta || {}).requiredRights || [])
.map((rightCode) => {
return store.getters['auth/rightsList'].includes(rightCode)
? '1'
: '0'
})
.join('')
.indexOf('0') === -1
) || null
)
}
/**
* Given a vue route (vue-router), returns TRUE/FALSE if the user has the required access rights.
* @param {*} vueRoute
* @returns
*/
export function isVueRouteGranted(vueRoute) {
return !![vueRoute].find(
(r) =>
((r.meta || {}).requiredRights || [])
.map((rightCode) => {
return store.getters['auth/rightsList'].includes(rightCode)
? '1'
: '0'
})
.join('')
.indexOf('0') === -1
)
}
/**
* Given a list of rights codes and a right code, decide whenever the logged user has the right or not.
* - sabadmin skip validation
* - url?rights=0 skip validation on non production environments
* - url?add_rights=XX add rights (during evaluation) on non production environments
* - url?remove_rights=xx remove rights (during evaluation) on non production environments
* - comparision is case insensitive
* @param {Array} rights List of rights codes
* @param {String} code Right code
* @param {String} loggedUsername Username of the logged user
* @param {String} options.startsWith (Optional) Match rights partially
*/
export function hasRight(rights, code, loggedUsername, options = {}) {
//Non production environments: Can bypass right checking
if (!envService.isProduction() && getQueryStringValue('rights') === '0') {
return true
}
//Non production: Can add rights
if (!envService.isProduction() && getQueryStringValue('add_rights')) {
let addRights = getQueryStringValue('add_rights')
.trim()
.split(',')
.map((code) => code.trim())
rights = R.uniq([...rights, ...addRights])
}
//Non production: Can remove rights
if (!envService.isProduction() && getQueryStringValue('remove_rights')) {
let removeRights = getQueryStringValue('remove_rights')
.trim()
.split(',')
.map((code) => code.trim())
rights = R.difference(rights, removeRights)
}
//Bypass if sabadmin
if (
!!loggedUsername &&
loggedUsername.toLowerCase() === 'sabadmin' &&
(envService.isProduction() ||
(!envService.isProduction() &&
getQueryStringValue('rights_ignore_sabadmin') === '0'))
) {
return true
}
//Bypass if env
if (envService.getEnvValue('VUE_APP_DISABLE_RIGHTS_CHECK', '0') === '1') {
return true
}
//Normalize right code
code = rightsTable[code] !== undefined ? rightsTable[code] : code
//Optional: Returns true if some rights match the code partially
if (options.startsWith) {
return (
rights.findIndex(
(c) => c.toUpperCase().indexOf(code.toUpperCase()) === 0
) !== -1
)
}
return rights.map((c) => c.toUpperCase()).indexOf(code.toUpperCase()) !== -1
}
Source