Skip to content

Commit

Permalink
fix: fixing self auth on doc gen with sparse protocol (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
woutersl committed Sep 12, 2024
1 parent b870503 commit 5b89fbc
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 61 deletions.
9 changes: 8 additions & 1 deletion README.docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ services:
REGISTRY_WEB_PUBLIC_URI: http://localhost
# REGISTRY_WEB_BODY_LIMIT: 10485760
REGISTRY_DATA_DIR: /data
# REGISTRY_INDEX_PROTOCOL_GIT: "true"
# REGISTRY_INDEX_PROTOCOL_GIT: "false"
# REGISTRY_INDEX_PROTOCOL_SPARSE: "true"
# REGISTRY_GIT_REMOTE:
# REGISTRY_GIT_REMOTE_SSH_KEY_FILENAME:
Expand Down Expand Up @@ -173,6 +173,13 @@ This is controlled by the following configuration :

### Index

The index can be served using both the legacy `git` and the new `sparse` protocols, see [Registry Protocols](https://doc.rust-lang.org/cargo/reference/registries.html#registry-protocols).
The legacy `git` protocol is disabled by default, and the new `sparse` protocol enabled:
* `REGISTRY_INDEX_PROTOCOL_GIT`, defaults to `false` to de-activate the legacy `git` "smart" protocol. Use `true` to activate.
* `REGISTRY_INDEX_PROTOCOL_SPARSE`, defaults to `true` to activate the `sparse` protocol. Any other value deactivates it.

Fetching the index always requires authentication, regardless of the used protocol.

The index for the registry is managed as a git repository.
When `cratery` commits to this repository as an author:
* `REGISTRY_GIT_USER_NAME` is the username to use,
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,9 @@ This is controlled by the following configuration :

### Index

The index can be served using both the `git` and `sparse` protocols.
Both are activated by default, but can be activated / deactivated as required:
* `REGISTRY_INDEX_PROTOCOL_GIT`, defaults to `true` to activate the `git` "smart" protocol. Any other value deactivates it.
The index can be served using both the legacy `git` and the new `sparse` protocols, see [Registry Protocols](https://doc.rust-lang.org/cargo/reference/registries.html#registry-protocols).
The legacy `git` protocol is disabled by default, and the new `sparse` protocol enabled:
* `REGISTRY_INDEX_PROTOCOL_GIT`, defaults to `false` to de-activate the legacy `git` "smart" protocol. Use `true` to activate.
* `REGISTRY_INDEX_PROTOCOL_SPARSE`, defaults to `true` to activate the `sparse` protocol. Any other value deactivates it.

Fetching the index always requires authentication, regardless of the used protocol.
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ services:
# REGISTRY_WEB_BODY_LIMIT: 10485760
REGISTRY_HOME_DIR: /home/cratery
REGISTRY_DATA_DIR: /data
# REGISTRY_INDEX_PROTOCOL_GIT: "true"
# REGISTRY_INDEX_PROTOCOL_GIT: "false"
# REGISTRY_INDEX_PROTOCOL_SPARSE: "true"
# REGISTRY_GIT_REMOTE:
# REGISTRY_GIT_REMOTE_SSH_KEY_FILENAME:
Expand Down
170 changes: 114 additions & 56 deletions src/model/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ impl IndexConfig {
Ok(IndexConfig {
home_dir: home_dir.to_string(),
location: format!("{data_dir}/index"),
allow_protocol_git: get_var("REGISTRY_INDEX_PROTOCOL_GIT").map(|v| v == "true").unwrap_or(true),
allow_protocol_git: get_var("REGISTRY_INDEX_PROTOCOL_GIT").map(|v| v == "true").unwrap_or(false),
allow_protocol_sparse: get_var("REGISTRY_INDEX_PROTOCOL_SPARSE").map(|v| v == "true").unwrap_or(true),
remote_origin: get_var("REGISTRY_GIT_REMOTE").ok(),
remote_ssh_key_file_name: get_var("REGISTRY_GIT_REMOTE_SSH_KEY_FILENAME").ok(),
Expand Down Expand Up @@ -550,69 +550,127 @@ impl Configuration {
///
/// Return an error when writing fail
pub async fn write_auth_config(&self) -> Result<(), ApiError> {
{
let file = File::create(self.get_home_path_for(&[".gitconfig"])).await?;
let mut writer = BufWriter::new(file);
writer.write_all("[credential]\n helper = store\n".as_bytes()).await?;
writer.flush().await?;
if self.index.allow_protocol_git {
self.write_auth_config_git_config().await?;
self.write_auth_config_git_credentials().await?;
}
{
let file = File::create(self.get_home_path_for(&[".git-credentials"])).await?;
let mut writer = BufWriter::new(file);
let index = self.web_public_uri.find('/').unwrap() + 2;
self.write_auth_config_cargo_config().await?;
self.write_auth_config_cargo_credentials().await?;
Ok(())
}

/// Write the configuration for authenticating to registries
async fn write_auth_config_git_config(&self) -> Result<(), ApiError> {
let file = File::create(self.get_home_path_for(&[".gitconfig"])).await?;
let mut writer = BufWriter::new(file);
writer.write_all("[credential]\n helper = store\n".as_bytes()).await?;
writer.flush().await?;
Ok(())
}

/// Write the configuration for authenticating to registries
async fn write_auth_config_git_credentials(&self) -> Result<(), ApiError> {
let file = File::create(self.get_home_path_for(&[".git-credentials"])).await?;
let mut writer = BufWriter::new(file);
let index = self.web_public_uri.find('/').unwrap() + 2;
writer
.write_all(
format!(
"{}{}:{}@{}\n",
&self.web_public_uri[..index],
self.self_service_login,
self.self_service_token,
&self.web_public_uri[index..]
)
.as_bytes(),
)
.await?;
for registry in &self.external_registries {
let index = registry.index.find('/').unwrap() + 2;
writer
.write_all(
format!(
"{}{}:{}@{}\n",
&self.web_public_uri[..index],
self.self_service_login,
self.self_service_token,
&self.web_public_uri[index..]
"{}{}:{}@{}",
&registry.index[..index],
registry.login,
registry.token,
&registry.index[index..]
)
.as_bytes(),
)
.await?;
for registry in &self.external_registries {
let index = registry.index.find('/').unwrap() + 2;
}
writer.flush().await?;
Ok(())
}

/// Write the configuration for authenticating to registries
async fn write_auth_config_cargo_config(&self) -> Result<(), ApiError> {
let file = File::create(self.get_home_path_for(&[".cargo", "config.toml"])).await?;
let mut writer = BufWriter::new(file);
writer.write_all("[registry]\n".as_bytes()).await?;
writer
.write_all("global-credential-providers = [\"cargo:token\"]\n".as_bytes())
.await?;
writer.write_all("\n".as_bytes()).await?;
writer.write_all("[registries]\n".as_bytes()).await?;
if self.index.allow_protocol_git {
writer
.write_all(format!("{} = {{ index = \"{}\" }}\n", self.self_local_name, self.web_public_uri).as_bytes())
.await?;
if self.index.allow_protocol_sparse {
// both git and sparse
writer
.write_all(
format!(
"{}{}:{}@{}",
&registry.index[..index],
registry.login,
registry.token,
&registry.index[index..]
"{}sparse = {{ index = \"sparse+{}/\" }}\n",
self.self_local_name, self.web_public_uri
)
.as_bytes(),
)
.await?;
}
writer.flush().await?;
}
{
let file = File::create(self.get_home_path_for(&[".cargo", "config.toml"])).await?;
let mut writer = BufWriter::new(file);
writer.write_all("[registry]\n".as_bytes()).await?;
} else if self.index.allow_protocol_sparse {
// sparse only
writer
.write_all("global-credential-providers = [\"cargo:token\"]\n".as_bytes())
.write_all(
format!(
"{} = {{ index = \"sparse+{}/\" }}\n",
self.self_local_name, self.web_public_uri
)
.as_bytes(),
)
.await?;
writer.write_all("\n".as_bytes()).await?;
writer.write_all("[registries]\n".as_bytes()).await?;
}
for registry in &self.external_registries {
writer
.write_all(format!("{} = {{ index = \"{}\" }}\n", self.self_local_name, self.web_public_uri).as_bytes())
.write_all(format!("{} = {{ index = \"{}\" }}\n", registry.name, registry.index).as_bytes())
.await?;
for registry in &self.external_registries {
writer
.write_all(format!("{} = {{ index = \"{}\" }}\n", registry.name, registry.index).as_bytes())
.await?;
}
writer.flush().await?;
}
{
let file = File::create(self.get_home_path_for(&[".cargo", "credentials.toml"])).await?;
let mut writer = BufWriter::new(file);
writer.flush().await?;
Ok(())
}

/// Write the configuration for authenticating to registries
async fn write_auth_config_cargo_credentials(&self) -> Result<(), ApiError> {
let file = File::create(self.get_home_path_for(&[".cargo", "credentials.toml"])).await?;
let mut writer = BufWriter::new(file);
writer
.write_all(format!("[registries.{}]\n", self.self_local_name).as_bytes())
.await?;
writer
.write_all(
format!(
"token = \"Basic {}\"\n",
STANDARD.encode(format!("{}:{}", self.self_service_login, self.self_service_token))
)
.as_bytes(),
)
.await?;
if self.index.allow_protocol_git && self.index.allow_protocol_sparse {
// add credential for specialized sparse registry
writer
.write_all(format!("[registries.{}]\n", self.self_local_name).as_bytes())
.write_all(format!("[registries.{}sparse]\n", self.self_local_name).as_bytes())
.await?;
writer
.write_all(
Expand All @@ -623,22 +681,22 @@ impl Configuration {
.as_bytes(),
)
.await?;
for registry in &self.external_registries {
writer
.write_all(format!("[registries.{}]\n", registry.name).as_bytes())
.await?;
writer
.write_all(
format!(
"token = \"Basic {}\"\n",
STANDARD.encode(format!("{}:{}", registry.login, registry.token))
)
.as_bytes(),
}
for registry in &self.external_registries {
writer
.write_all(format!("[registries.{}]\n", registry.name).as_bytes())
.await?;
writer
.write_all(
format!(
"token = \"Basic {}\"\n",
STANDARD.encode(format!("{}:{}", registry.login, registry.token))
)
.await?;
}
writer.flush().await?;
.as_bytes(),
)
.await?;
}
writer.flush().await?;
Ok(())
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/services/docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,13 @@ impl DocsGeneratorImpl {
"doc.extern-map.registries.{}=\"{}/docs\"",
self.configuration.self_local_name, self.configuration.web_public_uri
));
if self.configuration.index.allow_protocol_git && self.configuration.index.allow_protocol_sparse {
// both git and sparse => add specialized sparse
command.arg(format!(
"doc.extern-map.registries.{}sparse=\"{}/docs\"",
self.configuration.self_local_name, self.configuration.web_public_uri
));
}
for external in &self.configuration.external_registries {
command.arg("--config").arg(format!(
"doc.extern-map.registries.{}=\"{}\"",
Expand Down

0 comments on commit 5b89fbc

Please sign in to comment.