diff --git a/app-service/Dockerfile b/app-service/Dockerfile index 66b518bda..7c647dc7f 100644 --- a/app-service/Dockerfile +++ b/app-service/Dockerfile @@ -1,10 +1,8 @@ # Start with image that has the Rust toolchain installed -FROM rust:1.90-alpine AS chef +FROM rust:1.91-alpine AS chef USER root # Add cargo-chef to cache dependencies -RUN apk add --no-cache musl-dev -RUN rustup update stable -RUN cargo install cargo-chef --locked +RUN apk add --no-cache musl-dev && cargo install cargo-chef --locked WORKDIR /app FROM chef AS planner @@ -27,4 +25,4 @@ WORKDIR /app COPY --from=builder /app/target/release/app-service /usr/local/bin COPY --from=builder /app/assets /app/assets ENV AUTH_SERVICE_HOST_NAME=auth-service -ENTRYPOINT ["/usr/local/bin/app-service"] \ No newline at end of file +ENTRYPOINT ["/usr/local/bin/app-service"] diff --git a/auth-service/Dockerfile b/auth-service/Dockerfile index 4daaea84e..62e07d225 100644 --- a/auth-service/Dockerfile +++ b/auth-service/Dockerfile @@ -1,10 +1,8 @@ # Start with image that has the Rust toolchain installed -FROM rust:1.90-alpine AS chef +FROM rust:1.91-alpine AS chef USER root # Add cargo-chef to cache dependencies -RUN apk add --no-cache musl-dev -RUN rustup update stable -RUN cargo install cargo-chef --locked +RUN apk add --no-cache musl-dev && cargo install cargo-chef --locked WORKDIR /app FROM chef AS planner @@ -28,4 +26,4 @@ WORKDIR /app COPY --from=builder /app/target/release/auth-service /usr/local/bin COPY --from=builder /app/assets /app/assets ENV REDIS_HOST_NAME=redis -ENTRYPOINT ["/usr/local/bin/auth-service"] \ No newline at end of file +ENTRYPOINT ["/usr/local/bin/auth-service"] diff --git a/auth-service/src/routes/login.rs b/auth-service/src/routes/login.rs index af8f735b5..8f8fa1a46 100644 --- a/auth-service/src/routes/login.rs +++ b/auth-service/src/routes/login.rs @@ -14,15 +14,15 @@ pub async fn login( State(state): State, jar: CookieJar, Json(request): Json, -) -> (CookieJar, Result) { +) -> Result<(CookieJar, impl IntoResponse), AuthAPIError> { match HashedPassword::parse(request.password.clone()).await { Ok(password) => password, - Err(_) => return (jar, Err(AuthAPIError::InvalidCredentials)), + Err(_) => return Err(AuthAPIError::InvalidCredentials), }; let email = match Email::parse(request.email) { Ok(email) => email, - Err(_) => return (jar, Err(AuthAPIError::InvalidCredentials)), + Err(_) => return Err(AuthAPIError::InvalidCredentials), }; let user_store = &state.user_store.read().await; @@ -32,12 +32,12 @@ pub async fn login( .await .is_err() { - return (jar, Err(AuthAPIError::IncorrectCredentials)); + return Err(AuthAPIError::IncorrectCredentials); } let user = match user_store.get_user(&email).await { Ok(user) => user, - Err(_) => return (jar, Err(AuthAPIError::IncorrectCredentials)), + Err(_) => return Err(AuthAPIError::IncorrectCredentials), }; match user.requires_2fa { @@ -51,10 +51,7 @@ async fn handle_2fa( email: &Email, state: &AppState, jar: CookieJar, -) -> ( - CookieJar, - Result<(StatusCode, Json), AuthAPIError>, -) { +) -> Result<(CookieJar, (StatusCode, Json)), AuthAPIError> { let login_attempt_id = LoginAttemptId::default(); let two_fa_code = TwoFACode::default(); @@ -65,7 +62,7 @@ async fn handle_2fa( .add_code(email.clone(), login_attempt_id.clone(), two_fa_code.clone()) .await { - return (jar, Err(AuthAPIError::UnexpectedError(e.into()))); + return Err(AuthAPIError::UnexpectedError(e.into())); } if let Err(e) = state @@ -73,7 +70,7 @@ async fn handle_2fa( .send_email(email, "2FA Code", two_fa_code.as_ref().expose_secret()) .await { - return (jar, Err(AuthAPIError::UnexpectedError(e))); + return Err(AuthAPIError::UnexpectedError(e)); } let response = Json(LoginResponse::TwoFactorAuth(TwoFactorAuthResponse { @@ -81,28 +78,25 @@ async fn handle_2fa( login_attempt_id: login_attempt_id.as_ref().expose_secret().to_owned(), })); - (jar, Ok((StatusCode::PARTIAL_CONTENT, response))) + Ok((jar, (StatusCode::PARTIAL_CONTENT, response))) } #[tracing::instrument(name = "Handle non-2FA flow", skip_all)] async fn handle_no_2fa( email: &Email, jar: CookieJar, -) -> ( - CookieJar, - Result<(StatusCode, Json), AuthAPIError>, -) { +) -> Result<(CookieJar, (StatusCode, Json)), AuthAPIError> { let auth_cookie = match generate_auth_cookie(email) { Ok(cookie) => cookie, - Err(e) => return (jar, Err(AuthAPIError::UnexpectedError(e))), + Err(e) => return Err(AuthAPIError::UnexpectedError(e)), }; let updated_jar = jar.add(auth_cookie); - ( + Ok(( updated_jar, - Ok((StatusCode::OK, Json(LoginResponse::RegularAuth))), - ) + (StatusCode::OK, Json(LoginResponse::RegularAuth)), + )) } #[derive(Deserialize)] diff --git a/auth-service/src/routes/logout.rs b/auth-service/src/routes/logout.rs index a10e16710..7abb3ab54 100644 --- a/auth-service/src/routes/logout.rs +++ b/auth-service/src/routes/logout.rs @@ -12,17 +12,17 @@ use crate::{ pub async fn logout( State(state): State, jar: CookieJar, -) -> (CookieJar, Result) { +) -> Result<(CookieJar, impl IntoResponse), AuthAPIError> { let cookie = match jar.get(JWT_COOKIE_NAME) { Some(cookie) => cookie, - None => return (jar, Err(AuthAPIError::MissingToken)), + None => return Err(AuthAPIError::MissingToken), }; // Validate token let token = SecretString::new(cookie.value().to_owned().into_boxed_str()); let _ = match validate_token(&token, state.banned_token_store.clone()).await { Ok(claims) => claims, - Err(_) => return (jar, Err(AuthAPIError::InvalidToken)), + Err(_) => return Err(AuthAPIError::InvalidToken), }; // Add token to banned list @@ -33,11 +33,11 @@ pub async fn logout( .add_token(token.to_owned()) .await { - return (jar, Err(AuthAPIError::UnexpectedError(e.into()))); + return Err(AuthAPIError::UnexpectedError(e.into())); } // Remove jwt cookie let jar = jar.remove(cookie::Cookie::from(JWT_COOKIE_NAME)); - (jar, Ok(StatusCode::OK)) + Ok((jar, StatusCode::OK)) } diff --git a/auth-service/src/routes/verify_2fa.rs b/auth-service/src/routes/verify_2fa.rs index 6d0abed8a..cc55ee8a0 100644 --- a/auth-service/src/routes/verify_2fa.rs +++ b/auth-service/src/routes/verify_2fa.rs @@ -14,45 +14,45 @@ pub async fn verify_2fa( State(state): State, jar: CookieJar, Json(request): Json, -) -> (CookieJar, Result) { +) -> Result<(CookieJar, impl IntoResponse), AuthAPIError> { let email = match Email::parse(request.email.clone()) { Ok(email) => email, - Err(_) => return (jar, Err(AuthAPIError::InvalidCredentials)), + Err(_) => return Err(AuthAPIError::InvalidCredentials), }; let login_attempt_id = match LoginAttemptId::parse(request.login_attempt_id.clone()) { Ok(login_attempt_id) => login_attempt_id, - Err(_) => return (jar, Err(AuthAPIError::InvalidCredentials)), + Err(_) => return Err(AuthAPIError::InvalidCredentials), }; let two_fa_code = match TwoFACode::parse(request.two_fa_code) { Ok(two_fa_code) => two_fa_code, - Err(_) => return (jar, Err(AuthAPIError::InvalidCredentials)), + Err(_) => return Err(AuthAPIError::InvalidCredentials), }; let mut two_fa_code_store = state.two_fa_code_store.write().await; let code_tuple = match two_fa_code_store.get_code(&email).await { Ok(code_tuple) => code_tuple, - Err(_) => return (jar, Err(AuthAPIError::IncorrectCredentials)), + Err(_) => return Err(AuthAPIError::IncorrectCredentials), }; if !code_tuple.0.eq(&login_attempt_id) || !code_tuple.1.eq(&two_fa_code) { - return (jar, Err(AuthAPIError::IncorrectCredentials)); + return Err(AuthAPIError::IncorrectCredentials); } if let Err(e) = two_fa_code_store.remove_code(&email).await { - return (jar, Err(AuthAPIError::UnexpectedError(e.into()))); + return Err(AuthAPIError::UnexpectedError(e.into())); } let cookie = match generate_auth_cookie(&email) { Ok(cookie) => cookie, - Err(e) => return (jar, Err(AuthAPIError::UnexpectedError(e))), + Err(e) => return Err(AuthAPIError::UnexpectedError(e)), }; let updated_jar = jar.add(cookie); - (updated_jar, Ok(())) + Ok((updated_jar, ())) } #[derive(Debug, Deserialize)]