JWT-based authentication with role-based access control
Faculty Bot uses JWT (JSON Web Tokens) for stateless authentication with role-based access control. Tokens are stored in HTTP-only cookies and validated on every request.
pub fn create_token(&self, role: Roles) -> String { let secret_key = std::env::var("SECRET_KEY") .expect("SECRET_KEY must be set"); let key: Hmac<Sha256> = Hmac::new_from_slice(secret_key.as_bytes()) .expect("HMAC can take key of any size"); let mut claims = BTreeMap::new(); claims.insert("id", self.id); claims.insert("exp", chrono::Utc::now().timestamp() as u64 + 86400); // 24h claims.insert("iat", chrono::Utc::now().timestamp() as u64); claims.insert("role", role as u64); claims.sign_with_key(&key).unwrap()}
pub fn verify_token(token: &str) -> bool { let secret_key = std::env::var("SECRET_KEY") .expect("SECRET_KEY must be set"); let key: Hmac<Sha256> = Hmac::new_from_slice(secret_key.as_bytes()) .expect("HMAC can take key of any size"); token.verify_with_key(&key) .ok() .and_then(|claims: BTreeMap<String, u64>| { let exp = claims.get("exp")?; let current_time = chrono::Utc::now().timestamp() as u64; if current_time > *exp || !claims.contains_key("id") { None } else { Some(true) } }) .unwrap_or(false)}
pub fn user_has_role(token: &str, role: Roles) -> bool { let secret_key = std::env::var("SECRET_KEY") .expect("SECRET_KEY must be set"); let key: Hmac<Sha256> = Hmac::new_from_slice(secret_key.as_bytes()) .expect("HMAC can take key of any size"); token.verify_with_key(&key) .ok() .and_then(|claims: BTreeMap<String, u64>| { let exp = claims.get("exp")?; let role_claim = claims.get("role")?; let current_time = chrono::Utc::now().timestamp() as u64; if current_time > *exp { None } else if role_claim >= &(role as u64) { Some(true) } else { None } }) .unwrap_or(false)}
Role checking uses >= comparison, so Admin role (3) will pass checks for User role (1).