Initial commit: VRBattles API

This commit is contained in:
root
2026-01-20 05:41:25 +00:00
commit c26a1820d5
42 changed files with 6187 additions and 0 deletions

91
src/auth/jwt.rs Normal file
View File

@@ -0,0 +1,91 @@
use chrono::{Duration, Utc};
use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};
use crate::error::{AppError, Result};
/// JWT Claims structure
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Claims {
/// Subject (user ID)
pub sub: i32,
/// User's email
pub email: String,
/// Username
pub username: String,
/// Is admin flag
pub is_admin: bool,
/// Expiration time (Unix timestamp)
pub exp: i64,
/// Issued at time (Unix timestamp)
pub iat: i64,
}
impl Claims {
/// Create new claims for a user
pub fn new(user_id: i32, email: &str, username: &str, is_admin: bool, expiration_hours: i64) -> Self {
let now = Utc::now();
let exp = now + Duration::hours(expiration_hours);
Claims {
sub: user_id,
email: email.to_string(),
username: username.to_string(),
is_admin,
exp: exp.timestamp(),
iat: now.timestamp(),
}
}
/// Get the user ID from claims
pub fn user_id(&self) -> i32 {
self.sub
}
}
/// Create a JWT token for a user
pub fn create_token(
user_id: i32,
email: &str,
username: &str,
is_admin: bool,
secret: &str,
expiration_hours: i64,
) -> Result<String> {
let claims = Claims::new(user_id, email, username, is_admin, expiration_hours);
encode(
&Header::default(),
&claims,
&EncodingKey::from_secret(secret.as_bytes()),
)
.map_err(|e| AppError::Internal(format!("Failed to create token: {}", e)))
}
/// Decode and validate a JWT token
pub fn decode_token(token: &str, secret: &str) -> Result<Claims> {
let token_data = decode::<Claims>(
token,
&DecodingKey::from_secret(secret.as_bytes()),
&Validation::default(),
)?;
Ok(token_data.claims)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_and_decode_token() {
let secret = "test_secret_key_123";
let token = create_token(1, "test@example.com", "testuser", false, secret, 24).unwrap();
let claims = decode_token(&token, secret).unwrap();
assert_eq!(claims.sub, 1);
assert_eq!(claims.email, "test@example.com");
assert_eq!(claims.username, "testuser");
assert!(!claims.is_admin);
}
}