Microservice to bring 2FA to self hosted PDSes

logging

authored by baileytownsend.dev and committed by Tangled 01148f8a 94e9b2ee

Changed files
+29 -11
src
+29 -11
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 sqlx::Error; 14 + use sqlx::sqlite::SqliteQueryResult; 13 15 use tracing::log; 14 16 15 17 #[derive(Serialize, Deserialize, Debug, Clone)] ··· 155 157 // Email update asked for 156 158 if email_auth_update { 157 159 let email = payload.email.clone(); 158 - let email_confirmed = sqlx::query_as::<_, (String,)>( 160 + let email_confirmed = match sqlx::query_as::<_, (String,)>( 159 161 "SELECT did FROM account WHERE emailConfirmedAt IS NOT NULL AND email = ?", 160 162 ) 161 163 .bind(&email) 162 164 .fetch_optional(&state.account_pool) 163 165 .await 164 - .map_err(|_| StatusCode::BAD_REQUEST)?; 166 + { 167 + Ok(row) => row, 168 + Err(err) => { 169 + log::error!("Error checking if email is confirmed: {err}"); 170 + return Err(StatusCode::BAD_REQUEST); 171 + } 172 + }; 165 173 166 174 //Since the email is already confirmed we can enable 2fa 167 175 return match email_confirmed { ··· 184 192 if !email_auth_update && !email_auth_not_set { 185 193 //User wants auth turned off and has a token 186 194 if let Some(token) = &payload.token { 187 - let token_found = sqlx::query_as::<_, (String,)>( 195 + let token_found = match sqlx::query_as::<_, (String,)>( 188 196 "SELECT token FROM email_token WHERE token = ? AND did = ? AND purpose = 'update_email'", 189 197 ) 190 198 .bind(token) 191 199 .bind(&did.0) 192 200 .fetch_optional(&state.account_pool) 193 - .await 194 - .map_err(|_| StatusCode::BAD_REQUEST)?; 201 + .await{ 202 + Ok(token) => token, 203 + Err(err) => { 204 + log::error!("Error checking if token is valid: {err}"); 205 + return Err(StatusCode::BAD_REQUEST); 206 + } 207 + }; 195 208 196 209 return if token_found.is_some() { 197 - let _ = sqlx::query( 210 + //TODO I think there may be a bug here and need to do some retry logic 211 + // First try was erroring, seconds was allowing 212 + match sqlx::query( 198 213 "INSERT INTO two_factor_accounts (did, required) VALUES (?, 0) ON CONFLICT(did) DO UPDATE SET required = 0", 199 214 ) 200 215 .bind(&did.0) 201 216 .execute(&state.pds_gatekeeper_pool) 202 - .await 203 - .map_err(|_| StatusCode::BAD_REQUEST)?; 217 + .await { 218 + Ok(_) => {} 219 + Err(err) => { 220 + log::error!("Error updating email auth: {err}"); 221 + return Err(StatusCode::BAD_REQUEST); 222 + } 223 + } 204 224 205 225 Ok(StatusCode::OK.into_response()) 206 226 } else { ··· 275 295 ); 276 296 277 297 // Rewrite the URI to point at the upstream PDS; keep headers, method, and body intact 278 - *req.uri_mut() = uri 279 - .parse() 280 - .map_err(|_| StatusCode::BAD_REQUEST)?; 298 + *req.uri_mut() = uri.parse().map_err(|_| StatusCode::BAD_REQUEST)?; 281 299 282 300 let proxied = state 283 301 .reverse_proxy_client