Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gitlab): Introduce a self-hosted gitlab endpoint #9

Merged
merged 1 commit into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
51 changes: 51 additions & 0 deletions src/api/v1/gitlab/endpoints/get_repo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-FileCopyrightText: 2023 Gergely Nagy
// SPDX-FileContributor: Gergely Nagy
//
// SPDX-License-Identifier: AGPL-3.0-only

use axum::{
body::Body,
extract::Path,
http::{Request, StatusCode},
response::{IntoResponse, Redirect},
};

#[allow(unused)]
use log::{debug, error, info, trace, warn};

use super::super::utils::gitlab_api_get_latest_tag;

pub async fn get_repo(
Path((host, user, repo)): Path<(String, String, String)>,
request: Request<Body>,
) -> impl IntoResponse {
if repo.ends_with(".tar.gz") {
let tag = gitlab_api_get_latest_tag(
host.clone(),
user.clone(),
repo.clone()
.strip_suffix(".tar.gz")
.expect("couldn't strip .tar.gz suffix")
.to_string(),
)
.await
.expect("failed to await gitlab_api_get_latest_tag");
let result_uri = format!(
"/v1/gitlab/{}/{}/{}/v/{}.tar.gz",
host,
user,
repo.strip_suffix(".tar.gz")
.expect("couldn't strip .tar.gz suffix"),
tag,
);
trace!("{result_uri:#?}");
Redirect::to(&result_uri).into_response()
} else {
let body = format!(
"Hi friend, you probably meant to request {:#?}{}.tar.gz, that should work <3",
request.headers()["host"],
request.uri()
);
(StatusCode::BAD_REQUEST, body).into_response()
}
}
37 changes: 37 additions & 0 deletions src/api/v1/gitlab/endpoints/get_repo_ref.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-FileCopyrightText: 2023 Gergely Nagy
// SPDX-FileContributor: Gergely Nagy
//
// SPDX-License-Identifier: AGPL-3.0-only

use axum::{
body::Body,
extract::Path,
http::{Request, StatusCode},
response::{IntoResponse, Redirect},
};

#[allow(unused)]
use log::{debug, error, info, trace, warn};

pub async fn get_repo_ref(
Path((host, user, repo, git_ref)): Path<(String, String, String, String)>,
request: Request<Body>,
) -> impl IntoResponse {
if git_ref.ends_with(".tar.gz") {
let git_ref_name = git_ref
.strip_suffix(".tar.gz")
.expect("couldn't strip .tar.gz suffix");
let uri = format!(
"https://{}/{}/{}/-/archive/{}/{}-{}.tar.gz",
host, user, repo, git_ref_name, repo, git_ref_name,
);
Redirect::to(&uri).into_response()
} else {
let body = format!(
"Hi friend, you probably meant to request {:#?}{}.tar.gz, that should work <3",
request.headers()["host"],
request.uri()
);
(StatusCode::BAD_REQUEST, body).into_response()
}
}
9 changes: 9 additions & 0 deletions src/api/v1/gitlab/endpoints/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-FileCopyrightText: 2023 Gergely Nagy
// SPDX-FileContributor: Gergely Nagy
//
// SPDX-License-Identifier: AGPL-3.0-only

mod get_repo;
pub use self::get_repo::get_repo;
mod get_repo_ref;
pub use self::get_repo_ref::get_repo_ref;
9 changes: 9 additions & 0 deletions src/api/v1/gitlab/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-FileCopyrightText: 2023 Gergely Nagy
// SPDX-FileContributor: Gergely Nagy
//
// SPDX-License-Identifier: AGPL-3.0-only

pub mod routes;

mod endpoints;
mod utils;
19 changes: 19 additions & 0 deletions src/api/v1/gitlab/routes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-FileCopyrightText: 2023 Gergely Nagy
// SPDX-FileContributor: Gergely Nagy
//
// SPDX-License-Identifier: AGPL-3.0-only

use super::endpoints::{get_repo, get_repo_ref};

use axum::{routing::get, Router};

pub fn get_routes() -> Router {
Router::new()
.route("/:host/:user/:repo/b/:branch", get(get_repo_ref))
.route("/:host/:user/:repo/branch/:branch", get(get_repo_ref))
.route("/:host/:user/:repo/v/:version", get(get_repo_ref))
.route("/:host/:user/:repo/version/:version", get(get_repo_ref))
.route("/:host/:user/:repo/t/:version", get(get_repo_ref))
.route("/:host/:user/:repo/tag/:version", get(get_repo_ref))
.route("/:host/:user/:repo", get(get_repo))
}
40 changes: 40 additions & 0 deletions src/api/v1/gitlab/utils/gitlab_api_get_latest_tag.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-FileCopyrightText: 2023 Gergely Nagy
// SPDX-FileContributor: Gergely Nagy
//
// SPDX-License-Identifier: AGPL-3.0-only

#[allow(unused)]
use log::{debug, error, info, trace, warn};

pub async fn gitlab_api_get_latest_tag(
host: String,
user: String,
repo: String,
) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
use reqwest::{
header::{ACCEPT, USER_AGENT},
Url,
};
// TODO: The middle part, `{}%2F{}` is really `user/repo` URL-encoded. We
// should do proper URL encoding.
let version_uri = Url::parse(&format!(
"https://{}/api/v4/projects/{}%2F{}/repository/tags",
host, user, repo
))?;
trace!("{:#?}", version_uri);
let client = reqwest::Client::builder().user_agent(USER_AGENT).build()?;
let res = client
.get(version_uri)
.header(ACCEPT, "application/json")
.send()
.await?
.json::<serde_json::Value>()
.await?;

trace!("got:\n {:#?}", res[0]["name"]);

Ok(res[0]["name"]
.as_str()
.expect("failed to get release name as_str()")
.to_string())
}
7 changes: 7 additions & 0 deletions src/api/v1/gitlab/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// SPDX-FileCopyrightText: 2023 Gergely Nagy
// SPDX-FileContributor: Gergely Nagy
//
// SPDX-License-Identifier: AGPL-3.0-only

mod gitlab_api_get_latest_tag;
pub use self::gitlab_api_get_latest_tag::gitlab_api_get_latest_tag;
1 change: 1 addition & 0 deletions src/api/v1/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ pub mod routes;
mod flakehub;
mod forgejo;
mod github;
mod gitlab;
2 changes: 2 additions & 0 deletions src/api/v1/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use super::flakehub::routes::get_routes as get_flakehub_routes;
use super::forgejo::routes::get_redirect_routes as get_forgejo_redirect_routes;
use super::forgejo::routes::get_routes as get_forgejo_routes;
use super::github::routes::get_routes as get_github_routes;
use super::gitlab::routes::get_routes as get_gitlab_routes;
use axum::Router;

pub fn get_routes() -> Router {
Expand All @@ -15,5 +16,6 @@ pub fn get_routes() -> Router {
.nest("/flakehub", get_flakehub_routes())
.nest("/forgejo", get_forgejo_routes())
.nest("/gitea", get_forgejo_routes())
.nest("/gitlab", get_gitlab_routes())
.merge(get_forgejo_redirect_routes())
}