handleGetCompanies change
MODIFY
src/server/rest/v1/service/AuthorizationService.ts
src/server/rest/v1/service/AuthorizationService.ts
import { Action, AuthorizationFilter, Entity } from '../../../../types/Authorization';
+import { HttpCompaniesRequest, HttpCompanyRequest } from '../../../../types/requests/HttpCompanyRequest';
import { HttpSiteAssignUsersRequest, HttpSiteRequest, HttpSiteUsersRequest } from '../../../../types/requests/HttpSiteRequest';
import { HttpUserAssignSitesRequest, HttpUserRequest, HttpUserSitesRequest, HttpUsersRequest } from '../../../../types/requests/HttpUserRequest';
import User, { UserRole } from '../../../../types/User';
import AppAuthError from '../../../../exception/AppAuthError';
import Authorizations from '../../../../authorization/Authorizations';
-import CompanyStorage from '../../../../storage/mongodb/CompanyStorage';
+import Company from '../../../../types/Company';
import Constants from '../../../../utils/Constants';
import { HTTPAuthError } from '../../../../types/HTTPError';
-import { HttpCompanyRequest } from '../../../../types/requests/HttpCompanyRequest';
import { ServerAction } from '../../../../types/Server';
import Site from '../../../../types/Site';
import SiteStorage from '../../../../storage/mongodb/SiteStorage';
@@ -325,7 +325,62 @@ export default class AuthorizationService {
return authorizationFilters;
}
- // Replace HttpUserRequest with apporpriate
+ public static async addCompaniesAuthorizations(tenant: Tenant, userToken: UserToken, companies: Company[]): Promise<void> {
+ // Get Site Admins - needed?
+ const { siteAdminIDs, siteOwnerIDs } = await AuthorizationService.getSiteAdminOwnerIDs(tenant, userToken);
+ // Set to user
+ userToken.sitesAdmin = siteAdminIDs;
+ userToken.sitesOwner = siteOwnerIDs;
+ // Enrich
+ for (const company of companies) {
+ company.canRead = Authorizations.canReadCompany(userToken, company.id);
+ company.canUpdate = Authorizations.canUpdateCompany(userToken);
+ company.canDelete = Authorizations.canDeleteCompany(userToken);
+ }
+ }
+
+ public static async checkAndGetCompaniesAuthorizationFilters(tenant: Tenant, userToken: UserToken, filteredRequest: HttpCompaniesRequest):Promise<AuthorizationFilter> {
+ const authorizationFilters: AuthorizationFilter = {
+ filters: {},
+ projectFields: [ 'id', 'name', 'address', 'logo', 'issuer', 'distanceMeters', 'createdOn', 'lastChangedOn' ],
+ authorized: userToken.role === UserRole.ADMIN,
+ };
+ // Add user info
+ if (Authorizations.canListUsers(userToken)) {
+ authorizationFilters.projectFields.push(
+ 'createdBy.name', 'createdBy.firstName', 'lastChangedBy.name', 'lastChangedBy.firstName');
+ }
+ // Check Projection
+ if (!Utils.isEmptyArray(filteredRequest.ProjectFields)) {
+ authorizationFilters.projectFields = authorizationFilters.projectFields.filter((projectField) => filteredRequest.ProjectFields.includes(projectField));
+ }
+ // Not an Admin?
+ if (userToken.role !== UserRole.ADMIN) {
+ if (Utils.isTenantComponentActive(tenant, TenantComponents.ORGANIZATION)) {
+ // Get Company IDs from Site Admin flag
+ const companyIDs = await AuthorizationService.getAssignedSitesCompanyIDs(tenant.id, userToken);
+ if (!Utils.isEmptyArray(companyIDs)) {
+ // Force the filter
+ authorizationFilters.filters.companyIDs = companyIDs;
+ // Check if filter is provided
+ if (Utils.objectHasProperty(filteredRequest, 'CompanyID') &&
+ !Utils.isNullOrUndefined(filteredRequest['CompanyID'])) {
+ const filteredCompanyIDs: string[] = filteredRequest['CompanyID'].split('|');
+ // Override
+ authorizationFilters.filters.companyIDs = filteredCompanyIDs.filter(
+ (companyID) => authorizationFilters.filters.companyIDs.includes(companyID));
+ }
+ }
+ if (!Utils.isEmptyArray(authorizationFilters.filters.companyIDs)) {
+ authorizationFilters.authorized = true;
+ }
+ } else {
+ authorizationFilters.authorized = true;
+ }
+ }
+ return authorizationFilters;
+ }
+
public static async checkAndGetCompanyAuthorizationFilters(tenant: Tenant, userToken: UserToken, filteredRequest: HttpCompanyRequest):Promise<AuthorizationFilter> {
const authorizationFilters: AuthorizationFilter = {
filters: {},

MODIFY
src/server/rest/v1/service/CompanyService.ts
src/server/rest/v1/service/CompanyService.ts
@@ -56,7 +56,7 @@ export default class CompanyService {
// Delete
await CompanyStorage.deleteCompany(req.user.tenantID, company.id);
// Log
- Logging.logSecurityInfo({
+ await Logging.logSecurityInfo({
tenantID: req.user.tenantID,
user: req.user, module: MODULE_NAME, method: 'handleDeleteCompany',
message: `Company '${company.name}' has been deleted successfully`,
@@ -141,13 +141,14 @@ export default class CompanyService {
module: MODULE_NAME, method: 'handleGetCompanies'
});
}
- // Check User
- let userProject: string[] = [];
- if (Authorizations.canListUsers(req.user)) {
- userProject = [ 'createdBy.name', 'createdBy.firstName', 'lastChangedBy.name', 'lastChangedBy.firstName' ];
- }
// Filter
const filteredRequest = CompanySecurity.filterCompaniesRequest(req.query);
+ // Check auth
+ const authorizationCompaniesFilter = await AuthorizationService.checkAndGetCompaniesAuthorizationFilters(req.tenant, req.user, filteredRequest);
+ if (!authorizationCompaniesFilter.authorized) {
+ UtilsService.sendEmptyDataResult(res, next);
+ return;
+ }
// Get the companies
const companies = await CompanyStorage.getCompanies(req.user.tenantID,
{
@@ -158,10 +159,18 @@ export default class CompanyService {
withLogo: filteredRequest.WithLogo,
locCoordinates: filteredRequest.LocCoordinates,
locMaxDistanceMeters: filteredRequest.LocMaxDistanceMeters,
+ ...authorizationCompaniesFilter.filters
+ },
+ {
+ limit: filteredRequest.Limit,
+ skip: filteredRequest.Skip,
+ sort: filteredRequest.SortFields,
+ onlyRecordCount: filteredRequest.OnlyRecordCount
},
- { limit: filteredRequest.Limit, skip: filteredRequest.Skip, sort: filteredRequest.SortFields, onlyRecordCount: filteredRequest.OnlyRecordCount },
- [ 'id', 'name', 'address', 'logo', 'issuer', 'distanceMeters', 'createdOn', 'lastChangedOn', ...userProject ]
+ authorizationCompaniesFilter.projectFields
);
+ // Add Auth flags
+ AuthorizationService.addCompaniesAuthorizations(req.tenant, req.user, companies.result);
// Return
res.json(companies);
next();
@@ -194,7 +203,7 @@ export default class CompanyService {
// Save
newCompany.id = await CompanyStorage.saveCompany(req.user.tenantID, newCompany);
// Log
- Logging.logSecurityInfo({
+ await Logging.logSecurityInfo({
tenantID: req.user.tenantID,
user: req.user, module: MODULE_NAME, method: 'handleCreateCompany',
message: `Company '${newCompany.id}' has been created successfully`,
@@ -250,7 +259,7 @@ export default class CompanyService {
// Update Company
await CompanyStorage.saveCompany(req.user.tenantID, company, Utils.objectHasProperty(filteredRequest, 'logo') ? true : false);
// Log
- Logging.logSecurityInfo({
+ await Logging.logSecurityInfo({
tenantID: req.user.tenantID,
user: req.user, module: MODULE_NAME, method: 'handleUpdateCompany',
message: `Company '${company.name}' has been updated successfully`,

MODIFY
src/types/Company.ts
src/types/Company.ts
import Address from './Address';
+import { AuthorizationActions } from './Authorization';
import CreatedUpdatedProps from './CreatedUpdatedProps';
import Site from './Site';
-export default interface Company extends CreatedUpdatedProps {
+export default interface Company extends CreatedUpdatedProps, AuthorizationActions {
id: string;
name: string;
issuer: boolean;

handleGetCompanies change