Skip to content

Commit 99b1644

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents ed870c7 + 159874c commit 99b1644

File tree

23 files changed

+749
-142
lines changed

23 files changed

+749
-142
lines changed

Cargo.lock

Lines changed: 93 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Devrcfile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,11 @@ format:
7171
desc: "Apply code formatter"
7272
exec: |
7373
cargo +nightly fmt --all --
74+
75+
76+
prepare-release level="patch":
77+
desc: "Prepare next release"
78+
run: |
79+
cargo release version {{ level }}
80+
cargo build
81+
devrc --help > xtests/outputs/test_help_test_1_1_stdout.ansitxt

cli/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ anyhow = "1.0.62"
5151

5252
devrc-plugins = { path = "../plugins", version = "0.5.4"}
5353
devrc-core = { path = "../core", version = "0.5.4"}
54+
netrc-rs = "0.1.2"
55+
base64 = "0.21.2"
56+
duration-str = "0.5.1"
5457

5558
[build-dependencies]
5659
datetime = { version = "0.5.2", default_features = false }

cli/src/auth.rs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
use std::{convert::TryFrom, fs};
2+
3+
use netrc_rs::{Machine, Netrc};
4+
5+
use crate::{
6+
errors::DevrcError,
7+
netrc::get_user_defined_netrc_path,
8+
raw::auth::{NetrcAuth, NetrcAuthHeader},
9+
};
10+
11+
pub const HEADER_AUTHORIZATION: &str = "Authorization";
12+
13+
#[derive(Debug, Clone, Default)]
14+
pub enum AuthType {
15+
#[default]
16+
None,
17+
Bearer,
18+
BasicAuth,
19+
Header(String),
20+
}
21+
22+
#[derive(Debug, Clone, Default)]
23+
pub enum Auth {
24+
#[default]
25+
Empty,
26+
Loaded {
27+
machine: Machine,
28+
auth_type: AuthType,
29+
},
30+
}
31+
32+
impl TryFrom<crate::raw::auth::Auth> for Auth {
33+
type Error = DevrcError;
34+
35+
fn try_from(value: crate::raw::auth::Auth) -> Result<Self, Self::Error> {
36+
let file = get_user_defined_netrc_path().ok_or(DevrcError::NetrcNotFound)?;
37+
let content = fs::read_to_string(file).map_err(DevrcError::IoError)?;
38+
let netrc = Netrc::parse(content, false).map_err(DevrcError::NetrcParsingError)?;
39+
40+
match value {
41+
crate::raw::auth::Auth::Empty => Ok(Auth::Empty),
42+
crate::raw::auth::Auth::NetrcAuth(NetrcAuth {
43+
host,
44+
login,
45+
auth_type,
46+
}) => match get_machine(&netrc, &host, &login) {
47+
Some(machine) => Ok(Auth::Loaded {
48+
machine,
49+
auth_type: auth_type.into(),
50+
}),
51+
None => Ok(Auth::Empty),
52+
},
53+
crate::raw::auth::Auth::NetrcAuthHeader(NetrcAuthHeader {
54+
host,
55+
login,
56+
header,
57+
}) => match get_machine(&netrc, &host, &login) {
58+
Some(machine) => Ok(Auth::Loaded {
59+
machine,
60+
auth_type: AuthType::Header(header),
61+
}),
62+
None => Ok(Auth::Empty),
63+
},
64+
}
65+
}
66+
}
67+
68+
impl From<crate::raw::auth::AuthType> for AuthType {
69+
fn from(value: crate::raw::auth::AuthType) -> Self {
70+
match value {
71+
crate::raw::auth::AuthType::Empty => AuthType::None,
72+
crate::raw::auth::AuthType::Bearer => AuthType::Bearer,
73+
crate::raw::auth::AuthType::BasicAuth => AuthType::BasicAuth,
74+
}
75+
}
76+
}
77+
78+
fn get_machine(netrc: &Netrc, host: &str, login: &str) -> Option<Machine> {
79+
let mut default: Option<Machine> = None;
80+
81+
for machine in &netrc.machines {
82+
match (machine.name.as_ref(), machine.login.as_ref()) {
83+
(Some(record_host), Some(record_login))
84+
if record_host.as_str() == host && record_login.as_str() == login =>
85+
{
86+
return Some(machine.clone())
87+
}
88+
(None, Some(record_login)) if record_login.as_str() == login => {
89+
default = Some(machine.clone())
90+
}
91+
(_, _) => {}
92+
}
93+
}
94+
95+
default
96+
}
97+
98+
impl Auth {
99+
pub fn get_header(&self) -> Option<(String, String)> {
100+
if let Auth::Loaded { machine, auth_type } = self {
101+
let password = match &machine.password {
102+
Some(password) => password,
103+
None => return None,
104+
};
105+
let login = match &machine.login {
106+
Some(login) => login,
107+
None => return None,
108+
};
109+
110+
return match auth_type {
111+
AuthType::Bearer => Some((
112+
HEADER_AUTHORIZATION.to_string(),
113+
format!("Bearer {}", password),
114+
)),
115+
AuthType::BasicAuth => {
116+
let creds = format!("{:}:{:}", login, password);
117+
let b64 =
118+
base64::Engine::encode(&base64::engine::general_purpose::STANDARD, creds);
119+
Some((HEADER_AUTHORIZATION.to_string(), format!("Basic {}", b64)))
120+
}
121+
AuthType::Header(header) => Some((header.to_owned(), password.to_owned())),
122+
AuthType::None => None,
123+
};
124+
}
125+
None
126+
}
127+
}

0 commit comments

Comments
 (0)