this repo has no description
1use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD};
2use bspds::auth;
3use chrono::{Duration, Utc};
4use k256::SecretKey;
5use k256::ecdsa::{SigningKey, signature::Signer};
6use rand::rngs::OsRng;
7use serde_json::json;
8
9#[test]
10fn test_jwt_flow() {
11 let secret_key = SecretKey::random(&mut OsRng);
12 let key_bytes = secret_key.to_bytes();
13 let did = "did:plc:test";
14
15 let token = auth::create_access_token(did, &key_bytes).expect("create token");
16 let data = auth::verify_token(&token, &key_bytes).expect("verify token");
17 assert_eq!(data.claims.sub, did);
18 assert_eq!(data.claims.iss, did);
19 assert_eq!(data.claims.scope, Some("access".to_string()));
20
21 let r_token = auth::create_refresh_token(did, &key_bytes).expect("create refresh token");
22 let r_data = auth::verify_token(&r_token, &key_bytes).expect("verify refresh token");
23 assert_eq!(r_data.claims.scope, Some("refresh".to_string()));
24
25 let aud = "did:web:service";
26 let lxm = "com.example.test";
27 let s_token =
28 auth::create_service_token(did, aud, lxm, &key_bytes).expect("create service token");
29 let s_data = auth::verify_token(&s_token, &key_bytes).expect("verify service token");
30 assert_eq!(s_data.claims.aud, aud);
31 assert_eq!(s_data.claims.lxm, Some(lxm.to_string()));
32}
33
34#[test]
35fn test_verify_fails_with_wrong_key() {
36 let secret_key1 = SecretKey::random(&mut OsRng);
37 let key_bytes1 = secret_key1.to_bytes();
38
39 let secret_key2 = SecretKey::random(&mut OsRng);
40 let key_bytes2 = secret_key2.to_bytes();
41
42 let did = "did:plc:test";
43 let token = auth::create_access_token(did, &key_bytes1).expect("create token");
44
45 let result = auth::verify_token(&token, &key_bytes2);
46 assert!(result.is_err());
47}
48
49#[test]
50fn test_token_expiration() {
51 let secret_key = SecretKey::random(&mut OsRng);
52 let key_bytes = secret_key.to_bytes();
53 let signing_key = SigningKey::from_slice(&key_bytes).expect("key");
54
55 let header = json!({
56 "alg": "ES256K",
57 "typ": "JWT"
58 });
59 let claims = json!({
60 "iss": "did:plc:test",
61 "sub": "did:plc:test",
62 "aud": "did:web:test",
63 "exp": (Utc::now() - Duration::seconds(10)).timestamp(),
64 "iat": (Utc::now() - Duration::minutes(1)).timestamp(),
65 "jti": "unique",
66 });
67
68 let header_b64 = URL_SAFE_NO_PAD.encode(serde_json::to_string(&header).unwrap());
69 let claims_b64 = URL_SAFE_NO_PAD.encode(serde_json::to_string(&claims).unwrap());
70 let message = format!("{}.{}", header_b64, claims_b64);
71 let signature: k256::ecdsa::Signature = signing_key.sign(message.as_bytes());
72 let signature_b64 = URL_SAFE_NO_PAD.encode(signature.to_bytes());
73 let token = format!("{}.{}", message, signature_b64);
74
75 let result = auth::verify_token(&token, &key_bytes);
76 match result {
77 Ok(_) => panic!("Token should be expired"),
78 Err(e) => assert_eq!(e.to_string(), "Token expired"),
79 }
80}
81
82#[test]
83fn test_invalid_token_format() {
84 let secret_key = SecretKey::random(&mut OsRng);
85 let key_bytes = secret_key.to_bytes();
86
87 assert!(auth::verify_token("invalid.token", &key_bytes).is_err());
88 assert!(auth::verify_token("too.many.parts.here", &key_bytes).is_err());
89 assert!(auth::verify_token("bad_base64.payload.sig", &key_bytes).is_err());
90}
91
92#[test]
93fn test_tampered_token() {
94 let secret_key = SecretKey::random(&mut OsRng);
95 let key_bytes = secret_key.to_bytes();
96 let did = "did:plc:test";
97
98 let token = auth::create_access_token(did, &key_bytes).expect("create token");
99 let parts: Vec<&str> = token.split('.').collect();
100
101 let claims_json = String::from_utf8(URL_SAFE_NO_PAD.decode(parts[1]).unwrap()).unwrap();
102 let mut claims: serde_json::Value = serde_json::from_str(&claims_json).unwrap();
103 claims["sub"] = json!("did:plc:hacker");
104 let tampered_claims_b64 = URL_SAFE_NO_PAD.encode(serde_json::to_string(&claims).unwrap());
105
106 let tampered_token = format!("{}.{}.{}", parts[0], tampered_claims_b64, parts[2]);
107
108 let result = auth::verify_token(&tampered_token, &key_bytes);
109 assert!(result.is_err());
110}
111
112#[test]
113fn test_get_did_from_token() {
114 let secret_key = SecretKey::random(&mut OsRng);
115 let key_bytes = secret_key.to_bytes();
116 let did = "did:plc:test";
117
118 let token = auth::create_access_token(did, &key_bytes).expect("create token");
119 let extracted_did = auth::get_did_from_token(&token).expect("get did");
120 assert_eq!(extracted_did, did);
121
122 assert!(auth::get_did_from_token("bad.token").is_err());
123}