Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/common/copilotEmailAccess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,21 @@ function hasCopilotRole (currentUser) {
return helper.checkIfExists(['copilot'], currentUser.roles)
}

/**
* Check whether the copilot challenge-sharing email restriction applies to the caller.
* Used by MemberService.getMember and SearchService to decide whether member emails
* must be filtered down to members who share a challenge with the copilot.
* @param {Object} currentUser the authenticated user or M2M caller
* @returns {Boolean} true only for copilots without a sensitive data role (admin or Talent Manager)
*/
function shouldLimitCopilotEmailAccess (currentUser) {
if (!currentUser || currentUser.isMachine) {
return false
}

if (helper.hasAdminRole(currentUser)) {
// Admins and Talent Managers can already see every member email, so an extra
// copilot role must not narrow that access.
if (helper.hasSensitiveDataRole(currentUser)) {
return false
}

Expand Down
77 changes: 77 additions & 0 deletions test/unit/CopilotEmailAccess.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Unit tests of copilot email access rules.
*/

const placeholderDbUrl = 'postgresql://user:pass@localhost:5432/topcoder?schema=public'
process.env.DATABASE_URL = process.env.DATABASE_URL || placeholderDbUrl
process.env.SKILLS_DB_URL = process.env.SKILLS_DB_URL || placeholderDbUrl
process.env.CHALLENGES_DB_URL = process.env.CHALLENGES_DB_URL || placeholderDbUrl
process.env.ACADEMY_DB_URL = process.env.ACADEMY_DB_URL || placeholderDbUrl
process.env.RESOURCES_DB_URL = process.env.RESOURCES_DB_URL || placeholderDbUrl
process.env.ENGAGEMENTS_DB_URL = process.env.ENGAGEMENTS_DB_URL || placeholderDbUrl

const appConfig = require('config')
appConfig.DATABASE_URL = appConfig.DATABASE_URL || placeholderDbUrl
appConfig.RESOURCES_DB_URL = appConfig.RESOURCES_DB_URL || placeholderDbUrl

require('../../app-bootstrap')
const chai = require('chai')

const prismaManager = require('../../src/common/prisma')
const copilotEmailAccess = require('../../src/common/copilotEmailAccess')

const should = chai.should()

describe('copilot email access unit tests', () => {
const resourcesPrisma = prismaManager.getResourcesClient()
let originalFindMany
let findManyCalls

beforeEach(() => {
originalFindMany = resourcesPrisma.resource.findMany
findManyCalls = 0
// Simulate a copilot who shares no challenges with the requested members.
resourcesPrisma.resource.findMany = async () => {
findManyCalls += 1
return []
}
})

afterEach(() => {
resourcesPrisma.resource.findMany = originalFindMany
})

it('limits email access for a copilot without a sensitive data role', async () => {
const currentUser = { userId: 1001, roles: ['Topcoder User', 'copilot'] }

copilotEmailAccess.shouldLimitCopilotEmailAccess(currentUser).should.equal(true)
const canAccess = await copilotEmailAccess.canCopilotAccessMemberEmail(currentUser, 2002)
canAccess.should.equal(false)
findManyCalls.should.equal(1)
})

it('does not limit email access for a Talent Manager who is also a copilot', async () => {
const currentUser = {
userId: 1001,
roles: ['Project Manager', 'Talent Manager', 'Topcoder Talent', 'Topcoder User', 'copilot']
}

copilotEmailAccess.shouldLimitCopilotEmailAccess(currentUser).should.equal(false)
const canAccess = await copilotEmailAccess.canCopilotAccessMemberEmail(currentUser, 2002)
canAccess.should.equal(true)

const members = [{ userId: 2002, email: 'member@topcoder.com' }]
await copilotEmailAccess.stripUnauthorizedCopilotEmails(currentUser, members)
should.equal(members[0].email, 'member@topcoder.com')
findManyCalls.should.equal(0)
})

it('does not limit email access for an administrator who is also a copilot', async () => {
const currentUser = { userId: 1001, roles: ['administrator', 'copilot'] }

copilotEmailAccess.shouldLimitCopilotEmailAccess(currentUser).should.equal(false)
const canAccess = await copilotEmailAccess.canCopilotAccessMemberEmail(currentUser, 2002)
canAccess.should.equal(true)
findManyCalls.should.equal(0)
})
})
Loading