Skip to content

Commit 7fae2a9

Browse files
authored
[#IOPID-3234] Fix security override behaviour (#332)
1 parent f27a59b commit 7fae2a9

10 files changed

Lines changed: 562 additions & 141 deletions

File tree

__mocks__/api.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ host: localhost
77
basePath: /api/v1
88
schemes:
99
- https
10+
security:
11+
- customToken: []
1012
securityDefinitions:
1113
bearerToken:
1214
type: apiKey
@@ -307,6 +309,21 @@ paths:
307309
responses:
308310
"200":
309311
description: "Ok"
312+
/test-with-overridden-security:
313+
get:
314+
operationId: "testOverriddenSecurity"
315+
security:
316+
- bearerToken: []
317+
responses:
318+
"200":
319+
description: "Ok"
320+
/test-with-overridden-security-no-auth:
321+
get:
322+
operationId: "testOverriddenSecurityNoAuth"
323+
security: []
324+
responses:
325+
"200":
326+
description: "Ok"
310327

311328
definitions:
312329
Person:

__mocks__/openapi_v3/api.yaml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ info:
55
version: 1.0.0
66
servers:
77
- url: https://localhost/api/v1
8+
security:
9+
- customToken : []
810
paths:
911
/test-auth-bearer:
1012
get:
@@ -335,7 +337,22 @@ paths:
335337
responses:
336338
"200":
337339
description: "Ok"
338-
340+
/test-with-overridden-security:
341+
get:
342+
operationId: "testOverriddenSecurity"
343+
security:
344+
- bearerToken: []
345+
responses:
346+
"200":
347+
description: "Ok"
348+
/test-with-overridden-security-no-auth:
349+
get:
350+
operationId: "testOverriddenSecurityNoAuth"
351+
security: []
352+
responses:
353+
"200":
354+
description: "Ok"
355+
339356
# -------------
340357
# Components
341358
# -------------

e2e/src/__tests__/test-api-v3/client.test.ts

Lines changed: 65 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const { generatedFilesDir, mockPort, isSpecEnabled } = config.specs.testapiV3;
1818

1919
// if there's no need for this suite in this particular run, just skip it
2020
const describeSuite = skipClient || !isSpecEnabled ? describe.skip : describe;
21+
const customToken = "anAPIKey";
2122

2223
// given a spied fetch call, check if the request has been made using the provided parameter in querystring
2324
const hasQueryParam = (paramName: string) => ([input]: Parameters<
@@ -82,7 +83,8 @@ describeSuite("Http client generated from Test API spec", () => {
8283
headerInlineParam: "value",
8384
"path-param": "value",
8485
"request-id": "value",
85-
"x-header-param": "value"
86+
"x-header-param": "value",
87+
customToken
8688
});
8789
expect(isRight(result)).toBe(true);
8890
});
@@ -103,7 +105,8 @@ describeSuite("Http client generated from Test API spec", () => {
103105
headerInlineParam: "value",
104106
"path-param": "value",
105107
"request-id": "value",
106-
"x-header-param": "value"
108+
"x-header-param": "value",
109+
customToken
107110
});
108111
expect(isRight(result)).toBe(true);
109112
});
@@ -134,7 +137,8 @@ describeSuite("Http client generated from Test API spec", () => {
134137
headerInlineParam: "value",
135138
"path-param": "value",
136139
"request-id": "value",
137-
"x-header-param": "value"
140+
"x-header-param": "value",
141+
customToken
138142
});
139143

140144
expect(spiedFetch).toHaveBeenCalledTimes(1);
@@ -200,18 +204,21 @@ describeSuite("Http client generated from Test API spec", () => {
200204
// It can be called with expected query parameters
201205
const resultWithCursor = await client.testParametersAtPathLevel({
202206
"request-id": "an id",
203-
cursor: "a cursor"
207+
cursor: "a cursor",
208+
customToken
204209
});
205210

206211
// It can be called without optional parameters
207212
const result = await client.testParametersAtPathLevel({
208-
"request-id": "an id"
213+
"request-id": "an id",
214+
customToken
209215
});
210216

211217
// It cannot be called without optional parameters
212218
// @ts-expect-error
213219
await client.testParametersAtPathLevel({
214-
cursor: "a cursor"
220+
cursor: "a cursor",
221+
customToken
215222
});
216223
});
217224

@@ -239,7 +246,8 @@ describeSuite("Http client generated from Test API spec", () => {
239246
expect.assertions(2);
240247
try {
241248
await client.testBinaryFileUpload({
242-
body: {} as File
249+
body: {} as File,
250+
customToken
243251
});
244252
} catch (e) {
245253
expect(e).toEqual(
@@ -259,13 +267,7 @@ describeSuite("Http client generated from Test API spec", () => {
259267

260268
expect(client.testParameterWithDash).toEqual(expect.any(Function));
261269

262-
const result = await client.testSimplePatch({
263-
"foo-bar": "value",
264-
headerInlineParam: "value",
265-
"path-param": "value",
266-
"request-id": "value",
267-
"x-header-param": "value"
268-
});
270+
const result = await client.testSimplePatch({ customToken });
269271
expect(isRight(result)).toBe(true);
270272
});
271273

@@ -282,7 +284,7 @@ describeSuite("Http client generated from Test API spec", () => {
282284

283285
expect(client.testBinaryFileDownload).toEqual(expect.any(Function));
284286

285-
const result = await client.testBinaryFileDownload({});
287+
const result = await client.testBinaryFileDownload({ customToken });
286288

287289
expect(result).toMatchObject(
288290
right({
@@ -320,9 +322,9 @@ describeSuite("Http client generated from Test API spec", () => {
320322
};
321323

322324
expect(client.testParameterWithBodyReference).toEqual(expect.any(Function));
323-
client.testParameterWithBodyReference({ body: aData });
325+
client.testParameterWithBodyReference({ body: aData, customToken });
324326
// @ts-expect-error
325-
client.testParameterWithBodyReference({ body: "" });
327+
client.testParameterWithBodyReference({ body: "", customToken });
326328
});
327329

328330
it("should handle model ref model in body for put operation", async () => {
@@ -340,44 +342,72 @@ describeSuite("Http client generated from Test API spec", () => {
340342
expect(client.putTestParameterWithBodyReference).toEqual(
341343
expect.any(Function)
342344
);
343-
client.putTestParameterWithBodyReference({ body: aData });
345+
client.putTestParameterWithBodyReference({ body: aData, customToken });
344346
// @ts-expect-error
345-
client.putTestParameterWithBodyReference({ body: "" });
347+
client.putTestParameterWithBodyReference({ body: "", customToken });
346348
});
347-
348349

349350
it("should handle model ref model in body as readablestream", async () => {
350351
const aData: NewModel = {
351352
id: "anId",
352353
name: "aName"
353354
};
354355

355-
const mockTestEndpoint = jest.fn((request: IncomingMessage, response: ServerResponse) => {
356-
let data = "";
357-
request.on("data", chunk => data += chunk)
358-
request.on("end", () => {
359-
expect(JSON.parse(data)).toEqual(aData);
360-
response.statusCode = 201;
361-
response.end();
362-
})
363-
364-
} );
365-
const server = await startServer(mockPort+10, mockTestEndpoint);
356+
const mockTestEndpoint = jest.fn(
357+
(request: IncomingMessage, response: ServerResponse) => {
358+
let data = "";
359+
request.on("data", chunk => (data += chunk));
360+
request.on("end", () => {
361+
expect(JSON.parse(data)).toEqual(aData);
362+
response.statusCode = 201;
363+
response.end();
364+
});
365+
}
366+
);
367+
const server = await startServer(mockPort + 10, mockTestEndpoint);
366368

367369
const client = createClient({
368-
baseUrl: `http://localhost:${mockPort+10}`,
370+
baseUrl: `http://localhost:${mockPort + 10}`,
369371
fetchApi: (nodeFetch as any) as typeof fetch,
370372
basePath: ""
371373
});
372374

373-
const aDataAsBuffer = Readable.from(Buffer.from(JSON.stringify(aData))) as unknown as ReadableStream<Uint8Array>;
375+
const aDataAsBuffer = (Readable.from(
376+
Buffer.from(JSON.stringify(aData))
377+
) as unknown) as ReadableStream<Uint8Array>;
374378

375379
expect(client.testParameterWithBodyReference).toEqual(expect.any(Function));
376-
const response = await client.testParameterWithBodyReference({ body: aDataAsBuffer });
380+
const response = await client.testParameterWithBodyReference({
381+
body: aDataAsBuffer,
382+
customToken
383+
});
377384

378385
expect(mockTestEndpoint).toHaveBeenCalledTimes(1);
379-
380386

381387
await closeServer(server);
382388
});
389+
390+
it("should override global security for operation level strategy", async () => {
391+
const client = createClient({
392+
baseUrl: `http://localhost:${mockPort}`,
393+
fetchApi: (nodeFetch as any) as typeof fetch,
394+
basePath: ""
395+
});
396+
397+
const result = await client.testOverriddenSecurity({ bearerToken: "abc" });
398+
expect(isRight(result)).toBeTruthy();
399+
// @ts-expect-error
400+
client.putTestParameterWithBodyReference({});
401+
});
402+
403+
it("should override global security for operation level strategy with no auth", async () => {
404+
const client = createClient({
405+
baseUrl: `http://localhost:${mockPort}`,
406+
fetchApi: (nodeFetch as any) as typeof fetch,
407+
basePath: ""
408+
});
409+
410+
const result = await client.testOverriddenSecurityNoAuth({});
411+
expect(isRight(result)).toBeTruthy();
412+
});
383413
});

0 commit comments

Comments
 (0)