-
Notifications
You must be signed in to change notification settings - Fork 15
chenges to add universal member to groups #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,36 +74,36 @@ async function ensureExists(tx, model, id, isAdmin = false) { | |
if (model === 'Group') { | ||
if (validate(id, 4)) { | ||
if (!isAdmin) { | ||
res = await tx.run(`MATCH (e:${model} {id: {id}, status: '${constants.GroupStatus.Active}'}) RETURN e`, { | ||
id | ||
}) | ||
res = await tx.run(`MATCH (e:${model} {id: {id}, status: '${constants.GroupStatus.Active}'}) RETURN e`, {id}) | ||
} else { | ||
res = await tx.run(`MATCH (e:${model} {id: {id}}) RETURN e`, { | ||
id | ||
}) | ||
res = await tx.run(`MATCH (e:${model} {id: {id}}) RETURN e`, {id}) | ||
} | ||
} else { | ||
if (!isAdmin) { | ||
res = await tx.run(`MATCH (e:${model} {oldId: {id}, status: '${constants.GroupStatus.Active}'}) RETURN e`, { | ||
id | ||
}) | ||
} else { | ||
res = await tx.run(`MATCH (e:${model} {oldId: {id}}) RETURN e`, { | ||
id | ||
}) | ||
res = await tx.run(`MATCH (e:${model} {oldId: {id}}) RETURN e`, {id}) | ||
} | ||
} | ||
|
||
if (res && res.records.length === 0) { | ||
throw new errors.NotFoundError(`Not found ${model} of id ${id}`) | ||
} | ||
} else if (model === 'User') { | ||
res = await tx.run(`MATCH (e:${model} {id: {id}}) RETURN e`, { | ||
id | ||
}) | ||
if (validate(id, 4)) { | ||
res = await tx.run(`MATCH (e:${model} {universalUID: {id}}) RETURN e`, {id}) | ||
|
||
if (res && res.records.length === 0) { | ||
res = await tx.run(`CREATE (user:User {id: {id}}) RETURN user`, { id }) | ||
if (res && res.records.length === 0) { | ||
res = await tx.run(`CREATE (user:User {id: '00000000', universalUID: {id}}) RETURN user`, {id}) | ||
} | ||
} else { | ||
res = await tx.run(`MATCH (e:${model} {id: {id}}) RETURN e`, {id}) | ||
|
||
if (res && res.records.length === 0) { | ||
res = await tx.run(`CREATE (user:User {id: {id}, universalUID: '00000000'}) RETURN user`, {id}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we put a |
||
} | ||
} | ||
} | ||
|
||
|
@@ -123,7 +123,7 @@ async function ensureGroupMember(session, groupId, userId) { | |
try { | ||
const memberCheckRes = await session.run( | ||
'MATCH (g:Group {id: {groupId}})-[r:GroupContains {type: {membershipType}}]->(u:User {id: {userId}}) RETURN r', | ||
{ groupId, membershipType: config.MEMBERSHIP_TYPES.User, userId } | ||
{groupId, membershipType: config.MEMBERSHIP_TYPES.User, userId} | ||
) | ||
if (memberCheckRes.records.length === 0) { | ||
throw new errors.ForbiddenError(`User is not member of the group`) | ||
|
@@ -143,7 +143,7 @@ async function getChildGroups(session, groupId) { | |
try { | ||
const res = await session.run( | ||
'MATCH (g:Group {id: {groupId}})-[r:GroupContains]->(c:Group) RETURN c ORDER BY c.oldId', | ||
{ groupId } | ||
{groupId} | ||
) | ||
return _.map(res.records, (record) => record.get(0).properties) | ||
} catch (error) { | ||
|
@@ -161,7 +161,7 @@ async function getParentGroups(session, groupId) { | |
try { | ||
const res = await session.run( | ||
'MATCH (g:Group)-[r:GroupContains]->(c:Group {id: {groupId}}) RETURN g ORDER BY g.oldId', | ||
{ groupId } | ||
{groupId} | ||
) | ||
return _.map(res.records, (record) => record.get(0).properties) | ||
} catch (error) { | ||
|
@@ -176,7 +176,7 @@ async function getParentGroups(session, groupId) { | |
* @returns {String} link for the page | ||
*/ | ||
function getPageLink(req, page) { | ||
const q = _.assignIn({}, req.query, { page }) | ||
const q = _.assignIn({}, req.query, {page}) | ||
return `${req.protocol}://${req.get('Host')}${req.baseUrl}${req.path}?${querystring.stringify(q)}` | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,7 +67,7 @@ async function addGroupMember(currentUser, groupId, data) { | |
const targetObjectType = data.membershipType === config.MEMBERSHIP_TYPES.Group ? 'Group' : 'User' | ||
const memberCheckRes = await tx.run( | ||
`MATCH (g:Group {id: {groupId}})-[r:GroupContains]->(o:${targetObjectType} {id: {memberId}}) RETURN o`, | ||
{ groupId, memberId: data.memberId } | ||
{groupId, memberId: data.memberId} | ||
) | ||
if (memberCheckRes.records.length > 0) { | ||
throw new errors.ConflictError('The member is already in the group') | ||
|
@@ -77,7 +77,7 @@ async function addGroupMember(currentUser, groupId, data) { | |
if (data.membershipType === config.MEMBERSHIP_TYPES.Group) { | ||
const pathRes = await tx.run( | ||
'MATCH p=shortestPath( (g1:Group {id: {fromId}})-[*]->(g2:Group {id: {toId}}) ) RETURN p', | ||
{ fromId: data.memberId, toId: groupId } | ||
{fromId: data.memberId, toId: groupId} | ||
) | ||
if (pathRes.records.length > 0) { | ||
throw new errors.ConflictError('There is cyclical group reference') | ||
|
@@ -107,9 +107,9 @@ async function addGroupMember(currentUser, groupId, data) { | |
oldId: data.oldId, | ||
name: group.name, | ||
createdAt, | ||
...(currentUser === 'M2M' ? {} : { createdBy: currentUser.userId }), | ||
...(currentUser === 'M2M' ? {} : {createdBy: currentUser.userId}), | ||
memberId: data.memberId, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are we not using the M2M clientId for the createdUser/updatedUser values ? |
||
...(data.memberOldId ? { memberOldId: data.memberOldId } : {}), | ||
...(data.memberOldId ? {memberOldId: data.memberOldId} : {}), | ||
membershipType: data.membershipType | ||
} | ||
|
||
|
@@ -174,7 +174,7 @@ async function deleteGroupMember(currentUser, groupId, memberId) { | |
|
||
// delete membership | ||
const query = 'MATCH (g:Group {id: {groupId}})-[r:GroupContains]->(o {id: {memberId}}) DELETE r' | ||
await tx.run(query, { groupId, memberId }) | ||
await tx.run(query, {groupId, memberId}) | ||
|
||
if (validate(memberId, 4)) { | ||
const getMember = await helper.ensureExists(tx, 'Group', memberId) | ||
|
@@ -210,6 +210,102 @@ deleteGroupMember.schema = { | |
memberId: Joi.id() | ||
} | ||
|
||
/** | ||
* Add universal member. | ||
* @param {Object} currentUser the current user | ||
* @param {String} groupId the id of group to add member | ||
* @param {Object} data the data to add member | ||
* @returns {Object} the added group membership | ||
*/ | ||
async function addUniversalMember(currentUser, groupId, data) { | ||
logger.debug(`Enter in addGroupMember - Group = ${groupId} Criteria = ${data}`) | ||
let session = helper.createDBSession() | ||
let tx = session.beginTransaction() | ||
|
||
try { | ||
logger.debug(`Check for groupId ${groupId} exist or not`) | ||
const group = await helper.ensureExists( | ||
tx, | ||
'Group', | ||
groupId, | ||
currentUser !== 'M2M' && helper.hasAdminRole(currentUser) | ||
) | ||
data.oldId = group.oldId | ||
groupId = group.id | ||
|
||
if (currentUser !== 'M2M' && !helper.hasAdminRole(currentUser)) { | ||
throw new errors.ForbiddenError('You are not allowed to perform this action!') | ||
} | ||
|
||
logger.debug(`Check for memberId ${data.universalUID} exist or not`) | ||
await helper.ensureExists(tx, 'User', data.universalUID) | ||
|
||
logger.debug(`check member ${data.universalUID} is part of group ${groupId}`) | ||
const memberCheckRes = await tx.run( | ||
`MATCH (g:Group {id: {groupId}})-[r:GroupContains]->(o:User {universalUID: {universalUID}}) RETURN o`, | ||
{groupId, universalUID: data.universalUID} | ||
) | ||
if (memberCheckRes.records.length > 0) { | ||
throw new errors.ConflictError('The member is already in the group') | ||
} | ||
|
||
// add membership | ||
const membershipId = uuid() | ||
const createdAt = new Date().toISOString() | ||
const query = `MATCH (g:Group {id: {groupId}}) MATCH (o:User {universalUID: {universalUID}}) CREATE (g)-[r:GroupContains {universalUID: {universalUID}, type: {membershipType}, createdAt: {createdAt}, createdBy: {createdBy}}]->(o) RETURN r` | ||
|
||
const params = { | ||
groupId, | ||
universalUID: data.universalUID, | ||
membershipId, | ||
membershipType: data.membershipType, | ||
createdAt, | ||
createdBy: currentUser === 'M2M' ? '00000000' : currentUser.userId | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we use null instead of zeros? |
||
} | ||
|
||
logger.debug(`quey for adding membership ${query} with params ${JSON.stringify(params)}`) | ||
await tx.run(query, params) | ||
|
||
const result = { | ||
id: membershipId, | ||
groupId, | ||
oldId: data.oldId, | ||
name: group.name, | ||
createdAt, | ||
...(currentUser === 'M2M' ? {} : {createdBy: currentUser.userId}), | ||
memberId: '00000000', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nullable? |
||
universalUID: data.universalUID, | ||
handle: data.handle, | ||
...(data.memberOldId ? {memberOldId: data.memberOldId} : {}), | ||
membershipType: data.membershipType | ||
} | ||
|
||
logger.debug(`sending message ${JSON.stringify(result)} to kafka topic ${config.KAFKA_GROUP_MEMBER_ADD_TOPIC}`) | ||
await helper.postBusEvent(config.KAFKA_GROUP_MEMBER_ADD_TOPIC, result) | ||
|
||
await tx.commit() | ||
return result | ||
} catch (error) { | ||
logger.error(error) | ||
logger.debug('Transaction Rollback') | ||
await tx.rollback() | ||
throw error | ||
} finally { | ||
logger.debug('Session Close') | ||
await session.close() | ||
} | ||
} | ||
|
||
addUniversalMember.schema = { | ||
currentUser: Joi.any(), | ||
groupId: Joi.id(), // defined in app-bootstrap | ||
data: Joi.object() | ||
.keys({ | ||
universalUID: Joi.id(), | ||
handle: Joi.string().required() | ||
}) | ||
.required() | ||
} | ||
/** | ||
* Get group members | ||
* @param {Object} currentUser the current user | ||
|
@@ -235,7 +331,7 @@ async function getGroupMembers(currentUser, groupId, criteria) { | |
} | ||
|
||
const matchClause = 'MATCH (g:Group {id: {groupId}})-[r:GroupContains]->(o)' | ||
const params = { groupId } | ||
const params = {groupId} | ||
|
||
// query total record count | ||
const totalRes = await session.run(`${matchClause} RETURN COUNT(o)`, params) | ||
|
@@ -299,7 +395,7 @@ async function getGroupMemberWithSession(session, groupId, memberId) { | |
groupId = group.id | ||
|
||
const query = 'MATCH (g:Group {id: {groupId}})-[r:GroupContains]->(o {id: {memberId}}) RETURN r' | ||
const membershipRes = await session.run(query, { groupId, memberId }) | ||
const membershipRes = await session.run(query, {groupId, memberId}) | ||
if (membershipRes.records.length === 0) { | ||
throw new errors.NotFoundError('The member is not in the group') | ||
} | ||
|
@@ -375,9 +471,9 @@ async function getGroupMembersCount(groupId, query) { | |
queryToExecute = 'MATCH (g:Group {id: {groupId}})-[r:GroupContains]->(o:User) RETURN COUNT(o) AS count' | ||
} | ||
|
||
const res = await session.run(queryToExecute, { groupId }) | ||
const res = await session.run(queryToExecute, {groupId}) | ||
|
||
return { count: res.records[0]._fields[0].low } | ||
return {count: res.records[0]._fields[0].low} | ||
} catch (error) { | ||
logger.error(error) | ||
throw error | ||
|
@@ -426,6 +522,7 @@ getMemberGroups.schema = { | |
module.exports = { | ||
getGroupMembers, | ||
addGroupMember, | ||
addUniversalMember, | ||
getGroupMember, | ||
deleteGroupMember, | ||
getGroupMembersCount, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the
Id
field not allowed to benull
?