Pool cars can only be created by admin / Assign users can only be by admin
MODIFY
src/authorization/AuthorizationsDefinition.ts
src/authorization/AuthorizationsDefinition.ts
@@ -103,7 +103,6 @@ const AUTHORIZATION_DEFINITION: AuthorizationDefinition = {
{ resource: Entity.CAR, action: Action.CREATE, attributes: ['*'] },
{ resource: Entity.CARS, action: Action.LIST, attributes: ['*'] },
{ resource: Entity.CAR, action: Action.UPDATE, attributes: ['*'] },
- { resource: Entity.USERS_CARS, action: Action.UPDATE, attributes: ['*'] },
{ resource: Entity.CAR, action: Action.READ, attributes: ['*'] },
{

MODIFY
src/server/rest/service/CarService.ts
src/server/rest/service/CarService.ts
@@ -293,6 +293,8 @@ export default class CarService {
Action.UPDATE, Entity.CAR, MODULE_NAME, 'handleUpdateCar');
// Filter
const filteredRequest = CarSecurity.filterCarUpdateRequest(req.body);
+ // ID is mandatory
+ UtilsService.assertIdIsProvided(action, filteredRequest.id, 'CarSecurity', 'filterCarUpdateRequest', req.user);
// Check
Utils.checkIfCarValid(filteredRequest, req);
// Check auth
@@ -435,7 +437,7 @@ export default class CarService {
next();
}
- public static async handleGetUsersCar(action: Action, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handleGetUsersCar(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.CAR, Action.LIST, Entity.USERS_CARS,
MODULE_NAME, 'handleGetUsersCar');
@@ -449,6 +451,8 @@ export default class CarService {
});
}
const filteredRequest = CarSecurity.filterUsersCarsRequest(req.query);
+ // CarID is mandatory
+ UtilsService.assertIdIsProvided(action, filteredRequest.carID, 'CarSecurity', 'filterUsersCarsRequest', req.user);
// Get cars
const usersCars = await CarStorage.getUsersCars(req.user.tenantID,
{
@@ -464,7 +468,7 @@ export default class CarService {
next();
}
- public static async handleAssignUsersCar(action: Action, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handleAssignUsersCar(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.CAR, Action.CREATE, Entity.USERS_CARS,
MODULE_NAME, 'handleAssignUsersCar');
@@ -473,18 +477,20 @@ export default class CarService {
throw new AppAuthError({
errorCode: HTTPAuthError.ERROR,
user: req.user,
- action: Action.LIST, entity: Entity.USERS_CARS,
+ action: Action.CREATE, entity: Entity.USERS_CARS,
module: MODULE_NAME, method: 'handleAssignUsersCar'
});
}
const filteredRequest = CarSecurity.filterUsersAssignRequest(req.body);
+ // CarID is mandatory
+ UtilsService.assertIdIsProvided(action, filteredRequest.carID, 'CarSecurity', 'filterUsersAssignRequest', req.user);
const result = await CarStorage.assignUsersCar(req.user.tenantID, filteredRequest.carID, filteredRequest.usersCar);
// Return
res.json({ ...result, ...Constants.REST_RESPONSE_SUCCESS });
next();
}
- public static async handleUpdateUsersCar(action: Action, req: Request, res: Response, next: NextFunction): Promise<void> {
+ public static async handleUpdateUsersCar(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.CAR, Action.UPDATE, Entity.USERS_CARS,
MODULE_NAME, 'handleUpdateUsersCar');
@@ -498,6 +504,8 @@ export default class CarService {
});
}
const filteredRequest = CarSecurity.filterUsersAssignRequest(req.body);
+ // CarID is mandatory
+ UtilsService.assertIdIsProvided(action, filteredRequest.carID, 'CarSecurity', 'filterUsersAssignRequest', req.user);
const result = await CarStorage.updateUsersCar(req.user.tenantID, filteredRequest.carID, filteredRequest.usersCar);
res.json({ ...result, ...Constants.REST_RESPONSE_SUCCESS });

MODIFY
src/utils/Utils.ts
src/utils/Utils.ts
import { AnalyticsSettingsType, AssetSettingsType, BillingSettingsType, PricingSettingsType, RefundSettingsType, RoamingSettingsType, SettingDBContent, SmartChargingContentType } from '../types/Setting';
+import { Car, CarType } from '../types/Car';
import { ChargePointStatus, OCPPProtocol, OCPPVersion } from '../types/ocpp/OCPPServer';
import ChargingStation, { ChargePoint, Connector, ConnectorCurrentLimitSource, CurrentType, StaticLimitAmps } from '../types/ChargingStation';
import User, { UserRole, UserStatus } from '../types/User';
@@ -8,7 +9,6 @@ import AppError from '../exception/AppError';
import Asset from '../types/Asset';
import Authorizations from '../authorization/Authorizations';
import BackendError from '../exception/BackendError';
-import { Car } from '../types/Car';
import { ChargingProfile } from '../types/ChargingProfile';
import Company from '../types/Company';
import Configuration from './Configuration';
@@ -1726,6 +1726,26 @@ export default class Utils {
user: req.user.id
});
}
+ if (!car.type) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'Car type is mandatory',
+ module: MODULE_NAME,
+ method: 'checkIfCarValid',
+ user: req.user.id
+ });
+ }
+ if (Authorizations.isBasic(req.user) && car.type === CarType.POOL_CAR) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'Pool cars can only be created by admin',
+ module: MODULE_NAME,
+ method: 'checkIfCarValid',
+ user: req.user.id
+ });
+ }
}
private static _isUserEmailValid(email: string): boolean {

Pool cars can only be created by admin / Assign users can only be acceded by admin