fix session authentication

This commit is contained in:
c0repwn3r 2023-02-06 10:17:48 -05:00
parent 75ab376ebd
commit e79ee4c6c5
Signed by: core
GPG Key ID: FDBF740DADDCEECF
5 changed files with 24 additions and 11 deletions

View File

@ -14,7 +14,7 @@ pub struct PartialUserInfo {
#[derive(Debug)]
pub enum AuthenticationError {
MissingToken,
InvalidToken,
InvalidToken(usize),
DatabaseError,
RequiresTOTP
}
@ -31,16 +31,16 @@ impl<'r> FromRequest<'r> for PartialUserInfo {
// parse bearer token
let components = authorization.split(' ').collect::<Vec<&str>>();
if components.len() != 2 || components.len() != 3 {
if components.len() != 2 && components.len() != 3 {
return Outcome::Failure((Status::Unauthorized, AuthenticationError::MissingToken));
}
if components[0] != "Bearer" {
return Outcome::Failure((Status::Unauthorized, AuthenticationError::InvalidToken));
return Outcome::Failure((Status::Unauthorized, AuthenticationError::InvalidToken(0)));
}
if components.len() == 2 && components[1].starts_with("st-") {
return Outcome::Failure((Status::Unauthorized, AuthenticationError::InvalidToken));
if components.len() == 2 && !components[1].starts_with("st-") {
return Outcome::Failure((Status::Unauthorized, AuthenticationError::InvalidToken(1)));
}
let st: String;
@ -53,10 +53,10 @@ impl<'r> FromRequest<'r> for PartialUserInfo {
st = components[1].to_string();
match validate_session_token(st.clone(), req.rocket().state().unwrap()).await {
Ok(uid) => user_id = uid,
Err(_) => return Outcome::Failure((Status::Unauthorized, AuthenticationError::InvalidToken))
Err(_) => return Outcome::Failure((Status::Unauthorized, AuthenticationError::InvalidToken(2)))
}
},
_ => return Outcome::Failure((Status::Unauthorized, AuthenticationError::InvalidToken))
_ => return Outcome::Failure((Status::Unauthorized, AuthenticationError::InvalidToken(3)))
}
if components.len() == 3 {
@ -66,10 +66,10 @@ impl<'r> FromRequest<'r> for PartialUserInfo {
at = Some(components[2].to_string());
match validate_auth_token(at.clone().unwrap().clone(), st.clone(), req.rocket().state().unwrap()).await {
Ok(_) => (),
Err(_) => return Outcome::Failure((Status::Unauthorized, AuthenticationError::InvalidToken))
Err(_) => return Outcome::Failure((Status::Unauthorized, AuthenticationError::InvalidToken(4)))
}
},
_ => return Outcome::Failure((Status::Unauthorized, AuthenticationError::InvalidToken))
_ => return Outcome::Failure((Status::Unauthorized, AuthenticationError::InvalidToken(5)))
}
} else {
at = None;

View File

@ -81,7 +81,10 @@ async fn main() -> Result<(), Box<dyn Error>> {
.mount("/", routes![
crate::routes::v1::auth::magic_link::magiclink_request,
crate::routes::v1::signup::signup_request,
crate::routes::v1::auth::verify_magic_link::verify_magic_link
crate::routes::v1::auth::verify_magic_link::verify_magic_link,
crate::routes::v1::auth::check_auth,
])
.register("/", catchers![
crate::routes::handler_400,

View File

@ -1,2 +1,4 @@
use crate::auth::PartialUserInfo;
pub mod verify_magic_link;
pub mod magic_link;

View File

@ -53,6 +53,14 @@ pub async fn verify_magic_link(req: Json<VerifyMagicLinkRequest>, db: &State<PgP
}
};
// delete the token
match sqlx::query!("DELETE FROM magic_links WHERE id = $1", req.0.magic_link_token).execute(db.inner()).await {
Ok(_) => (),
Err(e) => {
return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"{}\",\"message\":\"{} - {}\"}}]}}", "ERR_UNABLE_TO_ISSUE", "an error occured trying to issue a session token, please try again later", e)))
}
}
Ok((ContentType::JSON, Json(VerifyMagicLinkResponse {
data: VerifyMagicLinkResponseData { session_token: token },
metadata: VerifyMagicLinkResponseMetadata {},

View File

@ -22,7 +22,7 @@ pub async fn generate_session_token(user_id: i64, db: &PgPool, config: &TFConfig
Ok(token)
}
pub async fn validate_session_token(token: String, db: &PgPool) -> Result<i64, Box<dyn Error>> {
Ok(sqlx::query!("SELECT user_id FROM session_tokens WHERE id = $1 AND expires_on < $2", token, SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i32).fetch_one(db).await?.user_id as i64)
Ok(sqlx::query!("SELECT user_id FROM session_tokens WHERE id = $1 AND expires_on > $2", token, SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as i32).fetch_one(db).await?.user_id as i64)
}
pub async fn generate_auth_token(user_id: i64, session_id: String, db: &PgPool, config: &TFConfig) -> Result<String, Box<dyn Error>> {