Refactor handleGetTags + add 2 new dynamic filters.
MODIFY
src/authorization/AuthorizationsDefinition.ts
src/authorization/AuthorizationsDefinition.ts
@@ -323,7 +323,6 @@ const AUTHORIZATION_DEFINITION: AuthorizationDefinition = {
]
}
},
- { resource: Entity.TAG, action: Action.READ, attributes: ['*'] },
{
resource: Entity.TAGS, action: Action.LIST, attributes: [
'id', 'userID', 'active', 'ocpiToken', 'description', 'issuer', 'default',
@@ -331,9 +330,10 @@ const AUTHORIZATION_DEFINITION: AuthorizationDefinition = {
],
condition: {
Fn: 'custom:dynamicAuthorizationFilters',
- args: { filters: ['SitesAdmin'] }
+ args: { filters: ['OwnUser'] }
}
},
+ { resource: Entity.TAG, action: Action.READ, attributes: ['*'] },
{
resource: Entity.CHARGING_STATION,
action: [Action.REMOTE_STOP_TRANSACTION, Action.STOP_TRANSACTION],
@@ -554,6 +554,16 @@ const AUTHORIZATION_DEFINITION: AuthorizationDefinition = {
attributes: ['*'],
args: { 'sites': '$.site' }
},
+ {
+ resource: Entity.TAGS, action: Action.LIST, attributes: [
+ 'id', 'userID', 'active', 'ocpiToken', 'description', 'issuer', 'default',
+ 'createdOn', 'lastChangedOn'
+ ],
+ condition: {
+ Fn: 'custom:dynamicAuthorizationFilters',
+ args: { filters: ['SiteAdminUsers'] }
+ }
+ },
{ resource: Entity.TAGS, action: Action.EXPORT, attributes: ['*'] },
]
},

MODIFY
src/authorization/DynamicAuthorizationFactory.ts
src/authorization/DynamicAuthorizationFactory.ts
@@ -8,6 +8,10 @@ import AssignedSitesDynamicAuthorizationDataSource from './dynamic-data-source/A
import AssignedSitesDynamicAuthorizationFilter from './dynamic-filters/AssignedSitesDynamicAuthorizationFilter';
import DynamicAuthorizationDataSource from './DynamicAuthorizationDataSource';
import DynamicAuthorizationFilter from './DynamicAuthorizationFilter';
+import OwnUserDynamicAuthorizationDataSource from './dynamic-data-source/OwnUserDynamicAuthorizationDataSource';
+import OwnUserDynamicAuthorizationFilter from './dynamic-filters/OwnUserDynamicAuthorizationFilter';
+import SiteAdminUsersDynamicAuthorizationDataSource from './dynamic-data-source/SiteAdminUsersDynamicAuthorizationDataSource';
+import SiteAdminUsersDynamicAuthorizationFilter from './dynamic-filters/SiteAdminUsersDynamicAuthorizationFilter';
import SitesAdminDynamicAuthorizationDataSource from './dynamic-data-source/SitesAdminDynamicAuthorizationDataSource';
import SitesAdminDynamicAuthorizationFilter from './dynamic-filters/SitesAdminDynamicAuthorizationFilter';
import Tenant from '../types/Tenant';
@@ -32,6 +36,12 @@ export default class DynamicAuthorizationFactory {
case DynamicAuthorizationFilterName.ASSIGNED_SITES:
dynamicFilter = new AssignedSitesDynamicAuthorizationFilter(tenant, userToken);
break;
+ case DynamicAuthorizationFilterName.SITE_ADMIN_USERS:
+ dynamicFilter = new SiteAdminUsersDynamicAuthorizationFilter(tenant, userToken);
+ break;
+ case DynamicAuthorizationFilterName.OWN_USER:
+ dynamicFilter = new OwnUserDynamicAuthorizationFilter(tenant, userToken);
+ break;
}
// Init Data Source
if (dynamicFilter) {
@@ -72,6 +82,10 @@ export default class DynamicAuthorizationFactory {
return new AssignedSiteAreasDynamicAuthorizationDataSource(tenant, user);
case DynamicAuthorizationDataSourceName.ASSIGNED_SITES:
return new AssignedSitesDynamicAuthorizationDataSource(tenant, user);
+ case DynamicAuthorizationDataSourceName.SITE_ADMIN_USERS:
+ return new SiteAdminUsersDynamicAuthorizationDataSource(tenant, user);
+ case DynamicAuthorizationDataSourceName.OWN_USER:
+ return new OwnUserDynamicAuthorizationDataSource(tenant, user);
}
}
}

ADD
src/authorization/dynamic-data-source/OwnUserDynamicAuthorizationDataSource.ts
+import { DynamicAuthorizationDataSourceName, OwnUserDynamicAuthorizationDataSourceData } from '../../types/Authorization';
+
+import DynamicAuthorizationDataSource from '../DynamicAuthorizationDataSource';
+
+export default class OwnUserDynamicAuthorizationDataSource
+ extends DynamicAuthorizationDataSource<OwnUserDynamicAuthorizationDataSourceData> {
+
+ public getName(): DynamicAuthorizationDataSourceName {
+ return DynamicAuthorizationDataSourceName.OWN_USER;
+ }
+
+ public async loadData(): Promise<void> {
+ const ownUserData: OwnUserDynamicAuthorizationDataSourceData = {};
+ // Get User ID
+ ownUserData.userID = await this.getOwnUserID();
+ // Set
+ this.setData(ownUserData);
+ }
+
+ private async getOwnUserID(): Promise<string> {
+ return Promise.resolve(this.userToken.id);
+ }
+}

ADD
src/authorization/dynamic-data-source/SiteAdminUsersDynamicAuthorizationDataSource.ts
+import { DynamicAuthorizationDataSourceName, SiteAdminUsersDynamicAuthorizationDataSourceData } from '../../types/Authorization';
+
+import Constants from '../../utils/Constants';
+import DynamicAuthorizationDataSource from '../DynamicAuthorizationDataSource';
+import UserStorage from '../../storage/mongodb/UserStorage';
+
+export default class SiteAdminUsersDynamicAuthorizationDataSource
+ extends DynamicAuthorizationDataSource<SiteAdminUsersDynamicAuthorizationDataSourceData> {
+
+ public getName(): DynamicAuthorizationDataSourceName {
+ return DynamicAuthorizationDataSourceName.SITE_ADMIN_USERS;
+ }
+
+ public async loadData(): Promise<void> {
+ const siteAdminUsersData: SiteAdminUsersDynamicAuthorizationDataSourceData = {};
+ // Get Site IDs from Site Admin flag
+ siteAdminUsersData.userIDs = await this.getSiteAdminUserIDs();
+ // Set
+ this.setData(siteAdminUsersData);
+ }
+
+ private async getSiteAdminUserIDs(): Promise<string[]> {
+ // Get the Site IDs where the logged on User is SiteAdmin
+ const sites = await UserStorage.getUserSites(this.tenant.id,
+ {
+ userID: this.userToken.id,
+ siteAdmin: true
+ }, Constants.DB_PARAMS_MAX_LIMIT,
+ ['siteID']
+ );
+ // Get the User IDs of the Users belonging to Sites where the logged on User is SiteAdmin
+ const users = await UserStorage.getUsers(this.tenant.id,
+ {
+ siteIDs: sites.result.map((userSite) => userSite.siteID)
+ }, Constants.DB_PARAMS_MAX_LIMIT,
+ ['id']);
+ return users.result.map((user) => user.id);
+ }
+}

ADD
src/authorization/dynamic-filters/OwnUserDynamicAuthorizationFilter.ts
+import { AuthorizationFilter, DynamicAuthorizationDataSourceName, Entity } from '../../types/Authorization';
+
+import DynamicAuthorizationFilter from '../DynamicAuthorizationFilter';
+import OwnUserDynamicAuthorizationDataSource from '../dynamic-data-source/OwnUserDynamicAuthorizationDataSource';
+import Utils from '../../utils/Utils';
+
+export default class OwnUserDynamicAuthorizationFilter extends DynamicAuthorizationFilter {
+ public processFilter(authorizationFilters: AuthorizationFilter, extraFilters: Record<string, any>): void {
+ // Get User ID
+ const ownUserDataSource = this.getDataSource(
+ DynamicAuthorizationDataSourceName.OWN_USER) as OwnUserDynamicAuthorizationDataSource;
+ const { userID } = ownUserDataSource.getData();
+ // Check
+ if (userID) {
+ // Force the filter
+ authorizationFilters.filters.userIDs = [userID];
+ // Check if filter is provided
+ if (Utils.objectHasProperty(extraFilters, 'UserID') &&
+ !Utils.isNullOrUndefined(extraFilters['UserID'])) {
+ const filteredUserIDs: string[] = extraFilters['UserID'].split('|');
+ // Override
+ authorizationFilters.filters.userIDs = filteredUserIDs.filter(
+ (user) => authorizationFilters.filters.userIDs.includes(user));
+ }
+ }
+ if (!Utils.isEmptyArray(authorizationFilters.filters.userIDs)) {
+ authorizationFilters.authorized = true;
+ }
+ }
+
+ public getApplicableEntities(): Entity[] {
+ return [
+ Entity.TAGS
+ ];
+ }
+
+ public getApplicableDataSources(): DynamicAuthorizationDataSourceName[] {
+ return [
+ DynamicAuthorizationDataSourceName.OWN_USER
+ ];
+ }
+}

ADD
src/authorization/dynamic-filters/SiteAdminUsersDynamicAuthorizationFilter.ts
+import { AuthorizationFilter, DynamicAuthorizationDataSourceName, Entity } from '../../types/Authorization';
+
+import DynamicAuthorizationFilter from '../DynamicAuthorizationFilter';
+import SiteAdminUsersDynamicAuthorizationDataSource from '../dynamic-data-source/SiteAdminUsersDynamicAuthorizationDataSource';
+import Utils from '../../utils/Utils';
+
+export default class SiteAdminUsersDynamicAuthorizationFilter extends DynamicAuthorizationFilter {
+ public processFilter(authorizationFilters: AuthorizationFilter, extraFilters: Record<string, any>): void {
+ // Get User IDs
+ const siteAdminUsersDataSource = this.getDataSource(
+ DynamicAuthorizationDataSourceName.SITE_ADMIN_USERS) as SiteAdminUsersDynamicAuthorizationDataSource;
+ const { userIDs } = siteAdminUsersDataSource.getData();
+ // Check
+ if (!Utils.isEmptyArray(userIDs)) {
+ // Force the filter
+ authorizationFilters.filters.userIDs = userIDs;
+ // Check if filter is provided
+ if (Utils.objectHasProperty(extraFilters, 'UserID') &&
+ !Utils.isNullOrUndefined(extraFilters['UserID'])) {
+ const filteredUserIDs: string[] = extraFilters['UserID'].split('|');
+ // Override
+ authorizationFilters.filters.userIDs = filteredUserIDs.filter(
+ (userID) => authorizationFilters.filters.userIDs.includes(userID));
+ }
+ }
+ if (!Utils.isEmptyArray(authorizationFilters.filters.userIDs)) {
+ authorizationFilters.authorized = true;
+ }
+ }
+
+ public getApplicableEntities(): Entity[] {
+ return [
+ Entity.TAGS
+ ];
+ }
+
+ public getApplicableDataSources(): DynamicAuthorizationDataSourceName[] {
+ return [
+ DynamicAuthorizationDataSourceName.SITE_ADMIN_USERS
+ ];
+ }
+}

MODIFY
src/authorization/dynamic-filters/SitesAdminDynamicAuthorizationFilter.ts
src/authorization/dynamic-filters/SitesAdminDynamicAuthorizationFilter.ts
@@ -30,7 +30,8 @@ export default class SitesAdminDynamicAuthorizationFilter extends DynamicAuthori
public getApplicableEntities(): Entity[] {
return [
- Entity.SITE
+ Entity.SITE,
+ Entity.USERS
];
}

MODIFY
src/server/rest/v1/service/TagService.ts
src/server/rest/v1/service/TagService.ts
@@ -733,36 +733,21 @@ export default class TagService {
module: MODULE_NAME, method: 'getTags'
});
}
- // Get authorization filters
+ // Get authorization filters for users
const authorizationUsersFilters = await AuthorizationService.checkAndGetUsersAuthorizationFilters(
req.tenant, req.user);
if (authorizationUsersFilters.authorized) {
authorizationTagsFilters.projectFields.push('userID', 'user.id', 'user.name', 'user.firstName', 'user.email',
'createdBy.name', 'createdBy.firstName', 'lastChangedBy.name', 'lastChangedBy.firstName');
}
- // todo: refactor
- // if (await Authorizations.canListUsers(userToken)) {
- // authorizationFilters.projectFields.push('userID', 'user.id', 'user.name', 'user.firstName', 'user.email',
- // 'createdBy.name', 'createdBy.firstName', 'lastChangedBy.name', 'lastChangedBy.firstName');
- // }
- // todo: dynamic filters
- // // Handle Sites
- // await AuthorizationService.checkAssignedSiteAdminsAndOwners(
- // tenant, userToken, null, authorizationFilters);
- let userID: string;
- if (Authorizations.isBasic(req.user)) {
- userID = req.user.id;
- } else {
- userID = filteredRequest.UserID;
- }
// Get the tags
const tags = await TagStorage.getTags(req.user.tenantID,
{
search: filteredRequest.Search,
- userIDs: userID ? userID.split('|') : null,
issuer: filteredRequest.Issuer,
active: filteredRequest.Active,
withUser: filteredRequest.WithUser,
+ ...authorizationTagsFilters.filters
},
{
limit: filteredRequest.Limit,

MODIFY
src/types/Authorization.ts
src/types/Authorization.ts
@@ -195,6 +195,8 @@ export enum DynamicAuthorizationFilterName {
SITES_ADMIN = 'SitesAdmin',
ASSIGNED_SITE_AREAS = 'AssignedSiteAreas',
ASSIGNED_SITES = 'AssignedSites',
+ SITE_ADMIN_USERS = 'SiteAdminUsers',
+ OWN_USER = 'OwnUser',
}
export enum DynamicAuthorizationDataSourceName {
@@ -202,6 +204,8 @@ export enum DynamicAuthorizationDataSourceName {
SITES_ADMIN = 'SitesAdmin',
ASSIGNED_SITE_AREAS = 'AssignedSiteAreas',
ASSIGNED_SITES = 'AssignedSites',
+ SITE_ADMIN_USERS = 'SiteAdminUsers',
+ OWN_USER = 'OwnUser',
}
export interface DynamicAuthorizationDataSourceData {}
@@ -221,3 +225,11 @@ export interface AssignedSiteAreasDynamicAuthorizationDataSourceData extends Dyn
export interface AssignedSitesDynamicAuthorizationDataSourceData extends DynamicAuthorizationDataSourceData {
siteIDs?: string[];
}
+
+export interface SiteAdminUsersDynamicAuthorizationDataSourceData extends DynamicAuthorizationDataSourceData {
+ userIDs?: string[];
+}
+
+export interface OwnUserDynamicAuthorizationDataSourceData extends DynamicAuthorizationDataSourceData {
+ userID?: string;
+}

Refactor handleGetTags + add 2 new dynamic filters.