History

Share secret-backed credential values (#454)

Rhys Sullivan committed 6 months ago

Commit 9639a681 parent 899a99e17 files · +768 −954Browse files

Showing the changes to packages/plugins/openapi/src (3 of 17 files). Show all

Unified · Split

3 files
  1. packages/plugins/openapi/src/api/group.ts +1 −9
  2. packages/plugins/openapi/src/sdk/plugin.ts +18 −25
  3. packages/plugins/openapi/src/sdk/types.ts +6 −16
packages/plugins/openapi/src/api/group.ts+1−9
@@ -1,6 +1,6 @@
11 import { HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from "@effect/platform";
22 import { Schema } from "effect";
3−import { ScopeId } from "@executor/sdk";
3+import { ScopeId, SecretBackedValue } from "@executor/sdk";
44 import { InternalError } from "@executor/api";
55
66 import { OpenApiParseError, OpenApiExtractionError, OpenApiOAuthError } from "../sdk/errors";
@@ -21,14 +21,6 @@ const scopeIdParam = HttpApiSchema.param("scopeId", ScopeId); · 14 unmodified lines
2121 const namespaceParam = HttpApiSchema.param("namespace", Schema.String);
2222 const sourceScopeIdParam = HttpApiSchema.param("sourceScopeId", ScopeId);
2323
24−const SecretBackedValue = Schema.Union(
25− Schema.String,
26− Schema.Struct({
27− secretId: Schema.String,
28− prefix: Schema.optional(Schema.String),
29− }),
30−);
31−
3224 const SpecFetchCredentialsPayload = Schema.Struct({
3325 headers: Schema.optional(Schema.Record({ key: Schema.String, value: SecretBackedValue })),
3426 queryParams: Schema.optional(Schema.Record({ key: Schema.String, value: SecretBackedValue })),
packages/plugins/openapi/src/sdk/plugin.ts+18−25
@@ -8,6 +8,7 @@ import { · 7 unmodified lines
88 SecretId,
99 SourceDetectionResult,
1010 definePlugin,
11+ resolveSecretBackedMap,
1112 type PluginCtx,
1213 type StorageFailure,
1314 type ToolAnnotations,
@@ -471,39 +472,31 @@ const resolveConfiguredHeaders = ( · 457 unmodified lines
471472 return resolved;
472473 });
473474
474−const resolveHeaderValue = (
475+const resolveHeaderValues = (
475476 ctx: PluginCtx<OpenapiStore>,
476− name: string,
477− value: HeaderValue,
478−): Effect.Effect<string, OpenApiOAuthError | StorageFailure> => {
479− if (typeof value === "string") return Effect.succeed(value);
480− return ctx.secrets.get(value.secretId).pipe(
481− Effect.mapError((err) =>
477+ values: Record<string, HeaderValue> | undefined,
478+): Effect.Effect<Record<string, string>, OpenApiOAuthError | StorageFailure> =>
479+ resolveSecretBackedMap({
480+ values,
481+ getSecret: ctx.secrets.get,
482+ onMissing: (name) =>
483+ new OpenApiOAuthError({
484+ message: `Secret not found for "${name}"`,
485+ }),
486+ onError: (err, name) =>
482487 "_tag" in err && err._tag === "SecretOwnedByConnectionError"
483488 ? new OpenApiOAuthError({
484489 message: `Secret not found for "${name}"`,
485490 })
486491 : err,
492+ }).pipe(
493+ Effect.mapError((err) =>
494+ "_tag" in err && err._tag === "SecretOwnedByConnectionError"
495+ ? new OpenApiOAuthError({ message: "Secret resolution failed" })
496+ : err,
487497 ),
488− Effect.flatMap((secret) =>
489− secret === null
490− ? Effect.fail(
491− new OpenApiOAuthError({
492− message: `Secret not found for "${name}"`,
493− }),
494− )
495− : Effect.succeed(value.prefix ? `${value.prefix}${secret}` : secret),
496− ),
498+ Effect.map((resolved) => resolved ?? {}),
497499 );
498−};
499−
500−const resolveHeaderValues = (
501− ctx: PluginCtx<OpenapiStore>,
502− values: Record<string, HeaderValue> | undefined,
503−): Effect.Effect<Record<string, string>, OpenApiOAuthError | StorageFailure> =>
504− Effect.forEach(Object.entries(values ?? {}), ([name, value]) =>
505− Effect.map(resolveHeaderValue(ctx, name, value), (resolved) => [name, resolved] as const),
506− ).pipe(Effect.map((entries) => Object.fromEntries(entries)));
507500
508501 const resolveOAuthConnectionId = (
509502 ctx: PluginCtx<OpenapiStore>,
packages/plugins/openapi/src/sdk/types.ts+6−16
@@ -1,5 +1,5 @@
11 import { Schema } from "effect";
2−import { ConnectionId, ScopeId, SecretId } from "@executor/sdk";
2+import { ConnectionId, ScopeId, SecretBackedValue, SecretId } from "@executor/sdk";
33
44 // ---------------------------------------------------------------------------
55 // Branded IDs
@@ -61,10 +61,9 @@ export class EncodingObject extends Schema.Class<EncodingObject>("EncodingObject · 55 unmodified lines
6161 export class MediaBinding extends Schema.Class<MediaBinding>("MediaBinding")({
6262 contentType: Schema.String,
6363 schema: Schema.optionalWith(Schema.Unknown, { as: "Option" }),
64− encoding: Schema.optionalWith(
65− Schema.Record({ key: Schema.String, value: EncodingObject }),
66− { as: "Option" },
67− ),
64+ encoding: Schema.optionalWith(Schema.Record({ key: Schema.String, value: EncodingObject }), {
65+ as: "Option",
66+ }),
6867 }) {}
6968
7069 export class OperationRequestBody extends Schema.Class<OperationRequestBody>(
@@ -137,13 +136,7 @@ export class OperationBinding extends Schema.Class<OperationBinding>("OperationB · 66 unmodified lines
137136 * A header value — either a static string or a reference to a secret.
138137 * Stored as JSON-serializable data.
139138 */
140−export const HeaderValue = Schema.Union(
141− Schema.String,
142− Schema.Struct({
143− secretId: Schema.String,
144− prefix: Schema.optional(Schema.String),
145− }),
146−);
139+export const HeaderValue = SecretBackedValue;
147140 export type HeaderValue = typeof HeaderValue.Type;
148141
149142 export class ConfiguredHeaderBinding extends Schema.Class<ConfiguredHeaderBinding>(
@@ -154,10 +147,7 @@ export class ConfiguredHeaderBinding extends Schema.Class<ConfiguredHeaderBindin · 4 unmodified lines
154147 prefix: Schema.optional(Schema.String),
155148 }) {}
156149
157−export const ConfiguredHeaderValue = Schema.Union(
158− Schema.String,
159− ConfiguredHeaderBinding,
160−);
150+export const ConfiguredHeaderValue = Schema.Union(Schema.String, ConfiguredHeaderBinding);
161151 export type ConfiguredHeaderValue = typeof ConfiguredHeaderValue.Type;
162152
163153 export const OpenApiSourceBindingValue = Schema.Union(

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t