From 155895d188ad6199247f1831b7188018532385d7 Mon Sep 17 00:00:00 2001 From: mo khan Date: Thu, 10 Jul 2025 13:58:58 -0600 Subject: refactor: extract an api type --- src/authorization/entities.rs | 62 ++++++--------------------------- src/gitlab/api.rs | 81 +++++++++++++++++++++++++++++++++++++++++++ src/gitlab/mod.rs | 2 ++ 3 files changed, 93 insertions(+), 52 deletions(-) create mode 100644 src/gitlab/api.rs (limited to 'src') diff --git a/src/authorization/entities.rs b/src/authorization/entities.rs index b4f5a762..6e7fd568 100644 --- a/src/authorization/entities.rs +++ b/src/authorization/entities.rs @@ -1,4 +1,4 @@ -use crate::gitlab::{Group, Member, Project}; +use crate::gitlab::Api; use serde::Serialize; use std::collections::HashSet; @@ -25,37 +25,23 @@ pub struct CedarParent { } pub struct EntitiesRepository { - pub token: String, - pub host: String, - pub project_url: String, + api: Api, + project: String, } impl EntitiesRepository { pub fn new(token: String, host: String, project: String) -> EntitiesRepository { EntitiesRepository { - token: token, - host: host.clone(), - project_url: format!( - "{}/api/v4/projects/{}", - host.trim_end_matches('/'), - urlencoding::encode(&project) - ), + api: Api::new(token, host), + project, } } pub async fn all(&self) -> Result, Box> { - let http = reqwest::Client::new(); let mut entities = Vec::new(); let mut groups = HashSet::new(); - let project: Project = http - .get(&self.project_url) - .header("PRIVATE-TOKEN", &self.token) - .send() - .await? - .error_for_status()? - .json() - .await?; + let project = self.api.get_project(&self.project).await?; entities.push(CedarEntity { uid: CedarUid { @@ -77,20 +63,7 @@ impl EntitiesRepository { }, }); - let members_url = format!( - "{}/api/v4/projects/{}/members/all", - self.host.trim_end_matches('/'), - project.id - ); - - let members: Vec = http - .get(&members_url) - .header("PRIVATE-TOKEN", &self.token) - .send() - .await? - .error_for_status()? - .json() - .await?; + let members = self.api.get_project_members(project.id).await?; for member in members { if member.state == "active" { @@ -110,7 +83,7 @@ impl EntitiesRepository { } if project.namespace.kind == "group" { - self.fetch_hierarchy(&http, project.namespace.id, &mut entities, &mut groups) + self.fetch_hierarchy(project.namespace.id, &mut entities, &mut groups) .await?; } @@ -119,7 +92,6 @@ impl EntitiesRepository { fn fetch_hierarchy<'a>( &'a self, - client: &'a reqwest::Client, group_id: u64, entities: &'a mut Vec, groups: &'a mut HashSet, @@ -133,24 +105,10 @@ impl EntitiesRepository { groups.insert(group_id); - let group_url = format!( - "{}/api/v4/groups/{}", - self.host.trim_end_matches('/'), - group_id - ); - - let group: Group = client - .get(&group_url) - .header("PRIVATE-TOKEN", &self.token) - .send() - .await? - .error_for_status()? - .json() - .await?; + let group = self.api.get_group(group_id).await?; let parents = if let Some(parent_id) = group.parent_id { - self.fetch_hierarchy(client, parent_id, entities, groups) - .await?; + self.fetch_hierarchy(parent_id, entities, groups).await?; vec![CedarParent { parent_type: "Group".to_string(), id: parent_id.to_string(), diff --git a/src/gitlab/api.rs b/src/gitlab/api.rs new file mode 100644 index 00000000..7f733b4c --- /dev/null +++ b/src/gitlab/api.rs @@ -0,0 +1,81 @@ +use crate::gitlab::{Group, Member, Project}; +use reqwest::Client; + +pub struct Api { + pub token: String, + pub host: String, + client: Client, +} + +impl Api { + pub fn new(token: String, host: String) -> Api { + Api { + token, + host, + client: Client::new(), + } + } + + pub async fn get_project(&self, project: &str) -> Result> { + let url = format!( + "{}/api/v4/projects/{}", + self.host.trim_end_matches('/'), + urlencoding::encode(project) + ); + + let project = self + .client + .get(&url) + .header("PRIVATE-TOKEN", &self.token) + .send() + .await? + .error_for_status()? + .json() + .await?; + + Ok(project) + } + + pub async fn get_project_members( + &self, + project_id: u64, + ) -> Result, Box> { + let url = format!( + "{}/api/v4/projects/{}/members/all", + self.host.trim_end_matches('/'), + project_id + ); + + let members = self + .client + .get(&url) + .header("PRIVATE-TOKEN", &self.token) + .send() + .await? + .error_for_status()? + .json() + .await?; + + Ok(members) + } + + pub async fn get_group(&self, group_id: u64) -> Result> { + let url = format!( + "{}/api/v4/groups/{}", + self.host.trim_end_matches('/'), + group_id + ); + + let group = self + .client + .get(&url) + .header("PRIVATE-TOKEN", &self.token) + .send() + .await? + .error_for_status()? + .json() + .await?; + + Ok(group) + } +} diff --git a/src/gitlab/mod.rs b/src/gitlab/mod.rs index 04e85786..e1993d81 100644 --- a/src/gitlab/mod.rs +++ b/src/gitlab/mod.rs @@ -1,8 +1,10 @@ +pub mod api; pub mod group; pub mod member; pub mod namespace; pub mod project; +pub use api::Api; pub use group::Group; pub use member::Member; pub use namespace::Namespace; -- cgit v1.2.3