|
| 1 | +// @flow |
| 2 | +import { Meteor } from 'meteor/meteor' |
| 3 | +import UnitRolesData, { addUserToRole, roleEnum } from '../../unit-roles-data' |
| 4 | +import { factoryOptions, idUrlTemplate, transformCaseForClient } from '../../cases' |
| 5 | +import { Accounts } from 'meteor/accounts-base' |
| 6 | +import { KEEP_DEFAULT } from '../../pending-invitations' |
| 7 | +import { callAPI } from '../../../util/bugzilla-api' |
| 8 | + |
| 9 | +type UserDoc = { |
| 10 | + _id: string, |
| 11 | + profile: { |
| 12 | + name?: string |
| 13 | + }, |
| 14 | + emails: Array<{ |
| 15 | + address: string |
| 16 | + }> |
| 17 | +} |
| 18 | + |
| 19 | +type UserTransformer = (user: UserDoc) => { |
| 20 | + userId?: string, |
| 21 | + name?: string, |
| 22 | + role?: ?string |
| 23 | +} |
| 24 | + |
| 25 | +type UnitMeta = { |
| 26 | + _id: string, |
| 27 | + bzId: string, |
| 28 | + ownerIds: Array<string> |
| 29 | +} |
| 30 | + |
| 31 | +export const caseAPIFields = [ |
| 32 | + 'product', |
| 33 | + 'summary', |
| 34 | + 'id', |
| 35 | + 'assigned_to', |
| 36 | + 'creation_time', |
| 37 | + 'cf_ipi_clust_1_next_step', |
| 38 | + 'cf_ipi_clust_1_next_step_date', |
| 39 | + 'description', |
| 40 | + 'cf_ipi_clust_1_solution', |
| 41 | + 'deadline', |
| 42 | + 'cc', |
| 43 | + 'platform', |
| 44 | + 'cf_ipi_clust_6_claim_type', |
| 45 | + 'creator', |
| 46 | + 'priority', |
| 47 | + 'bug_severity' |
| 48 | +] |
| 49 | + |
| 50 | +export const makeUserAPIObjGenerator = (unitMongoId: string) => { |
| 51 | + const unitRolesDict = UnitRolesData.find({ |
| 52 | + unitId: unitMongoId |
| 53 | + }, { |
| 54 | + fields: { |
| 55 | + 'members.id': 1, |
| 56 | + roleType: 1 |
| 57 | + } |
| 58 | + }).fetch().reduce((all, role) => { |
| 59 | + role.members.forEach(member => { |
| 60 | + all[member.id] = role.roleType |
| 61 | + }) |
| 62 | + return all |
| 63 | + }, {}) |
| 64 | + |
| 65 | + return (userDoc: UserDoc) => { |
| 66 | + const userObj = {} |
| 67 | + if (userDoc) { |
| 68 | + userObj.userId = userDoc._id |
| 69 | + userObj.name = userDoc.profile.name || userDoc.emails[0].address.split('@')[0] |
| 70 | + userObj.role = unitRolesDict[userDoc._id] || null |
| 71 | + } |
| 72 | + return userObj |
| 73 | + } |
| 74 | +} |
| 75 | + |
| 76 | +export const tranformCaseAPIObj = (bug: any, thisUser: { _id: string }, transformUserObj: UserTransformer) => { |
| 77 | + const { |
| 78 | + product, |
| 79 | + id, |
| 80 | + assigned_to: assignedTo, |
| 81 | + assigned_to_detail: a, |
| 82 | + cc, |
| 83 | + cc_detail: b, |
| 84 | + creator, |
| 85 | + creator_detail: c, |
| 86 | + creation_time: creationTime, |
| 87 | + ...relevantBugFields |
| 88 | + } = bug |
| 89 | + const userRelevance = [] |
| 90 | + const assigneeObj = transformUserObj(Meteor.users.findOne({ 'bugzillaCreds.login': assignedTo })) |
| 91 | + if (thisUser._id === assigneeObj.userId) { |
| 92 | + userRelevance.push('Assignee') |
| 93 | + } |
| 94 | + |
| 95 | + const reporterObj = transformUserObj(Meteor.users.findOne({ 'bugzillaCreds.login': creator })) |
| 96 | + if (thisUser._id === reporterObj.userId) { |
| 97 | + userRelevance.push('Reporter') |
| 98 | + } |
| 99 | + |
| 100 | + const involvedList = cc.map(ccItem => transformUserObj(Meteor.users.findOne({ 'bugzillaCreds.login': ccItem }))) |
| 101 | + if (involvedList.some(involved => involved.userId === thisUser._id)) { |
| 102 | + userRelevance.push('Invited To') |
| 103 | + } |
| 104 | + return { |
| 105 | + assignee: assigneeObj, |
| 106 | + reporter: reporterObj, |
| 107 | + caseId: id, |
| 108 | + involvedList, |
| 109 | + userRelevance, |
| 110 | + creationTime, |
| 111 | + ...transformCaseForClient(relevantBugFields) |
| 112 | + } |
| 113 | +} |
| 114 | + |
| 115 | +export const attemptUserGeneration = (newUserEmail: string, creator: UserDoc) => { |
| 116 | + const existingUser = Accounts.findUserByEmail(newUserEmail) |
| 117 | + if (existingUser) { |
| 118 | + // logger.warn(`Creating user by alias ID '${newUserEmail}' failed, another user with this email address already exists`) |
| 119 | + return existingUser |
| 120 | + } |
| 121 | + const userId = Accounts.createUser({ |
| 122 | + email: newUserEmail, |
| 123 | + profile: { |
| 124 | + isLimited: true, |
| 125 | + creatorId: creator._id |
| 126 | + } |
| 127 | + }) |
| 128 | + |
| 129 | + Meteor.users.update({ _id: userId }, { |
| 130 | + $set: { |
| 131 | + 'emails.0.verified': true, |
| 132 | + apiAliases: { |
| 133 | + userId: creator._id, |
| 134 | + id: newUserEmail |
| 135 | + } |
| 136 | + } |
| 137 | + }) |
| 138 | + |
| 139 | + return Meteor.users.findOne({ _id: userId }) |
| 140 | +} |
| 141 | + |
| 142 | +export const verifyRole = ( |
| 143 | + invitor: UserDoc, |
| 144 | + invitee: UserDoc, |
| 145 | + unitMetaData: UnitMeta, |
| 146 | + designatedRole: string, |
| 147 | + errorLogParams: {} |
| 148 | +) => { |
| 149 | + const existingAssigneeRole = UnitRolesData.findOne({ 'members.id': invitee._id, unitId: unitMetaData._id }) |
| 150 | + if (!existingAssigneeRole) { |
| 151 | + if (!unitMetaData.ownerIds.includes(invitor._id)) { |
| 152 | + throw new Meteor.Error('The specified user doesn\'t have a role in this unit, and you are not allowed to invite it', 'client error') |
| 153 | + } |
| 154 | + if (!designatedRole) { |
| 155 | + throw new Meteor.Error('You must provide a role for the user, so it can be permitted access to this unit', 'client error') |
| 156 | + } |
| 157 | + |
| 158 | + try { |
| 159 | + addUserToRole(invitor, invitee, unitMetaData.bzId, designatedRole, KEEP_DEFAULT, false, errorLogParams) |
| 160 | + } catch (e) { |
| 161 | + throw new Meteor.Error(e.message, 'server error') |
| 162 | + } |
| 163 | + } |
| 164 | +} |
| 165 | + |
| 166 | +export const assigneeAllowedRoles:Array<mixed> = Object.values(roleEnum).filter(val => val !== roleEnum.CONTRACTOR) |
| 167 | +export const isDateString = (str:string) => typeof str === 'string' && !isNaN((new Date(str)).getTime()) |
| 168 | + |
| 169 | +export const getCaseById = (id:number) => { |
| 170 | + const resp = callAPI('get', idUrlTemplate(id), { api_key: process.env.BUGZILLA_ADMIN_KEY }, false, true) |
| 171 | + return factoryOptions.dataResolver(resp.data)[0] |
| 172 | +} |
0 commit comments