Skip to content

Commit 979842b

Browse files
authored
Add Source trait (#21)
* Add source trait * Move github & gitlab into source module, implementing `Source` trait
1 parent 6ac2df6 commit 979842b

12 files changed

+52
-75
lines changed

Cargo.lock

+3-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ edition = "2021"
66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
77

88
[dependencies]
9+
async-trait = "0.1.80"
910
chrono = "0.4.37"
1011
clap = { version = "4.5.4", features = ["derive", "env", "string"] }
1112
figment = { version = "0.10.16", features = ["toml"] }

src/cli/manage_sources.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ pub enum ManageSources {
99
name: String,
1010
/// The Git provider used by the source.
1111
#[arg(short, long)]
12-
provider: config::GitProviderType,
12+
provider: config::SourceType, // TODO: Rename parameter to source type
1313
/// The URL of the source.
1414
#[arg(short, long)]
1515
url: Option<reqwest::Url>,

src/cli/update.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
//! The update subcommand used to get the latest allowed signers and write them to the output file.
2+
use crate::{AllowedSigner, Config, Source, SshPublicKey};
23
use std::collections::{HashMap, HashSet};
34

4-
use crate::{AllowedSigner, Config, SshPublicKey};
5-
65
pub(super) fn update(config: Config) {
76
let sources = config.get_sources();
87

98
let mut allowed_signers: HashSet<AllowedSigner> = HashSet::new();
109
if let Some(users) = config.users {
1110
for user in users {
12-
let public_keys = get_public_keys((), sources.clone());
11+
let public_keys = get_public_keys((), &sources);
1312
for public_key in public_keys {
1413
todo!("Insert allowed signer into set.");
1514
}
1615
}
1716
}
1817
}
1918

20-
fn get_public_keys(user: (), sources: HashMap<String, ()>) -> Vec<SshPublicKey> {
19+
fn get_public_keys(user: (), sources: &HashMap<String, Box<dyn Source>>) -> Vec<SshPublicKey> {
2120
todo!("Retrieve public keys for a user from all sources.");
2221
}

src/config.rs

+10-21
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::GitProvider;
1+
use crate::Source;
22
use figment::{
33
providers::{Format, Serialized, Toml},
44
Figment,
@@ -30,12 +30,12 @@ impl Default for Config {
3030
sources: vec![
3131
SourceConfiguration {
3232
name: "github".to_string(),
33-
provider: GitProviderType::Github,
33+
provider: SourceType::Github,
3434
url: "https://api.github.com".to_string(),
3535
},
3636
SourceConfiguration {
3737
name: "gitlab".to_string(),
38-
provider: GitProviderType::Gitlab,
38+
provider: SourceType::Gitlab,
3939
url: "https://gitlab.com".to_string(),
4040
},
4141
],
@@ -46,7 +46,7 @@ impl Default for Config {
4646
impl Config {
4747
/// Get the configured sources.
4848
#[must_use]
49-
pub fn get_sources(&self) -> HashMap<String, ()> {
49+
pub fn get_sources(&self) -> HashMap<String, Box<dyn Source>> {
5050
todo!()
5151
}
5252

@@ -87,13 +87,11 @@ fn git_allowed_signers() -> Option<PathBuf> {
8787
Some(path.into())
8888
}
8989

90-
/// The type of Git provider.
90+
/// The type of source.
9191
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, clap::ValueEnum)]
9292
#[serde(rename_all = "lowercase")]
93-
pub enum GitProviderType {
94-
/// A Git provider that implements the GitHub API.
93+
pub enum SourceType {
9594
Github,
96-
/// A Git provider that implements the GitLab API.
9795
Gitlab,
9896
}
9997

@@ -108,19 +106,10 @@ pub struct User {
108106
#[derive(Debug, Deserialize, Serialize, PartialEq)]
109107
struct SourceConfiguration {
110108
name: String,
111-
provider: GitProviderType,
109+
provider: SourceType,
112110
url: String,
113111
}
114112

115-
impl From<SourceConfiguration> for GitProvider {
116-
fn from(source: SourceConfiguration) -> Self {
117-
match source.provider {
118-
GitProviderType::Github => GitProvider::github(source.url.parse().unwrap()),
119-
GitProviderType::Gitlab => GitProvider::gitlab(source.url.parse().unwrap()),
120-
}
121-
}
122-
}
123-
124113
#[cfg(test)]
125114
mod tests {
126115
use super::*;
@@ -185,7 +174,7 @@ mod tests {
185174
sources: vec![
186175
SourceConfiguration {
187176
name: "acme-corp".to_string(),
188-
provider: GitProviderType::Gitlab,
177+
provider: SourceType::Gitlab,
189178
url: "https://git.acme.corp".to_string(),
190179
}
191180
]
@@ -201,12 +190,12 @@ mod tests {
201190
let default_sources = Config::default().sources;
202191
assert!(default_sources.contains(&SourceConfiguration {
203192
name: "github".to_string(),
204-
provider: GitProviderType::Github,
193+
provider: SourceType::Github,
205194
url: "https://api.github.com".to_string(),
206195
}));
207196
assert!(default_sources.contains(&SourceConfiguration {
208197
name: "gitlab".to_string(),
209-
provider: GitProviderType::Gitlab,
198+
provider: SourceType::Gitlab,
210199
url: "https://gitlab.com".to_string(),
211200
}));
212201
}

src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
pub use allowed_signers::{AllowedSigner, AllowedSignersFile};
66
pub use config::Config;
77
pub use core::*;
8-
pub use provider::GitProvider;
8+
pub use source::Source;
99

1010
mod allowed_signers;
1111
pub mod cli;
1212
mod config;
1313
mod core;
14-
mod provider;
14+
mod source;

src/provider/core.rs

-32
This file was deleted.

src/provider/mod.rs

-5
This file was deleted.

src/provider/github.rs src/source/github.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
use super::Source;
12
use crate::{SshPublicKey, USER_AGENT};
3+
use async_trait::async_trait;
24
use reqwest::{Client, Result, Url};
35

46
#[derive(Debug)]
@@ -14,11 +16,12 @@ impl Github {
1416
pub fn new(base_url: Url) -> Self {
1517
Self { base_url }
1618
}
19+
}
1720

18-
/// Get the signing keys of a user by their username.
19-
///
20-
/// [API documentation](https://docs.github.com/en/rest/users/ssh-signing-keys?apiVersion=2022-11-28#list-ssh-signing-keys-for-a-user)
21-
pub async fn get_keys_by_username(
21+
#[async_trait]
22+
impl Source for Github {
23+
// [API documentation](https://docs.github.com/en/rest/users/ssh-signing-keys?apiVersion=2022-11-28#list-ssh-signing-keys-for-a-user)
24+
async fn get_keys_by_username(
2225
&self,
2326
username: &str,
2427
client: &Client,

src/provider/gitlab.rs src/source/gitlab.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
use super::Source;
12
use crate::{SshPublicKey, USER_AGENT};
3+
use async_trait::async_trait;
24
use reqwest::{Client, Result, Url};
35
use serde::Deserialize;
46

@@ -15,11 +17,12 @@ impl Gitlab {
1517
pub fn new(base_url: Url) -> Self {
1618
Self { base_url }
1719
}
20+
}
1821

19-
/// Get the signing keys of a user by their username.
20-
///
21-
/// [API Documentation](https://docs.gitlab.com/16.10/ee/api/users.html#list-ssh-keys-for-user)
22-
pub async fn get_keys_by_username(
22+
#[async_trait]
23+
impl Source for Gitlab {
24+
// [API Documentation](https://docs.gitlab.com/16.10/ee/api/users.html#list-ssh-keys-for-user)
25+
async fn get_keys_by_username(
2326
&self,
2427
username: &str,
2528
client: &Client,

src/source/main.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use crate::SshPublicKey;
2+
use async_trait::async_trait;
3+
4+
/// A source implements a way to get public keys from a Git provider.
5+
#[async_trait]
6+
pub trait Source {
7+
/// Get a users public keys by their username.
8+
async fn get_keys_by_username(
9+
&self,
10+
username: &str,
11+
client: &reqwest::Client,
12+
) -> Result<Vec<SshPublicKey>, reqwest::Error>;
13+
}

src/source/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pub use main::Source;
2+
3+
mod github;
4+
mod gitlab;
5+
mod main;

0 commit comments

Comments
 (0)