History

Move source auth handling into plugins

Rhys Sullivan committed 7 months ago

Commit db9b84d1 parent 02d549c15 files · +98 −125Browse files

Showing the changes to plugins/openapi (4 of 15 files). Show all

Unified · Split

4 files
  1. plugins/openapi/react/index.tsx +36 −14
  2. plugins/openapi/sdk/index.ts +13 −21
  3. plugins/openapi/shared/index.ts +3 −2
  4. plugins/openapi/shared/package.json +1 −0
plugins/openapi/react/index.tsx+36−14
@@ -38,7 +38,7 @@ import { · 37 unmodified lines
3838 type SourceToolExplorerSearch,
3939 useSourcePluginNavigation,
4040 useSourcePluginSearch,
41−} from "@executor/react/source-plugins";
41+} from "@executor/react/plugins";
4242 import {
4343 openApiHttpApiExtension,
4444 } from "@executor/plugin-openapi-http";
@@ -169,6 +169,31 @@ const inputFromConfig = ( · 124 unmodified lines
169169 auth: config.auth,
170170 });
171171
172+const secretValue = (input: OpenApiConnectInput["auth"]): string =>
173+ input.kind === "bearer"
174+ ? JSON.stringify(input.tokenSecretRef)
175+ : "";
176+
177+const authFromSecretValue = (
178+ authKind: OpenApiConnectInput["auth"]["kind"],
179+ value: string,
180+): OpenApiConnectInput["auth"] => {
181+ if (authKind === "none") {
182+ return {
183+ kind: "none",
184+ };
185+ }
186+
187+ if (!value) {
188+ throw new Error("Select a secret for bearer auth.");
189+ }
190+
191+ return {
192+ kind: "bearer",
193+ tokenSecretRef: JSON.parse(value) as OpenApiConnectInput["auth"] & { tokenSecretRef: never }["tokenSecretRef"],
194+ };
195+};
196+
172197 const useAvailableSecrets = (
173198 openApiHttpClient: ReturnType<typeof getOpenApiHttpClient>,
174199 ) => {
@@ -205,9 +230,7 @@ function OpenApiSourceForm(props: { · 30 unmodified lines
205230 props.initialValue.auth.kind,
206231 );
207232 const [tokenSecretRef, setTokenSecretRef] = useState(
208− props.initialValue.auth.kind === "bearer"
209− ? props.initialValue.auth.tokenSecretRef
210− : "",
233+ secretValue(props.initialValue.auth),
211234 );
212235 const [error, setError] = useState<string | null>(null);
213236 const [preview, setPreview] = useState<OpenApiPreviewResponse | null>(null);
@@ -309,19 +332,12 @@ function OpenApiSourceForm(props: { · 95 unmodified lines
309332 }
310333
311334 try {
335+ const auth = authFromSecretValue(authKind, tokenSecretRef);
312336 await submitMutation.mutateAsync({
313337 name: trimmedName,
314338 specUrl: trimmedSpecUrl,
315339 baseUrl: trimmedBaseUrl || null,
316− auth:
317− authKind === "bearer"
318− ? {
319− kind: "bearer",
320− tokenSecretRef: tokenSecretRef.trim(),
321− }
322− : {
323− kind: "none",
324− },
340+ auth,
325341 });
326342 } catch (cause) {
327343 setError(cause instanceof Error ? cause.message : "Failed saving source.");
@@ -398,7 +414,13 @@ function OpenApiSourceForm(props: { · 70 unmodified lines
398414 >
399415 <option value="">Select a secret</option>
400416 {availableSecrets.map((secret) => (
401− <option key={secret.id} value={secret.id}>
417+ <option
418+ key={`${secret.providerId}:${secret.id}`}
419+ value={JSON.stringify({
420+ providerId: secret.providerId,
421+ handle: secret.id,
422+ })}
423+ >
402424 {secret.name || secret.id}
403425 </option>
404426 ))}
plugins/openapi/sdk/index.ts+13−21
@@ -13,6 +13,9 @@ import type { · 12 unmodified lines
1313 ExecutorSourceConnector,
1414 SourcePluginRuntime,
1515 } from "@executor/platform-sdk/plugins";
16+import {
17+ SecretMaterialResolverService,
18+} from "@executor/platform-sdk/runtime";
1619 import {
1720 OpenApiConnectionAuthSchema,
1821 deriveOpenApiNamespace,
@@ -64,12 +67,6 @@ export type OpenApiSourceStorage = { · 45 unmodified lines
6467 }) => Effect.Effect<void, Error, never>;
6568 };
6669
67−export type OpenApiSecrets = {
68− resolve: (input: {
69− ref: string;
70− }) => Effect.Effect<string, Error, never>;
71−};
72−
7370 export type OpenApiSdk = {
7471 previewDocument: (
7572 input: OpenApiPreviewRequest,
@@ -93,7 +90,6 @@ export type OpenApiSdk = { · 17 unmodified lines
9390
9491 export type OpenApiSdkPluginOptions = {
9592 storage: OpenApiSourceStorage;
96− secrets?: OpenApiSecrets;
9793 };
9894
9995 const OpenApiExecutorAddInputSchema = Schema.Struct({
@@ -414,22 +410,18 @@ const decodeResponseBody = async (response: Response): Promise<unknown> => { · 314 unmodified lines
414410 };
415411
416412 const resolveBearerToken = (
417− options: OpenApiSdkPluginOptions,
418413 stored: OpenApiStoredSourceData,
419−): Effect.Effect<string | null, Error, never> => {
420− if (stored.auth.kind === "none") {
414+): Effect.Effect<string | null, Error, any> => {
415+ const { auth } = stored;
416+ if (auth.kind === "none") {
421417 return Effect.succeed(null);
422418 }
423419
424− if (!options.secrets) {
425− return Effect.fail(
426− new Error("OpenAPI bearer auth is configured, but no secret resolver is available."),
427− );
428− }
429−
430− return options.secrets.resolve({
431− ref: stored.auth.tokenSecretRef,
432− }).pipe(Effect.map((token) => token.trim()));
420+ return Effect.flatMap(SecretMaterialResolverService, (resolveSecretMaterial) =>
421+ resolveSecretMaterial({
422+ ref: auth.tokenSecretRef,
423+ }).pipe(Effect.map((token) => token.trim()))
424+ );
433425 };
434426
435427 const openApiDocumentHeaders = (input: {
@@ -550,7 +542,7 @@ const createOpenApiSourceRuntime = ( · 114 unmodified lines
550542 });
551543 }
552544
553− const bearerToken = yield* resolveBearerToken(options, stored);
545+ const bearerToken = yield* resolveBearerToken(stored);
554546 const fetched = yield* fetchOpenApiDocument({
555547 stored,
556548 bearerToken,
@@ -686,7 +678,7 @@ const createOpenApiSourceRuntime = ( · 129 unmodified lines
686678 }
687679 }
688680
689− const bearerToken = yield* resolveBearerToken(options, stored);
681+ const bearerToken = yield* resolveBearerToken(stored);
690682 if (bearerToken && bearerToken.length > 0) {
691683 headers.authorization = `Bearer ${bearerToken}`;
692684 }
plugins/openapi/shared/index.ts+3−2
@@ -3,8 +3,9 @@ import * as Schema from "effect/Schema"; · 2 unmodified lines
33 import YAML from "yaml";
44
55 import {
6+ SecretRefSchema,
67 StringMapSchema,
7−} from "@executor/source-core";
8+} from "@executor/platform-sdk/schema";
89
910 export const OpenApiConnectionAuthSchema = Schema.Union(
1011 Schema.Struct({
@@ -12,7 +13,7 @@ export const OpenApiConnectionAuthSchema = Schema.Union( · 1 unmodified line
1213 }),
1314 Schema.Struct({
1415 kind: Schema.Literal("bearer"),
15− tokenSecretRef: Schema.String,
16+ tokenSecretRef: SecretRefSchema,
1617 }),
1718 );
1819
plugins/openapi/shared/package.json+1−0
@@ -12,6 +12,7 @@ · 11 unmodified lines
1212 "typecheck": "bunx tsc --noEmit -p tsconfig.json"
1313 },
1414 "dependencies": {
15+ "@executor/platform-sdk": "workspace:*",
1516 "@executor/source-core": "workspace:*",
1617 "effect": "catalog:",
1718 "yaml": "^2.8.1"