Skip to content

Commit

Permalink
chore: Release v1.2.3 - See CHANGELOG
Browse files Browse the repository at this point in the history
  • Loading branch information
Arun-KumarH committed Oct 21, 2023
1 parent 60b054d commit d6ad112
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 49 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
## 1.2.1 (October 11th, 2023)
## 1.2.3 (October 11th, 2023)

- on user deletion delete HR scopes and ACS cache

## 1.2.2 (October 11th, 2023)

- fix unit tests (revert the order of attributes match)

Expand Down
6 changes: 5 additions & 1 deletion cfg/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@
"userModified": {
"messageObject": "io.restorecommerce.user.User"
},
"userDeleted": {
"messageObject": "io.restorecommerce.user.Deleted"
},
"topics": {
"policy.resource": {
"topic": "io.restorecommerce.policies.resource",
Expand Down Expand Up @@ -186,7 +189,8 @@
"users.resource": {
"topic": "io.restorecommerce.users.resource",
"events": [
"userModified"
"userModified",
"userDeleted"
]
}
}
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@restorecommerce/access-control-srv",
"version": "1.2.2",
"version": "1.2.3",
"description": "Access Control Service",
"main": "lib/start.js",
"author": "n-fuse GmbH",
Expand Down
81 changes: 81 additions & 0 deletions src/core/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
UserServiceClient
} from '@restorecommerce/rc-grpc-clients/dist/generated-server/io/restorecommerce/user';
import { PolicySetWithCombinables, PolicyWithCombinables } from './interfaces';
import { RoleAssociation } from '@restorecommerce/rc-grpc-clients/dist/generated-server/io/restorecommerce/auth';
import { Topic } from '@restorecommerce/kafka-client';


export const formatTarget = (target: any): Target => {
Expand Down Expand Up @@ -337,4 +339,83 @@ export const getAllValues = (obj: any, pushedValues: any): any => {
getAllValues(value, pushedValues);
}
}
};

const nestedAttributesEqual = (redisAttributes, userAttributes) => {
if (!userAttributes) {
return true;
}
if (redisAttributes?.length > 0 && userAttributes?.length > 0) {
return userAttributes.every((obj) => redisAttributes.some((dbObj => dbObj.value === obj.value)));
} else if (redisAttributes?.length != userAttributes?.length) {
return false;
}
};

export const compareRoleAssociations = (userRoleAssocs: RoleAssociation[], redisRoleAssocs: RoleAssociation[], logger): boolean => {
let roleAssocsModified = false;
if (userRoleAssocs?.length != redisRoleAssocs?.length) {
roleAssocsModified = true;
logger.debug('Role associations length are not equal');
} else {
// compare each role and its association
if (userRoleAssocs?.length > 0 && redisRoleAssocs?.length > 0) {
for (let userRoleAssoc of userRoleAssocs) {
let found = false;
for (let redisRoleAssoc of redisRoleAssocs) {
if (redisRoleAssoc.role === userRoleAssoc.role) {
if (redisRoleAssoc?.attributes?.length > 0) {
for (let redisAttribute of redisRoleAssoc.attributes) {
const redisNestedAttributes = redisAttribute.attributes;
if (userRoleAssoc?.attributes?.length > 0) {
for (let userAttribute of userRoleAssoc.attributes) {
const userNestedAttributes = userAttribute.attributes;
if (userAttribute.id === redisAttribute.id &&
userAttribute.value === redisAttribute.value &&
nestedAttributesEqual(redisNestedAttributes, userNestedAttributes)) {
found = true;
break;
}
}
}
}
} else {
found = true;
break;
}
}
}
if (!found) {
roleAssocsModified = true;
}
if (roleAssocsModified) {
logger.debug('Role associations objects are not equal');
break;
} else {
logger.debug('Role assocations not changed');
}
}
}
}
return roleAssocsModified;
};

export const flushACSCache = async (userId: string, db_index, commandTopic: Topic, logger) => {
const payload = {
data: {
db_index,
pattern: userId
}
};
const eventObject = {
name: 'flush_cache',
payload: {}
};
const eventPayload = Buffer.from(JSON.stringify(payload)).toString('base64');
eventObject.payload = {
type_url: 'payload',
value: eventPayload
};
await commandTopic.emit('flushCacheCommand', eventObject);
logger.info('ACS flush cache command event emitted to kafka topic successfully');
};
52 changes: 8 additions & 44 deletions src/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
HealthDefinition
} from '@restorecommerce/rc-grpc-clients/dist/generated-server/grpc/health/v1/health';
import { BindConfig } from '@restorecommerce/chassis-srv/lib/microservice/transport/provider/grpc';
import { compareRoleAssociations, flushACSCache } from './core/utils';

const capitalized = (collectionName: string): string => {
const labels = collectionName.split('_').map((element) => {
Expand Down Expand Up @@ -260,34 +261,8 @@ export class Worker {
if (redisSubject) {
const redisRoleAssocs = redisSubject.role_associations;
const redisTokens = redisSubject.tokens;
let roleAssocEqual;
let roleAssocEqual = compareRoleAssociations(updatedRoleAssocs, redisRoleAssocs, that.logger);
let tokensEqual;
for (let userRoleAssoc of updatedRoleAssocs || []) {
let found = false;
for (let redisRoleAssoc of redisRoleAssocs || []) {
if (redisRoleAssoc?.role === userRoleAssoc?.role) {
let i = 0;
const attrLenght = userRoleAssoc?.attributes?.length;
for (let redisAttribute of redisRoleAssoc.attributes || []) {
for (let userAttribute of userRoleAssoc.attributes) {
if (userAttribute?.id === redisAttribute?.id && userAttribute?.value === redisAttribute?.value) {
i++;
}
}
}
if (attrLenght === i) {
found = true;
roleAssocEqual = true;
break;
}
}
}
if (!found) {
that.logger.debug('Subject Role assocation has been updated', { userRoleAssoc });
roleAssocEqual = false;
break;
}
}
// for interactive login after logout we receive userModified event
// with empty tokens, so below check is not to evict cache for this case
if (_.isEmpty(updatedTokens)) {
Expand All @@ -314,26 +289,15 @@ export class Worker {
await that.accessController.evictHRScopes(msg.id); // flush HR scopes
// TODO use tech user below once ACS check is implemented on chassis-srv for command-interface
// Flush ACS Cache via flushCache Command
const payload = {
data: {
db_index: that.cfg.get('authorization:cache:db-index'),
pattern: msg.id
}
};
const eventObject = {
name: 'flush_cache',
payload: {}
};
const eventPayload = Buffer.from(JSON.stringify(payload)).toString('base64');
eventObject.payload = {
type_url: 'payload',
value: eventPayload
};
await commandTopic.emit('flushCacheCommand', eventObject);
that.logger.info('ACS flush cache command event emitted to kafka topic successfully');
await flushACSCache(msg.id, that.cfg.get('authorization:cache:db-index'), commandTopic, that.logger);
}
}
}
} else if (eventName === 'userDeleted') {
that.logger.info('Evicting HR scope for Subject', { id: msg.id });
await that.accessController.evictHRScopes(msg.id); // flush HR scopes
// delete ACS cache
await flushACSCache(msg.id, that.cfg.get('authorization:cache:db-index'), commandTopic, that.logger);
} else {
await that.commandInterface.command(msg, context);
}
Expand Down

0 comments on commit d6ad112

Please sign in to comment.