feat: initial oauth2 implementation
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
use super::User;
|
||||
|
||||
#[cfg(feature = "validator")]
|
||||
use validator::Validate;
|
||||
|
||||
auto_derived!(
|
||||
/// Bot
|
||||
#[derive(Default)]
|
||||
@@ -48,6 +51,13 @@ auto_derived!(
|
||||
)]
|
||||
pub privacy_policy_url: String,
|
||||
|
||||
/// Oauth2 bot settings
|
||||
#[cfg_attr(
|
||||
feature = "serde",
|
||||
serde(skip_serializing_if = "Option::is_none", default)
|
||||
)]
|
||||
pub oauth2: Option<BotOauth2>,
|
||||
|
||||
/// Enum of bot flags
|
||||
#[cfg_attr(
|
||||
feature = "serde",
|
||||
@@ -60,6 +70,8 @@ auto_derived!(
|
||||
pub enum FieldsBot {
|
||||
Token,
|
||||
InteractionsURL,
|
||||
Oauth2,
|
||||
Oauth2Secret,
|
||||
}
|
||||
|
||||
/// Flags that may be attributed to a bot
|
||||
@@ -101,7 +113,7 @@ auto_derived!(
|
||||
|
||||
/// Bot Details
|
||||
#[derive(Default)]
|
||||
#[cfg_attr(feature = "validator", derive(validator::Validate))]
|
||||
#[cfg_attr(feature = "validator", derive(Validate))]
|
||||
pub struct DataCreateBot {
|
||||
/// Bot username
|
||||
#[cfg_attr(
|
||||
@@ -113,7 +125,7 @@ auto_derived!(
|
||||
|
||||
/// New Bot Details
|
||||
#[derive(Default)]
|
||||
#[cfg_attr(feature = "validator", derive(validator::Validate))]
|
||||
#[cfg_attr(feature = "validator", derive(Validate))]
|
||||
pub struct DataEditBot {
|
||||
/// Bot username
|
||||
#[cfg_attr(
|
||||
@@ -131,11 +143,24 @@ auto_derived!(
|
||||
/// Interactions URL
|
||||
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 2048)))]
|
||||
pub interactions_url: Option<String>,
|
||||
|
||||
#[cfg_attr(feature = "validator", validate)]
|
||||
pub oauth2: Option<DataEditBotOauth2>,
|
||||
|
||||
/// Fields to remove from bot object
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
pub remove: Vec<FieldsBot>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
#[cfg_attr(feature = "validator", derive(Validate))]
|
||||
pub struct DataEditBotOauth2 {
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
pub public: Option<bool>,
|
||||
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 10)))]
|
||||
pub redirects: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
/// Where we are inviting a bot to
|
||||
#[serde(untagged)]
|
||||
pub enum InviteBotDestination {
|
||||
@@ -170,3 +195,19 @@ auto_derived!(
|
||||
pub user: User,
|
||||
}
|
||||
);
|
||||
|
||||
auto_derived_partial!(
|
||||
/// Bot Oauth2 information
|
||||
pub struct BotOauth2 {
|
||||
/// Whether the oauth client is public and should not receive a secret key
|
||||
#[serde(default)]
|
||||
pub public: bool,
|
||||
/// Secret key used for authorisation, not provided if the client is public
|
||||
#[serde(default)]
|
||||
pub secret: Option<String>,
|
||||
/// Allowed redirects for the authorisation
|
||||
#[serde(default)]
|
||||
pub redirects: Vec<String>
|
||||
},
|
||||
"PartialBotOauth2"
|
||||
);
|
||||
@@ -7,6 +7,7 @@ mod embeds;
|
||||
mod emojis;
|
||||
mod files;
|
||||
mod messages;
|
||||
mod oauth2;
|
||||
mod policy_changes;
|
||||
mod safety_reports;
|
||||
mod server_bans;
|
||||
@@ -24,6 +25,7 @@ pub use embeds::*;
|
||||
pub use emojis::*;
|
||||
pub use files::*;
|
||||
pub use messages::*;
|
||||
pub use oauth2::*;
|
||||
pub use policy_changes::*;
|
||||
pub use safety_reports::*;
|
||||
pub use server_bans::*;
|
||||
|
||||
101
crates/core/models/src/v0/oauth2.rs
Normal file
101
crates/core/models/src/v0/oauth2.rs
Normal file
@@ -0,0 +1,101 @@
|
||||
use crate::v0::{Bot, User};
|
||||
|
||||
auto_derived!(
|
||||
pub struct OAuth2AuthorizeAuthResponse {
|
||||
/// Redirect URI which will contain the access token
|
||||
pub redirect_uri: String,
|
||||
}
|
||||
|
||||
pub struct OAuth2AuthorizeInfoResponse {
|
||||
pub bot: Bot,
|
||||
pub user: User,
|
||||
}
|
||||
|
||||
#[derive(Copy)]
|
||||
#[cfg_attr(feature = "serde", serde(rename = "lowercase"))]
|
||||
#[cfg_attr(feature = "rocket", derive(rocket::FromFormField))]
|
||||
pub enum OAuth2ResponseType {
|
||||
#[cfg_attr(feature = "rocket", field(value = "code"))]
|
||||
Code,
|
||||
#[cfg_attr(feature = "rocket", field(value = "token"))]
|
||||
Token,
|
||||
}
|
||||
|
||||
#[derive(Copy)]
|
||||
#[cfg_attr(feature = "rocket", derive(rocket::FromFormField))]
|
||||
pub enum OAuth2GrantType {
|
||||
#[cfg_attr(feature = "rocket", field(value = "code"))]
|
||||
#[cfg_attr(feature = "serde", serde(rename = "code"))]
|
||||
AuthorizationCode,
|
||||
#[cfg_attr(feature = "rocket", field(value = "implicit"))]
|
||||
#[cfg_attr(feature = "serde", serde(rename = "implicit"))]
|
||||
Implicit,
|
||||
}
|
||||
|
||||
#[derive(Copy)]
|
||||
#[cfg_attr(feature = "rocket", derive(rocket::FromFormField))]
|
||||
pub enum OAuth2CodeChallangeMethod {
|
||||
#[cfg_attr(feature = "rocket", field(value = "plain"))]
|
||||
#[cfg_attr(feature = "serde", serde(rename = "plain"))]
|
||||
Plain,
|
||||
S256
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "rocket", derive(rocket::FromForm))]
|
||||
pub struct OAuth2AuthorizationForm {
|
||||
pub client_id: String,
|
||||
pub scope: String,
|
||||
pub redirect_uri: String,
|
||||
pub response_type: OAuth2ResponseType,
|
||||
pub state: Option<String>,
|
||||
pub code_challenge: Option<String>,
|
||||
pub code_challenge_method: Option<OAuth2CodeChallangeMethod>,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "rocket", derive(rocket::FromForm))]
|
||||
pub struct OAuth2TokenExchangeForm {
|
||||
pub grant_type: OAuth2GrantType,
|
||||
|
||||
pub client_id: String,
|
||||
pub client_secret: Option<String>,
|
||||
|
||||
pub code: String,
|
||||
pub code_verifier: Option<String>,
|
||||
}
|
||||
|
||||
pub struct OAuth2TokenExchangeResponse {
|
||||
pub access_token: String,
|
||||
pub token_type: String,
|
||||
pub scope: String,
|
||||
}
|
||||
|
||||
pub enum OAuth2Scope {
|
||||
Identify,
|
||||
Full,
|
||||
}
|
||||
);
|
||||
|
||||
impl OAuth2Scope {
|
||||
#[allow(clippy::should_implement_trait)]
|
||||
pub fn from_str(str: &str) -> Option<OAuth2Scope> {
|
||||
match str {
|
||||
"identify" => Some(OAuth2Scope::Identify),
|
||||
"full" => Some(OAuth2Scope::Full),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scopes_from_str(string: &str) -> Option<Vec<OAuth2Scope>> {
|
||||
let mut scopes = Vec::new();
|
||||
|
||||
for scope in string.split(' ') {
|
||||
if let Some(scope) = OAuth2Scope::from_str(scope) {
|
||||
scopes.push(scope);
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
Some(scopes)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user