Skip to main content

hanzo_client/apis/
entitlement_api.rs

1/*
2 * Hanzo Cloud API
3 *
4 * The Hanzo Cloud API as a customer calls it: every operation under /v1/ except the operator's admin product, relay routes, legacy spellings and capabilities still reached by flag. Tagged by product: the first path segment after /v1/.
5 *
6 * The version of the OpenAPI document: v1
7 * 
8 * Generated by: https://openapi-generator.tech
9 */
10
11
12use reqwest;
13use serde::{Deserialize, Serialize, de::Error as _};
14use crate::{apis::ResponseContent, models};
15use super::{Error, configuration, ContentType};
16
17
18/// struct for typed errors of method [`get_entitlement`]
19#[derive(Debug, Clone, Serialize, Deserialize)]
20#[serde(untagged)]
21pub enum GetEntitlementError {
22    UnknownValue(serde_json::Value),
23}
24
25/// struct for typed errors of method [`get_entitlement_orgs_by_org`]
26#[derive(Debug, Clone, Serialize, Deserialize)]
27#[serde(untagged)]
28pub enum GetEntitlementOrgsByOrgError {
29    UnknownValue(serde_json::Value),
30}
31
32/// struct for typed errors of method [`post_entitlement_orgs_by_org`]
33#[derive(Debug, Clone, Serialize, Deserialize)]
34#[serde(untagged)]
35pub enum PostEntitlementOrgsByOrgError {
36    UnknownValue(serde_json::Value),
37}
38
39
40/// Projection reports which console apps the CALLER's org may open, and the plan slug that decides it. It is the READ side of the unified paywall: the org's plan tier resolved from commerce, which is a different authority from the enablement store behind GET /v1/entitlement/orgs/{org} (that one is the org's own on/off intent).  It fails SAFE-TO-LOCKED, never 500: an unvalidated principal is a 403, but a commerce outage reports every app locked at 200 rather than breaking the shell. The ENFORCEMENT path still fails open, so functionality survives the same outage even while the UI conservatively shows locked.
41pub async fn get_entitlement(configuration: &configuration::Configuration, ) -> Result<models::ProjectionView, Error<GetEntitlementError>> {
42
43    let uri_str = format!("{}/v1/entitlement", configuration.base_path);
44    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
45
46    if let Some(ref user_agent) = configuration.user_agent {
47        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
48    }
49    if let Some(ref token) = configuration.bearer_access_token {
50        req_builder = req_builder.bearer_auth(token.to_owned());
51    };
52
53    let req = req_builder.build()?;
54    let resp = configuration.client.execute(req).await?;
55
56    let status = resp.status();
57    let content_type = resp
58        .headers()
59        .get("content-type")
60        .and_then(|v| v.to_str().ok())
61        .unwrap_or("application/octet-stream");
62    let content_type = super::ContentType::from(content_type);
63
64    if !status.is_client_error() && !status.is_server_error() {
65        let content = resp.text().await?;
66        match content_type {
67            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
68            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ProjectionView`"))),
69            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ProjectionView`")))),
70        }
71    } else {
72        let content = resp.text().await?;
73        let entity: Option<GetEntitlementError> = serde_json::from_str(&content).ok();
74        Err(Error::ResponseError(ResponseContent { status, content, entity }))
75    }
76}
77
78/// Get lists the products an org has ENABLED — its own intent, which the console's paid-product sidebar reads to decide what to show. It is distinct from what the org's plan ENTITLES it to (that is GET /v1/entitlement, resolved from commerce).  A caller may only read its OWN org's row; a platform super admin may read any.
79pub async fn get_entitlement_orgs_by_org(configuration: &configuration::Configuration, org: &str) -> Result<models::EntitlementsView, Error<GetEntitlementOrgsByOrgError>> {
80    // add a prefix to parameters to efficiently prevent name collisions
81    let p_org = org;
82
83    let uri_str = format!("{}/v1/entitlement/orgs/{org}", configuration.base_path, org=crate::apis::urlencode(p_org));
84    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
85
86    if let Some(ref user_agent) = configuration.user_agent {
87        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
88    }
89    if let Some(ref token) = configuration.bearer_access_token {
90        req_builder = req_builder.bearer_auth(token.to_owned());
91    };
92
93    let req = req_builder.build()?;
94    let resp = configuration.client.execute(req).await?;
95
96    let status = resp.status();
97    let content_type = resp
98        .headers()
99        .get("content-type")
100        .and_then(|v| v.to_str().ok())
101        .unwrap_or("application/octet-stream");
102    let content_type = super::ContentType::from(content_type);
103
104    if !status.is_client_error() && !status.is_server_error() {
105        let content = resp.text().await?;
106        match content_type {
107            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
108            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::EntitlementsView`"))),
109            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::EntitlementsView`")))),
110        }
111    } else {
112        let content = resp.text().await?;
113        let entity: Option<GetEntitlementOrgsByOrgError> = serde_json::from_str(&content).ok();
114        Err(Error::ResponseError(ResponseContent { status, content, entity }))
115    }
116}
117
118/// Post turns products on or off for an org and returns the enabled set afterwards.  A product may only be ENABLED if the org's plan already ENTITLES it, so enabling never spends new money — a product the plan does not grant answers 402 and the console routes that to an upgrade prompt. DISABLING is never gated. A platform super admin bypasses the plan check (operator comp/grant) and may target any org; everyone else may only change their own. Commerce unreachable is a 503, never an implicit yes.
119pub async fn post_entitlement_orgs_by_org(configuration: &configuration::Configuration, org: &str, mutate_req: models::MutateReq) -> Result<models::EntitlementsView, Error<PostEntitlementOrgsByOrgError>> {
120    // add a prefix to parameters to efficiently prevent name collisions
121    let p_org = org;
122    let p_mutate_req = mutate_req;
123
124    let uri_str = format!("{}/v1/entitlement/orgs/{org}", configuration.base_path, org=crate::apis::urlencode(p_org));
125    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
126
127    if let Some(ref user_agent) = configuration.user_agent {
128        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
129    }
130    if let Some(ref token) = configuration.bearer_access_token {
131        req_builder = req_builder.bearer_auth(token.to_owned());
132    };
133    req_builder = req_builder.json(&p_mutate_req);
134
135    let req = req_builder.build()?;
136    let resp = configuration.client.execute(req).await?;
137
138    let status = resp.status();
139    let content_type = resp
140        .headers()
141        .get("content-type")
142        .and_then(|v| v.to_str().ok())
143        .unwrap_or("application/octet-stream");
144    let content_type = super::ContentType::from(content_type);
145
146    if !status.is_client_error() && !status.is_server_error() {
147        let content = resp.text().await?;
148        match content_type {
149            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
150            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::EntitlementsView`"))),
151            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::EntitlementsView`")))),
152        }
153    } else {
154        let content = resp.text().await?;
155        let entity: Option<PostEntitlementOrgsByOrgError> = serde_json::from_str(&content).ok();
156        Err(Error::ResponseError(ResponseContent { status, content, entity }))
157    }
158}
159