fix: tighten oauth and source resource handling

This commit is contained in:
lda
2026-06-14 00:53:42 +07:00 Verified
parent 2609679b87
commit d596898b96
19 changed files with 228 additions and 21 deletions
+3 -3
View File
@@ -6,12 +6,12 @@ param(
[Parameter(ValueFromRemainingArguments = $true)]
[string[]]$RemainingArgs
)
function funny([string] $output) {
function New-PandocDiagramMetadata([string] $outputFormat) {
return @{
"diagram" = @{
"engine" = @{
"mermaid" = @{
"outputFormat" = "$output"
"outputFormat" = "$outputFormat"
}
}
}
@@ -29,7 +29,7 @@ else {
exit 1
}
$metadata = funny $outputFormat | ConvertTo-Json -Depth 10
$metadata = New-PandocDiagramMetadata $outputFormat | ConvertTo-Json -Depth 10
$pandoc_diagram = Join-Path $PSScriptRoot "../../stuff/pandoc-diagram.ps1"
$metatempfile = New-TemporaryFile
@@ -514,7 +514,8 @@ class OAuthCodeLoginFlow:
provider: OAuthProviderConfig,
client_id: str,
client_secret: str | None,
authorization_response: str,
authorization_response: str | None,
authorization_url_callback: Callable[[str, str], str | None] | None = None,
) -> OAuthLoginResult:
client = self._client_factory(
client_id=client_id,
@@ -522,7 +523,17 @@ class OAuthCodeLoginFlow:
scope=" ".join(provider.scopes),
code_challenge_method="S256",
)
client.create_authorization_url(str(provider.auth_url))
authorization_url, state = client.create_authorization_url(
str(provider.auth_url),
redirect_uri=provider.redirect_uri,
**provider.extra_authorize_params,
)
if authorization_url_callback is not None:
callback_response = authorization_url_callback(authorization_url, state)
if authorization_response is None:
authorization_response = callback_response
if authorization_response is None:
raise ValueError("OAuth authorization response is required")
token = await client.fetch_token(
str(provider.token_url),
authorization_response=authorization_response,
@@ -536,6 +547,11 @@ class OAuthCodeLoginFlow:
```
This helper supports pasted authorization response first. Browser callback can be a later refinement.
`authorization_url_callback` is used by the CLI to show the generated URL and
collect the pasted redirected callback URL; tests can inject it to avoid prompt
I/O. Provider-specific authorization parameters such as Google's
`access_type=offline` and `prompt=consent` belong in
`provider.extra_authorize_params`, not in this generic helper.
- [ ] **Step 4: Run helper tests**
+34
View File
@@ -77,6 +77,40 @@ workflow-facing `CapabilitySource` objects. Provider-specific runtime pools,
admin/apply hooks, auth, catalog caches, and live health checks stay outside
this narrow seam until a source family needs them.
## Capability, Tool, Resource, And Prompt
Use these terms precisely:
- A **source** is the owner and namespace. Examples: `everything.default`,
`wf.std`, `wf.source`, or a future OpenAPI/Python source.
- A **tool** is provider-native. For MCP, it is an MCP tool discovered from an
upstream server.
- A **workflow capability** is workflow-native. It is the `NodeSpec` shape a
graph can call with typed input, typed output, outcomes, validation, and trace
behavior. Tools can be projected into workflow capabilities, but the two are
not identical concepts.
- A **resource** is source-owned addressable content. The URI is not globally
meaningful by itself; it must be interpreted with the source that owns it.
- A **prompt** is source-owned prompt/template inventory. Listing prompts is
inventory; rendering a prompt is an upstream operation and may be stateful.
Saved workflow data should prefer logical source references over concrete
source ids. For example, a resource ref should store:
```json
{"logical_source": "drive", "uri": "gdrive://file/abc"}
```
The deployment binding decides whether `drive` means `drive.personal`,
`drive.work`, or another concrete source. Platform sources such as `wf.std` and
`wf.source` are special because their logical source id is also their concrete
source id, so they do not require deployment bindings.
Runtime dereference is explicit. Passing a resource ref by value does not fetch
content. A helper capability such as `wf.source.read_resource` receives the ref,
uses runtime/platform context to resolve the logical source, and applies bounded
output policy before returning text into workflow state/output.
For MCP, the provider also owns stateful upstream sessions:
```text
+5 -1
View File
@@ -120,7 +120,11 @@ Provider profiles live in config under `auth.providers`:
"token_url": "https://oauth2.googleapis.com/token",
"client_id_env": "GOOGLE_OAUTH_CLIENT_ID",
"client_secret_env": "GOOGLE_OAUTH_CLIENT_SECRET",
"scopes": ["https://www.googleapis.com/auth/drive.readonly"]
"scopes": ["https://www.googleapis.com/auth/drive.readonly"],
"extra_authorize_params": {
"access_type": "offline",
"prompt": "consent"
}
}
}
}