use crate::auth::auth_state::{AuthState, AuthToken};
use crate::auth::jwt::{get_jwt_secret, validate_and_decode_jwt};
use crate::errors::*;
#[derive(Debug, Clone, Copy)]
pub enum AuthBlockLevel {
AllowAll,
BlockUnauthenticated,
AllowMissing,
}
pub fn get_token_state_from_header(
auth_header: Option<&str>,
secret_str: String,
) -> Result<AuthState> {
let bearer_token = match auth_header {
Some(header) => header
.split("Bearer")
.collect::<Vec<&str>>()
.get(1) .map(|token| token.trim()),
None => None,
};
match bearer_token {
Some(token) => {
let jwt_secret = get_jwt_secret(secret_str)?;
let decoded_jwt = validate_and_decode_jwt(&token, &jwt_secret);
match decoded_jwt {
Some(claims) => Ok(AuthState::Authorised(AuthToken(claims))),
None => Ok(AuthState::InvalidToken), }
}
None => Ok(AuthState::NoToken), }
}
#[derive(Clone, Debug)]
pub enum AuthVerdict {
Allow(AuthState),
Block,
Error(String),
}
pub fn get_auth_verdict(
token_state: Result<AuthState>,
block_state: AuthBlockLevel,
) -> AuthVerdict {
match token_state {
Ok(token_state @ AuthState::Authorised(_)) => AuthVerdict::Allow(token_state),
Ok(token_state @ AuthState::InvalidToken) => {
if let AuthBlockLevel::AllowAll = block_state {
AuthVerdict::Allow(token_state)
} else {
AuthVerdict::Block
}
}
Ok(token_state @ AuthState::NoToken) => {
if let AuthBlockLevel::AllowAll | AuthBlockLevel::AllowMissing = block_state {
AuthVerdict::Allow(token_state)
} else {
AuthVerdict::Block
}
}
Err(err) => AuthVerdict::Error(err.to_string()),
}
}