systemprompt-oauth 0.1.18

OAuth 2.0 authentication and authorization module for systemprompt.io OS
Documentation
pub mod api;
pub mod dynamic_registration;

use std::fmt;
use std::str::FromStr;

pub use systemprompt_models::auth::JwtClaims;
pub use systemprompt_models::oauth::OAuthServerConfig as OAuthConfig;

#[derive(Debug, Clone)]
#[allow(clippy::enum_variant_names)]
pub enum OAuthParseError {
    InvalidGrantType(String),
    InvalidPkceMethod(String),
    InvalidResponseType(String),
    InvalidResponseMode(String),
    InvalidDisplayMode(String),
    InvalidPrompt(String),
    InvalidTokenAuthMethod(String),
}

impl fmt::Display for OAuthParseError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::InvalidGrantType(s) => write!(f, "unknown grant type: '{}'", s),
            Self::InvalidPkceMethod(s) => write!(f, "unknown PKCE method: '{}'", s),
            Self::InvalidResponseType(s) => write!(f, "unknown response type: '{}'", s),
            Self::InvalidResponseMode(s) => write!(f, "unknown response mode: '{}'", s),
            Self::InvalidDisplayMode(s) => write!(f, "unknown display mode: '{}'", s),
            Self::InvalidPrompt(s) => write!(f, "unknown prompt type: '{}'", s),
            Self::InvalidTokenAuthMethod(s) => write!(f, "unknown token auth method: '{}'", s),
        }
    }
}

impl std::error::Error for OAuthParseError {}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GrantType {
    AuthorizationCode,
    RefreshToken,
    ClientCredentials,
}

impl GrantType {
    pub const fn as_str(&self) -> &'static str {
        match self {
            Self::AuthorizationCode => "authorization_code",
            Self::RefreshToken => "refresh_token",
            Self::ClientCredentials => "client_credentials",
        }
    }

    pub const fn default_grant_types() -> &'static [&'static str] {
        &["authorization_code", "refresh_token"]
    }
}

impl FromStr for GrantType {
    type Err = OAuthParseError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "authorization_code" => Ok(Self::AuthorizationCode),
            "refresh_token" => Ok(Self::RefreshToken),
            "client_credentials" => Ok(Self::ClientCredentials),
            _ => Err(OAuthParseError::InvalidGrantType(s.to_string())),
        }
    }
}

impl fmt::Display for GrantType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(self.as_str())
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PkceMethod {
    S256,
    Plain,
}

impl PkceMethod {
    pub const fn as_str(&self) -> &'static str {
        match self {
            Self::S256 => "S256",
            Self::Plain => "plain",
        }
    }
}

impl FromStr for PkceMethod {
    type Err = OAuthParseError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "S256" => Ok(Self::S256),
            "plain" => Ok(Self::Plain),
            _ => Err(OAuthParseError::InvalidPkceMethod(s.to_string())),
        }
    }
}

impl fmt::Display for PkceMethod {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(self.as_str())
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResponseType {
    Code,
}

impl ResponseType {
    pub const fn as_str(&self) -> &'static str {
        match self {
            Self::Code => "code",
        }
    }
}

impl FromStr for ResponseType {
    type Err = OAuthParseError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "code" => Ok(Self::Code),
            _ => Err(OAuthParseError::InvalidResponseType(s.to_string())),
        }
    }
}

impl fmt::Display for ResponseType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(self.as_str())
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResponseMode {
    Query,
    Fragment,
}

impl ResponseMode {
    pub const fn as_str(&self) -> &'static str {
        match self {
            Self::Query => "query",
            Self::Fragment => "fragment",
        }
    }
}

impl FromStr for ResponseMode {
    type Err = OAuthParseError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "query" => Ok(Self::Query),
            "fragment" => Ok(Self::Fragment),
            _ => Err(OAuthParseError::InvalidResponseMode(s.to_string())),
        }
    }
}

impl fmt::Display for ResponseMode {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(self.as_str())
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DisplayMode {
    Page,
    Popup,
    Touch,
    Wap,
}

impl DisplayMode {
    pub const fn as_str(&self) -> &'static str {
        match self {
            Self::Page => "page",
            Self::Popup => "popup",
            Self::Touch => "touch",
            Self::Wap => "wap",
        }
    }
}

impl FromStr for DisplayMode {
    type Err = OAuthParseError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "page" => Ok(Self::Page),
            "popup" => Ok(Self::Popup),
            "touch" => Ok(Self::Touch),
            "wap" => Ok(Self::Wap),
            _ => Err(OAuthParseError::InvalidDisplayMode(s.to_string())),
        }
    }
}

impl fmt::Display for DisplayMode {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(self.as_str())
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Prompt {
    None,
    Login,
    Consent,
    SelectAccount,
}

impl Prompt {
    pub const fn as_str(&self) -> &'static str {
        match self {
            Self::None => "none",
            Self::Login => "login",
            Self::Consent => "consent",
            Self::SelectAccount => "select_account",
        }
    }
}

impl FromStr for Prompt {
    type Err = OAuthParseError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "none" => Ok(Self::None),
            "login" => Ok(Self::Login),
            "consent" => Ok(Self::Consent),
            "select_account" => Ok(Self::SelectAccount),
            _ => Err(OAuthParseError::InvalidPrompt(s.to_string())),
        }
    }
}

impl fmt::Display for Prompt {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(self.as_str())
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TokenAuthMethod {
    ClientSecretPost,
    ClientSecretBasic,
    None,
}

impl TokenAuthMethod {
    pub const fn as_str(&self) -> &'static str {
        match self {
            Self::ClientSecretPost => "client_secret_post",
            Self::ClientSecretBasic => "client_secret_basic",
            Self::None => "none",
        }
    }

    pub const fn default() -> Self {
        Self::ClientSecretPost
    }
}

impl FromStr for TokenAuthMethod {
    type Err = OAuthParseError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "client_secret_post" => Ok(Self::ClientSecretPost),
            "client_secret_basic" => Ok(Self::ClientSecretBasic),
            "none" => Ok(Self::None),
            _ => Err(OAuthParseError::InvalidTokenAuthMethod(s.to_string())),
        }
    }
}

impl fmt::Display for TokenAuthMethod {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(self.as_str())
    }
}