Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for generation of invite links with custom OAuth2 scopes (#…
- Loading branch information
Showing
8 changed files
with
254 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
use url::Url; | ||
|
||
use crate::http::client::Http; | ||
use crate::internal::prelude::*; | ||
use crate::model::prelude::*; | ||
|
||
/// A builder for constructing an invite link with custom OAuth2 scopes. | ||
#[derive(Debug, Clone, Default)] | ||
pub struct CreateBotAuthParameters { | ||
client_id: UserId, | ||
scopes: Vec<OAuth2Scope>, | ||
permissions: Permissions, | ||
guild_id: GuildId, | ||
disable_guild_select: bool, | ||
} | ||
|
||
impl CreateBotAuthParameters { | ||
/// Builds the url with the provided data. | ||
pub fn build(self) -> String { | ||
let mut valid_data = vec![]; | ||
let bits = self.permissions.bits(); | ||
|
||
if self.client_id.0 != 0 { | ||
valid_data.push(("cliend_id", self.client_id.0.to_string())); | ||
} | ||
|
||
if !self.scopes.is_empty() { | ||
valid_data.push(( | ||
"scope", | ||
self.scopes.iter().map(|i| i.to_string()).collect::<Vec<_>>().join(" "), | ||
)); | ||
} | ||
|
||
if bits != 0 { | ||
valid_data.push(("permissions", bits.to_string())); | ||
} | ||
|
||
if self.guild_id.0 != 0 { | ||
valid_data.push(("guild", self.guild_id.0.to_string())); | ||
} | ||
|
||
if self.disable_guild_select { | ||
valid_data.push(("disable_guild_select", self.disable_guild_select.to_string())); | ||
} | ||
|
||
let url = Url::parse_with_params("https://discord.com/api/oauth2/authorize", &valid_data) | ||
.expect("failed to construct URL"); | ||
|
||
url.to_string() | ||
} | ||
|
||
/// Specify the client Id of your application. | ||
pub fn client_id<U: Into<UserId>>(&mut self, client_id: U) -> &mut Self { | ||
self.client_id = client_id.into(); | ||
self | ||
} | ||
|
||
/// Automatically fetch and set the client Id of your application by inquiring Discord's API. | ||
/// | ||
/// # Errors | ||
/// | ||
/// Returns an | ||
/// [`HttpError::UnsuccessfulRequest(Unauthorized)`][`HttpError::UnsuccessfulRequest`] | ||
/// If the user is not authorized for this endpoint. | ||
/// | ||
/// [`HttpError::UnsuccessfulRequest`]: crate::http::HttpError::UnsuccessfulRequest | ||
pub async fn auto_client_id(&mut self, http: impl AsRef<Http>) -> Result<&mut Self> { | ||
self.client_id = http.as_ref().get_current_application_info().await.map(|v| v.id)?; | ||
Ok(self) | ||
} | ||
|
||
/// Specify the scopes for your application. | ||
/// | ||
/// **Note**: This needs to include the [`Bot`] scope. | ||
/// | ||
/// [`Bot`]: crate::model::oauth2::OAuth2Scope::Bot | ||
pub fn scopes(&mut self, scopes: &[OAuth2Scope]) -> &mut Self { | ||
self.scopes = scopes.to_vec(); | ||
self | ||
} | ||
|
||
/// Specify the permissions your application requires. | ||
pub fn permissions(&mut self, permissions: Permissions) -> &mut Self { | ||
self.permissions = permissions; | ||
self | ||
} | ||
|
||
/// Specify the Id of the guild to prefill the dropdown picker for the user. | ||
pub fn guild_id<G: Into<GuildId>>(&mut self, guild_id: G) -> &mut Self { | ||
self.guild_id = guild_id.into(); | ||
self | ||
} | ||
|
||
/// Specify whether the user cannot change the guild in the dropdown picker. | ||
pub fn disable_guild_select(&mut self, disable: bool) -> &mut Self { | ||
self.disable_guild_select = disable; | ||
self | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
use std::fmt; | ||
|
||
/// The available OAuth2 Scopes. | ||
#[non_exhaustive] | ||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] | ||
pub enum OAuth2Scope { | ||
/// For oauth2 bots, this puts the bot in the user's selected guild by default. | ||
Bot, | ||
/// Allows your app to use Slash Commands in a guild. | ||
ApplicationsCommands, | ||
/// Allows your app to update its Slash Commands via this bearer token - client credentials grant only. | ||
ApplicationsCommandsUpdate, | ||
|
||
/// Allows `/users/@me` without [`Self::Email`]. | ||
Identify, | ||
/// Enables `/users/@me` to return an `email` field. | ||
Email, | ||
/// Allows `/users/@me/connections` to return linked third-party accounts. | ||
Connections, | ||
/// Allows `/users/@me/guilds` to return basic information about all of a user's guilds. | ||
Guilds, | ||
/// Allows `/guilds/{guild.id}/members/{user.id}` to be used for joining users to a guild. | ||
GuildsJoin, | ||
/// Allows your app to join users to a group dm. | ||
GdmJoin, | ||
/// For local rpc server access, this allows you to control a user's local Discord client - | ||
/// requires Discord approval. | ||
Rpc, | ||
/// For local rpc server api access, this allows you to receive notifications pushed out to the user - requires Discord approval. | ||
RpcNotificationsRead, | ||
RpcVoiceRead, | ||
RpcVoiceWrite, | ||
RpcActivitiesWrite, | ||
/// This generates a webhook that is returned in the oauth token response for authorization code grants. | ||
WebhookIncomming, | ||
/// For local rpc server api access, this allows you to read messages from all client channels | ||
/// (otherwise restricted to channels/guilds your app creates). | ||
MessagesRead, | ||
/// Allows your app to upload/update builds for a user's applications - requires Discord approval. | ||
ApplicationsBuildsUpload, | ||
/// Allows your app to read build data for a user's applications. | ||
ApplicationsBuildsRead, | ||
/// Allows your app to read and update store data (SKUs, store listings, achievements, etc.) for a user's applications. | ||
ApplicationsStoreUpdate, | ||
/// Allows your app to read entitlements for a user's applications. | ||
ApplicationsEntitlements, | ||
/// Allows your app to fetch data from a user's "Now Playing/Recently Played" list - requires Discord approval. | ||
ActivitiesRead, | ||
/// allows your app to update a user's activity - requires Discord approval (Not required for gamesdk activity manager!). | ||
ActivitiesWrite, | ||
/// Allows your app to know a user's friends and implicit relationships - requires Discord approval. | ||
RelactionshipsRead, | ||
} | ||
|
||
impl fmt::Display for OAuth2Scope { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
let val = match self { | ||
Self::Bot => "bot", | ||
Self::ApplicationsCommands => "applications.commands", | ||
Self::ApplicationsCommandsUpdate => "applications.commands.update", | ||
Self::Identify => "identify", | ||
Self::Email => "email", | ||
Self::Connections => "connections", | ||
Self::Guilds => "guilds", | ||
Self::GuildsJoin => "guilds.join", | ||
Self::GdmJoin => "gdm.join", | ||
Self::Rpc => "rpc", | ||
Self::RpcNotificationsRead => "rpc.notifications.read", | ||
Self::RpcVoiceRead => "rpc.voice.read", | ||
Self::RpcVoiceWrite => "rpc.voice.write", | ||
Self::RpcActivitiesWrite => "rpc.activities.write", | ||
Self::WebhookIncomming => "webhook.incoming", | ||
Self::MessagesRead => "messages.read", | ||
Self::ApplicationsBuildsUpload => "applications.builds.upload", | ||
Self::ApplicationsBuildsRead => "applications.builds.read", | ||
Self::ApplicationsStoreUpdate => "applications.store.update", | ||
Self::ApplicationsEntitlements => "applications.entitlements", | ||
Self::ActivitiesRead => "activities.read", | ||
Self::ActivitiesWrite => "activities.write", | ||
Self::RelactionshipsRead => "relationships.read", | ||
}; | ||
|
||
write!(f, "{}", val) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters