Skip to main content

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}