Skip to content

Commit

Permalink
Add OAuth2Token, OAuth2TokenRevocation, and `OAuth2AuthorizationC…
Browse files Browse the repository at this point in the history
…urrent` to `Route`
  • Loading branch information
valentinegb committed Aug 6, 2024
1 parent 640fa8a commit d506d98
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/http/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2944,7 +2944,7 @@ impl Http {
multipart: None,
headers: None,
method: LightMethod::Get,
route: Route::Oauth2ApplicationCurrent,
route: Route::OAuth2ApplicationCurrent,
params: None,
})
.await
Expand Down
6 changes: 3 additions & 3 deletions src/http/ratelimiting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ impl Ratelimiter {
timeout: Duration::from_secs_f64(retry_after),
limit: 50,
method: req.method,
path: req.route.path(),
path: req.route.clone().path(),
global: true,
});
sleep(Duration::from_secs_f64(retry_after)).await;
Expand Down Expand Up @@ -322,7 +322,7 @@ impl Ratelimit {
timeout: delay,
limit: self.limit,
method: req.method,
path: req.route.path(),
path: req.route.clone().path(),
global: false,
});

Expand Down Expand Up @@ -380,7 +380,7 @@ impl Ratelimit {
timeout: Duration::from_secs_f64(retry_after),
limit: self.limit,
method: req.method,
path: req.route.path(),
path: req.route.clone().path(),
global: false,
});

Expand Down
74 changes: 71 additions & 3 deletions src/http/routing.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use std::borrow::Cow;

use url::Url;

use crate::model::application::{GrantType, Scope, TokenTypeHint};
use crate::model::id::*;

/// Used to group requests together for ratelimiting.
Expand Down Expand Up @@ -32,7 +35,7 @@ macro_rules! routes {
$ratelimiting_kind:expr;
)+
}) => {
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Debug)]
pub enum Route<$lt> {
$(
$name $({ $($field_name: $field_type),* })?,
Expand Down Expand Up @@ -65,7 +68,7 @@ macro_rules! routes {
#[must_use]
pub fn ratelimiting_bucket(&self) -> RatelimitingBucket {
#[allow(unused_variables)]
let ratelimiting_kind = match *self {
let ratelimiting_kind = match self {
$(
Self::$name $({ $($field_name),* })? => $ratelimiting_kind,
)+
Expand Down Expand Up @@ -361,7 +364,7 @@ routes! ('a, {
api!("/invites/{}", code),
Some(RatelimitingKind::Path);

Oauth2ApplicationCurrent,
OAuth2ApplicationCurrent,
api!("/oauth2/applications/@me"),
None;

Expand Down Expand Up @@ -496,4 +499,69 @@ routes! ('a, {
StageInstance { channel_id: ChannelId },
api!("/stage-instances/{}", channel_id),
Some(RatelimitingKind::Path);

OAuth2Token {
state: Option<&'a str>,
grant_type: GrantType,
code: Option<&'a str>,
redirect_uri: Option<&'a Url>,
refresh_token: Option<&'a str>,
scope: Vec<Scope>
},
api!(
"/oauth2/token?{}grant_type={}{}{}{}{}",
if let Some(state) = state {
format!("state={state}&")
} else {
String::new()
},
grant_type,
if let Some(code) = code {
format!("&code={code}")
} else {
String::new()
},
if let Some(redirect_uri) = redirect_uri {
format!("&redirect_uri={redirect_uri}")
} else {
String::new()
},
if let Some(refresh_token) = refresh_token {
format!("&refresh_token={refresh_token}")
} else {
String::new()
},
if scope.is_empty() {
String::new()
} else {
format!(
"&scope={}",
scope
.into_iter()
.map(|scope| scope.to_string())
.collect::<Vec<String>>()
.join(" "),
)
},
),
None;

OAuth2TokenRevocation {
token: &'a str,
token_type_hint: Option<TokenTypeHint>
},
api!(
"/oauth2/token/revoke?token={}{}",
token,
if let Some(token_type_hint) = token_type_hint {
format!("&token_type_hint={token_type_hint}")
} else {
String::new()
},
),
None;

OAuth2AuthorizationCurrent,
api!("/oauth2/@me"),
None;
});
47 changes: 47 additions & 0 deletions src/model/application/oauth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,50 @@ impl fmt::Display for Scope {
self.serialize(f)
}
}

/// The type of OAuth2 grant.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GrantType {
/// Grants a token using a previously acquired authorization code.
///
/// [Discord docs](https://discord.com/developers/docs/topics/oauth2#authorization-code-grant).
AuthorizationCode,
/// Grants a new token using a refresh token.
///
/// [Discord docs](https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-refresh-token-exchange-example).
RefreshToken,
/// Grants the bot owner's token using client credentials.
///
/// [Discord docs](https://discord.com/developers/docs/topics/oauth2#client-credentials-grant).
ClientCredentials,
}

impl fmt::Display for GrantType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", match self {
GrantType::AuthorizationCode => "authorization_code",
GrantType::RefreshToken => "refresh_token",
GrantType::ClientCredentials => "client_credentials",
})
}
}

/// Hints a type of token.
///
/// [Discord docs](https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-token-revocation-example).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TokenTypeHint {
/// Hints that a token is an access token.
AccessToken,
/// Hints that a token is a refresh token.
RefreshToken,
}

impl fmt::Display for TokenTypeHint {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", match self {
TokenTypeHint::AccessToken => "access_token",
TokenTypeHint::RefreshToken => "refresh_token",
})
}
}

0 comments on commit d506d98

Please sign in to comment.