Skip to content

Commit 5b1eeb2

Browse files
committed
temp commit
1 parent f520e61 commit 5b1eeb2

35 files changed

+683
-750
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ reqwest = { version = "0.12", default-features = false, features = [
2525
"gzip",
2626
"rustls-tls",
2727
] }
28+
url = { version = "2" }
2829
uuid = { version = "1.8", features = ["v4", "fast-rng", "macro-diagnostics"] }
2930
zip = "4.2.0"
3031
sha256 = "1.5"

src/auth/github.rs

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::auth::AuthenticationError;
12
use crate::database::repository::github_login_attempts;
23
use crate::types::api::ApiError;
34
use crate::types::models::github_login_attempt::StoredLoginAttempt;
@@ -16,6 +17,40 @@ pub struct GithubStartAuth {
1617
interval: i32,
1718
}
1819

20+
#[derive(Deserialize)]
21+
pub enum GithubDeviceFlowErrorString {
22+
#[serde(rename(deserialize = "authorization_pending"))]
23+
AuthorizationPending,
24+
#[serde(rename(deserialize = "slow_down"))]
25+
SlowDown,
26+
#[serde(rename(deserialize = "expired_token"))]
27+
ExpiredToken,
28+
#[serde(rename(deserialize = "unsupported_grant_type"))]
29+
UnsupportedGrantType,
30+
#[serde(rename(deserialize = "incorrect_client_credentials"))]
31+
IncorrectClientCredentials,
32+
#[serde(rename(deserialize = "incorrect_device_code"))]
33+
IncorrectDeviceCode,
34+
#[serde(rename(deserialize = "access_denied"))]
35+
AccessDenied,
36+
#[serde(rename(deserialize = "device_flow_disabled"))]
37+
DeviceFlowDisabled,
38+
Unknown,
39+
}
40+
41+
impl Default for GithubDeviceFlowErrorString {
42+
fn default() -> Self {
43+
GithubDeviceFlowErrorString::Unknown
44+
}
45+
}
46+
47+
#[derive(Deserialize)]
48+
pub struct GithubErrorResponse {
49+
error: GithubDeviceFlowErrorString,
50+
error_description: String,
51+
error_uri: String,
52+
}
53+
1954
pub struct GithubClient {
2055
client_id: String,
2156
client_secret: String,
@@ -55,7 +90,7 @@ impl GithubClient {
5590
&self,
5691
ip: IpNetwork,
5792
pool: &mut PgConnection,
58-
) -> Result<StoredLoginAttempt, ApiError> {
93+
) -> Result<StoredLoginAttempt, AuthenticationError> {
5994
if let Some(r) = github_login_attempts::get_one_by_ip(ip, pool).await? {
6095
if r.is_expired() {
6196
let uuid = Uuid::parse_str(&r.uuid).unwrap();
@@ -74,26 +109,27 @@ impl GithubClient {
74109
}))
75110
.send()
76111
.await
77-
.map_err(|e| {
78-
log::error!("Failed to start OAuth device flow with GitHub: {}", e);
79-
ApiError::InternalError
80-
})?;
112+
.inspect_err(|e| log::error!("Failed to start OAuth device flow with GitHub: {e}"))?;
81113

82114
if !res.status().is_success() {
83115
log::error!(
84116
"GitHub OAuth device flow start request failed with code {}",
85117
res.status()
86118
);
87-
return Err(ApiError::InternalError);
119+
return Err(AuthenticationError::InternalError(
120+
"Failed to start GitHub device flow".into(),
121+
));
88122
}
89123

90-
let body = res.json::<GithubStartAuth>().await.map_err(|e| {
91-
log::error!(
92-
"Failed to parse OAuth device flow response from GitHub: {}",
93-
e
94-
);
95-
ApiError::InternalError
96-
})?;
124+
let body = res
125+
.json::<GithubStartAuth>()
126+
.await
127+
.inspect_err(|e| {
128+
log::error!("Failed to parse OAuth device flow response from GitHub: {e}")
129+
})
130+
.or(Err(AuthenticationError::InternalError(
131+
"Failed to parse response from GitHub".into(),
132+
)))?;
97133

98134
github_login_attempts::create(
99135
ip,
@@ -105,6 +141,7 @@ impl GithubClient {
105141
&mut *pool,
106142
)
107143
.await
144+
.map_err(|e| e.into())
108145
}
109146

110147
pub async fn poll_github(

src/auth/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ pub enum AuthenticationError {
66
NoToken,
77
#[error("Provided token is invalid")]
88
InvalidToken,
9+
#[error("Failed to communicate with GitHub")]
10+
RequestError(#[from] reqwest::Error),
11+
#[error("{0}")]
12+
InternalError(String),
13+
#[error("{0}")]
14+
Database(#[from] crate::database::DatabaseError),
915
#[error("Unknown database error")]
10-
SqlxError(#[from] sqlx::Error)
16+
SqlxError(#[from] sqlx::Error),
1117
}

src/database/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ pub mod repository;
22

33
#[derive(thiserror::Error, Debug)]
44
pub enum DatabaseError {
5+
#[error("Invalid input: {0}")]
6+
InvalidInput(String),
57
#[error("Unknown database error")]
68
SqlxError(#[from] sqlx::Error)
79
}
Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::types::api::ApiError;
1+
use crate::database::DatabaseError;
22
use chrono::{Days, Utc};
33
use sqlx::PgConnection;
44
use uuid::Uuid;
@@ -8,7 +8,7 @@ pub async fn generate_token(
88
developer_id: i32,
99
with_expiry: bool,
1010
conn: &mut PgConnection,
11-
) -> Result<Uuid, ApiError> {
11+
) -> Result<Uuid, DatabaseError> {
1212
let token = Uuid::new_v4();
1313
let hash = sha256::digest(token.to_string());
1414
let expiry = {
@@ -28,19 +28,14 @@ pub async fn generate_token(
2828
)
2929
.execute(&mut *conn)
3030
.await
31-
.map_err(|e| {
32-
log::error!(
33-
"Failed to insert auth_token for developer {}: {}",
34-
developer_id,
35-
e
36-
);
37-
ApiError::DbError
31+
.inspect_err(|e| {
32+
log::error!("Failed to insert auth_token for developer {developer_id}: {e}")
3833
})?;
3934

4035
Ok(token)
4136
}
4237

43-
pub async fn remove_token(token: Uuid, conn: &mut PgConnection) -> Result<(), ApiError> {
38+
pub async fn remove_token(token: Uuid, conn: &mut PgConnection) -> Result<(), DatabaseError> {
4439
let hash = sha256::digest(token.to_string());
4540

4641
sqlx::query!(
@@ -50,44 +45,35 @@ pub async fn remove_token(token: Uuid, conn: &mut PgConnection) -> Result<(), Ap
5045
)
5146
.execute(&mut *conn)
5247
.await
53-
.map_err(|e| {
54-
log::error!("Failed to remove auth token: {}", e);
55-
ApiError::DbError
56-
})?;
48+
.inspect_err(|e| log::error!("Failed to remove auth token: {e}"))?;
5749

5850
Ok(())
5951
}
6052

6153
pub async fn remove_developer_tokens(
6254
developer_id: i32,
6355
conn: &mut PgConnection,
64-
) -> Result<(), ApiError> {
56+
) -> Result<(), DatabaseError> {
6557
sqlx::query!(
6658
"DELETE FROM auth_tokens
6759
WHERE developer_id = $1",
6860
developer_id
6961
)
7062
.execute(&mut *conn)
7163
.await
72-
.map_err(|e| {
73-
log::error!("Failed to wipe developer tokens: {}", e);
74-
ApiError::DbError
75-
})?;
64+
.inspect_err(|e| log::error!("Failed to wipe developer tokens: {e}"))?;
7665

7766
Ok(())
7867
}
7968

80-
pub async fn cleanup(conn: &mut PgConnection) -> Result<(), ApiError> {
69+
pub async fn cleanup(conn: &mut PgConnection) -> Result<(), DatabaseError> {
8170
sqlx::query!(
8271
"DELETE FROM auth_tokens
8372
WHERE expires_at < NOW()"
8473
)
85-
.execute(conn)
86-
.await
87-
.map_err(|e| {
88-
log::error!("Auth token cleanup failed: {}", e);
89-
ApiError::DbError
90-
})?;
74+
.execute(conn)
75+
.await
76+
.inspect_err(|e| log::error!("Auth token cleanup failed: {e}"))?;
9177

9278
Ok(())
9379
}

0 commit comments

Comments
 (0)