basic_workflow/
basic_workflow.rs

1// examples/basic_usage.rs
2
3use base64::prelude::*;
4use ecdsa_jwt::{
5    auth::{AuthRequest, AuthService},
6    config::JwtConfig,
7};
8use secrecy::Secret;
9use std::collections::HashMap;
10
11fn main() -> Result<(), Box<dyn std::error::Error>> {
12    println!("ECDSA-JWT Basic Usage Example");
13
14    // 1. Setup authentication service
15    let jwt_config = JwtConfig {
16        secret: Secret::new(BASE64_STANDARD.encode("example-secret-key")),
17        ttl: 3600, // 1 hour
18    };
19    let auth_service = AuthService::new(jwt_config);
20
21    // 2. Simulate challenge storage (in real app, use Redis/DB)
22    let mut challenges: HashMap<String, String> = HashMap::new();
23
24    // 3. Generate challenge
25    let challenge = auth_service.generate_challenge();
26    let session_id = "example-session-123";
27    challenges.insert(session_id.to_string(), challenge.clone());
28
29    println!("Generated challenge: {challenge}");
30    println!("Stored with session ID: {session_id}");
31
32    // 4. Simulate client authentication (this would normally fail without real signature)
33    println!("\n Authentication attempt...");
34
35    let auth_request = AuthRequest {
36        challenge,
37        signature: "dummy-signature-for-example".to_string(),
38        public_key: "-----BEGIN PUBLIC KEY-----\nDummyKeyForExample\n-----END PUBLIC KEY-----"
39            .to_string(),
40    };
41
42    // This will fail, but demonstrates the API structure
43    match auth_service.authenticate(auth_request, false) {
44        Ok(response) => {
45            println!("Authentication successful!");
46            println!("   JWT Token: {}", response.session_token);
47            println!("   Session ID: {}", response.session_id);
48            println!("   Expires at: {}", response.expires_at);
49        }
50        Err(e) => {
51            println!(" Authentication failed (expected with dummy data): {e}");
52            println!("   In real usage, provide valid signature and public key.");
53        }
54    }
55
56    // 5. Demonstrate JWT validation with a real token
57    println!("\nJWT Token Operations...");
58
59    let session_id = uuid::Uuid::new_v4();
60    let jwt_token = ecdsa_jwt::crypto::jwt::create_jwt(session_id, None, &auth_service.jwt_config)?;
61
62    println!("Created JWT: {}...", &jwt_token[..50]);
63
64    match auth_service.validate_session(&jwt_token) {
65        Ok(claims) => {
66            println!("Token validation successful!");
67            println!("User/Session ID: {}", claims.sub);
68            println!("Issued at: {}", claims.iat);
69            println!("Expires at: {}", claims.exp);
70        }
71        Err(e) => {
72            println!("Token validation failed: {e}");
73        }
74    }
75
76    println!("\nExample completed! Check the documentation for real implementation details.");
77    Ok(())
78}
79
80#[cfg(test)]
81mod tests {
82    use super::*;
83
84    #[test]
85    fn test_example_runs() {
86        // Test that the example runs without panicking
87        main().unwrap();
88    }
89
90    #[test]
91    fn test_challenge_generation() {
92        let jwt_config = JwtConfig {
93            secret: Secret::new(BASE64_STANDARD.encode("test-secret")),
94            ttl: 3600,
95        };
96        let auth_service = AuthService::new(jwt_config);
97
98        let challenge = auth_service.generate_challenge();
99        assert!(!challenge.is_empty());
100
101        // Challenge should be base64 encoded 32 bytes
102        let decoded = BASE64_STANDARD.decode(&challenge).unwrap();
103        assert_eq!(decoded.len(), 32);
104    }
105}