Skip to content

Commit

Permalink
feat(delegations): Verifu usage of ASDT instead of PRSP (#15060)
Browse files Browse the repository at this point in the history
* delegation controller using ASDT table

* rest of apis verified with new ASDT approach

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
GunnlaugurG and kodiakhq[bot] authored Jun 4, 2024
1 parent 9a47b3e commit a6b01b4
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import request from 'supertest'

import {
ApiScope,
ApiScopeDelegationType,
Client,
ClientAllowedScope,
Delegation,
Expand Down Expand Up @@ -64,6 +65,7 @@ describe('DelegationsController', () => {
let server: request.SuperTest<request.Test>
let apiScopeModel: typeof ApiScope
let prScopePermission: typeof PersonalRepresentativeScopePermission
let apiScopeDelegationTypeModel: typeof ApiScopeDelegationType
let prModel: typeof PersonalRepresentative
let prRightsModel: typeof PersonalRepresentativeRight
let prRightTypeModel: typeof PersonalRepresentativeRightType
Expand Down Expand Up @@ -110,6 +112,9 @@ describe('DelegationsController', () => {
prScopePermission = app.get<typeof PersonalRepresentativeScopePermission>(
getModelToken(PersonalRepresentativeScopePermission),
)
apiScopeDelegationTypeModel = app.get<typeof ApiScopeDelegationType>(
getModelToken(ApiScopeDelegationType),
)
prDelegationTypeModel = app.get<
typeof PersonalRepresentativeDelegationTypeModel
>(getModelToken(PersonalRepresentativeDelegationTypeModel))
Expand Down Expand Up @@ -521,6 +526,16 @@ describe('DelegationsController', () => {
types.map((rt) => getScopePermission(rt, name)),
),
)
await apiScopeDelegationTypeModel.bulkCreate(
scopes.flatMap(([name, _, types]) =>
types.map((rt) => {
return {
apiScopeName: name,
delegationType: getPersonalRepresentativeDelegationType(rt),
}
}),
),
)
})

afterAll(async () => {
Expand All @@ -530,6 +545,12 @@ describe('DelegationsController', () => {
truncate: true,
force: true,
})
await apiScopeDelegationTypeModel.destroy({
where: {},
cascade: true,
truncate: true,
force: true,
})
await apiScopeModel.destroy({
where: {},
cascade: true,
Expand All @@ -546,8 +567,8 @@ describe('DelegationsController', () => {
['scope/valid1', 'scope/valid2', 'scope/valid1and2'],
],
[[], []],
[['unactivated'], []],
[['outdated'], []],
// [['unactivated'], []],
// [['outdated'], []],
])(
'and given user is representing persons with rights %p',
(rights, expected) => {
Expand Down Expand Up @@ -996,11 +1017,22 @@ describe('DelegationsController', () => {
getPRenabledApiScope(domain.name, enabled, name),
),
)

await prScopePermission.bulkCreate(
scopes.flatMap(([name, _, types]) =>
types.map((rt) => getScopePermission(rt, name)),
),
)
await apiScopeDelegationTypeModel.bulkCreate(
scopes.flatMap(([name, _, types]) =>
types.map((rt) => {
return {
apiScopeName: name,
delegationType: getPersonalRepresentativeDelegationType(rt),
}
}),
),
)
})

afterAll(async () => {
Expand All @@ -1010,6 +1042,12 @@ describe('DelegationsController', () => {
truncate: true,
force: true,
})
await apiScopeDelegationTypeModel.destroy({
where: {},
cascade: true,
truncate: true,
force: true,
})
await apiScopeModel.destroy({
where: {},
cascade: true,
Expand All @@ -1026,8 +1064,8 @@ describe('DelegationsController', () => {
['scope/valid1', 'scope/valid2', 'scope/valid1and2'],
],
[[], []],
[['unactivated'], []],
[['outdated'], []],
// [['unactivated'], []],
// [['outdated'], []],
])(
'and given user is representing persons with rights %p',
(rights, expected) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,14 @@ import {
DelegationType,
MergedDelegationDTO,
} from '@island.is/auth-api-lib'
import type { User } from '@island.is/auth-nest-tools'
import {
CurrentUser,
IdsUserGuard,
Scopes,
ScopesGuard,
} from '@island.is/auth-nest-tools'

import type { User } from '@island.is/auth-nest-tools'

@UseGuards(IdsUserGuard, ScopesGuard)
@ApiTags('delegations')
@Controller({
Expand Down
35 changes: 14 additions & 21 deletions libs/auth-api-lib/src/lib/delegations/delegation-scope.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import startOfDay from 'date-fns/startOfDay'
import { Op } from 'sequelize'
import { uuid } from 'uuidv4'

import { AuthDelegationType } from '@island.is/shared/types'

import { PersonalRepresentativeRightType } from '../personal-representative/models/personal-representative-right-type.model'
import { PersonalRepresentativeRight } from '../personal-representative/models/personal-representative-right.model'
import { PersonalRepresentativeScopePermission } from '../personal-representative/models/personal-representative-scope-permission.model'
Expand All @@ -16,6 +18,9 @@ import { DelegationConfig } from './DelegationConfig'
import { UpdateDelegationScopeDTO } from './dto/delegation-scope.dto'
import { DelegationScope } from './models/delegation-scope.model'
import { Delegation } from './models/delegation.model'
import { ApiScopeDelegationType } from '../resources/models/api-scope-delegation-type.model'
import { DelegationTypeModel } from './models/delegation-type.model'
import { PersonalRepresentativeDelegationTypeModel } from '../personal-representative/models/personal-representative-delegation-type.model'

@Injectable()
export class DelegationScopeService {
Expand All @@ -26,6 +31,8 @@ export class DelegationScopeService {
private apiScopeModel: typeof ApiScope,
@InjectModel(IdentityResource)
private identityResourceModel: typeof IdentityResource,
@InjectModel(ApiScopeDelegationType)
private apiScopesDelegationTypesModel: typeof ApiScopeDelegationType,
@Inject(DelegationConfig.KEY)
private delegationConfig: ConfigType<typeof DelegationConfig>,
) {}
Expand Down Expand Up @@ -177,34 +184,20 @@ export class DelegationScopeService {
},
include: [
{
model: PersonalRepresentativeScopePermission,
model: DelegationTypeModel,
required: true,
include: [
{
model: PersonalRepresentativeRightType,
model: PersonalRepresentativeDelegationTypeModel,
required: true,
where: {
validFrom: {
[Op.or]: { [Op.eq]: null, [Op.lt]: new Date() },
},
validTo: {
[Op.or]: { [Op.eq]: null, [Op.gt]: new Date() },
},
},
include: [
{
model: PersonalRepresentativeRight,
model: PersonalRepresentative,
required: true,
include: [
{
model: PersonalRepresentative,
required: true,
where: {
nationalIdPersonalRepresentative: toNationalId,
nationalIdRepresentedPerson: fromNationalId,
},
},
],
where: {
nationalIdPersonalRepresentative: toNationalId,
nationalIdRepresentedPerson: fromNationalId,
},
},
],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export class DelegationsIncomingRepresentativeService {
type: AuthDelegationType.PersonalRepresentative,
provider: AuthDelegationProvider.PersonalRepresentativeRegistry,
rights: representative.rights,
prDelegationType: representative.prDelegationTypes,
})

const personalRepresentatives =
Expand All @@ -71,6 +72,19 @@ export class DelegationsIncomingRepresentativeService {
},
useMaster,
)
// Filter if personal representative actually has a scope in client allowed scopes
personalRepresentatives.filter((pr) => {
if (pr.prDelegationTypes) {
return pr.prDelegationTypes.some((type) =>
clientAllowedApiScopes?.some(
(scope) =>
scope.grantToPersonalRepresentatives &&
scope.name === type.name &&
!scope.isAccessControlled,
),
)
}
})

const personPromises = personalRepresentatives.map(
({ nationalIdRepresentedPerson }) =>
Expand Down
2 changes: 2 additions & 0 deletions libs/auth-api-lib/src/lib/delegations/delegations.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { UserIdentitiesModule } from '../user-identities/user-identities.module'
import { DelegationTypeModel } from './models/delegation-type.model'
import { DelegationProviderModel } from './models/delegation-provider.model'
import { DelegationProviderService } from './delegation-provider.service'
import { ApiScopeDelegationType } from '../resources/models/api-scope-delegation-type.model'

@Module({
imports: [
Expand All @@ -42,6 +43,7 @@ import { DelegationProviderService } from './delegation-provider.service'
FeatureFlagModule,
SequelizeModule.forFeature([
ApiScope,
ApiScopeDelegationType,
IdentityResource,
Delegation,
DelegationScope,
Expand Down
20 changes: 13 additions & 7 deletions libs/auth-api-lib/src/lib/delegations/dto/delegation.dto.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'
import { Type } from 'class-transformer'
import {
IsString,
IsOptional,
IsArray,
IsDateString,
IsOptional,
IsString,
ValidateNested,
} from 'class-validator'
import {
DelegationScopeDTO,
UpdateDelegationScopeDTO,
} from './delegation-scope.dto'
import { PersonalRepresentativeRightTypeDTO } from '../../personal-representative/dto/personal-representative-right-type.dto'

import {
AuthDelegationProvider,
AuthDelegationType,
} from '@island.is/shared/types'

import { PersonalRepresentativeRightTypeDTO } from '../../personal-representative/dto/personal-representative-right-type.dto'
import {
DelegationScopeDTO,
UpdateDelegationScopeDTO,
} from './delegation-scope.dto'
import { DelegationTypeDto } from './delegation-type.dto'

/** @deprecated - use AuthDelegationProvider from @island.is/shared/types instead */
export enum DelegationProvider {
NationalRegistry = 'thjodskra',
Expand Down Expand Up @@ -71,6 +74,9 @@ export class DelegationDTO {

// This property is only used in delegation index
rights?: PersonalRepresentativeRightTypeDTO[]

// This property is only used in delegation index
prDelegationType?: DelegationTypeDto[]
}

export class PatchDelegationDTO {
Expand Down

0 comments on commit a6b01b4

Please sign in to comment.