Skip to content

Commit

Permalink
Merge pull request #1020 from gchq/bugfix/BAI-1082-when-a-bad-connect…
Browse files Browse the repository at this point in the history
…or-is-provided-no-way-to-tell-what-the-good-connectors-are

Update errors for bad connectors
  • Loading branch information
JR40159 authored Jan 22, 2024
2 parents 90ccbff + 8e0f552 commit d22ac92
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 26 deletions.
19 changes: 14 additions & 5 deletions backend/src/connectors/v2/audit/index.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
import config from '../../../utils/v2/config.js'
import { ConfigurationError } from '../../../utils/v2/error.js'
import { BaseAuditConnector } from './Base.js'
import { SillyAuditConnector } from './silly.js'
import { StdoutAuditConnector } from './stdout.js'

export const AuditKind = {
Silly: 'silly',
Stdout: 'stdout',
} as const
export type AuditKindKeys = (typeof AuditKind)[keyof typeof AuditKind]

let auditConnector: undefined | BaseAuditConnector = undefined
export function getAutheticationConnector(cache = true) {
export function getAuditConnector(cache = true) {
if (auditConnector && cache) {
return auditConnector
}

switch (config.connectors.audit.kind) {
case 'silly':
case AuditKind.Silly:
auditConnector = new SillyAuditConnector()
break
case 'stdout':
case AuditKind.Stdout:
auditConnector = new StdoutAuditConnector()
break
default:
throw new Error('No valid audit connector provided.')
throw ConfigurationError(`'${config.connectors.audit.kind}' is not a valid audit kind.`, {
validKinds: Object.values(AuditKind),
})
}

return auditConnector
}

export default getAutheticationConnector()
export default getAuditConnector()
16 changes: 12 additions & 4 deletions backend/src/connectors/v2/authentication/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
import config from '../../../utils/v2/config.js'
import { ConfigurationError } from '../../../utils/v2/error.js'
import { BaseAuthenticationConnector } from './Base.js'
import { SillyAuthenticationConnector } from './silly.js'

export const AuthenticationKind = {
Silly: 'silly',
} as const
export type AuthenticationKindKeys = (typeof AuthenticationKind)[keyof typeof AuthenticationKind]

let authenticationConnector: undefined | BaseAuthenticationConnector = undefined
export function getAutheticationConnector(cache = true) {
export function getAuthenticationConnector(cache = true) {
if (authenticationConnector && cache) {
return authenticationConnector
}

switch (config.connectors.authentication.kind) {
case 'silly':
case AuthenticationKind.Silly:
authenticationConnector = new SillyAuthenticationConnector()
break
default:
throw new Error('No valid authentication connector provided.')
throw ConfigurationError(`'${config.connectors.authentication.kind}' is not a valid authentication kind.`, {
validKinds: Object.values(AuthenticationKind),
})
}

return authenticationConnector
}

export default getAutheticationConnector()
export default getAuthenticationConnector()
22 changes: 15 additions & 7 deletions backend/src/connectors/v2/authorisation/index.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
import config from '../../../utils/v2/config.js'
import { ConfigurationError } from '../../../utils/v2/error.js'
import { BasicAuthorisationConnector } from './base.js'

let authConnector: undefined | BasicAuthorisationConnector = undefined
export const AuthorisationKind = {
Basic: 'basic',
} as const
export type AuthorisationKindKeys = (typeof AuthorisationKind)[keyof typeof AuthorisationKind]

let authorisationConnector: undefined | BasicAuthorisationConnector = undefined
export function getAuthorisationConnector(cache = true): BasicAuthorisationConnector {
if (authConnector && cache) {
return authConnector
if (authorisationConnector && cache) {
return authorisationConnector
}

switch (config.connectors.authorisation.kind) {
case 'basic':
authConnector = new BasicAuthorisationConnector()
case AuthorisationKind.Basic:
authorisationConnector = new BasicAuthorisationConnector()
break
default:
throw new Error('No valid authorisation connector provided.')
throw ConfigurationError(`'${config.connectors.authorisation.kind}' is not a valid authorisation kind.`, {
validKinds: Object.values(AuthorisationKind),
})
}

return authConnector
return authorisationConnector
}

export default getAuthorisationConnector()
57 changes: 54 additions & 3 deletions backend/src/utils/v2/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import bunyan from 'bunyan'
import _config from 'config'

import { AuditKindKeys } from '../../connectors/v2/audit/Base.js'
import { AuthenticationKindKeys } from '../../connectors/v2/authentication/index.js'
import { AuthorisationKindKeys } from '../../connectors/v2/authorisation/index.js'
import { deepFreeze } from './object.js'

export interface Config {
Expand All @@ -12,11 +15,15 @@ export interface Config {

connectors: {
authentication: {
kind: 'silly' | string
kind: AuthenticationKindKeys
}

authorisation: {
kind: 'basic' | string
kind: AuthorisationKindKeys
}

audit: {
kind: AuditKindKeys
}
}

Expand Down Expand Up @@ -66,7 +73,51 @@ export interface Config {
insecure: boolean
}
}

ui: {
banner: {
enabled: boolean
text: string
colour: string
textColor: string
}

issues: {
label: string
supportHref: string
contactHref: string
}

registry: {
host: string
}

uploadWarning: {
showWarning: boolean
checkboxText: string
}

deploymentWarning: {
showWarning: boolean
checkboxText: string
}

// Used by some admin pages (e.g. the logs) to directly open the correct page in your IDE
// Not needed in production
development: {
logUrl: string
}

// The available seldon versions that can be used to build images
seldonVersions: [
{
name: string
image: string
},
]
maxModelSizeGB: number
}
}

const config: Config = _config.util.toObject()
export default deepFreeze(config)
export default deepFreeze(config) as Config
4 changes: 4 additions & 0 deletions backend/src/utils/v2/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ export function NotFound(message: string, context?: BailoError['context'], logge
export function InternalError(message: string, context?: BailoError['context'], logger?: Logger) {
return GenericError(500, message, context, logger)
}

export function ConfigurationError(message: string, context?: BailoError['context'], logger?: Logger) {
return GenericError(503, `BAILO configuration error: ${message}`, context, logger)
}
35 changes: 35 additions & 0 deletions backend/test/connectors/audit/audit.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { describe, expect, test, vi } from 'vitest'

import { getAuditConnector } from '../../../src/connectors/v2/audit/index.js'

const configMock = vi.hoisted(() => ({
connectors: {
audit: {
kind: 'silly',
},
},
}))
vi.mock('../../../src/utils/v2/config.js', () => ({
__esModule: true,
default: configMock,
}))

describe('connectors > audit', () => {
test('silly', () => {
const connector = getAuditConnector(false)
expect(connector.constructor.name).toBe('SillyAuditConnector')
})

test('stdout', () => {
configMock.connectors.audit.kind = 'stdout'
const connector = getAuditConnector(false)
expect(connector.constructor.name).toBe('StdoutAuditConnector')
})

test('invalid', () => {
const invalidConnector = 'invalid'
configMock.connectors.audit.kind = invalidConnector

expect(() => getAuditConnector(false)).toThrowError(`'${invalidConnector}' is not a valid audit kind.`)
})
})
13 changes: 8 additions & 5 deletions backend/test/connectors/authentication/authentication.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, test, vi } from 'vitest'

import { getAutheticationConnector } from '../../../src/connectors/v2/authentication/index.js'
import { getAuthenticationConnector } from '../../../src/connectors/v2/authentication/index.js'

const configMock = vi.hoisted(() => ({
connectors: {
Expand All @@ -14,15 +14,18 @@ vi.mock('../../../src/utils/v2/config.js', () => ({
default: configMock,
}))

describe('connectors > user', () => {
describe('connectors > authentication', () => {
test('silly', () => {
const connector = getAutheticationConnector(false)
const connector = getAuthenticationConnector(false)
expect(connector.constructor.name).toBe('SillyAuthenticationConnector')
})

test('invalid', () => {
configMock.connectors.authentication.kind = 'invalid'
const invalidConnector = 'invalid'
configMock.connectors.authentication.kind = invalidConnector

expect(() => getAutheticationConnector(false)).toThrowError('No valid authentication connector provided.')
expect(() => getAuthenticationConnector(false)).toThrowError(
`'${invalidConnector}' is not a valid authentication kind.`,
)
})
})
7 changes: 5 additions & 2 deletions backend/test/connectors/authorisation/authorisation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ describe('connectors > authorisation', () => {
})

test('invalid', () => {
config.connectors.authorisation.kind = 'invalid'
const invalidConnector = 'invalid'
config.connectors.authorisation.kind = invalidConnector

expect(() => getAuthorisationConnector(false)).toThrowError('No valid authorisation connector provided.')
expect(() => getAuthorisationConnector(false)).toThrowError(
`'${invalidConnector}' is not a valid authorisation kind.`,
)
})
})

0 comments on commit d22ac92

Please sign in to comment.