nautilus_rs/resources/gate/types.rs
1/// A user identity managed by Gate.
2#[derive(Debug, Clone, serde::Deserialize)]
3pub struct Identity {
4 /// Unique identity identifier.
5 pub id: String,
6 /// The schema this identity conforms to (e.g. `"default"`).
7 pub schema_id: String,
8 /// Current lifecycle state (`"active"`, `"inactive"`, …).
9 pub state: String,
10 /// Profile traits attached to this identity.
11 pub traits: IdentityTraits,
12}
13
14/// Profile traits for an existing [`Identity`].
15#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
16pub struct IdentityTraits {
17 /// Primary email address.
18 pub email: String,
19 /// Arbitrary application-defined JSON data.
20 #[serde(skip_serializing_if = "Option::is_none")]
21 pub custom_data: Option<serde_json::Value>,
22 /// Tenant the identity belongs to.
23 #[serde(skip_serializing_if = "Option::is_none")]
24 pub tenant_id: Option<String>,
25}
26
27/// Profile traits supplied when creating a new identity.
28///
29/// Identical to [`IdentityTraits`] but omits the server-assigned `tenant_id`.
30#[derive(Debug, Clone, serde::Serialize)]
31pub struct IdentityTraitsInput {
32 /// Primary email address.
33 pub email: String,
34 /// Arbitrary application-defined JSON data.
35 #[serde(skip_serializing_if = "Option::is_none")]
36 pub custom_data: Option<serde_json::Value>,
37}
38
39/// Parameters for [`IdentitiesClient::create`](super::IdentitiesClient::create).
40///
41/// # Example
42///
43/// ```no_run
44/// use nautilus_rs::{Gate, CreateIdentityParams, IdentityTraitsInput};
45///
46/// # async fn run() -> Result<(), nautilus_rs::Error> {
47/// let gate = Gate::new("vrn_gate_live_sk_…");
48/// let identity = gate.identities().create(CreateIdentityParams {
49/// schema_id: "default".into(),
50/// traits: IdentityTraitsInput {
51/// email: "alice@example.com".into(),
52/// custom_data: None,
53/// },
54/// credentials: None,
55/// state: Some("active".into()),
56/// }).await?;
57/// println!("created: {}", identity.id);
58/// # Ok(())
59/// # }
60/// ```
61#[derive(Debug, Clone, serde::Serialize)]
62pub struct CreateIdentityParams {
63 /// Schema identifier the identity should conform to.
64 pub schema_id: String,
65 /// Profile traits for the new identity.
66 pub traits: IdentityTraitsInput,
67 /// Optional credential material (passwords, OIDC tokens, …) in the format
68 /// expected by the schema.
69 #[serde(skip_serializing_if = "Option::is_none")]
70 pub credentials: Option<serde_json::Value>,
71 /// Initial lifecycle state. Defaults to the schema default when `None`.
72 #[serde(skip_serializing_if = "Option::is_none")]
73 pub state: Option<String>,
74}
75
76/// A single [RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902) JSON
77/// Patch operation used with
78/// [`IdentitiesClient::patch`](super::IdentitiesClient::patch).
79///
80/// # Example — update an email address
81///
82/// ```no_run
83/// use nautilus_rs::{Gate, JsonPatchOp};
84/// use serde_json::json;
85///
86/// # async fn run() -> Result<(), nautilus_rs::Error> {
87/// let gate = Gate::new("vrn_gate_live_sk_…");
88/// gate.identities().patch("idn_…", vec![JsonPatchOp {
89/// op: "replace".into(),
90/// path: "/traits/email".into(),
91/// value: Some(json!("bob@example.com")),
92/// from: None,
93/// }]).await?;
94/// # Ok(())
95/// # }
96/// ```
97#[derive(Debug, Clone, serde::Serialize)]
98pub struct JsonPatchOp {
99 /// Operation type: `"add"`, `"remove"`, `"replace"`, `"move"`, `"copy"`,
100 /// or `"test"`.
101 pub op: String,
102 /// JSON Pointer (RFC 6901) to the target location.
103 pub path: String,
104 /// Value to apply (required for `add`, `replace`, `test`).
105 #[serde(skip_serializing_if = "Option::is_none")]
106 pub value: Option<serde_json::Value>,
107 /// Source location (required for `move` and `copy`).
108 #[serde(skip_serializing_if = "Option::is_none")]
109 pub from: Option<String>,
110}
111
112/// Security-related Gate Identity settings for a tenant.
113///
114/// Used both as the return value of
115/// [`SettingsClient::get_security`](super::SettingsClient::get_security) and as
116/// the input to
117/// [`SettingsClient::update_security`](super::SettingsClient::update_security).
118/// Updates are a full replacement — both fields are always sent.
119#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
120pub struct SecuritySettings {
121 /// Whether email-OTP (passwordless) login is enabled.
122 pub passwordless_enabled: bool,
123 /// Whether TOTP two-factor authentication is enabled.
124 pub mfa_enabled: bool,
125}
126
127/// A social login (OAuth 2.0 / OIDC) provider and whether it is enabled for a
128/// tenant's end-users.
129///
130/// Used both as an element of the list returned by
131/// [`SettingsClient::get_oidc_providers`](super::SettingsClient::get_oidc_providers)
132/// and as input to
133/// [`SettingsClient::update_oidc_providers`](super::SettingsClient::update_oidc_providers).
134#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
135pub struct OidcProvider {
136 /// Provider identifier, e.g. `"github"`, `"google"`, `"gitlab"`.
137 pub provider: String,
138 /// Whether the provider appears in the tenant's login/registration UI.
139 pub enabled: bool,
140}
141
142/// A short-lived access token issued by Gate.
143#[derive(Debug, Clone, serde::Deserialize)]
144pub struct AccessToken {
145 /// The signed access token string to pass to downstream services.
146 pub access_token: String,
147 /// ISO 8601 expiry timestamp.
148 pub expires_at: String,
149 /// The identity this token was issued for.
150 pub subject: String,
151 /// Tenant the subject belongs to.
152 pub tenant_id: String,
153}
154
155/// Parameters for [`TokensClient::create`](super::TokensClient::create).
156///
157/// # Example
158///
159/// ```no_run
160/// use nautilus_rs::{Gate, CreateTokenParams};
161///
162/// # async fn run() -> Result<(), nautilus_rs::Error> {
163/// let gate = Gate::new("vrn_gate_live_sk_…");
164/// let token = gate.tokens().create(CreateTokenParams {
165/// subject: "idn_alice".into(),
166/// scopes: Some(vec!["read:orders".into(), "write:orders".into()]),
167/// ttl_seconds: Some(3600),
168/// }).await?;
169/// println!("token: {}", token.access_token);
170/// # Ok(())
171/// # }
172/// ```
173#[derive(Debug, Clone, serde::Serialize)]
174pub struct CreateTokenParams {
175 /// The identity ID the token is issued for.
176 pub subject: String,
177 /// Permission scopes to embed in the token. The server grants all
178 /// configured scopes when `None`.
179 #[serde(skip_serializing_if = "Option::is_none")]
180 pub scopes: Option<Vec<String>>,
181 /// Token lifetime in seconds. Uses the server-side default when `None`.
182 #[serde(skip_serializing_if = "Option::is_none")]
183 pub ttl_seconds: Option<u64>,
184}
185
186/// Token validity and claims returned by
187/// [`TokensClient::introspect`](super::TokensClient::introspect).
188#[derive(Debug, Clone, serde::Deserialize)]
189pub struct TokenInfo {
190 /// `true` if the token is valid, unexpired, and not revoked.
191 pub active: bool,
192 /// The identity the token was issued for.
193 pub subject: String,
194 /// Tenant the subject belongs to.
195 pub tenant_id: String,
196 /// Scopes embedded in the token.
197 pub scopes: Vec<String>,
198 /// ISO 8601 expiry timestamp.
199 pub expires_at: String,
200}
201
202/// Parameters for [`Gate::authorize`](crate::Gate::authorize).
203///
204/// # Example
205///
206/// ```no_run
207/// use nautilus_rs::{Gate, AuthorizeParams};
208///
209/// # async fn run() -> Result<(), nautilus_rs::Error> {
210/// let gate = Gate::new("vrn_gate_live_sk_…");
211/// let decision = gate.authorize(AuthorizeParams {
212/// subject: "idn_alice".into(),
213/// action: "delete".into(),
214/// resource: "order:ord_123".into(),
215/// context: None,
216/// }).await?;
217///
218/// if decision.allowed {
219/// println!("access granted (decision {})", decision.decision_id);
220/// } else {
221/// println!("denied: {}", decision.reason);
222/// }
223/// # Ok(())
224/// # }
225/// ```
226#[derive(Debug, Clone, serde::Serialize)]
227pub struct AuthorizeParams {
228 /// The identity requesting access.
229 pub subject: String,
230 /// The action being performed (e.g. `"read"`, `"delete"`).
231 pub action: String,
232 /// The resource being accessed (e.g. `"order:ord_123"`).
233 pub resource: String,
234 /// Optional arbitrary JSON context passed to policy evaluation.
235 #[serde(skip_serializing_if = "Option::is_none")]
236 pub context: Option<serde_json::Value>,
237}
238
239/// The result of an authorization check.
240#[derive(Debug, Clone, serde::Deserialize)]
241pub struct AuthorizationDecision {
242 /// `true` if the subject is permitted to perform the action on the
243 /// resource.
244 pub allowed: bool,
245 /// Unique identifier for this specific decision, useful for audit logs.
246 pub decision_id: String,
247 /// Human-readable explanation of why access was granted or denied.
248 pub reason: String,
249}