Skip to content
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

feat(ids-admin): General Mandate delegation for companies #17026

Merged
merged 7 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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: 11 additions & 0 deletions apps/services/auth/admin-api/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@
},
"docker-express": {
"executor": "Intentionally left blank, only so this target is valid when using `nx show projects --with-target docker-express`"
},
"dev": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "yarn start --project services-auth-admin-api"
}
],
"parallel": true
}
}
}
}
11 changes: 11 additions & 0 deletions apps/services/auth/delegation-api/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@
"buildTarget": "services-auth-delegation-api:build"
}
},
"dev": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "yarn start services-auth-delegation-api"
}
],
"parallel": true
}
},
"lint": {
"executor": "@nx/eslint:lint"
},
Expand Down
6 changes: 6 additions & 0 deletions apps/services/auth/ids-api/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,12 @@
],
"parallel": true
}
},
"dev": {
"executor": "nx:run-commands",
"options": {
"commands": ["yarn start services-auth-ids-api"]
}
GunnlaugurG marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getModelToken } from '@nestjs/sequelize'
import addDays from 'date-fns/addDays'
import request from 'supertest'
import { uuid } from 'uuidv4'
import addDays from 'date-fns/addDays'

import {
ApiScope,
Expand All @@ -27,12 +27,16 @@ import {
} from '@island.is/shared/types'
import {
createCurrentUser,
createNationalId,
createNationalRegistryUser,
} from '@island.is/testing/fixtures'
import { TestApp } from '@island.is/testing/nest'

import { defaultScopes, setupWithAuth } from '../../../../test/setup'
import { getFakeNationalId } from '../../../../test/stubs/genericStubs'
import {
getFakeCompanyNationalId,
getFakeNationalId,
} from '../../../../test/stubs/genericStubs'

describe('DelegationsController', () => {
describe.each([false, true])(
Expand All @@ -57,6 +61,8 @@ describe('DelegationsController', () => {
clientId: '@island.is/webapp',
})

const representeeNationalId = createNationalId('person')

const scopeValid1 = 'scope/valid1'
const scopeValid2 = 'scope/valid2'
const scopeValid1and2 = 'scope/valid1and2'
Expand All @@ -76,7 +82,7 @@ describe('DelegationsController', () => {
scopeName: s,
}))

const userNationalId = getFakeNationalId()
const userNationalId = createNationalId('person')

const user = createCurrentUser({
nationalId: userNationalId,
Expand All @@ -85,6 +91,8 @@ describe('DelegationsController', () => {
})

const domain = createDomain()
let nationalRegistryApiSpy: jest.SpyInstance
let nationalRegistryV3ApiSpy: jest.SpyInstance

beforeAll(async () => {
app = await setupWithAuth({
Expand Down Expand Up @@ -117,36 +125,214 @@ describe('DelegationsController', () => {
>(getModelToken(DelegationDelegationType))
nationalRegistryApi = app.get(NationalRegistryClientService)
nationalRegistryV3Api = app.get(NationalRegistryV3ClientService)
factory = new FixtureFactory(app)

client.supportedDelegationTypes = [
AuthDelegationType.GeneralMandate,
AuthDelegationType.LegalGuardian,
AuthDelegationType.ProcurationHolder,
]
await factory.createClient(client)

nationalRegistryApiSpy = jest
.spyOn(nationalRegistryApi, 'getIndividual')
.mockImplementation(async (id) => {
const user = createNationalRegistryUser({
nationalId: representeeNationalId,
})

return user ?? null
})

nationalRegistryV3ApiSpy = jest
.spyOn(nationalRegistryV3Api, 'getAllDataIndividual')
.mockImplementation(async () => {
const user = createNationalRegistryUser({
nationalId: representeeNationalId,
})

return { kennitala: user.nationalId, nafn: user.name }
})

const nationalRegistryV3FeatureService = app.get(
NationalRegistryV3FeatureService,
)
jest
.spyOn(nationalRegistryV3FeatureService, 'getValue')
.mockImplementation(async () => featureFlag)
factory = new FixtureFactory(app)
})

afterAll(async () => {
await app.cleanUp()
nationalRegistryV3ApiSpy.mockClear()
nationalRegistryApiSpy.mockClear()
})

describe('GET with general mandate delegation type', () => {
const representeeNationalId = getFakeNationalId()
let nationalRegistryApiSpy: jest.SpyInstance
let nationalRegistryV3ApiSpy: jest.SpyInstance
describe('GET with general mandate delegation type for company', () => {
const companyNationalId = getFakeCompanyNationalId()

const scopeNames = [
'api-scope/generalMandate1',
'api-scope/generalMandate2',
'api-scope/generalMandate3',
'api-scope/procuration1',
'api-scope/procuration2',
]

beforeAll(async () => {
client.supportedDelegationTypes = [
AuthDelegationType.GeneralMandate,
AuthDelegationType.LegalGuardian,
const delegations = await delegationModel.create({
id: uuid(),
fromDisplayName: 'Company',
fromNationalId: companyNationalId,
toNationalId: userNationalId,
toName: 'Person',
})

await delegationDelegationTypeModel.create({
delegationId: delegations.id,
delegationTypeId: AuthDelegationType.GeneralMandate,
})

await apiScopeModel.bulkCreate(
scopeNames.map((name) => ({
name,
domainName: domain.name,
enabled: true,
description: `${name}: description`,
displayName: `${name}: display name`,
})),
)

await apiScopeDelegationTypeModel.bulkCreate([
{
apiScopeName: scopeNames[0],
delegationType: AuthDelegationType.GeneralMandate,
},
{
apiScopeName: scopeNames[1],
delegationType: AuthDelegationType.GeneralMandate,
},
{
apiScopeName: scopeNames[3],
delegationType: AuthDelegationType.ProcurationHolder,
},
{
apiScopeName: scopeNames[4],
delegationType: AuthDelegationType.ProcurationHolder,
},
])
})

afterAll(async () => {
await apiScopeDelegationTypeModel.destroy({
where: {},
cascade: true,
truncate: true,
force: true,
})
await apiScopeModel.destroy({
where: {},
cascade: true,
truncate: true,
force: true,
})
await delegationDelegationTypeModel.destroy({
where: {},
cascade: true,
truncate: true,
force: true,
})
await delegationModel.destroy({
where: {},
cascade: true,
truncate: true,
force: true,
})
})

it('should return mergedDelegationDTO with the generalMandate', async () => {
const response = await server.get('/v2/delegations')

expect(response.status).toEqual(200)
expect(response.body).toHaveLength(1)
})

it('should return all general mandate scopes and other preset scopes', async () => {
const response = await server.get('/delegations/scopes').query({
fromNationalId: companyNationalId,
delegationType: [
AuthDelegationType.GeneralMandate,
AuthDelegationType.ProcurationHolder,
],
})

const expected = [
scopeNames[0],
scopeNames[1],
scopeNames[3],
scopeNames[4],
]

expect(response.status).toEqual(200)
expect(response.body).toEqual(expect.arrayContaining(expected))
expect(response.body).toHaveLength(expected.length)
})

it('should return all general mandate scopes and all procuration scopes', async () => {
const response = await server.get('/delegations/scopes').query({
fromNationalId: companyNationalId,
delegationType: [AuthDelegationType.GeneralMandate],
})

const expected = [
scopeNames[0],
scopeNames[1],
scopeNames[3],
scopeNames[4],
]
await factory.createClient(client)

expect(response.status).toEqual(200)
expect(response.body).toEqual(expect.arrayContaining(expected))
expect(response.body).toHaveLength(expected.length)
})

it('should return all general mandate scopes, and not procuration scopes since from nationalId is person', async () => {
// Assert
const delegation = await delegationModel.create({
id: uuid(),
fromDisplayName: 'FromPersonPerson',
fromNationalId: representeeNationalId,
toNationalId: userNationalId,
toName: 'Person',
})

await delegationDelegationTypeModel.create({
delegationId: delegation.id,
delegationTypeId: AuthDelegationType.GeneralMandate,
})

// Act
const response = await server.get('/delegations/scopes').query({
fromNationalId: representeeNationalId,
delegationType: [AuthDelegationType.GeneralMandate],
})

const expected = [scopeNames[0], scopeNames[1]]

expect(response.status).toEqual(200)
expect(response.body).toEqual(expect.arrayContaining(expected))
expect(response.body).toHaveLength(expected.length)
})
})
GunnlaugurG marked this conversation as resolved.
Show resolved Hide resolved

describe('GET with general mandate delegation type', () => {
const scopeNames = [
'api-scope/generalMandate1',
'api-scope/generalMandate2',
'api-scope/generalMandate3',
]

beforeAll(async () => {
const delegations = await delegationModel.create({
id: uuid(),
fromDisplayName: 'Test',
Expand Down Expand Up @@ -187,32 +373,39 @@ describe('DelegationsController', () => {
delegationType: AuthDelegationType.GeneralMandate,
},
])

nationalRegistryApiSpy = jest
.spyOn(nationalRegistryApi, 'getIndividual')
.mockImplementation(async (id) => {
const user = createNationalRegistryUser({
nationalId: representeeNationalId,
})

return user ?? null
})

nationalRegistryV3ApiSpy = jest
.spyOn(nationalRegistryV3Api, 'getAllDataIndividual')
.mockImplementation(async () => {
const user = createNationalRegistryUser({
nationalId: representeeNationalId,
})

return { kennitala: user.nationalId, nafn: user.name }
})
})

afterAll(async () => {
await app.cleanUp()
nationalRegistryApiSpy.mockClear()
nationalRegistryV3ApiSpy.mockClear()
await apiScopeDelegationTypeModel.destroy({
where: {},
cascade: true,
truncate: true,
force: true,
})
await apiScopeModel.destroy({
where: {},
cascade: true,
truncate: true,
force: true,
})
await delegationProviderModel.destroy({
where: {},
cascade: true,
truncate: true,
force: true,
})
await delegationDelegationTypeModel.destroy({
where: {},
cascade: true,
truncate: true,
force: true,
})
await delegationModel.destroy({
where: {},
cascade: true,
truncate: true,
force: true,
})
})

it('should return mergedDelegationDTO with the generalMandate', async () => {
Expand Down
Loading
Loading