refactor(tests): reformat code and update dependency management
- Reorganized import statements in adapter tests for better readability - Replaced or_insert_with(Vec::new) with or_default() in test closures - Updated Cargo.lock with new dependency versions and checksums - Added TLS features to tonic dependency configuration - Included sqlx, chrono, and uuid dependencies with specific features - Added jsonwebtoken and arc-swap as project dependencies - Reformatted assertion statements to comply with line length limits - Adjusted base64 import order in engine codec module - Updated protobuf include statement formatting
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
//! JWT claims structure — mirrors proto `TokenClaims` for local verification.
|
||||
//!
|
||||
//! Used as the deserialization target for `jsonwebtoken::decode`.
|
||||
//! Field names match standard JWT claim names (`sub`, `iss`, `exp`, etc.).
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Parsed JWT payload, matching the proto `TokenClaims` shape.
|
||||
///
|
||||
/// Deserialized by `jsonwebtoken` during HS256 verification.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct TokenClaims {
|
||||
/// Subject — the user UUID.
|
||||
pub sub: String,
|
||||
/// Issuer — expected to be `"appks"`.
|
||||
pub iss: String,
|
||||
/// Issued-at (unix seconds).
|
||||
pub iat: i64,
|
||||
/// Expiration (unix seconds).
|
||||
pub exp: i64,
|
||||
/// Unique token ID (used for revocation tracking via `jti`).
|
||||
pub jti: String,
|
||||
/// Space-separated scopes, e.g. `"im:read im:write"`.
|
||||
pub scope: String,
|
||||
/// Extensible metadata (workspace_id, role, etc.).
|
||||
#[serde(default)]
|
||||
pub extra: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl TokenClaims {
|
||||
/// Check whether this token carries a specific scope.
|
||||
pub fn has_scope(&self, scope: &str) -> bool {
|
||||
self.scope.split_whitespace().any(|s| s == scope)
|
||||
}
|
||||
|
||||
/// Convert from the proto-generated `TokenClaims` (RPC verify response).
|
||||
pub fn from_proto(proto: crate::pb::core::TokenClaims) -> Self {
|
||||
Self {
|
||||
sub: proto.sub,
|
||||
iss: proto.iss,
|
||||
iat: proto.iat,
|
||||
exp: proto.exp,
|
||||
jti: proto.jti,
|
||||
scope: proto.scope,
|
||||
extra: proto.extra,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_has_scope() {
|
||||
let claims = TokenClaims {
|
||||
sub: "user-1".into(),
|
||||
iss: "appks".into(),
|
||||
iat: 0,
|
||||
exp: 9999999999,
|
||||
jti: "tok-1".into(),
|
||||
scope: "im:read im:write admin".into(),
|
||||
extra: HashMap::new(),
|
||||
};
|
||||
assert!(claims.has_scope("im:read"));
|
||||
assert!(claims.has_scope("admin"));
|
||||
assert!(!claims.has_scope("im:delete"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_deserialize_from_json() {
|
||||
let json = r#"{
|
||||
"sub": "user-1",
|
||||
"iss": "appks",
|
||||
"iat": 1000,
|
||||
"exp": 2000,
|
||||
"jti": "tok-1",
|
||||
"scope": "im:read",
|
||||
"extra": {"workspace_id": "ws-1"}
|
||||
}"#;
|
||||
let claims: TokenClaims = serde_json::from_str(json).unwrap();
|
||||
assert_eq!(claims.sub, "user-1");
|
||||
assert_eq!(claims.extra.get("workspace_id").unwrap(), "ws-1");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user