extension_host: Refactor capability checks (#35139)
This PR refactors the extension capability checks to be centralized in the `CapabilityGranter`. Release Notes: - N/A
This commit is contained in:
parent
290f84a9e1
commit
d7b403e981
6 changed files with 193 additions and 41 deletions
|
@ -100,26 +100,9 @@ impl ExtensionManifest {
|
|||
desired_args: &[impl AsRef<str> + std::fmt::Debug],
|
||||
) -> Result<()> {
|
||||
let is_allowed = self.capabilities.iter().any(|capability| match capability {
|
||||
ExtensionCapability::ProcessExec { command, args } if command == desired_command => {
|
||||
for (ix, arg) in args.iter().enumerate() {
|
||||
if arg == "**" {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ix >= desired_args.len() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if arg != "*" && arg != desired_args[ix].as_ref() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if args.len() < desired_args.len() {
|
||||
return false;
|
||||
}
|
||||
true
|
||||
ExtensionCapability::ProcessExec(capability) => {
|
||||
capability.allows(desired_command, desired_args)
|
||||
}
|
||||
_ => false,
|
||||
});
|
||||
|
||||
if !is_allowed {
|
||||
|
@ -153,13 +136,50 @@ pub fn build_debug_adapter_schema_path(
|
|||
#[serde(tag = "kind")]
|
||||
pub enum ExtensionCapability {
|
||||
#[serde(rename = "process:exec")]
|
||||
ProcessExec {
|
||||
/// The command to execute.
|
||||
command: String,
|
||||
/// The arguments to pass to the command. Use `*` for a single wildcard argument.
|
||||
/// If the last element is `**`, then any trailing arguments are allowed.
|
||||
args: Vec<String>,
|
||||
},
|
||||
ProcessExec(ProcessExecCapability),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct ProcessExecCapability {
|
||||
/// The command to execute.
|
||||
pub command: String,
|
||||
/// The arguments to pass to the command. Use `*` for a single wildcard argument.
|
||||
/// If the last element is `**`, then any trailing arguments are allowed.
|
||||
pub args: Vec<String>,
|
||||
}
|
||||
|
||||
impl ProcessExecCapability {
|
||||
/// Returns whether the capability allows the given command and arguments.
|
||||
pub fn allows(
|
||||
&self,
|
||||
desired_command: &str,
|
||||
desired_args: &[impl AsRef<str> + std::fmt::Debug],
|
||||
) -> bool {
|
||||
if self.command != desired_command && self.command != "*" {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (ix, arg) in self.args.iter().enumerate() {
|
||||
if arg == "**" {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ix >= desired_args.len() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if arg != "*" && arg != desired_args[ix].as_ref() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if self.args.len() < desired_args.len() {
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, PartialEq, Eq, Debug, Deserialize, Serialize)]
|
||||
|
@ -362,10 +382,10 @@ mod tests {
|
|||
#[test]
|
||||
fn test_allow_exact_match() {
|
||||
let manifest = ExtensionManifest {
|
||||
capabilities: vec![ExtensionCapability::ProcessExec {
|
||||
capabilities: vec![ExtensionCapability::ProcessExec(ProcessExecCapability {
|
||||
command: "ls".to_string(),
|
||||
args: vec!["-la".to_string()],
|
||||
}],
|
||||
})],
|
||||
..extension_manifest()
|
||||
};
|
||||
|
||||
|
@ -377,10 +397,10 @@ mod tests {
|
|||
#[test]
|
||||
fn test_allow_wildcard_arg() {
|
||||
let manifest = ExtensionManifest {
|
||||
capabilities: vec![ExtensionCapability::ProcessExec {
|
||||
capabilities: vec![ExtensionCapability::ProcessExec(ProcessExecCapability {
|
||||
command: "git".to_string(),
|
||||
args: vec!["*".to_string()],
|
||||
}],
|
||||
})],
|
||||
..extension_manifest()
|
||||
};
|
||||
|
||||
|
@ -393,10 +413,10 @@ mod tests {
|
|||
#[test]
|
||||
fn test_allow_double_wildcard() {
|
||||
let manifest = ExtensionManifest {
|
||||
capabilities: vec![ExtensionCapability::ProcessExec {
|
||||
capabilities: vec![ExtensionCapability::ProcessExec(ProcessExecCapability {
|
||||
command: "cargo".to_string(),
|
||||
args: vec!["test".to_string(), "**".to_string()],
|
||||
}],
|
||||
})],
|
||||
..extension_manifest()
|
||||
};
|
||||
|
||||
|
@ -413,10 +433,10 @@ mod tests {
|
|||
#[test]
|
||||
fn test_allow_mixed_wildcards() {
|
||||
let manifest = ExtensionManifest {
|
||||
capabilities: vec![ExtensionCapability::ProcessExec {
|
||||
capabilities: vec![ExtensionCapability::ProcessExec(ProcessExecCapability {
|
||||
command: "docker".to_string(),
|
||||
args: vec!["run".to_string(), "*".to_string(), "**".to_string()],
|
||||
}],
|
||||
})],
|
||||
..extension_manifest()
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue