merge: plugin https host api
This commit is contained in:
commit
6beb8625bf
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -2353,6 +2353,7 @@ dependencies = [
|
|||
"pod-store",
|
||||
"protocol",
|
||||
"provider",
|
||||
"reqwest",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
|
@ -2807,6 +2808,7 @@ dependencies = [
|
|||
"base64",
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
|
|
|
|||
|
|
@ -74,11 +74,13 @@ pub struct PluginGrantConfig {
|
|||
pub digest: Option<String>,
|
||||
/// Explicit capabilities granted for the pinned package identity/version/digest.
|
||||
pub permissions: Vec<PluginPermission>,
|
||||
/// Bounded outbound HTTPS allowlist entries for `host_api.https`.
|
||||
pub https: Vec<PluginHttpsGrant>,
|
||||
}
|
||||
|
||||
impl PluginGrantConfig {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.permissions.is_empty()
|
||||
self.permissions.is_empty() && self.https.is_empty()
|
||||
}
|
||||
|
||||
pub fn binding_error(
|
||||
|
|
@ -87,7 +89,7 @@ impl PluginGrantConfig {
|
|||
digest: &str,
|
||||
version: &str,
|
||||
) -> Option<&'static str> {
|
||||
if self.permissions.is_empty() {
|
||||
if self.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let Some(grant_id) = &self.id else {
|
||||
|
|
@ -128,6 +130,33 @@ pub enum PluginPermission {
|
|||
HostApi { api: PluginHostApi },
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
#[serde(default, deny_unknown_fields)]
|
||||
pub struct PluginHttpsGrant {
|
||||
/// Exact HTTPS request host allowed by this grant. Wildcards are intentionally unsupported.
|
||||
pub host: String,
|
||||
/// Uppercase HTTP methods allowed for this host, for example `GET` or `POST`.
|
||||
pub methods: Vec<String>,
|
||||
/// Optional path prefixes allowed for this host. Empty means any absolute path on the host.
|
||||
pub path_prefixes: Vec<String>,
|
||||
}
|
||||
|
||||
impl PluginHttpsGrant {
|
||||
pub fn label(&self) -> String {
|
||||
let methods = if self.methods.is_empty() {
|
||||
"<no-methods>".to_string()
|
||||
} else {
|
||||
self.methods.join(",")
|
||||
};
|
||||
let paths = if self.path_prefixes.is_empty() {
|
||||
"*".to_string()
|
||||
} else {
|
||||
self.path_prefixes.join(",")
|
||||
};
|
||||
format!("{} {} {}", self.host, methods, paths)
|
||||
}
|
||||
}
|
||||
|
||||
impl PluginPermission {
|
||||
pub fn label(&self) -> String {
|
||||
match self {
|
||||
|
|
@ -2052,6 +2081,7 @@ input_schema = { type = "object", properties = { query = { type = "string" } },
|
|||
version: Some(PluginExactVersion("0.1.0".to_string())),
|
||||
digest: Some(digest.clone()),
|
||||
permissions: vec![PluginPermission::surface(PluginSurface::Hook)],
|
||||
https: Vec::new(),
|
||||
};
|
||||
let resolution = resolve_enabled_plugins(
|
||||
&PluginConfig {
|
||||
|
|
@ -2077,18 +2107,21 @@ input_schema = { type = "object", properties = { query = { type = "string" } },
|
|||
version: Some(PluginExactVersion("0.1.0".to_string())),
|
||||
digest: Some(digest.clone()),
|
||||
permissions: vec![PluginPermission::surface(PluginSurface::Hook)],
|
||||
https: Vec::new(),
|
||||
},
|
||||
PluginGrantConfig {
|
||||
id: Some("project:example".to_string()),
|
||||
version: Some(PluginExactVersion("0.1.1".to_string())),
|
||||
digest: Some(digest.clone()),
|
||||
permissions: vec![PluginPermission::surface(PluginSurface::Hook)],
|
||||
https: Vec::new(),
|
||||
},
|
||||
PluginGrantConfig {
|
||||
id: Some("project:example".to_string()),
|
||||
version: Some(PluginExactVersion("0.1.0".to_string())),
|
||||
digest: Some("sha256:unrelated".to_string()),
|
||||
permissions: vec![PluginPermission::surface(PluginSurface::Hook)],
|
||||
https: Vec::new(),
|
||||
},
|
||||
] {
|
||||
let resolution = resolve_enabled_plugins(
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ client = { workspace = true }
|
|||
pod-registry = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
reqwest = { version = "0.13", default-features = false, features = ["blocking", "native-tls"] }
|
||||
thiserror = { workspace = true }
|
||||
tokio = { workspace = true, features = ["fs", "io-util", "macros", "net", "process", "rt-multi-thread", "signal", "sync", "time"] }
|
||||
toml = { workspace = true }
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -185,6 +185,11 @@ fn render_item_human(item: &PluginInspectionItem) -> Result<String> {
|
|||
" configured_grants: {}",
|
||||
join_or_none(&item.configured_grants)
|
||||
)?;
|
||||
writeln!(
|
||||
out,
|
||||
" configured_https_grants: {}",
|
||||
join_or_none(&item.configured_https_grants)
|
||||
)?;
|
||||
|
||||
if let Some(runtime) = &item.static_runtime {
|
||||
writeln!(
|
||||
|
|
@ -354,6 +359,7 @@ fn snapshot_from_resolution(
|
|||
builder.configured = true;
|
||||
builder.enabled_surfaces = surface_strings(enablement.surfaces.iter().copied());
|
||||
builder.configured_grants = permission_strings(&enablement.grants.permissions);
|
||||
builder.configured_https_grants = https_grant_strings(&enablement.grants.https);
|
||||
if let Ok(identity) = SourceQualifiedPluginId::parse(&enablement.id) {
|
||||
builder
|
||||
.source
|
||||
|
|
@ -445,6 +451,7 @@ fn fill_resolved(builder: &mut ItemBuilder, resolved: &ResolvedPlugin) {
|
|||
builder.enabled_surfaces = surface_strings(resolved.enabled_surfaces.iter().copied());
|
||||
builder.requested_permissions = permission_strings(&resolved.manifest.permissions);
|
||||
builder.configured_grants = permission_strings(&resolved.grants.permissions);
|
||||
builder.configured_https_grants = https_grant_strings(&resolved.grants.https);
|
||||
|
||||
let record = ResolvedPluginRecord::from_resolved(resolved);
|
||||
let static_runtime = inspect_resolved_plugin_static(&record);
|
||||
|
|
@ -540,6 +547,13 @@ fn permission_strings(permissions: &[PluginPermission]) -> Vec<String> {
|
|||
values
|
||||
}
|
||||
|
||||
fn https_grant_strings(grants: &[manifest::plugin::PluginHttpsGrant]) -> Vec<String> {
|
||||
let mut values: Vec<_> = grants.iter().map(|grant| grant.label()).collect();
|
||||
values.sort();
|
||||
values.dedup();
|
||||
values
|
||||
}
|
||||
|
||||
fn permission_requested(manifest: &PluginPackageManifest, permission: &PluginPermission) -> bool {
|
||||
manifest
|
||||
.permissions
|
||||
|
|
@ -610,6 +624,7 @@ struct PluginInspectionItem {
|
|||
enabled_surfaces: Vec<String>,
|
||||
requested_permissions: Vec<String>,
|
||||
configured_grants: Vec<String>,
|
||||
configured_https_grants: Vec<String>,
|
||||
tools: Vec<ToolSummary>,
|
||||
static_runtime: Option<PluginStaticInspection>,
|
||||
diagnostics: Vec<DiagnosticSummary>,
|
||||
|
|
@ -677,6 +692,7 @@ struct ItemBuilder {
|
|||
enabled_surfaces: Vec<String>,
|
||||
requested_permissions: Vec<String>,
|
||||
configured_grants: Vec<String>,
|
||||
configured_https_grants: Vec<String>,
|
||||
tools: Vec<ToolSummary>,
|
||||
static_runtime: Option<PluginStaticInspection>,
|
||||
diagnostics: Vec<DiagnosticSummary>,
|
||||
|
|
@ -702,6 +718,7 @@ impl ItemBuilder {
|
|||
enabled_surfaces: Vec::new(),
|
||||
requested_permissions: Vec::new(),
|
||||
configured_grants: Vec::new(),
|
||||
configured_https_grants: Vec::new(),
|
||||
tools: Vec::new(),
|
||||
static_runtime: None,
|
||||
diagnostics: Vec::new(),
|
||||
|
|
@ -772,6 +789,7 @@ impl ItemBuilder {
|
|||
enabled_surfaces: self.enabled_surfaces,
|
||||
requested_permissions: self.requested_permissions,
|
||||
configured_grants: self.configured_grants,
|
||||
configured_https_grants: self.configured_https_grants,
|
||||
tools: self.tools,
|
||||
static_runtime: self.static_runtime,
|
||||
diagnostics: self.diagnostics,
|
||||
|
|
@ -864,6 +882,7 @@ mod tests {
|
|||
PluginPermission::surface(PluginSurface::Tool),
|
||||
PluginPermission::tool("Echo"),
|
||||
],
|
||||
https: Vec::new(),
|
||||
},
|
||||
config: None,
|
||||
});
|
||||
|
|
@ -880,6 +899,7 @@ mod tests {
|
|||
PluginPermission::surface(PluginSurface::Tool),
|
||||
PluginPermission::tool("Echo"),
|
||||
],
|
||||
https: Vec::new(),
|
||||
},
|
||||
config: None,
|
||||
});
|
||||
|
|
@ -996,6 +1016,7 @@ mod tests {
|
|||
PluginPermission::surface(PluginSurface::Tool),
|
||||
PluginPermission::tool("Echo"),
|
||||
],
|
||||
https: Vec::new(),
|
||||
},
|
||||
config: None,
|
||||
});
|
||||
|
|
@ -1258,6 +1279,7 @@ mod tests {
|
|||
PluginPermission::surface(PluginSurface::Tool),
|
||||
PluginPermission::tool("Echo"),
|
||||
],
|
||||
https: Vec::new(),
|
||||
},
|
||||
config: None,
|
||||
}],
|
||||
|
|
@ -1287,6 +1309,7 @@ mod tests {
|
|||
version: Some(PluginExactVersion(version.to_string())),
|
||||
digest: Some(digest),
|
||||
permissions,
|
||||
https: Vec::new(),
|
||||
},
|
||||
config: None,
|
||||
}
|
||||
|
|
@ -1313,6 +1336,7 @@ mod tests {
|
|||
version: Some(PluginExactVersion(version.to_string())),
|
||||
digest: None,
|
||||
permissions,
|
||||
https: Vec::new(),
|
||||
},
|
||||
config: None,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ rustPlatform.buildRustPackage rec {
|
|||
filter = sourceFilter;
|
||||
};
|
||||
|
||||
cargoHash = "sha256-ud+3INcXnT5W26Bz0K4QXUqoqw3p/ER9c4F2Fhq3YuQ=";
|
||||
cargoHash = "sha256-xqax43t9IevkNG2lZvfRP562ORKb3aHxUNsQwS1FK/k=";
|
||||
|
||||
depsExtraArgs = {
|
||||
# Older fetchCargoVendor utilities used crates.io's API download endpoint,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user