Skip to content

Commit

Permalink
chore: Release v1.1.0 - See CHANGELOG
Browse files Browse the repository at this point in the history
  • Loading branch information
Arun-KumarH committed Sep 21, 2023
1 parent 3db89fc commit d95c1b6
Show file tree
Hide file tree
Showing 8 changed files with 497 additions and 557 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.1.0 (September 21st, 2023)

- up protos and deps (set all fields as optionals)

## 1.0.2 (July 28th, 2023)

- for owner and role Association object restructuring
Expand Down
879 changes: 405 additions & 474 deletions package-lock.json

Large diffs are not rendered by default.

32 changes: 16 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@restorecommerce/resource-srv",
"version": "1.0.2",
"version": "1.1.0",
"description": "Restore Commerce Resource Microservice",
"main": "lib/start.js",
"author": "n-fuse GmbH",
Expand All @@ -16,31 +16,31 @@
"resource"
],
"dependencies": {
"@restorecommerce/acs-client": "^1.1.14",
"@restorecommerce/chassis-srv": "^1.2.5",
"@restorecommerce/acs-client": "^1.1.17",
"@restorecommerce/chassis-srv": "^1.3.1",
"@restorecommerce/cluster-service": "^1.0.2",
"@restorecommerce/grpc-client": "^2.0.3",
"@restorecommerce/kafka-client": "^1.0.17",
"@restorecommerce/rc-grpc-clients": "^5.0.1",
"@restorecommerce/resource-base-interface": "^1.2.5",
"@restorecommerce/kafka-client": "^1.1.1",
"@restorecommerce/rc-grpc-clients": "^5.1.1",
"@restorecommerce/resource-base-interface": "^1.3.0",
"@restorecommerce/service-config": "^1.0.6",
"lodash": "^4.17.21",
"redis": "^4.6.7",
"uuid": "^9.0.0"
"redis": "^4.6.9",
"uuid": "^9.0.1"
},
"devDependencies": {
"@alenon/grpc-mock-server": "^3.0.21",
"@grpc/proto-loader": "^0.7.8",
"@alenon/grpc-mock-server": "^3.1.1",
"@grpc/proto-loader": "^0.7.10",
"@restorecommerce/logger": "^1.2.4",
"@types/mocha": "^10.0.1",
"@types/node": "^20.4.5",
"@types/node": "^20.6.3",
"@types/redis": "^4.0.11",
"@typescript-eslint/eslint-plugin": "^6.2.0",
"@typescript-eslint/eslint-plugin-tslint": "^6.2.0",
"@typescript-eslint/parser": "^6.2.0",
"@typescript-eslint/eslint-plugin": "^6.7.2",
"@typescript-eslint/eslint-plugin-tslint": "^6.7.2",
"@typescript-eslint/parser": "^6.7.2",
"coveralls": "^3.1.1",
"cross-env": "^7.0.3",
"eslint": "^8.45.0",
"eslint": "^8.49.0",
"eslint-plugin-prefer-arrow-functions": "^3.1.4",
"mocha": "^10.2.0",
"nodemon": "^3.0.1",
Expand All @@ -49,7 +49,7 @@
"rimraf": "^5.0.1",
"should": "^13.2.3",
"ts-node": "^10.9.1",
"typescript": "^5.1.6"
"typescript": "^5.2.2"
},
"scripts": {
"start": "node lib/start.js",
Expand Down
20 changes: 10 additions & 10 deletions src/commandInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,20 @@ export class ResourceCommandInterface extends CommandInterface {
that.decodeBufferField(message, resource);
if (that.edgeCfg[collectionName]) {
const result = await db.findByID(collectionName, message.id);
if (result.length > 0) {
if (result?.length > 0) {
return {};
}
await db.createVertex(collectionName, message);
// Based on graphCfg create the necessary edges
for (let eachEdgeCfg of that.edgeCfg[collectionName]) {
const fromIDkey = eachEdgeCfg.from;
const fromIDkey = eachEdgeCfg?.from;
const from_id = message[fromIDkey];
const toIDkey = eachEdgeCfg.to;
const toIDkey = eachEdgeCfg?.to;
const to_id = message[toIDkey];
const fromVerticeName = collectionName;
const toVerticeName = eachEdgeCfg.toVerticeName;
const toVerticeName = eachEdgeCfg?.toVerticeName;
if (fromVerticeName && toVerticeName) {
const edgeDefRes = await db.addEdgeDefinition(eachEdgeCfg.edgeName, [fromVerticeName],
await db.addEdgeDefinition(eachEdgeCfg.edgeName, [fromVerticeName],
[toVerticeName]);
}
if (from_id && to_id) {
Expand Down Expand Up @@ -67,7 +67,7 @@ export class ResourceCommandInterface extends CommandInterface {
const foundDocs = await db.find(collectionName, { id: message.id });
const dbDoc = foundDocs[0];
for (let eachEdgeCfg of that.edgeCfg[collectionName]) {
const toIDkey = eachEdgeCfg.to;
const toIDkey = eachEdgeCfg?.to;
let modified_to_idValues = message[toIDkey];
let db_to_idValues = dbDoc[toIDkey];
if (_.isArray(modified_to_idValues)) {
Expand All @@ -78,12 +78,12 @@ export class ResourceCommandInterface extends CommandInterface {
}
// delete and recreate only if there is a difference in references
if (!_.isEqual(modified_to_idValues, db_to_idValues)) {
const fromIDkey = eachEdgeCfg.from;
const fromIDkey = eachEdgeCfg?.from;
const from_id = message[fromIDkey];
const fromVerticeName = collectionName;
const toVerticeName = eachEdgeCfg.toVerticeName;
const toVerticeName = eachEdgeCfg?.toVerticeName;

const edgeCollectionName = eachEdgeCfg.edgeName;
const edgeCollectionName = eachEdgeCfg?.edgeName;
let outgoingEdges: any = await db.getOutEdges(edgeCollectionName, `${collectionName}/${dbDoc.id}`);
for (let outgoingEdge of outgoingEdges) {
const removedEdge = await db.removeEdge(edgeCollectionName, outgoingEdge._id);
Expand All @@ -92,7 +92,7 @@ export class ResourceCommandInterface extends CommandInterface {
if (from_id && modified_to_idValues) {
if (_.isArray(modified_to_idValues)) {
for (let toID of modified_to_idValues) {
await db.createEdge(eachEdgeCfg.edgeName, null,
await db.createEdge(eachEdgeCfg?.edgeName, null,
`${fromVerticeName}/${from_id}`, `${toVerticeName}/${toID}`);
}
continue;
Expand Down
42 changes: 21 additions & 21 deletions src/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export class ResourceService extends ServiceBase<any, any> {
readRequest.filters.push(...acsFilters);
}

if (acsResponse?.custom_query_args && acsResponse.custom_query_args.length > 0) {
if (acsResponse?.custom_query_args?.length > 0) {
readRequest.custom_queries = acsResponse.custom_query_args[0].custom_queries;
readRequest.custom_arguments = acsResponse.custom_query_args[0].custom_arguments;
}
Expand Down Expand Up @@ -201,16 +201,16 @@ export class ResourceService extends ServiceBase<any, any> {
// add user and subject scope as default owner
orgOwnerAttributes.push(
{
id: urns.ownerIndicatoryEntity,
value: urns.organization,
id: urns?.ownerIndicatoryEntity,
value: urns?.organization,
attributes: [{
id: urns.ownerInstance,
value: subject.scope
id: urns?.ownerInstance,
value: subject?.scope
}]
});
}

if (resources) {
if (resources?.length > 0) {
for (let resource of resources) {
if (!resource.meta) {
resource.meta = {};
Expand All @@ -221,52 +221,52 @@ export class ResourceService extends ServiceBase<any, any> {
filters: [{
field: 'id',
operation: Filter_Operation.eq,
value: resource.id
value: resource?.id
}]
}]
}) as any, {});
// update owner info
if (result.items.length === 1) {
if (result?.items?.length === 1) {
let item = result.items[0].payload;
resource.meta.owners = item.meta.owners;
} else if (result.items.length === 0) {
if (_.isEmpty(resource.id)) {
resource.meta.owners = item?.meta?.owners;
} else if (result?.items?.length === 0) {
if (_.isEmpty(resource?.id)) {
resource.id = uuid.v4().replace(/-/g, '');
}
let ownerAttributes;
if (!resource.meta.owners) {
if (!resource?.meta?.owners) {
ownerAttributes = _.cloneDeep(orgOwnerAttributes);
} else {
ownerAttributes = resource.meta.owners;
}
ownerAttributes.push(
{
id: urns.ownerIndicatoryEntity,
value: urns.user,
id: urns?.ownerIndicatoryEntity,
value: urns?.user,
attributes: [{
id: urns.ownerInstance,
value: resource.id
id: urns?.ownerInstance,
value: resource?.id
}]
});
resource.meta.owners = ownerAttributes;
}
} else if (action === AuthZAction.CREATE) {
if (_.isEmpty(resource.id)) {
if (_.isEmpty(resource?.id)) {
resource.id = uuid.v4().replace(/-/g, '');
}
let ownerAttributes;
if (!resource.meta.owners) {
if (!resource?.meta?.owners) {
ownerAttributes = _.cloneDeep(orgOwnerAttributes);
} else {
ownerAttributes = resource.meta.owners;
}
if (subject?.id) {
ownerAttributes.push(
{
id: urns.ownerIndicatoryEntity,
value: urns.user,
id: urns?.ownerIndicatoryEntity,
value: urns?.user,
attributes: [{
id: urns.ownerInstance,
id: urns?.ownerInstance,
value: subject?.id
}]
});
Expand Down
15 changes: 8 additions & 7 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,13 +261,14 @@ export const createHRScope = async (user, token, graphClient, cache, cfg, logger
reducedUserRoleAssocs = userRoleAssocs;
}
for (let roleObj of reducedUserRoleAssocs) {
for (let roleAttribute of roleObj.attributes) {

if (roleAttribute.id === roleScopingEntityURN) {
for (let roleScopInstObj of roleAttribute.attributes) {
if (roleScopInstObj.id === roleScopingInstanceURN) {
let obj = { userScope: roleScopInstObj.value, role: roleObj.role };
assignedUserScopes.add(obj);
if (roleObj?.attributes?.length > 0) {
for (let roleAttribute of roleObj?.attributes) {
if (roleAttribute.id === roleScopingEntityURN) {
for (let roleScopInstObj of roleAttribute.attributes) {
if (roleScopInstObj.id === roleScopingInstanceURN) {
let obj = { userScope: roleScopInstObj.value, role: roleObj.role };
assignedUserScopes.add(obj);
}
}
}
}
Expand Down
46 changes: 24 additions & 22 deletions test/resource_srv_acs_test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import * as should from 'should';
import { createChannel, createClient } from '@restorecommerce/grpc-client';
import {Events, Topic} from '@restorecommerce/kafka-client';
import {Worker} from '../lib/worker';
import { Events, Topic } from '@restorecommerce/kafka-client';
import { Worker } from '../lib/worker';
import { GrpcMockServer, ProtoUtils } from '@alenon/grpc-mock-server';
import * as proto_loader from '@grpc/proto-loader';
import * as grpc from '@grpc/grpc-js';
import {createLogger} from '@restorecommerce/logger';
import {createServiceConfig} from '@restorecommerce/service-config';
import { createLogger } from '@restorecommerce/logger';
import { createServiceConfig } from '@restorecommerce/service-config';
import { CommandInterfaceServiceDefinition, CommandInterfaceServiceClient as cisClient } from '@restorecommerce/rc-grpc-clients/dist/generated-server/io/restorecommerce/commandinterface';
import { CommandServiceDefinition as command } from '@restorecommerce/rc-grpc-clients/dist/generated-server/io/restorecommerce/command';
import { OrganizationServiceDefinition as organization } from '@restorecommerce/rc-grpc-clients/dist/generated-server/io/restorecommerce/organization';
Expand Down Expand Up @@ -52,7 +52,7 @@ const permitAllEntitiesRule = {
id: 'permit_rule_id',
target: {
actions: [],
resources: [{id: 'urn:restorecommerce:acs:names:model:entity', value: 'urn:restorecommerce:acs:model:*.*'}],
resources: [{ id: 'urn:restorecommerce:acs:names:model:entity', value: 'urn:restorecommerce:acs:model:*.*' }],
subjects: [
{
id: 'urn:restorecommerce:acs:names:role',
Expand Down Expand Up @@ -241,7 +241,7 @@ const stopIDSGrpcMockServer = async () => {

// get client connection object
async function getClientResourceServices() {
const options: any = {microservice: {}};
const options: any = { microservice: {} };
options.microservice = {
service: {},
mapClients: new Map()
Expand Down Expand Up @@ -291,9 +291,11 @@ describe('resource-srv testing with ACS enabled', () => {
let events: Events;
let commandTopic: Topic;
let organizationTopic: Topic;
let baseValidation = function (result: any) {
let baseValidation = function (result: any, itemsShouldExist: boolean = true) {
should.exist(result);
should.exist(result.items);
if (itemsShouldExist) {
should.exist(result.items);
}
should.exist(result.operation_status);
};

Expand Down Expand Up @@ -332,8 +334,8 @@ describe('resource-srv testing with ACS enabled', () => {
it('should create contact_point resource', async function createContactPoints() {
// start mock acs-srv - needed for read operation since acs-client makes a req to acs-srv
// to get applicable policies although acs-lookup is disabled
startGrpcMockServer([{method: 'WhatIsAllowed', output: policySetRQ},
{method: 'IsAllowed', output: {decision: 'PERMIT'}}]);
startGrpcMockServer([{ method: 'WhatIsAllowed', output: policySetRQ },
{ method: 'IsAllowed', output: { decision: 'PERMIT' } }]);

// start mock ids-srv needed for findByToken response and return subject
await startIDSGrpcMockServer([{ method: 'findByToken', output: subject }]);
Expand Down Expand Up @@ -362,34 +364,34 @@ describe('resource-srv testing with ACS enabled', () => {
// store user with tokens and role associations to Redis index `db-findByToken`
await tokenRedisClient.set('admin-token', JSON.stringify(subject));

const result = await contactPointsService.create({items: listOfContactPoints, subject});
const result = await contactPointsService.create({ items: listOfContactPoints, subject });
baseValidation(result);
result.items.should.be.length(2);
result.items[0].payload.website.should.equal('http://TestOrg1.de');
result.items[1].payload.website.should.equal('http://TestOrg2.de');
});
it('should throw an error when creating contact_point resource with invalid subject scope', async function createContactPoints() {
subject.scope = 'orgD';
const result = await contactPointsService.create({items: listOfContactPoints, subject});
const result = await contactPointsService.create({ items: listOfContactPoints, subject });
should.exist(result.operation_status);
result.operation_status.code.should.equal(403);
result.operation_status.message.should.equal('Access not allowed for request with subject:admin_user_id, resource:contact_point, action:CREATE, target_scope:orgD; the response was DENY');
});
it('should throw error updating contact point resource with invalid subject scope', async function deleteContactPoint() {
const updateResult = await contactPointsService.update({items: listOfContactPoints, subject});
const updateResult = await contactPointsService.update({ items: listOfContactPoints, subject });
should.exist(updateResult.operation_status);
updateResult.operation_status.code.should.equal(403);
updateResult.operation_status.message.should.equal('Access not allowed for request with subject:admin_user_id, resource:contact_point, action:MODIFY, target_scope:orgD; the response was DENY');
});
it('should throw error upserting contact point resource with invalid subject scope', async function deleteContactPoint() {
const updateResult = await contactPointsService.upsert({items: listOfContactPoints, subject});
const updateResult = await contactPointsService.upsert({ items: listOfContactPoints, subject });
should.exist(updateResult.operation_status);
updateResult.operation_status.code.should.equal(403);
updateResult.operation_status.message.should.equal('Access not allowed for request with subject:admin_user_id, resource:contact_point, action:MODIFY, target_scope:orgD; the response was DENY');
});
it('should throw error deleting contact point resource with invalid subject scope', async function deleteContactPoint() {
const deletedResult = await contactPointsService.delete({ids: ['contact_point_1', 'contact_point_2'], subject});
deletedResult.status.should.be.empty();
const deletedResult = await contactPointsService.delete({ ids: ['contact_point_1', 'contact_point_2'], subject });
should.not.exist(deletedResult.status);
should.exist(deletedResult.operation_status);
deletedResult.operation_status.code.should.equal(403);
deletedResult.operation_status.message.should.equal('Access not allowed for request with subject:admin_user_id, resource:contact_point, action:DELETE, target_scope:orgD; the response was DENY');
Expand All @@ -398,7 +400,7 @@ describe('resource-srv testing with ACS enabled', () => {
subject.scope = 'orgC';
listOfContactPoints[0].website = 'http://newtest1.de';
listOfContactPoints[1].website = 'http://newtest2.de';
const updateResult = await contactPointsService.update({items: listOfContactPoints, subject});
const updateResult = await contactPointsService.update({ items: listOfContactPoints, subject });
baseValidation(updateResult);
updateResult.items[0].payload.website.should.equal('http://newtest1.de');
updateResult.items[1].payload.website.should.equal('http://newtest2.de');
Expand All @@ -409,7 +411,7 @@ describe('resource-srv testing with ACS enabled', () => {
website: 'http://TestOrg3.de',
meta
}];
const updateResult = await contactPointsService.update({items: contactPoint, subject});
const updateResult = await contactPointsService.update({ items: contactPoint, subject });
should.exist(updateResult.operation_status);
// update status for item failure
updateResult.items[0].status.id.should.equal('contact_point_3');
Expand All @@ -425,13 +427,13 @@ describe('resource-srv testing with ACS enabled', () => {
website: 'http://TestOrg3.de',
meta
}];
const upsertResult = await contactPointsService.upsert({items: contactPoint, subject});
const upsertResult = await contactPointsService.upsert({ items: contactPoint, subject });
baseValidation(upsertResult);
upsertResult.items[0].payload.website.should.equal(contactPoint[0].website);
});
it('should delete contact point resource', async function deleteContactPoint() {
subject.scope = 'orgC';
const deletedResult = await contactPointsService.delete({collection: true, subject});
const deletedResult = await contactPointsService.delete({ collection: true, subject });
should.exist(deletedResult);
deletedResult.status[0].id.should.equal('contact_point_1');
deletedResult.status[0].code.should.equal(200);
Expand All @@ -450,7 +452,7 @@ describe('resource-srv testing with ACS enabled', () => {
}],
subject
});
baseValidation(resultAfterDeletion);
resultAfterDeletion.items.should.be.length(0);
baseValidation(resultAfterDeletion, false);
should.not.exist(resultAfterDeletion.items);
});
});
Loading

0 comments on commit d95c1b6

Please sign in to comment.