Skip to content

Commit

Permalink
enclave_build: Extract parse_docker_host method
Browse files Browse the repository at this point in the history
Extract parse_docker_host method from get_credentials for reusability.

Signed-off-by: Erdem Meydanli <[email protected]>
  • Loading branch information
meerd committed Apr 9, 2024
1 parent 33d91bd commit e19f4b8
Showing 1 changed file with 49 additions and 46 deletions.
95 changes: 49 additions & 46 deletions enclave_build/src/docker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,67 +63,70 @@ impl DockerUtil {
})
}

/// Returns the credentials by reading ${HOME}/.docker/config.json or ${DOCKER_CONFIG}
///
/// config.json doesn't seem to have a schema that we could use to validate
/// we are parsing it correctly, so the parsing mechanism had been infered by
/// reading a config.json created by:
// Docker version 19.03.2
fn get_credentials(&self) -> Result<DockerCredentials, DockerError> {
let image = self.docker_image.clone();
let host = if let Ok(uri) = Url::parse(&image) {
fn parse_docker_host(docker_image: &str) -> Option<String> {
if let Ok(uri) = Url::parse(docker_image) {
uri.host().map(|s| s.to_string())
} else {
// Some Docker URIs don't have the protocol included, so just use
// a dummy one to trick Url that it's a properly defined Uri.
let uri = format!("dummy://{image}");
let uri = format!("dummy://{docker_image}");
if let Ok(uri) = Url::parse(&uri) {
uri.host().map(|s| s.to_string())
} else {
None
}
}
}
/// Returns the credentials by reading ${HOME}/.docker/config.json or ${DOCKER_CONFIG}
///
/// config.json doesn't seem to have a schema that we could use to validate
/// we are parsing it correctly, so the parsing mechanism had been infered by
/// reading a config.json created by:
// Docker version 19.03.2
fn get_credentials(&self) -> Result<DockerCredentials, DockerError> {
let host = match Self::parse_docker_host(&self.docker_image) {
Some(host) => host,
None => return Err(CredentialsError("Invalid docker image URI!".to_string())),
};

if let Some(registry_domain) = host {
let config_file = self.get_config_file()?;

let config_json: serde_json::Value = serde_json::from_reader(&config_file)
.map_err(|err| CredentialsError(format!("JSON was not well-formatted: {err}")))?;

let auths = config_json.get("auths").ok_or_else(|| {
CredentialsError("Could not find auths key in config JSON".to_string())
})?;
let config_file = self.get_config_file()?;

if let Value::Object(auths) = auths {
for (registry_name, registry_auths) in auths.iter() {
if !registry_name.to_string().contains(&registry_domain) {
continue;
}
let config_json: serde_json::Value = serde_json::from_reader(&config_file)
.map_err(|err| CredentialsError(format!("JSON was not well-formatted: {err}")))?;

let auth = registry_auths
.get("auth")
.ok_or_else(|| {
CredentialsError("Could not find auth key in config JSON".to_string())
})?
.to_string();
let auths = config_json.get("auths").ok_or_else(|| {
CredentialsError("Could not find auths key in config JSON".to_string())
})?;

let auth = auth.replace('"', "");
let decoded = general_purpose::STANDARD.decode(auth).map_err(|err| {
CredentialsError(format!("Invalid Base64 encoding for auth: {err}"))
})?;
let decoded = std::str::from_utf8(&decoded).map_err(|err| {
CredentialsError(format!("Invalid utf8 encoding for auth: {err}"))
})?;
if let Value::Object(auths) = auths {
for (registry_name, registry_auths) in auths.iter() {
if !registry_name.to_string().contains(&host) {
continue;
}

if let Some(index) = decoded.rfind(':') {
let (user, after_user) = decoded.split_at(index);
let (_, password) = after_user.split_at(1);
return Ok(DockerCredentials {
username: Some(user.to_string()),
password: Some(password.to_string()),
..Default::default()
});
}
let auth = registry_auths
.get("auth")
.ok_or_else(|| {
CredentialsError("Could not find auth key in config JSON".to_string())
})?
.to_string();

let auth = auth.replace('"', "");
let decoded = general_purpose::STANDARD.decode(auth).map_err(|err| {
CredentialsError(format!("Invalid Base64 encoding for auth: {err}"))
})?;
let decoded = std::str::from_utf8(&decoded).map_err(|err| {
CredentialsError(format!("Invalid utf8 encoding for auth: {err}"))
})?;

if let Some(index) = decoded.rfind(':') {
let (user, after_user) = decoded.split_at(index);
let (_, password) = after_user.split_at(1);
return Ok(DockerCredentials {
username: Some(user.to_string()),
password: Some(password.to_string()),
..Default::default()
});
}
}
}
Expand Down

0 comments on commit e19f4b8

Please sign in to comment.