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(auth-api-lib): Use db to look up delegation types and providers when validating #16116

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import {
createNationalId,
} from '@island.is/testing/fixtures'
import { AuthScope } from '@island.is/auth/scopes'
import { DelegationIndex } from '@island.is/auth-api-lib'
import {
DelegationIndex,
DelegationProviderModel,
DelegationTypeModel,
} from '@island.is/auth-api-lib'
import {
AuthDelegationProvider,
AuthDelegationType,
Expand Down Expand Up @@ -70,7 +74,29 @@ const invalidDelegationTypeAndProviderMapTestcases: Record<
],
}

const DELEGATION_PROVIDERS = [
{
provider: AuthDelegationProvider.NationalRegistry,
type: AuthDelegationType.LegalGuardian,
},
{
provider: AuthDelegationProvider.Custom,
type: AuthDelegationType.Custom,
},
{
provider: AuthDelegationProvider.PersonalRepresentativeRegistry,
type: AuthDelegationType.PersonalRepresentativePostbox,
},
{
provider: AuthDelegationProvider.CompanyRegistry,
type: AuthDelegationType.ProcurationHolder,
},
]

describe('DelegationIndexController', () => {
let delegationTypeModel: typeof DelegationTypeModel
let delegationProviderModel: typeof DelegationProviderModel
baering marked this conversation as resolved.
Show resolved Hide resolved

describe('Without valid scope', () => {
let app: TestApp
let server: request.SuperTest<request.Test>
Expand All @@ -85,6 +111,8 @@ describe('DelegationIndexController', () => {
})

server = request(app.getHttpServer())
;({ delegationProviderModel, delegationTypeModel } =
await setupDelegationModels(app))
})

afterAll(async () => {
Expand Down Expand Up @@ -143,6 +171,8 @@ describe('DelegationIndexController', () => {
})

server = request(app.getHttpServer())
;({ delegationProviderModel, delegationTypeModel } =
await setupDelegationModels(app))
})

afterAll(async () => {
Expand Down Expand Up @@ -207,6 +237,8 @@ describe('DelegationIndexController', () => {
})

server = request(app.getHttpServer())
;({ delegationProviderModel, delegationTypeModel } =
await setupDelegationModels(app))
})

afterAll(async () => {
Expand Down Expand Up @@ -265,6 +297,8 @@ describe('DelegationIndexController', () => {
server = request(app.getHttpServer())

delegationIndexModel = app.get(getModelToken(DelegationIndex))
;({ delegationProviderModel, delegationTypeModel } =
await setupDelegationModels(app))
})

afterAll(async () => {
Expand Down Expand Up @@ -414,3 +448,43 @@ describe('DelegationIndexController', () => {
})
})
})

async function setupDelegationModels(app: TestApp) {
const delegationProviderModel = app.get(
getModelToken(DelegationProviderModel),
)
const delegationTypeModel = app.get(getModelToken(DelegationTypeModel))

await createDelegationProvidersAndTypes(
delegationProviderModel,
delegationTypeModel,
)

return { delegationProviderModel, delegationTypeModel }
}

async function createDelegationProvidersAndTypes(
delegationProviderModel: typeof DelegationProviderModel,
delegationTypeModel: typeof DelegationTypeModel,
) {
for (const { provider, type } of DELEGATION_PROVIDERS) {
const [providerInstance] = await delegationProviderModel.findOrCreate({
where: { id: provider },
defaults: {
id: provider,
name: type,
description: 'Testing',
},
})

await delegationTypeModel.findOrCreate({
where: { id: type },
defaults: {
id: type,
name: type,
description: 'Testing',
providerId: providerInstance.id,
},
})
}
}
baering marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ import {
import { DelegationDTO } from './dto/delegation.dto'
import { DelegationIndexMeta } from './models/delegation-index-meta.model'
import { DelegationIndex } from './models/delegation-index.model'
import { DelegationTypeModel } from './models/delegation-type.model'
import { DelegationDirection } from './types/delegationDirection'
import {
DelegationRecordType,
PersonalRepresentativeDelegationType,
} from './types/delegationRecord'
import {
delegationProviderTypeMap,
validateDelegationTypeAndProvider,
validateToAndFromNationalId,
} from './utils/delegations'

Expand Down Expand Up @@ -90,25 +90,6 @@ const getTimeUntilEighteen = (nationalId: string) => {
return timeUntilEighteen > 0 ? new Date(timeUntilEighteen) : null
}

const validateCrudParams = (delegation: DelegationRecordInputDTO) => {
if (!validateDelegationTypeAndProvider(delegation)) {
throw new BadRequestException(
'Invalid delegation type and provider combination',
)
}

if (!validateToAndFromNationalId(delegation)) {
throw new BadRequestException('Invalid national ids')
}

if (
delegation.validTo &&
new Date(delegation.validTo).getTime() <= new Date().getTime()
) {
throw new BadRequestException('Invalid validTo')
}
}

const hasAllSameScopes = (
a: string[] | undefined,
b: string[] | undefined,
Expand Down Expand Up @@ -151,6 +132,8 @@ export class DelegationsIndexService {
private apiScopeModel: typeof ApiScope,
@InjectModel(DelegationIndex)
private delegationIndexModel: typeof DelegationIndex,
@InjectModel(DelegationTypeModel)
private delegationTypeModel: typeof DelegationTypeModel,
@InjectModel(DelegationIndexMeta)
private delegationIndexMetaModel: typeof DelegationIndexMeta,
private delegationsIncomingCustomService: DelegationsIncomingCustomService,
Expand Down Expand Up @@ -280,7 +263,7 @@ export class DelegationsIndexService {

/* Add item to index */
async createOrUpdateDelegationRecord(delegation: DelegationRecordInputDTO) {
validateCrudParams(delegation)
await this.validateCrudParams(delegation)

const [updatedDelegation] = await this.delegationIndexModel.upsert(
delegation,
Expand All @@ -291,7 +274,7 @@ export class DelegationsIndexService {

/* Delete record from index */
async removeDelegationRecord(delegation: DelegationRecordInputDTO) {
validateCrudParams(delegation)
await this.validateCrudParams(delegation)

await this.delegationIndexModel.destroy({
where: {
Expand Down Expand Up @@ -659,4 +642,43 @@ export class DelegationsIndexService {
})
.then((d) => d.map((d) => d.toDTO()))
}

private async validateDelegationTypeAndProvider(
delegation: DelegationRecordInputDTO,
) {
const { type, provider } = delegation

const validTypes = await this.delegationTypeModel
.findAll({
where: {
provider,
},
})
.then((d) => d.map((d) => d.name))

return validTypes.includes(type)
}

private async validateCrudParams(delegation: DelegationRecordInputDTO) {
const isValidDelegationType = await this.validateDelegationTypeAndProvider(
delegation,
)

if (!isValidDelegationType) {
throw new BadRequestException(
'Invalid delegation type and provider combination',
)
}

if (!validateToAndFromNationalId(delegation)) {
throw new BadRequestException('Invalid national ids')
}

if (
delegation.validTo &&
new Date(delegation.validTo).getTime() <= new Date().getTime()
) {
throw new BadRequestException('Invalid validTo')
}
}
saevarma marked this conversation as resolved.
Show resolved Hide resolved
}
16 changes: 0 additions & 16 deletions libs/auth-api-lib/src/lib/delegations/utils/delegations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,6 @@ export const getDelegationNoActorWhereClause = (user: User): WhereOptions => {
return {}
}

export const validateDelegationTypeAndProvider = ({
type,
provider,
}: {
type: DelegationRecordType
provider: AuthDelegationProvider
}) => {
const validTypes = delegationProviderTypeMap[provider]

if (!validTypes) {
return false
}

return validTypes.includes(type)
}

export const validateToAndFromNationalId = ({
fromNationalId,
toNationalId,
Expand Down
1 change: 1 addition & 0 deletions libs/shared/types/src/lib/delegation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export enum AuthDelegationType {
LegalGuardian = 'LegalGuardian',
Custom = 'Custom',
PersonalRepresentative = 'PersonalRepresentative',
PersonalRepresentativePostbox = 'PersonalRepresentative:postholf',
baering marked this conversation as resolved.
Show resolved Hide resolved
LegalRepresentative = 'LegalRepresentative',
GeneralMandate = 'GeneralMandate',
}
Expand Down
Loading