1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-07-26 13:48:33 +02:00

Add option to run unleash in strict schema validation (#3073)

feat: strict schema validation
This commit is contained in:
Jaanus Sellin 2023-02-09 15:21:03 +02:00 committed by GitHub
parent c1679a9222
commit 8ee9b75e48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 26 additions and 2 deletions

View File

@ -83,6 +83,7 @@ exports[`should create default config 1`] = `
"proxyReturnAllToggles": false, "proxyReturnAllToggles": false,
"responseTimeWithAppName": false, "responseTimeWithAppName": false,
"showProjectApiAccess": false, "showProjectApiAccess": false,
"strictSchemaValidation": false,
"variantsPerEnvironment": false, "variantsPerEnvironment": false,
}, },
}, },
@ -104,6 +105,7 @@ exports[`should create default config 1`] = `
"proxyReturnAllToggles": false, "proxyReturnAllToggles": false,
"responseTimeWithAppName": false, "responseTimeWithAppName": false,
"showProjectApiAccess": false, "showProjectApiAccess": false,
"strictSchemaValidation": false,
"variantsPerEnvironment": false, "variantsPerEnvironment": false,
}, },
"externalResolver": { "externalResolver": {

View File

@ -21,6 +21,7 @@ export const featureSchema = {
}, },
description: { description: {
type: 'string', type: 'string',
nullable: true,
}, },
archived: { archived: {
type: 'boolean', type: 'boolean',

View File

@ -16,6 +16,7 @@ export const groupSchema = {
}, },
description: { description: {
type: 'string', type: 'string',
nullable: true,
}, },
mappingsSSO: { mappingsSSO: {
type: 'array', type: 'array',

View File

@ -24,6 +24,7 @@ import {
createRequestSchema, createRequestSchema,
createResponseSchema, createResponseSchema,
emptyResponse, emptyResponse,
featureEnvironmentSchema,
FeatureEnvironmentSchema, FeatureEnvironmentSchema,
featureSchema, featureSchema,
FeatureSchema, FeatureSchema,
@ -590,7 +591,13 @@ export default class ProjectFeaturesController extends Controller {
const result = { const result = {
...environmentInfo, ...environmentInfo,
strategies: environmentInfo.strategies.map((strategy) => { strategies: environmentInfo.strategies.map((strategy) => {
const { strategyName, ...rest } = strategy; const {
strategyName,
projectId: project,
environment: environmentId,
createdAt,
...rest
} = strategy;
return { ...rest, name: strategyName }; return { ...rest, name: strategyName };
}), }),
}; };
@ -598,7 +605,7 @@ export default class ProjectFeaturesController extends Controller {
this.openApiService.respondWithValidation( this.openApiService.respondWithValidation(
200, 200,
res, res,
featureSchema.$id, featureEnvironmentSchema.$id,
serializeDates(result), serializeDates(result),
); );
} }

View File

@ -10,6 +10,7 @@ import {
import { ApiOperation } from '../openapi/util/api-operation'; import { ApiOperation } from '../openapi/util/api-operation';
import { Logger } from '../logger'; import { Logger } from '../logger';
import { validateSchema } from '../openapi/validate'; import { validateSchema } from '../openapi/validate';
import { IFlagResolver } from '../types';
export class OpenApiService { export class OpenApiService {
private readonly config: IUnleashConfig; private readonly config: IUnleashConfig;
@ -18,8 +19,11 @@ export class OpenApiService {
private readonly api: IExpressOpenApi; private readonly api: IExpressOpenApi;
private flagResolver: IFlagResolver;
constructor(config: IUnleashConfig) { constructor(config: IUnleashConfig) {
this.config = config; this.config = config;
this.flagResolver = config.flagResolver;
this.logger = config.getLogger('openapi-service.ts'); this.logger = config.getLogger('openapi-service.ts');
this.api = openapi( this.api = openapi(
@ -78,6 +82,9 @@ export class OpenApiService {
'Invalid response:', 'Invalid response:',
JSON.stringify(errors, null, 4), JSON.stringify(errors, null, 4),
); );
if (this.flagResolver.isEnabled('strictSchemaValidation')) {
throw new Error(JSON.stringify(errors, null, 4));
}
} }
Object.entries(headers).forEach(([header, value]) => Object.entries(headers).forEach(([header, value]) =>

View File

@ -66,6 +66,10 @@ const flags = {
process.env.UNLEASH_EXPERIMENTAL_PROJECT_API_ACCESS, process.env.UNLEASH_EXPERIMENTAL_PROJECT_API_ACCESS,
false, false,
), ),
strictSchemaValidation: parseEnvVarBoolean(
process.env.UNLEASH_STRICT_SCHEMA_VALIDTION,
false,
),
}; };
export const defaultExperimentalOptions: IExperimentalOptions = { export const defaultExperimentalOptions: IExperimentalOptions = {

View File

@ -1245,6 +1245,7 @@ exports[`should serve the OpenAPI spec 1`] = `
"type": "string", "type": "string",
}, },
"description": { "description": {
"nullable": true,
"type": "string", "type": "string",
}, },
"enabled": { "enabled": {
@ -1524,6 +1525,7 @@ exports[`should serve the OpenAPI spec 1`] = `
"type": "string", "type": "string",
}, },
"description": { "description": {
"nullable": true,
"type": "string", "type": "string",
}, },
"id": { "id": {