pub struct TokenValidator { /* private fields */ }Expand description
Token validator.
Holds the NonceBook (LRU+TTL nonce store) and the
TokenPolicyTable (per-vendor policy lookup). The
validator is Send + Sync so it can sit behind an Arc
and be shared across threads and requests without locking.
§Example
use std::time::Duration;
use stygian_charon::token_lifecycle::{
ChallengeClass, TokenContract, TokenPolicyTable, TokenValidator,
};
use stygian_charon::vendor_classifier::VendorId;
let policy = TokenPolicyTable::with_builtin_defaults();
let validator = TokenValidator::new(
stygian_charon::token_lifecycle::NonceBook::with_defaults(),
policy,
);
let contract = TokenContract {
token_id: "x".to_string(),
issued_at_unix_secs: 0,
ttl: Duration::from_mins(5),
nonce: "n".to_string(),
vendor_family: VendorId::Unknown,
challenge_class: ChallengeClass::None,
single_use: false,
bound_session: None,
description: String::new(),
};
let outcome = validator.validate(&contract, None, 0);
assert!(outcome.is_ok());Implementations§
Source§impl TokenValidator
impl TokenValidator
Sourcepub const fn new(nonce_book: NonceBook, policy: TokenPolicyTable) -> Self
pub const fn new(nonce_book: NonceBook, policy: TokenPolicyTable) -> Self
Build a validator with an explicit nonce book and policy table.
§Example
use std::num::NonZeroUsize;
use std::time::Duration;
use stygian_charon::token_lifecycle::{NonceBook, TokenPolicyTable, TokenValidator};
let validator = TokenValidator::new(
NonceBook::new(NonZeroUsize::new(8).expect("non-zero"), Duration::from_mins(1)),
TokenPolicyTable::with_builtin_defaults(),
);
assert_eq!(validator.policy().len(), 11);Sourcepub fn with_defaults(policy: TokenPolicyTable) -> Self
pub fn with_defaults(policy: TokenPolicyTable) -> Self
Build a validator with the default
NonceBook::with_defaults()
nonce book and the supplied policy table.
§Example
use stygian_charon::token_lifecycle::{TokenPolicyTable, TokenValidator};
let validator = TokenValidator::with_defaults(TokenPolicyTable::with_builtin_defaults());
assert!(validator.nonce_book().is_empty());Sourcepub const fn nonce_book(&self) -> &NonceBook
pub const fn nonce_book(&self) -> &NonceBook
Borrow the nonce book.
Sourcepub const fn policy(&self) -> &TokenPolicyTable
pub const fn policy(&self) -> &TokenPolicyTable
Borrow the policy table.
Sourcepub fn validate(
&self,
contract: &TokenContract,
session_id: Option<&str>,
now_unix_secs: u64,
) -> ValidationOutcome
pub fn validate( &self, contract: &TokenContract, session_id: Option<&str>, now_unix_secs: u64, ) -> ValidationOutcome
Validate a TokenContract against the supplied
session_id (when the submission carries one) and the
supplied now_unix_secs clock.
On accept, the nonce is recorded in the NonceBook
(so the next submission is rejected as a replay) and the
outcome’s consumed flag is true. On reject, the
outcome is ValidationOutcome::Rejected with the
structured InvalidationReason the runner can route
into the per-family audit log.