Skip to content

Commit

Permalink
Improve SSH cache
Browse files Browse the repository at this point in the history
commit-id:b4c3585d
  • Loading branch information
vlad-ivanov-name committed Jan 23, 2023
1 parent 160f097 commit 3ecb5a0
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 57 deletions.
54 changes: 54 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions josh-proxy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ url = "2.3.1"
uuid = { version = "1.2.2", features = ["v4"] }
josh-rpc = { path = "../josh-rpc" }
tokio-util = "0.7.4"
tempdir = "0.3.7"
34 changes: 15 additions & 19 deletions josh-proxy/src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,6 @@ pub async fn check_auth(url: &str, auth: &Handle, required: bool) -> josh::JoshR
return Ok(false);
}

// If the upsteam is ssh we don't really handle authentication here.
// All we need is a username, the private key is expected to available localy.
// This is really not secure at all and should never be used in a production deployment.
if url.starts_with("ssh") {
return Ok(auth.hash != "");
}

if let Some(last) = AUTH_TIMERS.lock()?.get(&(url.to_string(), auth.clone())) {
let since = std::time::Instant::now().duration_since(*last);
tracing::trace!("last: {:?}, since: {:?}", last, since);
Expand All @@ -99,47 +92,50 @@ pub async fn check_auth(url: &str, auth: &Handle, required: bool) -> josh::JoshR
.get(auth)
.unwrap_or(&Header { header: None })
.to_owned();
let nurl = format!("{}/info/refs?service=git-upload-pack", url);
let refs_url = format!("{}/info/refs?service=git-upload-pack", url);

let builder = hyper::Request::builder().method("GET").uri(&nurl);
let builder = hyper::Request::builder()
.method(hyper::Method::GET)
.uri(&refs_url);

let builder = if let Some(h) = password.header {
builder.header("authorization", h)
let builder = if let Some(value) = password.header {
builder.header(hyper::header::AUTHORIZATION, value)
} else {
builder
};

let r = builder.body(hyper::Body::empty())?;
let resp = client.request(r).await?;
let request = builder.body(hyper::Body::empty())?;
let resp = client.request(request).await?;

let status = resp.status();

tracing::trace!("http resp.status {:?}", resp.status());

let msg = format!("got http response: {} {:?}", nurl, resp);
let err_msg = format!("got http response: {} {:?}", refs_url, resp);

if status == 200 {
if status == hyper::StatusCode::OK {
AUTH_TIMERS
.lock()?
.insert((url.to_string(), auth.clone()), std::time::Instant::now());
Ok(true)
} else if status == 401 {
tracing::warn!("resp.status == 401: {:?}", &msg);
} else if status == hyper::StatusCode::UNAUTHORIZED {
tracing::warn!("resp.status == 401: {:?}", &err_msg);
tracing::trace!(
"body: {:?}",
std::str::from_utf8(&hyper::body::to_bytes(resp.into_body()).await?)
);
Ok(false)
} else {
return Err(josh::josh_error(&msg));
return Err(josh::josh_error(&err_msg));
}
}

pub fn strip_auth(
req: hyper::Request<hyper::Body>,
) -> josh::JoshResult<(Handle, hyper::Request<hyper::Body>)> {
let mut req = req;
let header: Option<hyper::header::HeaderValue> = req.headers_mut().remove("authorization");
let header: Option<hyper::header::HeaderValue> =
req.headers_mut().remove(hyper::header::AUTHORIZATION);

if let Some(header) = header {
let hp = Handle {
Expand Down
Loading

0 comments on commit 3ecb5a0

Please sign in to comment.