re aligned user sites / site users
userSites are SITEs
siteUsers are USERs
MODIFY
src/authorization/Authorizations.ts
src/authorization/Authorizations.ts
@@ -132,17 +132,17 @@ export default class Authorizations {
const siteAdminIDs = [];
const siteOwnerIDs = [];
// Get User's site
- const siteUsers = (await UserStorage.getSiteUsers(tenant, { userIDs: [user.id] },
+ const userSites = (await UserStorage.getUserSites(tenant, { userIDs: [user.id] },
Constants.DB_PARAMS_MAX_LIMIT)).result;
- for (const siteUser of siteUsers) {
+ for (const userSite of userSites) {
if (!Authorizations.isAdmin(user)) {
- siteIDs.push(siteUser.site.id);
- if (siteUser.siteAdmin) {
- siteAdminIDs.push(siteUser.site.id);
+ siteIDs.push(userSite.site.id);
+ if (userSite.siteAdmin) {
+ siteAdminIDs.push(userSite.site.id);
}
}
- if (siteUser.siteOwner) {
- siteOwnerIDs.push(siteUser.site.id);
+ if (userSite.siteOwner) {
+ siteOwnerIDs.push(userSite.site.id);
}
}
let tenantHashID = Constants.DEFAULT_TENANT_ID;

MODIFY
src/authorization/dynamic-data-source/SitesAdminDynamicAuthorizationDataSource.ts
src/authorization/dynamic-data-source/SitesAdminDynamicAuthorizationDataSource.ts
@@ -21,13 +21,13 @@ export default class SitesAdminDynamicAuthorizationDataSource
private async getSitesAdminSiteIDs(): Promise<string[]> {
// Get the Site IDs of the Sites for which the user is Site Admin
- const siteUsers = await UserStorage.getSiteUsers(this.tenant,
+ const userSites = await UserStorage.getUserSites(this.tenant,
{
userIDs: [this.userToken.id],
siteAdmin: true
}, Constants.DB_PARAMS_MAX_LIMIT,
['siteID']
);
- return siteUsers.result.map((siteUser) => siteUser.siteID);
+ return userSites.result.map((userSite) => userSite.siteID);
}
}

MODIFY
src/authorization/dynamic-data-source/SitesOwnerDynamicAuthorizationDataSource.ts
src/authorization/dynamic-data-source/SitesOwnerDynamicAuthorizationDataSource.ts
@@ -21,13 +21,13 @@ export default class SitesOwnerDynamicAuthorizationDataSource
private async getSitesOwnerSiteIDs(): Promise<string[]> {
// Get the Site IDs of the Sites for which the user is Site Owner
- const siteUsers = await UserStorage.getSiteUsers(this.tenant,
+ const userSites = await UserStorage.getUserSites(this.tenant,
{
userIDs: [this.userToken.id],
siteOwner: true
}, Constants.DB_PARAMS_MAX_LIMIT,
['siteID']
);
- return siteUsers.result.map((siteUser) => siteUser.siteID);
+ return userSites.result.map((userSite) => userSite.siteID);
}
}

MODIFY
src/server/rest/v1/service/AuthorizationService.ts
src/server/rest/v1/service/AuthorizationService.ts
@@ -60,14 +60,14 @@ export default class AuthorizationService {
// Add Meta Data
userSites.metadata = authorizationFilter.metadata;
// Add Authorizations
- userSites.canUpdateUserSite = await AuthorizationService.canPerformAuthorizationAction(tenant, userToken, Entity.USERS_SITES, Action.UPDATE, authorizationFilter);
+ userSites.canUpdateUserSites = await AuthorizationService.canPerformAuthorizationAction(tenant, userToken, Entity.USERS_SITES, Action.UPDATE, authorizationFilter);
}
public static async addSiteUsersAuthorizations(tenant: Tenant, userToken: UserToken, siteUsers: SiteUserDataResult, authorizationFilter: AuthorizationFilter): Promise<void> {
// Add Meta Data
siteUsers.metadata = authorizationFilter.metadata;
// Add Authorizations
- siteUsers.canUpdateUserSite = await AuthorizationService.canPerformAuthorizationAction(tenant, userToken, Entity.USERS_SITES, Action.UPDATE, authorizationFilter);
+ siteUsers.canUpdateSiteUsers = await AuthorizationService.canPerformAuthorizationAction(tenant, userToken, Entity.USERS_SITES, Action.UPDATE, authorizationFilter);
}
public static async addSitesAuthorizations(tenant: Tenant, userToken: UserToken, sites: SiteDataResult, authorizationFilter: AuthorizationFilter): Promise<void> {
@@ -248,6 +248,10 @@ export default class AuthorizationService {
tenant, userToken, Entity.USERS_SITES, Action.ASSIGN, authorizationFilter, { UserID: user.id }, user);
user.canUnassignSites = await AuthorizationService.canPerformAuthorizationAction(
tenant, userToken, Entity.USERS_SITES, Action.UNASSIGN, authorizationFilter, { UserID: user.id }, user);
+ user.canListSites = await AuthorizationService.canPerformAuthorizationAction(
+ tenant, userToken, Entity.SITE, Action.LIST, authorizationFilter, { UserID: user.id }, user);
+ user.canListTokens = await AuthorizationService.canPerformAuthorizationAction(
+ tenant, userToken, Entity.REGISTRATION_TOKEN, Action.LIST, authorizationFilter, { UserID: user.id }, user);
Utils.removeCanPropertiesWithFalseValue(user);
}

MODIFY
src/server/rest/v1/service/SiteService.ts
src/server/rest/v1/service/SiteService.ts
import { Action, Entity } from '../../../../types/Authorization';
import { NextFunction, Request, Response } from 'express';
-import { SiteDataResult, UserSiteDataResult } from '../../../../types/DataResult';
+import { SiteDataResult, SiteUserDataResult, UserSiteDataResult } from '../../../../types/DataResult';
import AppError from '../../../../exception/AppError';
import AuthorizationService from './AuthorizationService';
@@ -130,7 +130,7 @@ export default class SiteService {
return;
}
// Get Users
- const userSites = await SiteStorage.getUserSites(req.tenant,
+ const siteUsers = await SiteStorage.getSiteUsers(req.tenant,
{
search: filteredRequest.Search,
siteIDs: [filteredRequest.SiteID],
@@ -145,15 +145,15 @@ export default class SiteService {
authorizations.projectFields
);
// Filter
- userSites.result = userSites.result.map((userSite) => ({
- siteID: userSite.siteID,
- siteAdmin: userSite.siteAdmin,
- siteOwner: userSite.siteOwner,
- user: userSite.user
+ siteUsers.result = siteUsers.result.map((siteUser) => ({
+ siteID: siteUser.siteID,
+ siteAdmin: siteUser.siteAdmin,
+ siteOwner: siteUser.siteOwner,
+ user: siteUser.user
}));
// add user auth
- await AuthorizationService.addUserSitesAuthorizations(req.tenant, req.user, userSites as UserSiteDataResult, authorizations);
- res.json(userSites);
+ await AuthorizationService.addSiteUsersAuthorizations(req.tenant, req.user, siteUsers as SiteUserDataResult, authorizations);
+ res.json(siteUsers);
next();
}

MODIFY
src/server/rest/v1/service/UserService.ts
src/server/rest/v1/service/UserService.ts
@@ -3,7 +3,7 @@ import { ActionsResponse, ImportStatus } from '../../../../types/GlobalType';
import { AsyncTaskType, AsyncTasks } from '../../../../types/AsyncTask';
import Busboy, { FileInfo } from 'busboy';
import { Car, CarType } from '../../../../types/Car';
-import { DataResult, SiteDataResult, SiteUserDataResult, UserDataResult } from '../../../../types/DataResult';
+import { DataResult, UserDataResult, UserSiteDataResult } from '../../../../types/DataResult';
import { HTTPAuthError, HTTPError } from '../../../../types/HTTPError';
import { NextFunction, Request, Response } from 'express';
import Tenant, { TenantComponents } from '../../../../types/Tenant';
@@ -341,14 +341,12 @@ export default class UserService {
// Check dynamic auth for reading Sites
const authorizations = await AuthorizationService.checkAndGetUserSitesAuthorizations(req.tenant,
req.user, filteredRequest);
- // const authorizations = await AuthorizationService.checkAndGetSitesAuthorizations(req.tenant,
- // req.user, filteredRequest);
if (!authorizations.authorized) {
UtilsService.sendEmptyDataResult(res, next);
return;
}
// Get Sites
- const siteUsers = await UserStorage.getSiteUsers(req.tenant,
+ const userSites = await UserStorage.getUserSites(req.tenant,
{
search: filteredRequest.Search,
userIDs: [filteredRequest.UserID],
@@ -363,16 +361,15 @@ export default class UserService {
authorizations.projectFields
);
// Filter
- siteUsers.result = siteUsers.result.map((siteUser) => ({
- userID: siteUser.userID,
- siteAdmin: siteUser.siteAdmin,
- siteOwner: siteUser.siteOwner,
- site: siteUser.site
+ userSites.result = userSites.result.map((userSite) => ({
+ userID: userSite.userID,
+ siteAdmin: userSite.siteAdmin,
+ siteOwner: userSite.siteOwner,
+ site: userSite.site
}));
// Add Auth flags
- await AuthorizationService.addSiteUsersAuthorizations(req.tenant, req.user, siteUsers as SiteUserDataResult , authorizations);
- // await AuthorizationService.addSiteAuthorizations(req.tenant, req.user, siteUsers.result. as SiteDataResult , authorizations);
- res.json(siteUsers);
+ await AuthorizationService.addUserSitesAuthorizations(req.tenant, req.user, userSites as UserSiteDataResult , authorizations);
+ res.json(userSites);
next();
}

MODIFY
src/storage/mongodb/SiteStorage.ts
src/storage/mongodb/SiteStorage.ts
@@ -10,9 +10,9 @@ import Logging from '../../utils/Logging';
import { ObjectId } from 'mongodb';
import Site from '../../types/Site';
import SiteAreaStorage from './SiteAreaStorage';
+import { SiteUser } from '../../types/User';
import Tenant from '../../types/Tenant';
import TransactionStorage from './TransactionStorage';
-import { UserSite } from '../../types/User';
import Utils from '../../utils/Utils';
const MODULE_NAME = 'SiteStorage';
@@ -96,9 +96,9 @@ export default class SiteStorage {
await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'addUsersToSite', startTime, userIDs);
}
- public static async getUserSites(tenant: Tenant,
+ public static async getSiteUsers(tenant: Tenant,
params: { search?: string; siteIDs: string[]; siteOwnerOnly?: boolean },
- dbParams: DbParams, projectFields?: string[]): Promise<DataResult<UserSite>> {
+ dbParams: DbParams, projectFields?: string[]): Promise<DataResult<SiteUser>> {
const startTime = Logging.traceDatabaseRequestStart();
DatabaseUtils.checkTenantObject(tenant);
// Clone before updating the values
@@ -155,14 +155,14 @@ export default class SiteStorage {
aggregation.push({ $limit: Constants.DB_RECORD_COUNT_CEIL });
}
// Count Records
- const userSitesCountMDB = await global.database.getCollection<any>(tenant.id, 'siteusers')
+ const siteUsersCountMDB = await global.database.getCollection<any>(tenant.id, 'siteusers')
.aggregate([...aggregation, { $count: 'count' }], DatabaseUtils.buildAggregateOptions())
.toArray() as DatabaseCount[];
// Check if only the total count is requested
if (dbParams.onlyRecordCount) {
- await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'getSitesUsers', startTime, aggregation, userSitesCountMDB);
+ await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'getSitesUsers', startTime, aggregation, siteUsersCountMDB);
return {
- count: (userSitesCountMDB.length > 0 ? userSitesCountMDB[0].count : 0),
+ count: (siteUsersCountMDB.length > 0 ? siteUsersCountMDB[0].count : 0),
result: []
};
}
@@ -191,13 +191,13 @@ export default class SiteStorage {
// Project
DatabaseUtils.projectFields(aggregation, projectFields);
// Read DB
- const userSitesMDB = await global.database.getCollection<any>(tenant.id, 'siteusers')
+ const siteUsersMDB = await global.database.getCollection<any>(tenant.id, 'siteusers')
.aggregate<any>(aggregation, DatabaseUtils.buildAggregateOptions())
- .toArray() as UserSite[];
- await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'getSitesUsers', startTime, aggregation, userSitesCountMDB);
+ .toArray() as SiteUser[];
+ await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'getSitesUsers', startTime, aggregation, siteUsersCountMDB);
return {
- count: DatabaseUtils.getCountFromDatabaseCount(userSitesCountMDB[0]),
- result: userSitesMDB
+ count: DatabaseUtils.getCountFromDatabaseCount(siteUsersCountMDB[0]),
+ result: siteUsersMDB
};
}
@@ -536,17 +536,4 @@ export default class SiteStorage {
await SiteStorage.deleteSites(tenant, siteIDs);
await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'deleteCompanySites', startTime, { companyID });
}
-
- // public static async siteHasUser(tenant: Tenant, siteID: string, userID: string): Promise<boolean> {
- // const startTime = Logging.traceDatabaseRequestStart();
- // DatabaseUtils.checkTenantObject(tenant);
- // // Exec
- // const result = await global.database.getCollection<any>(tenant.id, 'siteusers').findOne(
- // { siteID: DatabaseUtils.convertToObjectID(siteID), userID: DatabaseUtils.convertToObjectID(userID) });
- // await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'siteHasUser', startTime, { siteID });
- // if (!result) {
- // return false;
- // }
- // return true;
- // }
}

MODIFY
src/storage/mongodb/UserStorage.ts
src/storage/mongodb/UserStorage.ts
@@ -14,9 +14,9 @@ import Eula from '../../types/Eula';
import Logging from '../../utils/Logging';
import Mustache from 'mustache';
import { ObjectId } from 'mongodb';
-import { SiteUser } from '../../types/Site';
import TagStorage from './TagStorage';
import UserNotifications from '../../types/UserNotifications';
+import { UserSite } from '../../types/Site';
import Utils from '../../utils/Utils';
import fs from 'fs';
import moment from 'moment';
@@ -149,10 +149,10 @@ export default class UserStorage {
DatabaseUtils.checkTenantObject(tenant);
// At least one Site
if (!Utils.isEmptyArray(siteIDs)) {
- const siteUsersMDB = [];
+ const userSitesMDB = [];
// Create the list
for (const siteID of siteIDs) {
- siteUsersMDB.push({
+ userSitesMDB.push({
'_id': Utils.hash(`${siteID}~${userID}`),
'userID': DatabaseUtils.convertToObjectID(userID),
'siteID': DatabaseUtils.convertToObjectID(siteID),
@@ -160,7 +160,7 @@ export default class UserStorage {
});
}
// Execute
- await global.database.getCollection<any>(tenant.id, 'siteusers').insertMany(siteUsersMDB);
+ await global.database.getCollection<any>(tenant.id, 'siteusers').insertMany(userSitesMDB);
}
await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'addSitesToUser', startTime, siteIDs);
}
@@ -182,7 +182,7 @@ export default class UserStorage {
public static async addSiteToUser(tenant: Tenant, userID: string, siteID: string): Promise<string> {
const startTime = Logging.traceDatabaseRequestStart();
DatabaseUtils.checkTenantObject(tenant);
- const siteUserMDB = {
+ const userSiteMDB = {
'_id': Utils.hash(`${siteID}~${userID}`),
'userID': DatabaseUtils.convertToObjectID(userID),
'siteID': DatabaseUtils.convertToObjectID(siteID),
@@ -190,12 +190,12 @@ export default class UserStorage {
};
// Execute
await global.database.getCollection<any>(tenant.id, 'siteusers').findOneAndUpdate(
- { userID: siteUserMDB.userID, siteID: siteUserMDB.siteID },
- { $set: siteUserMDB },
+ { userID: userSiteMDB.userID, siteID: userSiteMDB.siteID },
+ { $set: userSiteMDB },
{ upsert: true }
);
await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'addSiteToUser', startTime, siteID);
- return siteUserMDB._id;
+ return userSiteMDB._id;
}
public static async saveUser(tenant: Tenant, userToSave: User, saveImage = false): Promise<string> {
@@ -910,9 +910,9 @@ export default class UserStorage {
await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'deleteUser', startTime, { id });
}
- public static async getSiteUsers(tenant: Tenant,
+ public static async getUserSites(tenant: Tenant,
params: { search?: string; userIDs: string[]; siteIDs?: string[]; siteAdmin?: boolean; siteOwner?: boolean },
- dbParams: DbParams, projectFields?: string[]): Promise<DataResult<SiteUser>> {
+ dbParams: DbParams, projectFields?: string[]): Promise<DataResult<UserSite>> {
const startTime = Logging.traceDatabaseRequestStart();
DatabaseUtils.checkTenantObject(tenant);
// Clone before updating the values
@@ -970,14 +970,14 @@ export default class UserStorage {
aggregation.push({ $limit: Constants.DB_RECORD_COUNT_CEIL });
}
// Count Records
- const siteUsersCountMDB = await global.database.getCollection<any>(tenant.id, 'siteusers')
+ const userSitesCountMDB = await global.database.getCollection<any>(tenant.id, 'siteusers')
.aggregate([...aggregation, { $count: 'count' }], DatabaseUtils.buildAggregateOptions())
.toArray() as DatabaseCount[];
// Check if only the total count is requested
if (dbParams.onlyRecordCount) {
- await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'getUserSites', startTime, siteUsersCountMDB);
+ await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'getUserSites', startTime, userSitesCountMDB);
return {
- count: (!Utils.isEmptyArray(siteUsersCountMDB) ? siteUsersCountMDB[0].count : 0),
+ count: (!Utils.isEmptyArray(userSitesCountMDB) ? userSitesCountMDB[0].count : 0),
result: []
};
}
@@ -1006,13 +1006,13 @@ export default class UserStorage {
// Project
DatabaseUtils.projectFields(aggregation, projectFields);
// Read DB
- const siteUsersMDB = await global.database.getCollection<any>(tenant.id, 'siteusers')
+ const userSitesMDB = await global.database.getCollection<any>(tenant.id, 'siteusers')
.aggregate<any>(aggregation, DatabaseUtils.buildAggregateOptions())
- .toArray() as SiteUser[];
- await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'getUserSites', startTime, siteUsersMDB);
+ .toArray() as UserSite[];
+ await Logging.traceDatabaseRequestEnd(tenant, MODULE_NAME, 'getUserSites', startTime, userSitesMDB);
return {
- count: DatabaseUtils.getCountFromDatabaseCount(siteUsersCountMDB[0]),
- result: siteUsersMDB,
+ count: DatabaseUtils.getCountFromDatabaseCount(userSitesCountMDB[0]),
+ result: userSitesMDB,
projectFields: projectFields
};
}

MODIFY
src/types/Authorization.ts
src/types/Authorization.ts
@@ -191,6 +191,8 @@ export interface AuthorizationActions {
export interface UserAuthorizationActions extends AuthorizationActions {
canAssignSites?: boolean;
canUnassignSites?: boolean;
+ canListSites?: boolean;
+ canListTokens?: boolean;
}
export interface TagAuthorizationActions extends AuthorizationActions {

MODIFY
src/types/DataResult.ts
src/types/DataResult.ts
import { BillingInvoice, BillingPaymentMethod } from './Billing';
import { Car, CarCatalog } from './Car';
-import Site, { SiteUser } from './Site';
+import Site, { UserSite } from './Site';
import Transaction, { TransactionStats } from './Transaction';
-import User, { UserSite } from './User';
+import User, { SiteUser } from './User';
import Asset from './Asset';
import { AuthorizationDefinitionFieldMetadata } from './Authorization';
@@ -45,11 +45,11 @@ export interface SiteDataResult extends DataResult<Site> {
}
export interface UserSiteDataResult extends DataResult<UserSite> {
- canUpdateUserSite: boolean;
+ canUpdateUserSites: boolean;
}
export interface SiteUserDataResult extends DataResult<SiteUser> {
- canUpdateUserSite: boolean;
+ canUpdateSiteUsers: boolean;
}
export interface LogDataResult extends DataResult<Log> {

MODIFY
src/types/Site.ts
src/types/Site.ts
@@ -24,7 +24,7 @@ export default interface Site extends CreatedUpdatedProps, SiteAuthorizationActi
tariffID?: string;
}
-export interface SiteUser {
+export interface UserSite {
site: Site;
siteID?: string;
userID: string;

MODIFY
src/types/User.ts
src/types/User.ts
@@ -54,7 +54,7 @@ export interface StartTransactionUserData {
lastDepartureTime: Date;
}
-export interface UserSite {
+export interface SiteUser {
user: User;
userID?: string;
siteID: string;

re aligned user sites / site users
userSites are SITEs
siteUsers are USERs