#![doc = "Generated transport-independent contract objects."]
use std::collections::BTreeMap;
use std::error::Error as StdError;
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_json::Value;
use spiral_contract::error::{ErrorEnvelope, ServiceError};
use spiral_contract::strict::{DeserializeStrict, Strict};
use uuid::Uuid;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum AppAccessDecision {
Allow,
Block,
Unknown(String),
}
impl Serialize for AppAccessDecision {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(match self {
Self::Allow => "allow",
Self::Block => "block",
Self::Unknown(value) => value,
})
}
}
impl<'de> Deserialize<'de> for AppAccessDecision {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(match String::deserialize(deserializer)?.as_str() {
"allow" => Self::Allow,
"block" => Self::Block,
value => Self::Unknown(value.to_owned()),
})
}
}
impl<'de> DeserializeStrict<'de> for AppAccessDecision {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
enum __Known {
#[serde(rename = "allow")]
Allow,
#[serde(rename = "block")]
Block,
}
Ok(match __Known::deserialize(deserializer)? {
__Known::Allow => Self::Allow,
__Known::Block => Self::Block,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ClientAppAccess {
#[serde(rename = "clientId")]
pub client_id: String,
#[serde(rename = "decision")]
pub decision: AppAccessDecision,
}
impl<'de> DeserializeStrict<'de> for ClientAppAccess {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct __Wire {
#[serde(rename = "clientId")]
client_id: Strict<String>,
#[serde(rename = "decision")]
decision: Strict<AppAccessDecision>,
}
let wire = __Wire::deserialize(deserializer)?;
Ok(Self {
client_id: wire.client_id.0,
decision: wire.decision.0,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ClientRedirect {
#[serde(rename = "redirectUri")]
pub redirect_uri: String,
}
impl<'de> DeserializeStrict<'de> for ClientRedirect {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct __Wire {
#[serde(rename = "redirectUri")]
redirect_uri: Strict<String>,
}
let wire = __Wire::deserialize(deserializer)?;
Ok(Self {
redirect_uri: wire.redirect_uri.0,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ClientRegistration {
#[serde(rename = "audience")]
pub audience: Vec<String>,
#[serde(rename = "clientName")]
pub client_name: String,
#[serde(rename = "enabled")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub enabled: Option<bool>,
#[serde(rename = "grantTypes")]
pub grant_types: Vec<GrantType>,
#[serde(rename = "jwks")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub jwks: Option<Value>,
#[serde(rename = "jwtBearerIssuers")]
pub jwt_bearer_issuers: Vec<JwtBearerIssuer>,
#[serde(rename = "signIn")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub sign_in: Option<SignInRegistration>,
}
impl<'de> DeserializeStrict<'de> for ClientRegistration {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct __Wire {
#[serde(rename = "audience")]
audience: Strict<Vec<String>>,
#[serde(rename = "clientName")]
client_name: Strict<String>,
#[serde(rename = "enabled")]
#[serde(default)]
enabled: Strict<Option<bool>>,
#[serde(rename = "grantTypes")]
grant_types: Strict<Vec<GrantType>>,
#[serde(rename = "jwks")]
#[serde(default)]
jwks: Strict<Option<Value>>,
#[serde(rename = "jwtBearerIssuers")]
jwt_bearer_issuers: Strict<Vec<JwtBearerIssuer>>,
#[serde(rename = "signIn")]
#[serde(default)]
sign_in: Strict<Option<SignInRegistration>>,
}
let wire = __Wire::deserialize(deserializer)?;
Ok(Self {
audience: wire.audience.0,
client_name: wire.client_name.0,
enabled: wire.enabled.0,
grant_types: wire.grant_types.0,
jwks: wire.jwks.0,
jwt_bearer_issuers: wire.jwt_bearer_issuers.0,
sign_in: wire.sign_in.0,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ConsentClient {
#[serde(rename = "id")]
pub id: String,
#[serde(rename = "loopbackOnly")]
pub loopback_only: bool,
#[serde(rename = "managed")]
pub managed: bool,
#[serde(rename = "name")]
pub name: String,
#[serde(rename = "publisher")]
pub publisher: String,
#[serde(rename = "publisherName")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub publisher_name: Option<String>,
#[serde(rename = "redirectHost")]
pub redirect_host: String,
}
impl<'de> DeserializeStrict<'de> for ConsentClient {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct __Wire {
#[serde(rename = "id")]
id: Strict<String>,
#[serde(rename = "loopbackOnly")]
loopback_only: Strict<bool>,
#[serde(rename = "managed")]
managed: Strict<bool>,
#[serde(rename = "name")]
name: Strict<String>,
#[serde(rename = "publisher")]
publisher: Strict<String>,
#[serde(rename = "publisherName")]
#[serde(default)]
publisher_name: Strict<Option<String>>,
#[serde(rename = "redirectHost")]
redirect_host: Strict<String>,
}
let wire = __Wire::deserialize(deserializer)?;
Ok(Self {
id: wire.id.0,
loopback_only: wire.loopback_only.0,
managed: wire.managed.0,
name: wire.name.0,
publisher: wire.publisher.0,
publisher_name: wire.publisher_name.0,
redirect_host: wire.redirect_host.0,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ConsentDecision {
#[serde(rename = "approve")]
pub approve: bool,
#[serde(rename = "scopes")]
pub scopes: Vec<String>,
}
impl<'de> DeserializeStrict<'de> for ConsentDecision {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct __Wire {
#[serde(rename = "approve")]
approve: Strict<bool>,
#[serde(rename = "scopes")]
scopes: Strict<Vec<String>>,
}
let wire = __Wire::deserialize(deserializer)?;
Ok(Self {
approve: wire.approve.0,
scopes: wire.scopes.0,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ConsentRedirect {
#[serde(rename = "redirectTo")]
pub redirect_to: String,
}
impl<'de> DeserializeStrict<'de> for ConsentRedirect {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct __Wire {
#[serde(rename = "redirectTo")]
redirect_to: Strict<String>,
}
let wire = __Wire::deserialize(deserializer)?;
Ok(Self {
redirect_to: wire.redirect_to.0,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ConsentRequest {
#[serde(rename = "client")]
pub client: ConsentClient,
#[serde(rename = "resource")]
pub resource: String,
#[serde(rename = "scopes")]
pub scopes: Vec<String>,
#[serde(rename = "skip")]
pub skip: bool,
#[serde(rename = "subject")]
pub subject: ConsentSubject,
}
impl<'de> DeserializeStrict<'de> for ConsentRequest {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct __Wire {
#[serde(rename = "client")]
client: Strict<ConsentClient>,
#[serde(rename = "resource")]
resource: Strict<String>,
#[serde(rename = "scopes")]
scopes: Strict<Vec<String>>,
#[serde(rename = "skip")]
skip: Strict<bool>,
#[serde(rename = "subject")]
subject: Strict<ConsentSubject>,
}
let wire = __Wire::deserialize(deserializer)?;
Ok(Self {
client: wire.client.0,
resource: wire.resource.0,
scopes: wire.scopes.0,
skip: wire.skip.0,
subject: wire.subject.0,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ConsentSubject {
#[serde(rename = "organizationId")]
pub organization_id: String,
#[serde(rename = "organizationName")]
pub organization_name: String,
#[serde(rename = "userId")]
pub user_id: String,
}
impl<'de> DeserializeStrict<'de> for ConsentSubject {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct __Wire {
#[serde(rename = "organizationId")]
organization_id: Strict<String>,
#[serde(rename = "organizationName")]
organization_name: Strict<String>,
#[serde(rename = "userId")]
user_id: Strict<String>,
}
let wire = __Wire::deserialize(deserializer)?;
Ok(Self {
organization_id: wire.organization_id.0,
organization_name: wire.organization_name.0,
user_id: wire.user_id.0,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum GrantType {
ClientCredentials,
JwtBearer,
TokenExchange,
AuthorizationCode,
RefreshToken,
Unknown(String),
}
impl Serialize for GrantType {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(match self {
Self::ClientCredentials => "client_credentials",
Self::JwtBearer => "jwt_bearer",
Self::TokenExchange => "token_exchange",
Self::AuthorizationCode => "authorization_code",
Self::RefreshToken => "refresh_token",
Self::Unknown(value) => value,
})
}
}
impl<'de> Deserialize<'de> for GrantType {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(match String::deserialize(deserializer)?.as_str() {
"client_credentials" => Self::ClientCredentials,
"jwt_bearer" => Self::JwtBearer,
"token_exchange" => Self::TokenExchange,
"authorization_code" => Self::AuthorizationCode,
"refresh_token" => Self::RefreshToken,
value => Self::Unknown(value.to_owned()),
})
}
}
impl<'de> DeserializeStrict<'de> for GrantType {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
enum __Known {
#[serde(rename = "client_credentials")]
ClientCredentials,
#[serde(rename = "jwt_bearer")]
JwtBearer,
#[serde(rename = "token_exchange")]
TokenExchange,
#[serde(rename = "authorization_code")]
AuthorizationCode,
#[serde(rename = "refresh_token")]
RefreshToken,
}
Ok(match __Known::deserialize(deserializer)? {
__Known::ClientCredentials => Self::ClientCredentials,
__Known::JwtBearer => Self::JwtBearer,
__Known::TokenExchange => Self::TokenExchange,
__Known::AuthorizationCode => Self::AuthorizationCode,
__Known::RefreshToken => Self::RefreshToken,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct JwtBearerIssuer {
#[serde(rename = "audience")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub audience: Option<String>,
#[serde(rename = "claims")]
pub claims: BTreeMap<String, String>,
#[serde(rename = "issuer")]
pub issuer: String,
}
impl<'de> DeserializeStrict<'de> for JwtBearerIssuer {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct __Wire {
#[serde(rename = "audience")]
#[serde(default)]
audience: Strict<Option<String>>,
#[serde(rename = "claims")]
claims: Strict<BTreeMap<String, String>>,
#[serde(rename = "issuer")]
issuer: Strict<String>,
}
let wire = __Wire::deserialize(deserializer)?;
Ok(Self {
audience: wire.audience.0,
claims: wire.claims.0,
issuer: wire.issuer.0,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrganizationAppAccess {
#[serde(rename = "clients")]
pub clients: Vec<ClientAppAccess>,
#[serde(rename = "unlisted")]
pub unlisted: UnlistedAppAccess,
}
impl<'de> DeserializeStrict<'de> for OrganizationAppAccess {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct __Wire {
#[serde(rename = "clients")]
clients: Strict<Vec<ClientAppAccess>>,
#[serde(rename = "unlisted")]
unlisted: Strict<UnlistedAppAccess>,
}
let wire = __Wire::deserialize(deserializer)?;
Ok(Self {
clients: wire.clients.0,
unlisted: wire.unlisted.0,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum SignInAudience {
Internal,
Public,
Unknown(String),
}
impl Serialize for SignInAudience {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(match self {
Self::Internal => "internal",
Self::Public => "public",
Self::Unknown(value) => value,
})
}
}
impl<'de> Deserialize<'de> for SignInAudience {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(match String::deserialize(deserializer)?.as_str() {
"internal" => Self::Internal,
"public" => Self::Public,
value => Self::Unknown(value.to_owned()),
})
}
}
impl<'de> DeserializeStrict<'de> for SignInAudience {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
enum __Known {
#[serde(rename = "internal")]
Internal,
#[serde(rename = "public")]
Public,
}
Ok(match __Known::deserialize(deserializer)? {
__Known::Internal => Self::Internal,
__Known::Public => Self::Public,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct SignInRegistration {
#[serde(rename = "allowedCorsOrigins")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub allowed_cors_origins: Option<Vec<String>>,
#[serde(rename = "audience")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub audience: Option<SignInAudience>,
#[serde(rename = "organizationId")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub organization_id: Option<String>,
#[serde(rename = "publisher")]
pub publisher: String,
#[serde(rename = "redirectUris")]
pub redirect_uris: Vec<String>,
#[serde(rename = "resources")]
pub resources: Vec<String>,
#[serde(rename = "scopes")]
pub scopes: Vec<String>,
}
impl<'de> DeserializeStrict<'de> for SignInRegistration {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct __Wire {
#[serde(rename = "allowedCorsOrigins")]
#[serde(default)]
allowed_cors_origins: Strict<Option<Vec<String>>>,
#[serde(rename = "audience")]
#[serde(default)]
audience: Strict<Option<SignInAudience>>,
#[serde(rename = "organizationId")]
#[serde(default)]
organization_id: Strict<Option<String>>,
#[serde(rename = "publisher")]
publisher: Strict<String>,
#[serde(rename = "redirectUris")]
redirect_uris: Strict<Vec<String>>,
#[serde(rename = "resources")]
resources: Strict<Vec<String>>,
#[serde(rename = "scopes")]
scopes: Strict<Vec<String>>,
}
let wire = __Wire::deserialize(deserializer)?;
Ok(Self {
allowed_cors_origins: wire.allowed_cors_origins.0,
audience: wire.audience.0,
organization_id: wire.organization_id.0,
publisher: wire.publisher.0,
redirect_uris: wire.redirect_uris.0,
resources: wire.resources.0,
scopes: wire.scopes.0,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum UnlistedAppAccess {
AllowReviewed,
Block,
Unknown(String),
}
impl Serialize for UnlistedAppAccess {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(match self {
Self::AllowReviewed => "allow_reviewed",
Self::Block => "block",
Self::Unknown(value) => value,
})
}
}
impl<'de> Deserialize<'de> for UnlistedAppAccess {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(match String::deserialize(deserializer)?.as_str() {
"allow_reviewed" => Self::AllowReviewed,
"block" => Self::Block,
value => Self::Unknown(value.to_owned()),
})
}
}
impl<'de> DeserializeStrict<'de> for UnlistedAppAccess {
fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
enum __Known {
#[serde(rename = "allow_reviewed")]
AllowReviewed,
#[serde(rename = "block")]
Block,
}
Ok(match __Known::deserialize(deserializer)? {
__Known::AllowReviewed => Self::AllowReviewed,
__Known::Block => Self::Block,
})
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum AuthnError {
ClientConflict { client_id: String },
ClientNotFound { client_id: String },
ConsentConflict { reason: String },
InvalidClient { reason: String },
InvalidConsent { reason: String },
}
impl AuthnError {
pub fn status(&self) -> u16 {
match self {
Self::ClientConflict { .. } => 409,
Self::ClientNotFound { .. } => 404,
Self::ConsentConflict { .. } => 409,
Self::InvalidClient { .. } => 400,
Self::InvalidConsent { .. } => 400,
}
}
pub fn envelope(&self, instance: String) -> ErrorEnvelope {
match self {
Self::ClientConflict { client_id } => {
let mut envelope = ErrorEnvelope::new("CONFLICT", "Authn:ClientConflict", instance);
envelope
.parameters
.insert("clientId".into(), client_id.to_string());
envelope
}
Self::ClientNotFound { client_id } => {
let mut envelope =
ErrorEnvelope::new("NOT_FOUND", "Authn:ClientNotFound", instance);
envelope
.parameters
.insert("clientId".into(), client_id.to_string());
envelope
}
Self::ConsentConflict { reason } => {
let mut envelope =
ErrorEnvelope::new("CONFLICT", "Authn:ConsentConflict", instance);
envelope
.parameters
.insert("reason".into(), reason.to_string());
envelope
}
Self::InvalidClient { reason } => {
let mut envelope =
ErrorEnvelope::new("INVALID_ARGUMENT", "Authn:InvalidClient", instance);
envelope
.parameters
.insert("reason".into(), reason.to_string());
envelope
}
Self::InvalidConsent { reason } => {
let mut envelope =
ErrorEnvelope::new("INVALID_ARGUMENT", "Authn:InvalidConsent", instance);
envelope
.parameters
.insert("reason".into(), reason.to_string());
envelope
}
}
}
pub fn decode_envelope(envelope: &ErrorEnvelope) -> Option<Self> {
if envelope.error_instance_id.len() != 36
|| Uuid::parse_str(&envelope.error_instance_id).is_err()
{
return None;
}
match envelope.error_name.as_str() {
"Authn:ClientConflict" => {
if envelope.error_code != "CONFLICT" {
return None;
}
let client_id = envelope.parameters.get("clientId")?.clone();
Some(Self::ClientConflict { client_id })
}
"Authn:ClientNotFound" => {
if envelope.error_code != "NOT_FOUND" {
return None;
}
let client_id = envelope.parameters.get("clientId")?.clone();
Some(Self::ClientNotFound { client_id })
}
"Authn:ConsentConflict" => {
if envelope.error_code != "CONFLICT" {
return None;
}
let reason = envelope.parameters.get("reason")?.clone();
Some(Self::ConsentConflict { reason })
}
"Authn:InvalidClient" => {
if envelope.error_code != "INVALID_ARGUMENT" {
return None;
}
let reason = envelope.parameters.get("reason")?.clone();
Some(Self::InvalidClient { reason })
}
"Authn:InvalidConsent" => {
if envelope.error_code != "INVALID_ARGUMENT" {
return None;
}
let reason = envelope.parameters.get("reason")?.clone();
Some(Self::InvalidConsent { reason })
}
_ => None,
}
}
}
impl Display for AuthnError {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
match self {
Self::ClientConflict { client_id } => {
write!(formatter, "Authn:ClientConflict (clientId: {})", client_id)
}
Self::ClientNotFound { client_id } => {
write!(formatter, "Authn:ClientNotFound (clientId: {})", client_id)
}
Self::ConsentConflict { reason } => {
write!(formatter, "Authn:ConsentConflict (reason: {})", reason)
}
Self::InvalidClient { reason } => {
write!(formatter, "Authn:InvalidClient (reason: {})", reason)
}
Self::InvalidConsent { reason } => {
write!(formatter, "Authn:InvalidConsent (reason: {})", reason)
}
}
}
}
impl StdError for AuthnError {}
impl ServiceError for AuthnError {
fn to_envelope(&self, instance: String) -> ErrorEnvelope {
Self::envelope(self, instance)
}
fn from_envelope(envelope: &ErrorEnvelope) -> Option<Self> {
Self::decode_envelope(envelope)
}
}