Skip to main content

fluidattacks_core_git/clone/
codecommit.rs

1use anyhow::Result;
2use std::path::Path;
3use tokio::process::Command;
4
5use super::{build_clone_args, reason, redirect_config, CloneOpts};
6use crate::aws;
7use crate::types::CredentialKind;
8
9pub async fn clone_codecommit(opts: &CloneOpts, dest: &Path) -> Result<()> {
10    let (arn, external_id, via) = match &opts.credentials.as_ref().map(|c| &c.kind) {
11        Some(CredentialKind::AwsRole {
12            arn,
13            external_id,
14            via,
15        }) => (arn.as_str(), external_id.as_str(), via.as_deref()),
16        _ => anyhow::bail!("expected AwsRole credentials for CodeCommit clone"),
17    };
18
19    let creds = aws::assume_role(arn, external_id, &opts.repo_url, via).await?;
20
21    reason::run(
22        Command::new("git")
23            .args(clone_args(opts, dest))
24            .env("AWS_ACCESS_KEY_ID", &creds.access_key)
25            .env("AWS_SECRET_ACCESS_KEY", &creds.secret_key)
26            .env("AWS_SESSION_TOKEN", &creds.session_token)
27            .env("AWS_DEFAULT_REGION", &creds.region),
28        &[],
29    )
30    .await?;
31
32    Ok(())
33}
34
35fn clone_args(opts: &CloneOpts, dest: &Path) -> Vec<std::ffi::OsString> {
36    build_clone_args(
37        opts,
38        &opts.repo_url,
39        dest,
40        &redirect_config(opts.follow_redirects),
41    )
42}
43
44#[cfg(test)]
45mod tests {
46    use std::path::Path;
47
48    use super::clone_args;
49    use crate::clone::tests::opts;
50    use crate::clone::{CloneOpts, CloneShape};
51
52    #[test]
53    fn a_redirect_is_followed_only_when_the_root_asks_for_one() {
54        for follow_redirects in [false, true] {
55            let opts = CloneOpts {
56                follow_redirects,
57                ..opts(CloneShape::SingleBranch)
58            };
59
60            let args = clone_args(&opts, Path::new("/tmp/a_root"));
61
62            let config = format!("http.followRedirects={follow_redirects}");
63            assert!(args.windows(2).any(|pair| pair == ["-c", config.as_str()]));
64        }
65    }
66}