Microservice to bring 2FA to self hosted PDSes

Started better error handling. DOES NOT BUILD

Changed files
+57 -43
src
+56 -42
src/xrpc/com_atproto_server.rs
··· 10 10 use axum::{Extension, Json, debug_handler, extract, extract::Request}; 11 11 use serde::{Deserialize, Serialize}; 12 12 use serde_json; 13 + use tracing::log; 13 14 14 15 #[derive(Serialize, Deserialize, Debug, Clone)] 15 16 #[serde(rename_all = "camelCase")] ··· 68 69 let auth_factor_token = payload.auth_factor_token.clone(); 69 70 70 71 // Run the shared pre-auth logic to validate and check 2FA requirement 71 - match preauth_check(&state, &identifier, &password, auth_factor_token).await? { 72 - AuthResult::WrongIdentityOrPassword => json_error_response( 73 - StatusCode::UNAUTHORIZED, 74 - "AuthenticationRequired", 75 - "Invalid identifier or password", 76 - ), 77 - AuthResult::TwoFactorRequired => { 78 - // Email sending step can be handled here if needed in the future. 79 - json_error_response( 72 + match preauth_check(&state, &identifier, &password, auth_factor_token).await { 73 + Ok(result) => match result { 74 + AuthResult::WrongIdentityOrPassword => json_error_response( 80 75 StatusCode::UNAUTHORIZED, 81 - "AuthFactorTokenRequired", 82 - "A sign in code has been sent to your email address", 83 - ) 84 - } 85 - AuthResult::ProxyThrough => { 86 - //No 2FA or already passed 87 - let uri = format!( 88 - "{}{}", 89 - state.pds_base_url, "/xrpc/com.atproto.server.createSession" 90 - ); 91 - 92 - let mut req = axum::http::Request::post(uri); 93 - if let Some(req_headers) = req.headers_mut() { 94 - req_headers.extend(headers.clone()); 76 + "AuthenticationRequired", 77 + "Invalid identifier or password", 78 + ), 79 + AuthResult::TwoFactorRequired => { 80 + // Email sending step can be handled here if needed in the future. 81 + json_error_response( 82 + StatusCode::UNAUTHORIZED, 83 + "AuthFactorTokenRequired", 84 + "A sign in code has been sent to your email address", 85 + ) 95 86 } 87 + AuthResult::ProxyThrough => { 88 + //No 2FA or already passed 89 + let uri = format!( 90 + "{}{}", 91 + state.pds_base_url, "/xrpc/com.atproto.server.createSession" 92 + ); 96 93 97 - let payload_bytes = 98 - serde_json::to_vec(&payload).map_err(|_| StatusCode::BAD_REQUEST)?; 99 - let req = req 100 - .body(Body::from(payload_bytes)) 101 - .map_err(|_| StatusCode::BAD_REQUEST)?; 94 + let mut req = axum::http::Request::post(uri); 95 + if let Some(req_headers) = req.headers_mut() { 96 + req_headers.extend(headers.clone()); 97 + } 102 98 103 - let proxied = state 104 - .reverse_proxy_client 105 - .request(req) 106 - .await 107 - .map_err(|_| StatusCode::BAD_REQUEST)? 108 - .into_response(); 99 + let payload_bytes = 100 + serde_json::to_vec(&payload).map_err(|_| StatusCode::BAD_REQUEST)?; 101 + let req = req 102 + .body(Body::from(payload_bytes)) 103 + .map_err(|_| StatusCode::BAD_REQUEST)?; 104 + 105 + let proxied = state 106 + .reverse_proxy_client 107 + .request(req) 108 + .await 109 + .map_err(|_| StatusCode::BAD_REQUEST)? 110 + .into_response(); 109 111 110 - Ok(proxied) 111 - } 112 - AuthResult::TokenCheckFailed(err) => match err { 113 - TokenCheckError::InvalidToken => { 114 - json_error_response(StatusCode::BAD_REQUEST, "InvalidToken", "Token is invalid") 112 + Ok(proxied) 115 113 } 116 - TokenCheckError::ExpiredToken => { 117 - json_error_response(StatusCode::BAD_REQUEST, "ExpiredToken", "Token is expired") 118 - } 114 + AuthResult::TokenCheckFailed(err) => match err { 115 + TokenCheckError::InvalidToken => { 116 + json_error_response(StatusCode::BAD_REQUEST, "InvalidToken", "Token is invalid") 117 + } 118 + TokenCheckError::ExpiredToken => { 119 + json_error_response(StatusCode::BAD_REQUEST, "ExpiredToken", "Token is expired") 120 + } 121 + }, 119 122 }, 123 + Err(err) => { 124 + log::error!( 125 + "Error during pre-auth check. This happens on the create_session endpoint when trying to decide if the user has access\n {}", 126 + err 127 + ); 128 + json_error_response( 129 + StatusCode::INTERNAL_SERVER_ERROR, 130 + "InternalServerError", 131 + "This error was not generated by the PDS, but PDS Gatekeeper. Please contact your PDS administrator for help and for them to review the server logs.", 132 + ) 133 + } 120 134 } 121 135 } 122 136
+1 -1
src/xrpc/helpers.rs
··· 181 181 identifier: &str, 182 182 password: &str, 183 183 two_factor_code: Option<String>, 184 - ) -> Result<AuthResult, StatusCode> { 184 + ) -> anyhow::Result<AuthResult> { 185 185 // Determine identifier type 186 186 let id_type = IdentifierType::what_is_it(identifier.to_string()); 187 187