Skip to content

Commit

Permalink
fix(auth-api): Add audit logs to index with alsoLog set to true for s…
Browse files Browse the repository at this point in the history
…erver logs (#16203)

* Adding audit log to delegationIndex saveToIndex method to track changes to users delegations records in the index.

* Add audit to create and remove in index service.

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
saevarma and kodiakhq[bot] authored Sep 29, 2024
1 parent c14f868 commit d399cd8
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,14 @@ export class DelegationIndexController {
...parsedDelegationInfo,
},
},
this.delegationIndexService.createOrUpdateDelegationRecord({
...parsedDelegationInfo,
provider: auth.delegationProvider,
validTo: body.validTo,
}),
this.delegationIndexService.createOrUpdateDelegationRecord(
{
...parsedDelegationInfo,
provider: auth.delegationProvider,
validTo: body.validTo,
},
auth,
),
)
}

Expand Down Expand Up @@ -126,10 +129,13 @@ export class DelegationIndexController {
...parsedDelegationInfo,
},
},
this.delegationIndexService.removeDelegationRecord({
...parsedDelegationInfo,
provider: auth.delegationProvider,
}),
this.delegationIndexService.removeDelegationRecord(
{
...parsedDelegationInfo,
provider: auth.delegationProvider,
},
auth,
),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ describe('DelegationsIndexService', () => {
const nationalId = user.nationalId

// Act
await delegationIndexService.indexCustomDelegations(nationalId)
await delegationIndexService.indexCustomDelegations(nationalId, user)

// Assert
const delegations = await delegationIndexModel.findAll({
Expand Down Expand Up @@ -480,7 +480,10 @@ describe('DelegationsIndexService', () => {
const nationalId = user.nationalId

// Act
await delegationIndexService.indexRepresentativeDelegations(nationalId)
await delegationIndexService.indexRepresentativeDelegations(
nationalId,
user,
)

// Assert
const delegations = await delegationIndexModel.findAll({
Expand Down Expand Up @@ -625,7 +628,7 @@ describe('DelegationsIndexService', () => {
const nationalId = user.nationalId

// Act
await delegationIndexService.indexCustomDelegations(nationalId)
await delegationIndexService.indexCustomDelegations(nationalId, user)

// Assert
const delegations = await delegationModel.findAll({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ export class PersonalRepresentativesController {

return personalRepresentative
}

/** Removes a personal representative by its id */
@Delete(':id')
@Documentation({
Expand Down Expand Up @@ -135,6 +136,7 @@ export class PersonalRepresentativesController {
// Index personal representative delegations for the personal representative
void this.delegationIndexService.indexRepresentativeDelegations(
deletedPersonalRepresentative.nationalIdPersonalRepresentative,
user,
)
}
}
Expand Down Expand Up @@ -203,6 +205,7 @@ export class PersonalRepresentativesController {
// Index personal representative delegations for the personal representative
void this.delegationIndexService.indexRepresentativeDelegations(
createdPersonalRepresentative.nationalIdPersonalRepresentative,
user,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import kennitala from 'kennitala'
import { uuid } from 'uuidv4'

import { AuthDelegationType } from '@island.is/shared/types'
import { User } from '@island.is/auth-nest-tools'
import { Auth, User } from '@island.is/auth-nest-tools'
import { NoContentException } from '@island.is/nest/problem'
import {
Ticket,
Expand Down Expand Up @@ -201,7 +201,7 @@ export class DelegationAdminCustomService {
)

// Index delegations for the toNationalId
void this.indexDelegations(delegation.toNationalId)
void this.indexDelegations(delegation.toNationalId, user)

return newDelegation.toDTO(AuthDelegationType.GeneralMandate)
}
Expand Down Expand Up @@ -244,7 +244,7 @@ export class DelegationAdminCustomService {
}

// Index delegations for the toNationalId
void this.indexDelegations(delegation.toNationalId)
void this.indexDelegations(delegation.toNationalId, user)
})
}

Expand All @@ -267,8 +267,11 @@ export class DelegationAdminCustomService {
}
}

private indexDelegations(nationalId: string) {
void this.delegationIndexService.indexCustomDelegations(nationalId)
void this.delegationIndexService.indexGeneralMandateDelegations(nationalId)
private indexDelegations(nationalId: string, auth: Auth) {
void this.delegationIndexService.indexCustomDelegations(nationalId, auth)
void this.delegationIndexService.indexGeneralMandateDelegations(
nationalId,
auth,
)
}
}
25 changes: 13 additions & 12 deletions libs/auth-api-lib/src/lib/delegations/delegation-scope.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { DelegationTypeModel } from './models/delegation-type.model'
import { Delegation } from './models/delegation.model'

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

@Injectable()
export class DelegationScopeService {
constructor(
Expand Down Expand Up @@ -309,24 +310,27 @@ export class DelegationScopeService {
}

private async findDistrictCommissionersRegistryScopesTo(
toNationalId: string,
user: User,
fromNationalId: string,
): Promise<string[]> {
// if no valid delegation exists, return empty array
try {
const delegationFound =
await this.syslumennService.checkIfDelegationExists(
toNationalId,
user.nationalId,
fromNationalId,
)

if (!delegationFound) {
this.delegationsIndexService.removeDelegationRecord({
fromNationalId,
toNationalId,
type: AuthDelegationType.LegalRepresentative,
provider: AuthDelegationProvider.DistrictCommissionersRegistry,
})
void this.delegationsIndexService.removeDelegationRecord(
{
fromNationalId,
toNationalId: user.nationalId,
type: AuthDelegationType.LegalRepresentative,
provider: AuthDelegationProvider.DistrictCommissionersRegistry,
},
user,
)
return []
}
} catch (error) {
Expand Down Expand Up @@ -429,10 +433,7 @@ export class DelegationScopeService {
providers.includes(AuthDelegationProvider.DistrictCommissionersRegistry)
)
scopePromises.push(
this.findDistrictCommissionersRegistryScopesTo(
user.nationalId,
fromNationalId,
),
this.findDistrictCommissionersRegistryScopesTo(user, fromNationalId),
)

const scopeSets = await Promise.all(scopePromises)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,12 +302,15 @@ export class DelegationsIncomingService {
if (delegationFound) {
return true
} else {
this.delegationsIndexService.removeDelegationRecord({
fromNationalId,
toNationalId: user.nationalId,
type: AuthDelegationType.LegalRepresentative,
provider: AuthDelegationProvider.DistrictCommissionersRegistry,
})
void this.delegationsIndexService.removeDelegationRecord(
{
fromNationalId,
toNationalId: user.nationalId,
type: AuthDelegationType.LegalRepresentative,
provider: AuthDelegationProvider.DistrictCommissionersRegistry,
},
user,
)
}
} catch (error) {
logger.error(
Expand Down
91 changes: 70 additions & 21 deletions libs/auth-api-lib/src/lib/delegations/delegations-index.service.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { BadRequestException, Injectable } from '@nestjs/common'
import { BadRequestException, Inject, Injectable } from '@nestjs/common'
import { InjectModel } from '@nestjs/sequelize'
import startOfDay from 'date-fns/startOfDay'
import * as kennitala from 'kennitala'
import union from 'lodash/union'
import { Op } from 'sequelize'

import { User } from '@island.is/auth-nest-tools'
import { Auth, User } from '@island.is/auth-nest-tools'
import { AuditService } from '@island.is/nest/audit'
import { type Logger, LOGGER_PROVIDER } from '@island.is/logging'
import {
AuthDelegationProvider,
AuthDelegationType,
Expand Down Expand Up @@ -170,6 +172,9 @@ export class DelegationsIndexService {
private delegationsIncomingWardService: DelegationsIncomingWardService,
private personalRepresentativeScopePermissionService: PersonalRepresentativeScopePermissionService,
private userIdentitiesService: UserIdentitiesService,
@Inject(LOGGER_PROVIDER)
private logger: Logger,
private auditService: AuditService,
) {}

/* Lookup delegations in index for user for specific scope */
Expand Down Expand Up @@ -258,7 +263,7 @@ export class DelegationsIndexService {
this.getWardDelegations(user),
]).then((d) => d.flat())

await this.saveToIndex(user.nationalId, delegations)
await this.saveToIndex(user.nationalId, delegations, user)

// set next reindex to one week in the future
await this.delegationIndexMetaModel.update(
Expand All @@ -275,49 +280,76 @@ export class DelegationsIndexService {
}

/* Index incoming custom delegations */
async indexCustomDelegations(nationalId: string) {
async indexCustomDelegations(nationalId: string, auth: Auth) {
const delegations = await this.getCustomDelegations(nationalId, true)
await this.saveToIndex(nationalId, delegations)
await this.saveToIndex(nationalId, delegations, auth)
}

/* Index incoming general mandate delegations */
async indexGeneralMandateDelegations(nationalId: string) {
async indexGeneralMandateDelegations(nationalId: string, auth: Auth) {
const delegations = await this.getGeneralMandateDelegation(nationalId, true)
await this.saveToIndex(nationalId, delegations)
await this.saveToIndex(nationalId, delegations, auth)
}

/* Index incoming personal representative delegations */
async indexRepresentativeDelegations(nationalId: string) {
async indexRepresentativeDelegations(nationalId: string, auth: Auth) {
const delegations = await this.getRepresentativeDelegations(
nationalId,
true,
)
await this.saveToIndex(nationalId, delegations)
await this.saveToIndex(nationalId, delegations, auth)
}

/* Add item to index */
async createOrUpdateDelegationRecord(delegation: DelegationRecordInputDTO) {
async createOrUpdateDelegationRecord(
delegation: DelegationRecordInputDTO,
auth: Auth,
) {
validateCrudParams(delegation)

const [updatedDelegation] = await this.delegationIndexModel.upsert(
delegation,
const [updatedDelegation] = await this.auditService.auditPromise(
{
auth,
action:
'@island.is/auth/delegation-index/create-or-update-delegation-record',
resources: delegation.toNationalId,
alsoLog: true,
meta: {
delegation,
},
},
this.delegationIndexModel.upsert(delegation),
)

return updatedDelegation.toDTO()
}

/* Delete record from index */
async removeDelegationRecord(delegation: DelegationRecordInputDTO) {
async removeDelegationRecord(
delegation: DelegationRecordInputDTO,
auth: Auth,
) {
validateCrudParams(delegation)

await this.delegationIndexModel.destroy({
where: {
fromNationalId: delegation.fromNationalId,
toNationalId: delegation.toNationalId,
provider: delegation.provider,
type: delegation.type,
await this.auditService.auditPromise(
{
auth,
action: '@island.is/auth/delegation-index/remove-delegation-record',
resources: delegation.toNationalId,
alsoLog: true,
meta: {
delegation,
},
},
})
this.delegationIndexModel.destroy({
where: {
fromNationalId: delegation.fromNationalId,
toNationalId: delegation.toNationalId,
provider: delegation.provider,
type: delegation.type,
},
}),
)
}

async getAvailableDistrictCommissionersRegistryRecords(
Expand All @@ -338,7 +370,7 @@ export class DelegationsIndexService {
}
}

return await this.delegationIndexModel
return this.delegationIndexModel
.findAll({
where: {
toNationalId: user.nationalId,
Expand All @@ -356,6 +388,9 @@ export class DelegationsIndexService {
private async saveToIndex(
nationalId: string,
delegations: DelegationIndexInfo[],
// Some entrypoints to indexing do not have a user auth object or have a 3rd party user
// so we take the auth separately from the subject nationalId
auth: Auth,
) {
const currRecords = await this.delegationIndexModel.findAll({
where: {
Expand Down Expand Up @@ -398,6 +433,20 @@ export class DelegationsIndexService {
}),
),
])

// saveToIndex is used by multiple entry points, when indexing so this
// is the common place to audit updates in the index.
this.auditService.audit({
auth,
action: '@island.is/auth/delegation-index/save-to-index',
alsoLog: true,
resources: nationalId,
meta: {
created,
updated,
deleted,
},
})
}

private sortDelegation({
Expand Down
Loading

0 comments on commit d399cd8

Please sign in to comment.