From 2ef2e950ef48b65483cf8e66795d7be3a7ac1595 Mon Sep 17 00:00:00 2001 From: David Wilson Date: Mon, 28 Aug 2023 17:24:26 +0300 Subject: [PATCH] Avoid runtime errors when given invalid OAuth2Auth flow arguments --- .../http/use-auth-error_2023-08-28-14-25.json | 10 ++++++++ packages/http/src/decorators.ts | 11 +++++++-- packages/http/test/http-decorators.test.ts | 24 +++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 common/changes/@typespec/http/use-auth-error_2023-08-28-14-25.json diff --git a/common/changes/@typespec/http/use-auth-error_2023-08-28-14-25.json b/common/changes/@typespec/http/use-auth-error_2023-08-28-14-25.json new file mode 100644 index 00000000000..152cf5de815 --- /dev/null +++ b/common/changes/@typespec/http/use-auth-error_2023-08-28-14-25.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@typespec/http", + "comment": "Avoid runtime errors when `OAuth2Auth` is given invalid `OAuth2Flow` arguments", + "type": "none" + } + ], + "packageName": "@typespec/http" +} \ No newline at end of file diff --git a/packages/http/src/decorators.ts b/packages/http/src/decorators.ts index 0c561f7e963..09efb1ab307 100644 --- a/packages/http/src/decorators.ts +++ b/packages/http/src/decorators.ts @@ -551,12 +551,19 @@ function extractHttpAuthentication( } function extractOAuth2Auth(data: any): HttpAuth { + // Validation of OAuth2Flow models in this function is minimal because the + // type system already validates whether the model represents a flow + // configuration. This code merely avoids runtime errors. + const flows = + Array.isArray(data.flows) && data.flows.every((x: any) => typeof x === "object") + ? data.flows + : []; return { ...data, - flows: data.flows.map((flow: any) => { + flows: flows.map((flow: any) => { return { ...flow, - scopes: flow.scopes.map((x: string) => ({ value: x })), + scopes: (flow.scopes || []).map((x: string) => ({ value: x })), }; }), }; diff --git a/packages/http/test/http-decorators.test.ts b/packages/http/test/http-decorators.test.ts index b0969083c54..04bd210de61 100644 --- a/packages/http/test/http-decorators.test.ts +++ b/packages/http/test/http-decorators.test.ts @@ -577,6 +577,30 @@ describe("http: decorators", () => { }); }); + it("emit diagnostic when OAuth2 flow is not a valid model", async () => { + const diagnostics = await runner.diagnose(` + @useAuth(OAuth2Auth<["foo"]>) + namespace Foo {} + + model Flow { noscopes: "boom"; }; + @useAuth(OAuth2Auth<[Flow]>) + namespace Bar {} + `); + + expectDiagnostics(diagnostics, [ + { + code: "unassignable", + message: + "Type 'foo' is not assignable to type 'TypeSpec.Http.AuthorizationCodeFlow | TypeSpec.Http.ImplicitFlow | TypeSpec.Http.PasswordFlow | TypeSpec.Http.ClientCredentialsFlow'", + }, + { + code: "unassignable", + message: + "Type 'Flow' is not assignable to type 'TypeSpec.Http.AuthorizationCodeFlow | TypeSpec.Http.ImplicitFlow | TypeSpec.Http.PasswordFlow | TypeSpec.Http.ClientCredentialsFlow'", + }, + ]); + }); + it("can specify BasicAuth", async () => { const { Foo } = (await runner.compile(` @useAuth(BasicAuth)