Skip to content

Commit 821c2d3

Browse files
bountyC0d3rbountyCoder
authored and
bountyCoder
committed
fixed the issue of OR validation, not create the resouce if the member is not part of all the associted folder; remove the resource on challenge update if not part of all associated groups
1 parent 9daea63 commit 821c2d3

File tree

4 files changed

+105
-5
lines changed

4 files changed

+105
-5
lines changed

config/default.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ module.exports = {
2323
KAFKA_CLIENT_CERT_KEY: process.env.KAFKA_CLIENT_CERT_KEY,
2424
// Topics
2525
CHALLENGE_CREATE_TOPIC: process.env.CHALLENGE_CREATE_TOPIC || 'challenge.notification.create',
26+
CHALLENGE_UPDATE_TOPIC: process.env.CHALLENGE_UPDATE_TOPIC || 'challenge.notification.update',
2627
PROJECT_MEMBER_ADDED_TOPIC: process.env.PROJECT_MEMBER_ADDED_TOPIC || 'connect.notification.project.member.joined',
2728
PROJECT_MEMBER_REMOVED_TOPIC: process.env.PROJECT_MEMBER_REMOVED_TOPIC || 'connect.notification.project.member.removed',
2829

@@ -37,5 +38,9 @@ module.exports = {
3738
RESOURCES_API: process.env.RESOURCES_API || 'http://localhost:4000/v5/resources',
3839
CHALLENGE_API: process.env.CHALLENGE_API || 'http://localhost:4000/v5/challenges',
3940

40-
IGNORED_ORIGINATORS: process.env.IGNORED_ORIGINATORS ? process.env.IGNORED_ORIGINATORS.split(',') : ['legacy-migration-script']
41+
IGNORED_ORIGINATORS: process.env.IGNORED_ORIGINATORS ? process.env.IGNORED_ORIGINATORS.split(',') : ['legacy-migration-script'],
42+
43+
GROUPS_TO_IGNORE: process.env.GROUPS_TO_IGNORE ? process.env.GROUPS_TO_IGNORE.split(',') : ['72a0b8a0-aa45-44f7-86c2-bf9de6321e5b'],
44+
GROUPS_API_URL: process.env.GROUPS_API_URL || 'http://localhost:4000/v5/groups',
45+
4146
}

src/app.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ const dataHandler = (messageSet, topic, partition) => Promise.each(messageSet, (
4040
} else {
4141
if (topic === config.CHALLENGE_CREATE_TOPIC) {
4242
await ProcessorService.handleChallengeCreate(messageJSON)
43+
} else if (topic === config.CHALLENGE_UPDATE_TOPIC) {
44+
await ProcessorService.handleChallengeUpdate(messageJSON)
4345
} else if (topic === config.PROJECT_MEMBER_ADDED_TOPIC) {
4446
await ProcessorService.handleMemberAdded(messageJSON)
4547
} else if (topic === config.PROJECT_MEMBER_REMOVED_TOPIC) {
@@ -71,6 +73,7 @@ consumer
7173
.init([{
7274
subscriptions: [
7375
config.CHALLENGE_CREATE_TOPIC,
76+
config.CHALLENGE_UPDATE_TOPIC,
7477
config.PROJECT_MEMBER_ADDED_TOPIC,
7578
config.PROJECT_MEMBER_REMOVED_TOPIC
7679
],

src/common/helper.js

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,48 @@ async function deleteResource (challengeId, memberHandle, roleId) {
188188
return res.body
189189
}
190190

191+
/**
192+
* Search members of the given group ids
193+
* @param {Array} members
194+
* @param {Array} groupIds
195+
* @return {Array} filtered members
196+
*/
197+
async function filterMemberForGroups(memberIds, groupIds) {
198+
for (const memberId of memberIds) {
199+
const res = await Promise.allSettled(groupIds.map(groupId => memberGroupsCall(groupId, memberId)));
200+
const memberGroups =_.compact(_.flattenDeep(_.map(res, 'value')))
201+
202+
if (memberGroups.length != groupIds.length) memberList.push(memberId)
203+
}
204+
}
205+
206+
/**
207+
* Return the memberId if member is part of the groups
208+
* @param {String} groupId
209+
* @param {String} memberId
210+
* @returns {String} memberId in case of member of group
211+
*/
212+
async function memberGroupsCall(groupId, memberId) {
213+
// M2M token is cached by 'tc-core-library-js' lib
214+
const token = await getM2MToken()
215+
216+
const url = `${config.GROUPS_API_URL}/${groupId}/members/${memberId}`
217+
const res = await superagent
218+
.get(url)
219+
.set('Authorization', `Bearer ${token}`)
220+
.timeout(config.REQUEST_TIMEOUT)
221+
222+
return memberId
223+
}
224+
225+
191226
module.exports = {
192227
getKafkaOptions,
193228
getProject,
194229
searchMembers,
195230
createResource,
196231
deleteResource,
197232
getProjectChallenges,
198-
getChallengeResources
233+
getChallengeResources,
234+
filterMemberForGroups
199235
}

src/services/ProcessorService.js

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,20 @@ async function handleChallengeCreate (message) {
2424
logger.info(`Found member ids [${memberIds.join(', ')}] of project id ${projectId}`)
2525

2626
// search members
27-
const members = await helper.searchMembers(memberIds)
27+
let members = await helper.searchMembers(memberIds)
28+
29+
// fetch all members of groups
30+
const groupIds = _.difference(message.payload.groups, config.GROUPS_TO_IGNORE)
31+
32+
// filter members who are NOT part of all the groups
33+
if (groupIds.length > 0 && members.length > 0) {
34+
const memberIds = members.map(m => m.id)
35+
const filteredMemberIds = await helper.filterMemberForGroups(memberIds, groupIds)
36+
37+
// remove the members who are not part of all the groups
38+
members = members.filter(m => !filteredMemberIds.includes(m.id))
39+
}
40+
2841
// create resource for each member
2942
for (const member of members) {
3043
const resource = await helper.createResource(challengeId, member.handle)
@@ -46,6 +59,49 @@ handleChallengeCreate.schema = {
4659
}).required()
4760
}
4861

62+
/**
63+
* Process Kafka message of challenge updated
64+
* @param {Object} message the challenge update message
65+
*/
66+
async function handleChallengeUpdate (message) {
67+
const challengeId = message.payload.id
68+
const projectId = message.payload.projectId
69+
logger.info(`Process message of challenge id ${challengeId} and project id ${projectId}`)
70+
71+
// get challenge resources (all observers for the challenge)
72+
let challengeResources = await helper.getChallengeResources(challengeId, config.RESOURCE_ROLE_ID)
73+
74+
// fetch all members of groups
75+
const groupIds = _.difference(message.payload.groups, config.GROUPS_TO_IGNORE)
76+
77+
// filter members who are NOT part of all the groups
78+
if (groupIds.length > 0 && challengeResources.length > 0) {
79+
const memberIds = challengeResources.map(cr => cr.memberId)
80+
const filteredMemberIds = await helper.filterMemberForGroups(memberIds, groupIds)
81+
82+
// filter the members who are not part of all the groups
83+
challengeResources = challengeResources.filter(member => filteredMemberIds.includes(member.memberId) )
84+
85+
// remove members from resources who are not part of all the groups
86+
await Promise.allSettled(challengeResources.map(member => helper.deleteResource(challengeId, member.memberHandle, config.RESOURCE_ROLE_ID)));
87+
}
88+
89+
logger.info(`Successfully processed message of challenge id ${challengeId} and project id ${projectId}`)
90+
}
91+
92+
handleChallengeUpdate.schema = {
93+
message: Joi.object().keys({
94+
topic: Joi.string().required(),
95+
originator: Joi.string().required(),
96+
timestamp: Joi.date().required(),
97+
'mime-type': Joi.string().required(),
98+
payload: Joi.object().keys({
99+
id: Joi.string().uuid().required(), // challenge id
100+
projectId: Joi.number().integer().positive().required()
101+
}).unknown(true).required()
102+
}).required()
103+
}
104+
49105
/**
50106
* Handle project member changes
51107
* @param {Number} projectId the project ID
@@ -61,8 +117,8 @@ async function handleProjectMemberChange (projectId, userId, isDeleted) {
61117
const [memberDetails] = await helper.searchMembers([userId])
62118
const { handle } = memberDetails
63119
for (const challenge of challenges) {
64-
const challenngeResources = await helper.getChallengeResources(challenge.id, config.MANAGER_RESOURCE_ROLE_ID)
65-
const existing = _.find(challenngeResources, r => _.toString(r.memberId) === _.toString(userId))
120+
const challengeResources = await helper.getChallengeResources(challenge.id, config.MANAGER_RESOURCE_ROLE_ID)
121+
const existing = _.find(challengeResources, r => _.toString(r.memberId) === _.toString(userId))
66122
if (isDeleted) {
67123
if (existing) {
68124
await helper.deleteResource(challenge.id, handle, config.MANAGER_RESOURCE_ROLE_ID)

0 commit comments

Comments
 (0)