Skip to content

Commit

Permalink
chore(assets): Configure token exchange for Properties API (#6131)
Browse files Browse the repository at this point in the history
* Refactor assets configuration

* Configure token exchange in properties api

* Remove properties scope from service portal

* Charts

* Feedback

* Fixes

* Format

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
eirikurn and kodiakhq[bot] authored Jan 9, 2022
1 parent 4f24b0a commit 13ff809
Show file tree
Hide file tree
Showing 16 changed files with 154 additions and 130 deletions.
17 changes: 7 additions & 10 deletions apps/api/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,16 @@ import { ApiDomainsPaymentModule } from '@island.is/api/domains/payment'
import { LicenseServiceModule } from '@island.is/api/domains/license-service'
import { IslykillModule } from '@island.is/api/domains/islykill'
import { PaymentScheduleModule } from '@island.is/api/domains/payment-schedule'
import { AssetsClientConfig } from '@island.is/clients/assets'
import { AuthPublicApiClientConfig } from '@island.is/clients/auth-public-api'
import { NationalRegistryClientConfig } from '@island.is/clients/national-registry-v2'
import { AuditModule } from '@island.is/nest/audit'
import { ConfigModule, XRoadConfig } from '@island.is/nest/config'
import { FeatureFlagConfig } from '@island.is/nest/feature-flags'
import { ProblemModule } from '@island.is/nest/problem'
import { CriminalRecordModule } from '@island.is/api/domains/criminal-record'

import { maskOutFieldsMiddleware } from './graphql.middleware'
import { AuthPublicApiClientConfig } from '@island.is/clients/auth-public-api'
import { FeatureFlagConfig } from '@island.is/nest/feature-flags'

const debug = process.env.NODE_ENV === 'development'
const playground = debug || process.env.GQL_PLAYGROUND_ENABLED === 'true'
Expand Down Expand Up @@ -202,12 +203,7 @@ const autoSchemaFile = environment.production
xroadBaseUrl: environment.xroad.baseUrl,
xroadClientId: environment.xroad.clientId,
}),
AssetsModule.register({
xRoadBasePathWithEnv: environment.propertiesXRoad.url,
xRoadAssetsMemberCode: environment.propertiesXRoad.memberCode,
xRoadAssetsApiPath: environment.propertiesXRoad.apiPath,
xRoadClientId: environment.propertiesXRoad.clientId,
}),
AssetsModule,
NationalRegistryXRoadModule,
ApiDomainsPaymentModule.register({
xRoadProviderId: environment.paymentDomain.xRoadProviderId,
Expand Down Expand Up @@ -258,11 +254,12 @@ const autoSchemaFile = environment.production
ConfigModule.forRoot({
isGlobal: true,
load: [
XRoadConfig,
NationalRegistryClientConfig,
AssetsClientConfig,
AuthPublicApiClientConfig,
FeatureFlagConfig,
NationalRegistryClientConfig,
SyslumennClientConfig,
XRoadConfig,
],
}),
],
Expand Down
15 changes: 0 additions & 15 deletions apps/api/src/app/environments/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,6 @@ const prodConfig = () => ({
endorsementSystem: {
baseApiUrl: process.env.ENDORSEMENT_SYSTEM_BASE_API_URL,
},
propertiesXRoad: {
url: process.env.XROAD_BASE_PATH_WITH_ENV,
memberCode: process.env.XROAD_TJODSKRA_MEMBER_CODE,
apiPath: process.env.XROAD_PROPERTIES_API_PATH,
clientId: process.env.XROAD_CLIENT_ID,
},
paymentDomain: {
xRoadBaseUrl: process.env.XROAD_BASE_PATH,
xRoadProviderId: process.env.XROAD_PAYMENT_PROVIDER_ID,
Expand Down Expand Up @@ -273,15 +267,6 @@ const devConfig = () => ({
endorsementSystem: {
baseApiUrl: 'http://localhost:4246',
},
propertiesXRoad: {
url:
process.env.XROAD_BASE_PATH_WITH_ENV ?? 'http://localhost:8081/r1/IS-DEV',
memberCode: process.env.XROAD_TJODSKRA_MEMBER_CODE ?? '10001',
apiPath:
process.env.XROAD_PROPERTIES_API_PATH ?? '/SKRA-Protected/Fasteignir-v1',
clientId:
process.env.XROAD_CLIENT_ID ?? 'IS-DEV/GOV/10000/island-is-client',
},
paymentDomain: {
xRoadBaseUrl: process.env.XROAD_BASE_PATH,
xRoadProviderId:
Expand Down
1 change: 0 additions & 1 deletion apps/service-portal/src/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ if (userMocked) {
AuthScope.readDelegations,
AuthScope.writeDelegations,
NationalRegistryScope.individuals,
NationalRegistryScope.properties,
DocumentsScope.main,
EndorsementsScope.main,
EndorsementsScope.admin,
Expand Down
2 changes: 2 additions & 0 deletions charts/islandis/values.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ api:
XROAD_PAYMENT_BASE_CALLBACK_URL: 'XROAD:/IS-DEV/GOV/10000/island-is/application-payment-v1/'
XROAD_PAYMENT_PROVIDER_ID: 'IS-DEV/GOV/10021/FJS-Public'
XROAD_PROPERTIES_API_PATH: '/SKRA-Protected/Fasteignir-v1'
XROAD_PROPERTIES_SERVICE_PATH: 'IS-DEV/GOV/10001/SKRA-Protected/Fasteignir-v1'
XROAD_TJODSKRA_API_PATH: '/SKRA-Protected/Einstaklingar-v1'
XROAD_TJODSKRA_MEMBER_CODE: '10001'
XROAD_TLS_BASE_PATH: 'https://securityserver.dev01.devland.is'
Expand Down Expand Up @@ -300,6 +301,7 @@ api:
XROAD_HEALTH_INSURANCE_V2_XROAD_USERNAME: '/k8s/api/HEALTH_INSURANCE_V2_XROAD_USERNAME'
XROAD_PAYMENT_PASSWORD: '/k8s/application-system-api/PAYMENT_PASSWORD'
XROAD_PAYMENT_USER: '/k8s/application-system-api/PAYMENT_USER'
XROAD_PROPERTIES_CLIENT_SECRET: '/k8s/xroad/client/NATIONAL-REGISTRY/IDENTITYSERVER_SECRET'
XROAD_VMST_API_KEY: '/k8s/vmst-client/VMST_API_KEY'
ZENDESK_CONTACT_FORM_EMAIL: '/k8s/api/ZENDESK_CONTACT_FORM_EMAIL'
ZENDESK_CONTACT_FORM_TOKEN: '/k8s/api/ZENDESK_CONTACT_FORM_TOKEN'
Expand Down
2 changes: 2 additions & 0 deletions charts/islandis/values.prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ api:
XROAD_PAYMENT_BASE_CALLBACK_URL: 'XROAD:/IS/GOV/5501692829/island-is/application-payment-v1/'
XROAD_PAYMENT_PROVIDER_ID: 'IS/GOV/5402697509/FJS-Public'
XROAD_PROPERTIES_API_PATH: '/SKRA-Protected/Fasteignir-v1'
XROAD_PROPERTIES_SERVICE_PATH: 'IS/GOV/6503760649/SKRA-Protected/Fasteignir-v1'
XROAD_TJODSKRA_API_PATH: '/SKRA-Protected/Einstaklingar-v1'
XROAD_TJODSKRA_MEMBER_CODE: '6503760649'
XROAD_TLS_BASE_PATH: 'https://securityserver.island.is'
Expand Down Expand Up @@ -292,6 +293,7 @@ api:
XROAD_HEALTH_INSURANCE_V2_XROAD_USERNAME: '/k8s/api/HEALTH_INSURANCE_V2_XROAD_USERNAME'
XROAD_PAYMENT_PASSWORD: '/k8s/application-system-api/PAYMENT_PASSWORD'
XROAD_PAYMENT_USER: '/k8s/application-system-api/PAYMENT_USER'
XROAD_PROPERTIES_CLIENT_SECRET: '/k8s/xroad/client/NATIONAL-REGISTRY/IDENTITYSERVER_SECRET'
XROAD_VMST_API_KEY: '/k8s/vmst-client/VMST_API_KEY'
ZENDESK_CONTACT_FORM_EMAIL: '/k8s/api/ZENDESK_CONTACT_FORM_EMAIL'
ZENDESK_CONTACT_FORM_TOKEN: '/k8s/api/ZENDESK_CONTACT_FORM_TOKEN'
Expand Down
2 changes: 2 additions & 0 deletions charts/islandis/values.staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ api:
XROAD_PAYMENT_BASE_CALLBACK_URL: 'XROAD:'
XROAD_PAYMENT_PROVIDER_ID: 'IS-TEST/GOV/10021/FJS-DEV-Public'
XROAD_PROPERTIES_API_PATH: '/SKRA-Protected/Fasteignir-v1'
XROAD_PROPERTIES_SERVICE_PATH: 'IS-TEST/GOV/6503760649/SKRA-Protected/Fasteignir-v1'
XROAD_TJODSKRA_API_PATH: '/SKRA-Protected/Einstaklingar-v1'
XROAD_TJODSKRA_MEMBER_CODE: '6503760649'
XROAD_TLS_BASE_PATH: 'https://securityserver.staging01.devland.is'
Expand Down Expand Up @@ -298,6 +299,7 @@ api:
XROAD_HEALTH_INSURANCE_V2_XROAD_USERNAME: '/k8s/api/HEALTH_INSURANCE_V2_XROAD_USERNAME'
XROAD_PAYMENT_PASSWORD: '/k8s/application-system-api/PAYMENT_PASSWORD'
XROAD_PAYMENT_USER: '/k8s/application-system-api/PAYMENT_USER'
XROAD_PROPERTIES_CLIENT_SECRET: '/k8s/xroad/client/NATIONAL-REGISTRY/IDENTITYSERVER_SECRET'
XROAD_VMST_API_KEY: '/k8s/vmst-client/VMST_API_KEY'
ZENDESK_CONTACT_FORM_EMAIL: '/k8s/api/ZENDESK_CONTACT_FORM_EMAIL'
ZENDESK_CONTACT_FORM_TOKEN: '/k8s/api/ZENDESK_CONTACT_FORM_TOKEN'
Expand Down
10 changes: 10 additions & 0 deletions infra/src/dsl/xroad.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,18 @@ export const Finance = new XroadConf({

export const Properties = new XroadConf({
env: {
XROAD_PROPERTIES_SERVICE_PATH: {
dev: 'IS-DEV/GOV/10001/SKRA-Protected/Fasteignir-v1',
staging: 'IS-TEST/GOV/6503760649/SKRA-Protected/Fasteignir-v1',
prod: 'IS/GOV/6503760649/SKRA-Protected/Fasteignir-v1',
},
// Deprecated:
XROAD_PROPERTIES_API_PATH: '/SKRA-Protected/Fasteignir-v1',
},
secrets: {
XROAD_PROPERTIES_CLIENT_SECRET:
'/k8s/xroad/client/NATIONAL-REGISTRY/IDENTITYSERVER_SECRET',
},
})

export const Education = new XroadConf({
Expand Down
43 changes: 7 additions & 36 deletions libs/api/domains/assets/src/lib/api-domains-assets.module.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,13 @@
import { DynamicModule, Module } from '@nestjs/common'
import fetch from 'isomorphic-fetch'
import { Module } from '@nestjs/common'
import { AuthModule } from '@island.is/auth-nest-tools'
import { AssetsClientModule } from '@island.is/clients/assets'
import { FasteignirApi, Configuration } from '@island.is/clients/assets'
import {
createXRoadAPIPath,
XRoadMemberClass,
} from '@island.is/shared/utils/server'

import { AssetsXRoadResolver } from './api-domains-assets.resolver'
import { AssetsXRoadService } from './api-domains-assets.service'

export interface AssetsXRoadConfig {
xRoadBasePathWithEnv: string
xRoadAssetsMemberCode: string
xRoadAssetsApiPath: string
xRoadClientId: string
}

@Module({})
export class AssetsModule {
static register(config: AssetsXRoadConfig): DynamicModule {
return {
module: AssetsModule,
providers: [AssetsXRoadResolver, AssetsXRoadService],
imports: [
AssetsClientModule.register({
xRoadPath: createXRoadAPIPath(
config.xRoadBasePathWithEnv,
XRoadMemberClass.GovernmentInstitution,
config.xRoadAssetsMemberCode,
config.xRoadAssetsApiPath,
),
xRoadClient: config.xRoadClientId,
}),
AuthModule,
],
exports: [AssetsXRoadService],
}
}
}
@Module({
providers: [AssetsXRoadResolver, AssetsXRoadService],
imports: [AssetsClientModule, AuthModule],
exports: [AssetsXRoadService],
})
export class AssetsModule {}
2 changes: 0 additions & 2 deletions libs/api/domains/assets/src/lib/api-domains-assets.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { AuthMiddleware } from '@island.is/auth-nest-tools'
import type { Auth, User } from '@island.is/auth-nest-tools'
import type { Logger } from '@island.is/logging'
import { LOGGER_PROVIDER } from '@island.is/logging'
import { AuthorizationIdentityMiddleware } from './authorization-identity.middleware'

const getAssetString = (str: string) =>
str.charAt(0).toLowerCase() === 'f' ? str.substring(1) : str
Expand All @@ -30,7 +29,6 @@ export class AssetsXRoadService {
private getRealEstatesWithAuth(auth: Auth) {
return this.FasteignirApi.withMiddleware(
new AuthMiddleware(auth, { forwardUserInfo: true }),
new AuthorizationIdentityMiddleware(auth.authorization),
)
}

Expand Down

This file was deleted.

6 changes: 2 additions & 4 deletions libs/clients/assets/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
export {
AssetsClientModule,
ModuleConfig as AssetsModuleConfig,
} from './lib/assets.module'
export { AssetsClientModule } from './lib/assets.module'
export { AssetsClientConfig } from './lib/assets.config'
export * from '../gen/fetch'
48 changes: 48 additions & 0 deletions libs/clients/assets/src/lib/PropertiesApiProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Provider } from '@nestjs/common/interfaces/modules/provider.interface'
import nodeFetch, { Request } from 'node-fetch'

import {
createEnhancedFetch,
EnhancedFetchOptions,
} from '@island.is/clients/middlewares'
import {
ConfigType,
LazyDuringDevScope,
XRoadConfig,
} from '@island.is/nest/config'

import { Configuration, FasteignirApi } from '../../gen/fetch'
import { AssetsClientConfig } from './assets.config'

export const PropertiesApiProvider: Provider<FasteignirApi> = {
provide: FasteignirApi,
scope: LazyDuringDevScope,
useFactory: (
xroadConfig: ConfigType<typeof XRoadConfig>,
config: ConfigType<typeof AssetsClientConfig>,
) =>
new FasteignirApi(
new Configuration({
fetchApi: createEnhancedFetch({
name: 'clients-assets',
...config.fetch,
fetch: (url, init) => {
// The Properties API expects two different authorization headers for some reason.
const request = new Request(url, init)
request.headers.set(
'authorization-identity',
request.headers.get('authorization') ?? '',
)
return nodeFetch(request)
},
} as EnhancedFetchOptions),
// TODO: Remove ^ "as EnhancedFetchOptions" after making API projects strict TS.
basePath: `${xroadConfig.xRoadBasePath}/r1/${config.xRoadServicePath}`,
headers: {
'X-Road-Client': xroadConfig.xRoadClient,
Accept: 'application/json',
},
}),
),
inject: [XRoadConfig.KEY, AssetsClientConfig.KEY],
}
53 changes: 53 additions & 0 deletions libs/clients/assets/src/lib/assets.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { NationalRegistryScope } from '@island.is/auth/scopes'
import { defineConfig } from '@island.is/nest/config'
import * as z from 'zod'

const schema = z.object({
xRoadServicePath: z.string(),
fetch: z.object({
timeout: z.number().int(),
autoAuth: z
.object({
mode: z.enum(['token', 'tokenExchange', 'auto']),
issuer: z.string(),
clientId: z.string(),
clientSecret: z.string(),
scope: z.array(z.string()),
})
.optional(),
}),
})

export const AssetsClientConfig = defineConfig<z.infer<typeof schema>>({
name: 'AssetsClient',
schema,
load(env) {
const clientSecret = env.optional('XROAD_PROPERTIES_CLIENT_SECRET')
return {
xRoadServicePath: env.required(
'XROAD_PROPERTIES_SERVICE_PATH',
'IS-DEV/GOV/10001/SKRA-Protected/Fasteignir-v1',
),
fetch: {
timeout: env.optionalJSON('XROAD_PROPERTIES_TIMEOUT') ?? 10000,
autoAuth: clientSecret
? {
mode: 'tokenExchange',
issuer: env.required(
'IDENTITY_SERVER_ISSUER_URL',
'https://identity-server.dev01.devland.is',
),
clientId:
env.optional('XROAD_PROPERTIES_CLIENT_ID') ??
'@island.is/clients/national-registry',
clientSecret,
scope: env.optionalJSON('XROAD_PROPERTIES_SCOPE') ?? [
NationalRegistryScope.properties,
'api_resource.scope',
],
}
: undefined,
},
}
},
})
48 changes: 8 additions & 40 deletions libs/clients/assets/src/lib/assets.module.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,8 @@
import { DynamicModule } from '@nestjs/common'
import { createEnhancedFetch } from '@island.is/clients/middlewares'
import type { EnhancedFetchOptions } from '@island.is/clients/middlewares'

import { Configuration, FasteignirApi } from '../../gen/fetch'

export interface ModuleConfig {
xRoadPath?: string
xRoadClient: string
userAuth?: any
fetch?: Partial<EnhancedFetchOptions>
}

export class AssetsClientModule {
static register(config: ModuleConfig): DynamicModule {
const headers = {
'X-Road-Client': config.xRoadClient,
Accept: 'application/json',
}
const providerConfiguration = new Configuration({
fetchApi: createEnhancedFetch({
name: 'clients-assets',
...config.fetch,
}),
basePath: config.xRoadPath,
headers,
})

const exportedApis = [FasteignirApi]

return {
module: AssetsClientModule,
providers: exportedApis.map((Api) => ({
provide: Api,
useFactory: () => new Api(providerConfiguration),
})),
exports: exportedApis,
}
}
}
import { Module } from '@nestjs/common'
import { PropertiesApiProvider } from './PropertiesApiProvider'

@Module({
providers: [PropertiesApiProvider],
exports: [PropertiesApiProvider],
})
export class AssetsClientModule {}
Loading

0 comments on commit 13ff809

Please sign in to comment.