Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ services:
# Optional GitLab parameters
# The base URL for API calls, e.g. "https://gitlab.com/"
- GITLAB_URL=
# The GitLab group that contains the bridgehead configuration repositories, e.g. "bridgehead-configurations"
- GITLAB_GROUP=
# A long-living personal (or impersonation) access token that is used to create short-living project access tokens. Requires at least the "api" scope. Note that group access tokens and project access tokens cannot be used to create project access tokens.
- GITLAB_API_ACCESS_TOKEN=
```
Expand All @@ -88,6 +90,6 @@ Create a GitLab project access token for read access (git clone/pull) to the bri

Secret type: `GitLabProjectAccessToken`

The argument is always `bridgehead-configuration`.
The third value after the final `:` is unused.

Example: `GitLabProjectAccessToken:GIT_CONFIG_REPO_TOKEN:bridgehead-configuration`
Example: `GitLabProjectAccessToken:GIT_CONFIG_REPO_TOKEN:`
41 changes: 17 additions & 24 deletions central/src/gitlab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ struct GitLabApiConfig {
/// The base URL for API calls, e.g. "https://gitlab.com/"
#[clap(long, env)]
pub gitlab_url: Url,
/// The GitLab group that contains the bridgehead configuration repositories, e.g. "bridgehead-configurations"
#[clap(long, env)]
pub gitlab_group: String,
/// A long-living personal (or impersonation) access token that is used to create short-living project access tokens. Requires at least the "api" scope. Note that group access tokens and project access tokens cannot be used to create project access tokens.
#[clap(long, env)]
pub gitlab_api_access_token: String,
Expand All @@ -24,28 +27,6 @@ pub struct GitLabProjectAccessTokenProvider {
client: reqwest::Client,
}

/// Derive the bridgehead configuration repository from the beam id of the requester.
/// Example return value: "bridgehead-configurations/bridgehead-config-berlin"
fn derive_bridgehead_config_repo_from_beam_id(requester: &AppId) -> Result<String, String> {
let mut parts = requester.as_ref().splitn(3, '.');
let (_app, proxy, broker) = (parts.next().unwrap(), parts.next().unwrap(), parts.next().unwrap());

let group = match broker {
"broker.ccp-it.dktk.dkfz.de" => "bridgehead-configurations", // ccp
"broker.bbmri.sample.de" => "bbmri-bridgehead-configs", // bbmri
"broker.bbmri.de" => "bbmri-bridgehead-configs", // gbn
"test-no-real-data.broker.samply.de" => "bridgehead-configurations", // cce, itcc, kr
"broker.hector.dkfz.de" => "dhki", // dhki
_ => return Err(format!("Bridgehead configuration repository group not known for broker {broker}")),
};

Ok(match group {
"bridgehead-configurations" => format!("{group}/bridgehead-config-{proxy}"),
"dhki" => format!("{group}/{proxy}-bk"),
_ => format!("{group}/{proxy}"),
})
}

impl GitLabProjectAccessTokenProvider {
pub fn try_init() -> Option<Self> {
match GitLabApiConfig::try_parse() {
Expand All @@ -60,12 +41,24 @@ impl GitLabProjectAccessTokenProvider {
}
}

/// Derive the bridgehead configuration repository from the beam id of the requester.
/// Example return value: "bridgehead-configurations/bridgehead-config-berlin"
fn derive_bridgehead_config_repo_from_beam_id(&self, requester: &AppId) -> String {
let name = requester.as_ref().split('.').nth(1).unwrap();
let group = self.config.gitlab_group.as_str();
match group {
"bridgehead-configurations" => format!("{group}/bridgehead-config-{name}"),
"dhki" => format!("{group}/{name}-bk"),
_ => format!("{group}/{name}"),
}
}

/// Create a project access token using the GitLab API
pub async fn create_token(
&self,
requester: &AppId,
) -> Result<SecretResult, String> {
let project_path = derive_bridgehead_config_repo_from_beam_id(requester)?;
let project_path = self.derive_bridgehead_config_repo_from_beam_id(requester);

// Expire in 1 week
let expires_at = (chrono::Local::now() + chrono::TimeDelta::weeks(1))
Expand Down Expand Up @@ -115,7 +108,7 @@ impl GitLabProjectAccessTokenProvider {
requester: &AppId,
secret: &str,
) -> Result<bool, String> {
let project_path = derive_bridgehead_config_repo_from_beam_id(requester)?;
let project_path = self.derive_bridgehead_config_repo_from_beam_id(requester);

let response = self
.client
Expand Down
5 changes: 1 addition & 4 deletions local/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,7 @@ impl FromStr for SecretArg {
}))
}
"GitLabProjectAccessToken" => {
match args {
"bridgehead-configuration" => Ok(SecretRequest::GitLabProjectAccessToken),
_ => return Err(format!("Invalid GitLabProjectAccessToken parameter '{args}'")),
}
Ok(SecretRequest::GitLabProjectAccessToken)
}
_ => Err(format!("Unknown secret type {secret_type}")),
}?;
Expand Down