1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//! User credential types and verification abstractions.
//!
//! This module defines the authentication boundary for `webgates-core`.
//! It intentionally stays small: the crate represents user-supplied credentials,
//! but leaves verification strategy and storage details to higher-level code.
//!
//! This module exposes:
//!
//! - [`Credentials`] stores a caller-provided identifier and plaintext secret
//! - [`credentials_verifier::CredentialsVerifier`] defines the async verification contract used by
//! higher-level authentication services
//!
//! Import [`Credentials`] directly from `webgates_core::credentials` and
//! [`credentials_verifier::CredentialsVerifier`] from the owning submodule.
//!
//! # Quick Start
//!
//! ```rust
//! use webgates_core::credentials::Credentials;
//!
//! let credentials = Credentials::new(&"user@example.com".to_string(), "password123");
//!
//! let json = r#"{"id":"admin@company.com","secret":"admin_pass"}"#;
//! let parsed: Credentials<String> = serde_json::from_str(json)?;
//!
//! assert_eq!(parsed.id, "admin@company.com");
//! # let _ = credentials;
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! # Verification boundary
//!
//! Concrete verifier implementations belong in higher-level crates or in your
//! application code. `webgates-core` only defines the shared types and the
//! verification trait that those layers implement.
//!
//! # Security Considerations
//!
//! - Credentials contain plaintext secrets and should be short-lived.
//! - Never log or persist raw credentials.
//! - Only transmit credentials over secure channels such as HTTPS/TLS.
//! - Verification backends should avoid leaking identifier existence through
//! observable timing or error details.
use ;
/// Async verification contract for credential backends.
/// Authentication credentials containing a user identifier and plaintext secret.
///
/// This type represents raw login input at the authentication boundary. It
/// stores the caller-provided identifier together with a plaintext secret so a
/// verifier can compare it against stored authentication material.
///
/// # Type Parameter
///
/// - `Id`: Identifier type used by the calling application, commonly [`String`]
/// or [`uuid::Uuid`]
///
/// # Security
///
/// - The `secret` field contains plaintext sensitive data.
/// - Keep instances short-lived and avoid cloning them unnecessarily.
/// - Never log, persist, or expose the raw secret.
/// - Use secure transport when credentials cross process or network boundaries.
///
/// # Examples
///
/// Create credentials from application input:
///
/// ```rust
/// use webgates_core::credentials::Credentials;
///
/// let credentials = Credentials::new(&"user@example.com".to_string(), "user_password");
///
/// assert_eq!(credentials.id, "user@example.com");
/// assert_eq!(credentials.secret, "user_password");
/// ```
///
/// Deserialize credentials from JSON:
///
/// ```rust
/// use webgates_core::credentials::Credentials;
///
/// let json = r#"{"id":"user@example.com","secret":"password123"}"#;
/// let credentials: Credentials<String> = serde_json::from_str(json)?;
///
/// assert_eq!(credentials.id, "user@example.com");
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// Use a UUID identifier:
///
/// ```rust
/// use uuid::Uuid;
/// use webgates_core::credentials::Credentials;
///
/// let user_id = Uuid::now_v7();
/// let credentials = Credentials::new(&user_id, "user_password");
///
/// assert_eq!(credentials.id, user_id);
/// ```