Skip to content

Commit ab2b32f

Browse files
committed
improve: code restructuring/cleanup
1 parent b54a578 commit ab2b32f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+1023
-1423
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ bon = "3.8"
3232

3333
# Error handling
3434
anyhow = "1.0"
35-
thiserror = "2.0"
35+
snafu = { version = "0.8", features = ["backtrace"] }
3636

3737
# System
3838
num_cpus = "1.16"

crates/inferadb-control-api/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ version.workspace = true
1111

1212
[dependencies]
1313
# Workspace crates
14+
inferadb-control-config = { path = "../inferadb-control-config" }
1415
inferadb-control-const = { path = "../inferadb-control-const" }
1516
inferadb-control-core = { path = "../inferadb-control-core" }
1617
inferadb-control-storage = { path = "../inferadb-control-storage" }

crates/inferadb-control-api/src/audit.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
use inferadb_control_core::{
2-
entities::{AuditEventType, AuditLog, AuditResourceType},
3-
repository::AuditLogRepository,
4-
};
1+
use inferadb_control_core::repository::AuditLogRepository;
2+
use inferadb_control_types::entities::{AuditEventType, AuditLog, AuditResourceType};
53
use serde_json::Value as JsonValue;
64

75
use crate::handlers::AppState;

crates/inferadb-control-api/src/handlers/audit_logs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ pub async fn list_audit_logs(
136136
mod tests {
137137
use std::sync::Arc;
138138

139-
use inferadb_control_core::AuditEventType;
140139
use inferadb_control_storage::Backend;
140+
use inferadb_control_types::entities::AuditEventType;
141141

142142
use super::*;
143143

crates/inferadb-control-api/src/handlers/auth.rs

Lines changed: 26 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,10 @@ use axum::{
99
use axum_extra::extract::cookie::{Cookie, CookieJar, SameSite};
1010
use bon::Builder;
1111
use inferadb_control_const::auth::{SESSION_COOKIE_MAX_AGE, SESSION_COOKIE_NAME};
12-
use inferadb_control_core::{
13-
IdGenerator, RepositoryContext, UserPasswordResetToken, error::Error as CoreError,
14-
hash_password, verify_password,
15-
};
12+
use inferadb_control_core::{IdGenerator, RepositoryContext, hash_password, verify_password};
1613
use inferadb_control_storage::Backend;
1714
use inferadb_control_types::{
15+
Error as CoreError,
1816
dto::{
1917
AuthVerifyEmailRequest, AuthVerifyEmailResponse, ErrorResponse, LoginRequest,
2018
LoginResponse, LogoutResponse, PasswordResetConfirmRequest, PasswordResetConfirmResponse,
@@ -23,7 +21,7 @@ use inferadb_control_types::{
2321
},
2422
entities::{
2523
Organization, OrganizationMember, OrganizationRole, OrganizationTier, SessionType, User,
26-
UserEmail, UserEmailVerificationToken, UserSession,
24+
UserEmail, UserEmailVerificationToken, UserPasswordResetToken, UserSession,
2725
},
2826
};
2927
use time;
@@ -33,7 +31,7 @@ use time;
3331
#[builder(on(Arc<_>, into))]
3432
pub struct AppState {
3533
pub storage: Arc<Backend>,
36-
pub config: Arc<inferadb_control_core::ControlConfig>,
34+
pub config: Arc<inferadb_control_config::ControlConfig>,
3735
pub worker_id: u16,
3836
#[builder(default = std::time::SystemTime::now())]
3937
pub start_time: std::time::SystemTime,
@@ -46,7 +44,7 @@ impl AppState {
4644
/// Create AppState for testing with default configuration
4745
/// This is used by both unit tests and integration tests
4846
pub fn new_test(storage: Arc<Backend>) -> Self {
49-
use inferadb_control_core::ControlConfig;
47+
use inferadb_control_config::ControlConfig;
5048

5149
// Create a minimal test config using builder pattern
5250
// WebAuthnConfig defaults to localhost which is correct for tests
@@ -79,23 +77,9 @@ impl From<CoreError> for ApiError {
7977

8078
impl IntoResponse for ApiError {
8179
fn into_response(self) -> Response {
82-
let (status, error_message) = match self.0 {
83-
CoreError::Config(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg),
84-
CoreError::Storage(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg),
85-
CoreError::Auth(msg) => (StatusCode::UNAUTHORIZED, msg),
86-
CoreError::Authz(msg) => (StatusCode::FORBIDDEN, msg),
87-
CoreError::Validation(msg) => (StatusCode::BAD_REQUEST, msg),
88-
CoreError::NotFound(msg) => (StatusCode::NOT_FOUND, msg),
89-
CoreError::AlreadyExists(msg) => (StatusCode::CONFLICT, msg),
90-
CoreError::RateLimit(msg) => (StatusCode::TOO_MANY_REQUESTS, msg),
91-
CoreError::TierLimit(msg) => (StatusCode::PAYMENT_REQUIRED, msg),
92-
CoreError::TooManyPasskeys { max } => {
93-
(StatusCode::BAD_REQUEST, format!("Too many passkeys registered (maximum: {max})"))
94-
},
95-
CoreError::External(msg) => (StatusCode::BAD_GATEWAY, msg),
96-
CoreError::Internal(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg),
97-
CoreError::Other(err) => (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()),
98-
};
80+
let status =
81+
StatusCode::from_u16(self.0.status_code()).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
82+
let error_message = self.0.to_string();
9983

10084
// Log errors at appropriate levels
10185
if status.is_server_error() {
@@ -127,17 +111,17 @@ pub async fn register(
127111

128112
// Validate inputs
129113
if payload.name.trim().is_empty() {
130-
return Err(CoreError::Validation("Name cannot be empty".to_string()).into());
114+
return Err(CoreError::validation("Name cannot be empty".to_string()).into());
131115
}
132116

133117
if payload.email.trim().is_empty() {
134-
return Err(CoreError::Validation("Email cannot be empty".to_string()).into());
118+
return Err(CoreError::validation("Email cannot be empty".to_string()).into());
135119
}
136120

137121
// Check if email is already in use
138122
if repos.user_email.is_email_in_use(&payload.email).await? {
139123
return Err(
140-
CoreError::Validation(format!("Email '{}' is already in use", payload.email)).into()
124+
CoreError::validation(format!("Email '{}' is already in use", payload.email)).into()
141125
);
142126
}
143127

@@ -279,19 +263,19 @@ pub async fn login(
279263
.user_email
280264
.get_by_email(&payload.email)
281265
.await?
282-
.ok_or_else(|| CoreError::Auth("Invalid email or password".to_string()))?;
266+
.ok_or_else(|| CoreError::auth("Invalid email or password".to_string()))?;
283267

284268
// Get user
285269
let user = repos
286270
.user
287271
.get(email.user_id)
288272
.await?
289-
.ok_or_else(|| CoreError::Auth("Invalid email or password".to_string()))?;
273+
.ok_or_else(|| CoreError::auth("Invalid email or password".to_string()))?;
290274

291275
// Verify password
292276
let password_hash = user
293277
.password_hash
294-
.ok_or_else(|| CoreError::Auth("Password login not available for this user".to_string()))?;
278+
.ok_or_else(|| CoreError::auth("Password login not available for this user".to_string()))?;
295279

296280
verify_password(&payload.password, &password_hash)?;
297281

@@ -357,13 +341,13 @@ pub async fn verify_email(
357341
// Get token
358342
let mut token =
359343
repos.user_email_verification_token.get_by_token(&payload.token).await?.ok_or_else(
360-
|| CoreError::Validation("Invalid or expired verification token".to_string()),
344+
|| CoreError::validation("Invalid or expired verification token".to_string()),
361345
)?;
362346

363347
// Check if token is valid (not expired and not used)
364348
if !token.is_valid() {
365349
return Err(
366-
CoreError::Validation("Invalid or expired verification token".to_string()).into()
350+
CoreError::validation("Invalid or expired verification token".to_string()).into()
367351
);
368352
}
369353

@@ -372,7 +356,7 @@ pub async fn verify_email(
372356
.user_email
373357
.get(token.user_email_id)
374358
.await?
375-
.ok_or_else(|| CoreError::NotFound("Email not found".to_string()))?;
359+
.ok_or_else(|| CoreError::not_found("Email not found".to_string()))?;
376360

377361
// Check if already verified
378362
if email.is_verified() {
@@ -410,13 +394,13 @@ pub async fn request_password_reset(
410394
// Find the email
411395
let email = repos.user_email.get_by_email(&payload.email).await?.ok_or_else(|| {
412396
// Don't reveal whether email exists for security
413-
CoreError::Validation("If the email exists, a reset link will be sent".to_string())
397+
CoreError::validation("If the email exists, a reset link will be sent".to_string())
414398
})?;
415399

416400
// Verify the email is verified and primary
417401
if !email.is_verified() {
418402
return Err(
419-
CoreError::Validation("Email must be verified to reset password".to_string()).into()
403+
CoreError::validation("Email must be verified to reset password".to_string()).into()
420404
);
421405
}
422406

@@ -425,10 +409,10 @@ pub async fn request_password_reset(
425409
.user
426410
.get(email.user_id)
427411
.await?
428-
.ok_or_else(|| CoreError::NotFound("User not found".to_string()))?;
412+
.ok_or_else(|| CoreError::not_found("User not found".to_string()))?;
429413

430414
if user.is_deleted() {
431-
return Err(CoreError::Validation("User account is deleted".to_string()).into());
415+
return Err(CoreError::validation("User account is deleted".to_string()).into());
432416
}
433417

434418
// Generate password reset token
@@ -494,7 +478,7 @@ pub async fn confirm_password_reset(
494478
) -> Result<Json<PasswordResetConfirmResponse>> {
495479
// Validate new password
496480
if payload.new_password.len() < 12 || payload.new_password.len() > 128 {
497-
return Err(CoreError::Validation(
481+
return Err(CoreError::validation(
498482
"Password must be between 12 and 128 characters".to_string(),
499483
)
500484
.into());
@@ -507,22 +491,22 @@ pub async fn confirm_password_reset(
507491
.user_password_reset_token
508492
.get_by_token(&payload.token)
509493
.await?
510-
.ok_or_else(|| CoreError::Validation("Invalid or expired reset token".to_string()))?;
494+
.ok_or_else(|| CoreError::validation("Invalid or expired reset token".to_string()))?;
511495

512496
// Check if token is valid (not expired and not used)
513497
if !token.is_valid() {
514-
return Err(CoreError::Validation("Invalid or expired reset token".to_string()).into());
498+
return Err(CoreError::validation("Invalid or expired reset token".to_string()).into());
515499
}
516500

517501
// Get the user
518502
let mut user = repos
519503
.user
520504
.get(token.user_id)
521505
.await?
522-
.ok_or_else(|| CoreError::NotFound("User not found".to_string()))?;
506+
.ok_or_else(|| CoreError::not_found("User not found".to_string()))?;
523507

524508
if user.is_deleted() {
525-
return Err(CoreError::Validation("User account is deleted".to_string()).into());
509+
return Err(CoreError::validation("User account is deleted".to_string()).into());
526510
}
527511

528512
// Hash the new password

crates/inferadb-control-api/src/handlers/cli_auth.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use chrono::Utc;
99
use inferadb_control_core::{IdGenerator, RepositoryContext};
1010
use inferadb_control_types::{
1111
dto::{CliAuthorizeRequest, CliAuthorizeResponse, CliTokenRequest, CliTokenResponse},
12-
entities::{AuthorizationCode, UserSession},
12+
entities::{AuthorizationCode, SessionType, UserSession},
1313
};
1414

1515
use crate::{handlers::AppState, middleware::session::SessionContext};
@@ -126,7 +126,7 @@ pub async fn cli_token_exchange(
126126
let cli_session = UserSession::builder()
127127
.id(cli_session_id)
128128
.user_id(original_session.user_id)
129-
.session_type(inferadb_control_core::SessionType::Cli)
129+
.session_type(SessionType::Cli)
130130
.user_agent("InferaDB CLI")
131131
.create();
132132

0 commit comments

Comments
 (0)