diff --git a/Cargo.lock b/Cargo.lock index d746042..aec1397 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -431,6 +431,18 @@ dependencies = [ ] [[package]] +name = "deadpool" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb84100978c1c7b37f09ed3ce3e5f843af02c2a2c431bae5b19230dad2c1b490" +dependencies = [ + "async-trait", + "deadpool-runtime", + "num_cpus", + "tokio", +] + +[[package]] name = "deadpool-runtime" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -739,7 +751,7 @@ dependencies = [ "bincode", "chrono", "color-eyre", - "deadpool", + "deadpool 0.10.0", "futures-util", "giterated-models", "jsonwebtoken", @@ -766,7 +778,7 @@ dependencies = [ "base64 0.21.3", "bincode", "chrono", - "deadpool", + "deadpool 0.9.5", "futures-util", "git2", "giterated-api", @@ -979,6 +991,20 @@ dependencies = [ ] [[package]] +name = "hyper-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + +[[package]] name = "hyper-tls" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1658,6 +1684,7 @@ dependencies = [ "http", "http-body", "hyper", + "hyper-rustls", "hyper-tls", "ipnet", "js-sys", @@ -1667,16 +1694,20 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "rustls", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", "tokio", "tokio-native-tls", + "tokio-rustls", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "webpki-roots", "winreg", ] @@ -2827,6 +2858,12 @@ dependencies = [ ] [[package]] +name = "webpki-roots" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" + +[[package]] name = "whoami" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/giterated-daemon/src/backend/git.rs b/giterated-daemon/src/backend/git.rs index b18ea41..eba4a42 100644 --- a/giterated-daemon/src/backend/git.rs +++ b/giterated-daemon/src/backend/git.rs @@ -11,7 +11,7 @@ use giterated_models::repository::{ RepositoryDiffPatchRequest, RepositoryDiffRequest, RepositoryFile, RepositoryFileFromIdRequest, RepositoryFileFromPathRequest, RepositoryFileInspectRequest, RepositoryIssue, RepositoryIssueLabelsRequest, RepositoryIssuesCountRequest, RepositoryIssuesRequest, - RepositoryObjectType, RepositoryTreeEntry, RepositoryVisibility, Visibility, RepositoryCommitFromIdRequest, RepositoryLastCommitOfFileRequest, RepositoryStatisticsRequest, RepositoryStatistics, + RepositoryObjectType, RepositoryTreeEntry, RepositoryVisibility, Visibility, RepositoryCommitFromIdRequest, RepositoryLastCommitOfFileRequest, RepositoryStatisticsRequest, RepositoryStatistics, RepositoryBranchesRequest, RepositoryBranch, }; use giterated_models::settings::{AnySetting, Setting}; use giterated_models::user::{User, UserParseError}; @@ -876,6 +876,32 @@ impl RepositoryBackend for GitBackend { }) } + async fn repository_get_branches( + &mut self, + requester: &Option, + repository: &Repository, + _request: &RepositoryBranchesRequest, + ) -> Result, Error> { + let git = self + .open_repository_and_check_permissions(&repository.owner, &repository.name, requester) + .await?; + + let mut branches = vec![]; + + // TODO: Add details like stale and such + for branch in git.branches(None)? { + let branch = branch?; + + let Some(name) = branch.0.name().ok().flatten() else { + continue; + }; + + branches.push(RepositoryBranch { name: name.to_string() }) + } + + Ok(branches) + } + async fn repository_diff( &mut self, requester: &Option, diff --git a/giterated-daemon/src/backend/mod.rs b/giterated-daemon/src/backend/mod.rs index e11638c..33c3ea9 100644 --- a/giterated-daemon/src/backend/mod.rs +++ b/giterated-daemon/src/backend/mod.rs @@ -21,7 +21,7 @@ use giterated_models::repository::{ RepositoryDiffPatchRequest, RepositoryDiffRequest, RepositoryFile, RepositoryFileFromIdRequest, RepositoryFileFromPathRequest, RepositoryFileInspectRequest, RepositoryIssue, RepositoryIssueLabelsRequest, RepositoryIssuesCountRequest, RepositoryIssuesRequest, - RepositorySummary, RepositoryTreeEntry, RepositoryCommitFromIdRequest, RepositoryLastCommitOfFileRequest, RepositoryStatistics, RepositoryStatisticsRequest, + RepositorySummary, RepositoryTreeEntry, RepositoryCommitFromIdRequest, RepositoryLastCommitOfFileRequest, RepositoryStatistics, RepositoryStatisticsRequest, RepositoryBranchesRequest, RepositoryBranch, }; use giterated_models::settings::AnySetting; use giterated_models::user::User; @@ -88,6 +88,12 @@ pub trait RepositoryBackend { repository: &Repository, request: &RepositoryStatisticsRequest, ) -> Result; + async fn repository_get_branches( + &mut self, + requester: &Option, + repository: &Repository, + request: &RepositoryBranchesRequest, + ) -> Result, Error>; async fn get_value( &mut self, user: &Repository, diff --git a/giterated-daemon/src/database_backend/handler.rs b/giterated-daemon/src/database_backend/handler.rs index 69b2d80..45c7142 100644 --- a/giterated-daemon/src/database_backend/handler.rs +++ b/giterated-daemon/src/database_backend/handler.rs @@ -13,7 +13,7 @@ use giterated_models::{ RepositoryCommitBeforeRequest, RepositoryDiff, RepositoryDiffPatchRequest, RepositoryDiffRequest, RepositoryFile, RepositoryFileFromIdRequest, RepositoryFileFromPathRequest, RepositoryFileInspectRequest, RepositoryInfoRequest, - RepositorySummary, RepositoryView, Visibility, RepositoryCommitFromIdRequest, RepositoryLastCommitOfFileRequest, RepositoryStatisticsRequest, RepositoryStatistics, + RepositorySummary, RepositoryView, Visibility, RepositoryCommitFromIdRequest, RepositoryLastCommitOfFileRequest, RepositoryStatisticsRequest, RepositoryStatistics, RepositoryBranchesRequest, RepositoryBranch, }, settings::{AnySetting, GetSetting, GetSettingError, SetSetting, SetSettingError}, user::{User, UserRepositoriesRequest}, @@ -211,6 +211,38 @@ pub fn repository_get_statistics( .boxed() } +pub fn repository_get_branches( + object: &Repository, + operation: RepositoryBranchesRequest, + state: DatabaseBackend, + operation_state: StackOperationState, + backend: BackendWrapper, + requester: Option, +) -> BoxFuture<'static, Result, OperationError>> { + let object = object.clone(); + + async move { + let object = backend + .get_object::(&object.to_string(), &operation_state) + .await + .unwrap(); + + let mut repository_backend = state.repository_backend.lock().await; + let branches = repository_backend + .repository_get_branches( + &requester, + object.object(), + &operation, + ) + .await + .map_err(|err| OperationError::Internal(format!("{:?}", err)))?; + drop(repository_backend); + + Ok(branches) + } + .boxed() +} + pub fn repository_file_from_id( object: &Repository, operation: RepositoryFileFromIdRequest, diff --git a/giterated-daemon/src/database_backend/mod.rs b/giterated-daemon/src/database_backend/mod.rs index 95e2cdf..0749969 100644 --- a/giterated-daemon/src/database_backend/mod.rs +++ b/giterated-daemon/src/database_backend/mod.rs @@ -21,7 +21,7 @@ use self::handler::{ instance_registration_request, repository_commit_before, repository_diff, repository_diff_patch, repository_file_from_id, repository_file_from_path, repository_get_setting, repository_get_value, repository_info, repository_set_setting, - user_get_repositories, user_get_setting, user_get_value, user_set_setting, repository_commit_by_id, repository_last_commit_of_file, repository_get_statistics, + user_get_repositories, user_get_setting, user_get_value, user_set_setting, repository_commit_by_id, repository_last_commit_of_file, repository_get_statistics, repository_get_branches, }; #[derive(Clone, Debug)] @@ -87,6 +87,7 @@ impl DatabaseBackend { .insert(repository_diff) .insert(repository_diff_patch) .insert(repository_commit_before) + .insert(repository_get_branches) .insert(repository_get_value) .insert(repository_get_setting) .insert(repository_set_setting) @@ -128,7 +129,7 @@ mod test { Commit, Description, Repository, RepositoryCommitBeforeRequest, RepositoryDiff, RepositoryDiffPatchRequest, RepositoryDiffRequest, RepositoryFile, RepositoryFileFromIdRequest, RepositoryFileFromPathRequest, RepositoryFileInspectRequest, - RepositorySummary, RepositoryTreeEntry, RepositoryCommitFromIdRequest, RepositoryLastCommitOfFileRequest, RepositoryStatisticsRequest, RepositoryStatistics, + RepositorySummary, RepositoryTreeEntry, RepositoryCommitFromIdRequest, RepositoryLastCommitOfFileRequest, RepositoryStatisticsRequest, RepositoryStatistics, RepositoryBranch, RepositoryBranchesRequest, }; use giterated_models::settings::AnySetting; use giterated_models::user::{DisplayName, User}; @@ -280,6 +281,14 @@ mod test { ) -> Result { todo!() } + async fn repository_get_branches( + &mut self, + _requester: &Option, + _repository: &Repository, + _request: &RepositoryBranchesRequest, + ) -> Result, Error> { + todo!() + } async fn get_value( &mut self, _repository: &Repository, diff --git a/giterated-models/src/repository/mod.rs b/giterated-models/src/repository/mod.rs index b328ff4..7d87dca 100644 --- a/giterated-models/src/repository/mod.rs +++ b/giterated-models/src/repository/mod.rs @@ -150,6 +150,13 @@ pub struct RepositoryStatistics { pub tags: usize, } +/// Repository branch +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct RepositoryBranch { + /// Full reference name + pub name: String, +} + #[derive(Clone, Debug, Serialize, Deserialize)] pub struct RepositoryFile { /// ID of the file diff --git a/giterated-models/src/repository/operations.rs b/giterated-models/src/repository/operations.rs index 446cad1..9909810 100644 --- a/giterated-models/src/repository/operations.rs +++ b/giterated-models/src/repository/operations.rs @@ -9,7 +9,7 @@ use crate::{ use super::{ Commit, IssueLabel, Repository, RepositoryDiff, RepositoryFile, RepositoryIssue, - RepositoryTreeEntry, RepositoryView, RepositoryStatistics, + RepositoryTreeEntry, RepositoryView, RepositoryStatistics, RepositoryBranch, }; /// A request to get a repository's information. @@ -253,6 +253,24 @@ impl GiteratedOperation for RepositoryStatisticsRequest { type Failure = RepositoryError; } +/// A request to get a list of branches in the repository. +/// Skips over references with invalid UTF-8 names. +/// +/// # Authentication +/// - Instance Authentication +/// - Validate request against the `issued_for` public key +/// - Validate User token against the user's instance's public key +/// # Authorization +/// - User Authorization +/// - Potential User permissions checks +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct RepositoryBranchesRequest; + +impl GiteratedOperation for RepositoryBranchesRequest { + type Success = Vec; + type Failure = RepositoryError; +} + impl + std::fmt::Debug> Object<'_, S, Repository, B> { pub async fn info( &mut self, @@ -363,7 +381,7 @@ impl + std::fmt::Debug> Object<'_, S .await } - pub async fn repository_get_statistics( + pub async fn statistics( &mut self, rev: Option, operation_state: &S, @@ -375,6 +393,17 @@ impl + std::fmt::Debug> Object<'_, S .await } + pub async fn branches( + &mut self, + operation_state: &S, + ) -> Result, OperationError> { + self.request::( + RepositoryBranchesRequest, + operation_state + ) + .await + } + // pub async fn issues_count(&mut self) -> Result> { // self.request::(RepositoryIssuesCountRequest) // .await