Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions app-service/Dockerfile
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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"]
ENTRYPOINT ["/usr/local/bin/app-service"]
8 changes: 3 additions & 5 deletions auth-service/Dockerfile
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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"]
ENTRYPOINT ["/usr/local/bin/auth-service"]
34 changes: 14 additions & 20 deletions auth-service/src/routes/login.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ pub async fn login(
State(state): State<AppState>,
jar: CookieJar,
Json(request): Json<LoginRequest>,
) -> (CookieJar, Result<impl IntoResponse, AuthAPIError>) {
) -> 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;
Expand All @@ -30,12 +30,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 {
Expand All @@ -48,10 +48,7 @@ async fn handle_2fa(
email: &Email,
state: &AppState,
jar: CookieJar,
) -> (
CookieJar,
Result<(StatusCode, Json<LoginResponse>), AuthAPIError>,
) {
) -> Result<(CookieJar, (StatusCode, Json<LoginResponse>)), AuthAPIError> {
let login_attempt_id = LoginAttemptId::default();
let two_fa_code = TwoFACode::default();

Expand All @@ -63,7 +60,7 @@ async fn handle_2fa(
.await
.is_err()
{
return (jar, Err(AuthAPIError::UnexpectedError));
return Err(AuthAPIError::UnexpectedError);
}

if state
Expand All @@ -72,35 +69,32 @@ async fn handle_2fa(
.await
.is_err()
{
return (jar, Err(AuthAPIError::UnexpectedError));
return Err(AuthAPIError::UnexpectedError);
}

let response = Json(LoginResponse::TwoFactorAuth(TwoFactorAuthResponse {
message: "2FA required".to_owned(),
login_attempt_id: login_attempt_id.as_ref().to_owned(),
}));

(jar, Ok((StatusCode::PARTIAL_CONTENT, response)))
Ok((jar, (StatusCode::PARTIAL_CONTENT, response)))
}

async fn handle_no_2fa(
email: &Email,
jar: CookieJar,
) -> (
CookieJar,
Result<(StatusCode, Json<LoginResponse>), AuthAPIError>,
) {
) -> Result<(CookieJar, (StatusCode, Json<LoginResponse>)), AuthAPIError> {
let auth_cookie = match generate_auth_cookie(email) {
Ok(cookie) => cookie,
Err(_) => return (jar, Err(AuthAPIError::UnexpectedError)),
Err(_) => return Err(AuthAPIError::UnexpectedError),
};

let updated_jar = jar.add(auth_cookie);

(
Ok((
updated_jar,
Ok((StatusCode::OK, Json(LoginResponse::RegularAuth))),
)
(StatusCode::OK, Json(LoginResponse::RegularAuth)),
))
}

#[derive(Deserialize)]
Expand Down
10 changes: 5 additions & 5 deletions auth-service/src/routes/logout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ use crate::{
pub async fn logout(
State(state): State<AppState>,
jar: CookieJar,
) -> (CookieJar, Result<impl IntoResponse, AuthAPIError>) {
) -> 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 = cookie.value().to_owned();
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
Expand All @@ -32,11 +32,11 @@ pub async fn logout(
.await
.is_err()
{
return (jar, Err(AuthAPIError::UnexpectedError));
return Err(AuthAPIError::UnexpectedError);
}

// Remove jwt cookie
let jar = jar.remove(cookie::Cookie::from(JWT_COOKIE_NAME));

(jar, Ok(StatusCode::OK))
Ok((jar, StatusCode::OK))
}
18 changes: 9 additions & 9 deletions auth-service/src/routes/verify_2fa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,45 +12,45 @@ pub async fn verify_2fa(
State(state): State<AppState>,
jar: CookieJar,
Json(request): Json<Verify2FARequest>,
) -> (CookieJar, Result<impl IntoResponse, AuthAPIError>) {
) -> 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 two_fa_code_store.remove_code(&email).await.is_err() {
return (jar, Err(AuthAPIError::UnexpectedError));
return Err(AuthAPIError::UnexpectedError);
}

let cookie = match generate_auth_cookie(&email) {
Ok(cookie) => cookie,
Err(_) => return (jar, Err(AuthAPIError::UnexpectedError)),
Err(_) => return Err(AuthAPIError::UnexpectedError),
};

let updated_jar = jar.add(cookie);

(updated_jar, Ok(()))
Ok((updated_jar, ()))
}

#[derive(Debug, Deserialize)]
Expand Down