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

fix(auth-delegations): Fix missing domains for legal representative delegations #17320

Merged
merged 1 commit into from
Dec 20, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ import { DelegationDelegationType } from './models/delegation-delegation-type.mo
import { DelegationScope } from './models/delegation-scope.model'
import { DelegationTypeModel } from './models/delegation-type.model'
import { Delegation } from './models/delegation.model'
import { ApiScopeInfo } from './delegations-incoming.service'

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

@Injectable()
export class DelegationScopeService {
Expand Down Expand Up @@ -222,7 +224,18 @@ export class DelegationScopeService {
},
],
})
.then((apiScopes) => apiScopes.map((apiScope) => apiScope.name))
.then((apiScopes) =>
apiScopes
.filter((scope) =>
// Remove scopes that are not allowed for the delegation type
filterByCustomScopeRule(
scope,
[AuthDelegationType.GeneralMandate],
this.delegationConfig.customScopeRules,
),
)
.map((apiScope) => apiScope.name),
)
}

private async findAllNationalRegistryScopes(): Promise<string[]> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { Delegation } from './models/delegation.model'
import { NationalRegistryV3FeatureService } from './national-registry-v3-feature.service'
import { DelegationValidity } from './types/delegationValidity'
import { getScopeValidityWhereClause } from './utils/scopes'
import filterByCustomScopeRule from './utils/filterByScopeCustomScopeRule'

type FindAllValidIncomingOptions = {
nationalId: string
Expand Down Expand Up @@ -182,20 +183,6 @@ export class DelegationsIncomingCustomService {
})
}

private filterByCustomScopeRule(scope: ApiScopeInfo) {
const foundCSR = this.delegationConfig.customScopeRules.find(
(csr) => csr.scopeName === scope.name,
)

if (!foundCSR) {
return true
}

return foundCSR.onlyForDelegationType.includes(
AuthDelegationType.GeneralMandate,
)
}

/**
* Finds all companies that have a general mandate for the user.
* @param user
Expand Down Expand Up @@ -233,7 +220,11 @@ export class DelegationsIncomingCustomService {
const customApiScopes = clientAllowedApiScopes.filter(
(s) =>
!s.isAccessControlled &&
this.filterByCustomScopeRule(s) &&
filterByCustomScopeRule(
s,
[AuthDelegationType.GeneralMandate],
this.delegationConfig.customScopeRules,
) &&
s.supportedDelegationTypes?.some((dt) =>
supportedDelegationTypes.includes(
dt.delegationType as AuthDelegationType,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { AuthDelegationType } from '@island.is/shared/types'
import { ApiScopeInfo } from '../delegations-incoming.service'

export default function filterByCustomScopeRule(
scope: ApiScopeInfo,
filterOutForDelegationType: AuthDelegationType[],
customScopeRules: {
scopeName: string
onlyForDelegationType: string[]
}[],
): boolean {
const foundCSR = customScopeRules.find((csr) => csr.scopeName === scope.name)

if (!foundCSR) {
return true
}

return foundCSR.onlyForDelegationType.some((type) =>
filterOutForDelegationType.includes(type as AuthDelegationType),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { mapToScopeTree } from './utils/scope-tree.mapper'

import type { Attributes, WhereOptions } from 'sequelize'
import type { ConfigType } from '@island.is/nest/config'
import { ApiScopeDelegationType } from './models/api-scope-delegation-type.model'

type DelegationConfigType = ConfigType<typeof DelegationConfig>
type ScopeRule = DelegationConfigType['customScopeRules'] extends Array<
Expand All @@ -42,6 +43,8 @@ export class DelegationResourcesService {
private domainModel: typeof Domain,
@InjectModel(DelegationScope)
private delegationScopeModel: typeof DelegationScope,
@InjectModel(ApiScopeDelegationType)
private apiScopeDelegationTypeModel: typeof ApiScopeDelegationType,
private resourceTranslationService: ResourceTranslationService,
@Inject(DelegationConfig.KEY)
private delegationConfig: ConfigType<typeof DelegationConfig>,
Expand Down Expand Up @@ -304,20 +307,37 @@ export class DelegationResourcesService {
}

private async delegationTypeFilter(user: User, prefix?: string) {
if (!user.delegationType || !user.actor) {
if (!user.delegationType) {
return []
}

// We currently only support access control for company (delegation) actors.
// Actors for individuals should not have the scope required to reach this
// point, but we assert it just to be safe.
// EDIT: This is no longer true, as we now support LegalRepresentative delegations for individuals.
if (!isCompany(user.nationalId)) {
throw new ForbiddenException(
'Actors for individuals should not be able to manage delegations.',
)
if (
!user.delegationType.includes(AuthDelegationType.LegalRepresentative)
) {
throw new ForbiddenException(
'Actors for individuals should not be able to manage delegations.',
)
}
}

const delegationOr: Array<WhereOptions<ApiScope>> = []
if (user.delegationType.includes(AuthDelegationType.LegalRepresentative)) {
const scopes = await this.apiScopeDelegationTypeModel.findAll({
attributes: ['apiScopeName'],
where: {
delegationType: AuthDelegationType.LegalRepresentative,
},
})

delegationOr.push({
[col(prefix, 'name')]: scopes.map((scope) => scope.apiScopeName),
})
}
if (user.delegationType.includes(AuthDelegationType.ProcurationHolder)) {
delegationOr.push({ [col(prefix, 'grantToProcuringHolders')]: true })
}
Expand Down
2 changes: 2 additions & 0 deletions libs/auth-api-lib/src/lib/resources/resources.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { ResourceTranslationService } from './resource-translation.service'
import { ResourcesService } from './resources.service'
import { ScopeService } from './scope.service'
import { TenantsService } from './tenants.service'
import { ApiScopeDelegationType } from './models/api-scope-delegation-type.model'

@Module({
imports: [
Expand All @@ -39,6 +40,7 @@ import { TenantsService } from './tenants.service'
ApiScopeUser,
ApiScopeUserAccess,
ApiResourceScope,
ApiScopeDelegationType,
IdentityResourceUserClaim,
ApiScopeUserClaim,
ApiResourceUserClaim,
Expand Down
Loading