Skip to content

Commit 0be3fc9

Browse files
committed
refactor rollout + implement ephemeral errors
1 parent d33593c commit 0be3fc9

File tree

5 files changed

+157
-78
lines changed

5 files changed

+157
-78
lines changed

src/db/rollout.rs

+1
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ pub struct Rollout {
264264
// temporary implementation - so that there is no warning
265265
impl Rollout {
266266
#[allow(dead_code)]
267+
267268
pub fn get_created_at(
268269
&self
269270
) -> &str {

src/discord.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub mod commands;
2+
pub mod utils;
23

34
use poise::{
45
framework,

src/discord/commands/rollout.rs

+49-78
Original file line numberDiff line numberDiff line change
@@ -14,41 +14,12 @@ pub async fn create_rollout(
1414
crate::discord::commands::Error
1515
> {
1616

17-
let guild = ctx
18-
.http()
19-
.get_guild(
20-
crate::env::GUILD_ID
21-
.as_str()
22-
.parse()
23-
.unwrap()
24-
)
25-
.await?;
26-
27-
let role = guild
28-
.roles
29-
.get(
30-
&crate::env::ROLE_ID
31-
.as_str()
32-
.parse()
33-
.unwrap()
34-
)
35-
.unwrap();
36-
37-
if !ctx
38-
.author()
39-
.has_role(
40-
ctx.http(),
41-
&guild,
42-
role
43-
)
44-
.await?
45-
{
46-
47-
ctx.say("You don't have permission to use this command")
48-
.await?;
49-
17+
if !crate::discord::utils::no_perm::check_and_send_no_perm(
18+
ctx,
19+
ctx.author()
20+
).await? {
5021
return Ok(());
51-
}
22+
};
5223

5324
// Add rollout to queue
5425
let build_queue = ctx
@@ -95,51 +66,51 @@ pub async fn create_rollout(
9566

9667
ctx.send(response).await?;
9768

98-
while let Some(mci) = serenity_prelude::ComponentInteractionCollector::new(ctx.serenity_context())
69+
while let Some(component_interaction) = serenity_prelude::ComponentInteractionCollector::new(ctx.serenity_context())
9970
.timeout(std::time::Duration::from_secs(120))
10071
.filter(move |mci| mci.data.custom_id.starts_with("approve-") || mci.data.custom_id.starts_with("reject-"))
10172
.await
10273
{
10374

10475
// check permissions
10576

106-
if !mci.
107-
user
108-
.has_role(
109-
ctx.http(),
110-
&guild,
111-
role
112-
)
113-
.await?
114-
{
115-
116-
let embed = serenity_prelude::CreateEmbed::default()
117-
.title("Oops!")
118-
.description("You don't have permission to use this interaction".to_string())
119-
.author(
120-
serenity_prelude::CreateEmbedAuthor::new(&mci.user.name)
121-
.icon_url(mci.user.avatar_url().unwrap_or_default())
122-
.url(mci.user.avatar_url().unwrap_or_default())
77+
crate::discord::utils::no_perm::check_and_send_no_perm(ctx, &component_interaction.user).await?;
78+
79+
// If interactor and creator are same, disregard it because
80+
// author can't approve or deny their own rollout
81+
if component_interaction.user.id == ctx.author().id {
82+
ctx
83+
.send(
84+
poise::CreateReply::default()
85+
.embed(
86+
poise::serenity_prelude::CreateEmbed::new()
87+
.title("Invalid action")
88+
.description(
89+
"You are not allowed to approve or deny your own rollout"
90+
)
91+
.color(0xFF0000)
12392
)
124-
.color(0xFF0000);
125-
126-
let reply = serenity_prelude::CreateInteractionResponseMessage::new()
127-
.embed(embed);
93+
.ephemeral(true)
94+
).await?;
12895

129-
mci.create_response(ctx, serenity_prelude::CreateInteractionResponse::Message(reply)).await?;
96+
component_interaction
97+
.create_response(
98+
ctx,
99+
serenity_prelude::CreateInteractionResponse::Acknowledge
100+
).await?;
130101

131-
continue;
102+
return Ok(());
132103
}
133104

134-
if mci.data.custom_id == format!("approve-{}", version) {
105+
if component_interaction.data.custom_id == format!("approve-{}", version) {
135106
let build_queue = ctx
136107
.data()
137108
.build_queue
138109
.lock()
139110
.await;
140111

141112
let success = build_queue
142-
.approve_rollout(&version, mci.user.id.get())
113+
.approve_rollout(&version, component_interaction.user.id.get())
143114
.expect(
144115
"failed to approve rollout",
145116
);
@@ -152,15 +123,15 @@ pub async fn create_rollout(
152123

153124
if !success {
154125
let embed = serenity_prelude::CreateEmbed::default()
155-
.title("Oops!")
156-
.description("There was an error approving the rollout. This version may have already been approved or rejected or it was your own rollout.")
126+
.title("Invalid action")
127+
.description("There was an error approving the rollout. This version may have already been approved.")
157128
.color(0xFF0000);
158129

159130
let reply = poise::CreateReply::default()
160131
.embed(embed);
161132

162133
ctx.send(reply).await?;
163-
mci.create_response(ctx, serenity_prelude::CreateInteractionResponse::Acknowledge).await?;
134+
component_interaction.create_response(ctx, serenity_prelude::CreateInteractionResponse::Acknowledge).await?;
164135
continue;
165136
}
166137

@@ -173,30 +144,30 @@ pub async fn create_rollout(
173144
". The rollout has not been started because it has not been approved by enough people."
174145
};
175146

176-
let embed_author = serenity_prelude::CreateEmbedAuthor::new(&mci.user.name)
177-
.icon_url(mci.user.avatar_url().unwrap_or_default())
178-
.url(mci.user.avatar_url().unwrap_or_default());
147+
let embed_author = serenity_prelude::CreateEmbedAuthor::new(&component_interaction.user.name)
148+
.icon_url(component_interaction.user.avatar_url().unwrap_or_default())
149+
.url(component_interaction.user.avatar_url().unwrap_or_default());
179150

180151
let embed = serenity_prelude::CreateEmbed::default()
181152
.title("Rollout Approved")
182-
.description(format!("Rollout of version {} has been approved by {}{} FUCK THIS SHIT {}", version, &mci.user.name, extra, &mci.data.custom_id))
153+
.description(format!("Rollout of version {} has been approved by {}{}. ID: {}", version, &component_interaction.user.name, extra, &component_interaction.data.custom_id))
183154
.author(embed_author)
184155
.color(0x00FF00);
185156

186157
let reply = poise::CreateReply::default()
187158
.embed(embed);
188159

189160
ctx.send(reply).await?;
190-
mci.create_response(ctx, serenity_prelude::CreateInteractionResponse::Acknowledge).await?;
191-
} else if mci.data.custom_id == format!("reject-{}", version) {
161+
component_interaction.create_response(ctx, serenity_prelude::CreateInteractionResponse::Acknowledge).await?;
162+
} else if component_interaction.data.custom_id == format!("reject-{}", version) {
192163
let build_queue = ctx
193164
.data()
194165
.build_queue
195166
.lock()
196167
.await;
197168

198169
let success = build_queue
199-
.reject_rollout(&version, mci.user.id.get())
170+
.reject_rollout(&version, component_interaction.user.id.get())
200171
.expect(
201172
"failed to reject rollout",
202173
);
@@ -205,33 +176,33 @@ pub async fn create_rollout(
205176

206177
if !success {
207178
let embed = serenity_prelude::CreateEmbed::default()
208-
.title("Oops!")
209-
.description("There was an error rejecting the rollout. This version may have already been approved or rejected or it was your own rollout.")
179+
.title("Invalid action")
180+
.description("There was an error rejecting the rollout. This version may have already been rejected.")
210181
.color(0xFF0000);
211182

212183
let reply = poise::CreateReply::default()
213184
.embed(embed);
214185

215186
ctx.send(reply).await?;
216-
mci.create_response(ctx, serenity_prelude::CreateInteractionResponse::Acknowledge).await?;
187+
component_interaction.create_response(ctx, serenity_prelude::CreateInteractionResponse::Acknowledge).await?;
217188
continue;
218189
}
219190

220-
let embed_author = serenity_prelude::CreateEmbedAuthor::new(&mci.user.name)
221-
.icon_url(mci.user.avatar_url().unwrap_or_default())
222-
.url(mci.user.avatar_url().unwrap_or_default());
191+
let embed_author = serenity_prelude::CreateEmbedAuthor::new(&component_interaction.user.name)
192+
.icon_url(component_interaction.user.avatar_url().unwrap_or_default())
193+
.url(component_interaction.user.avatar_url().unwrap_or_default());
223194

224195
let embed = serenity_prelude::CreateEmbed::default()
225196
.title("Rollout Rejected")
226-
.description(format!("Rollout of version {} has been rejected by {}. Cancelling rollout", version, &mci.user.name))
197+
.description(format!("Rollout of version {} has been rejected by {}. Cancelling rollout", version, &component_interaction.user.name))
227198
.author(embed_author)
228199
.color(0xFF0000);
229200

230201
let reply = poise::CreateReply::default()
231202
.embed(embed);
232203

233204
ctx.send(reply).await?;
234-
mci.create_response(ctx, serenity_prelude::CreateInteractionResponse::Acknowledge).await?;
205+
component_interaction.create_response(ctx, serenity_prelude::CreateInteractionResponse::Acknowledge).await?;
235206
}
236207
}
237208

src/discord/utils.rs

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
pub mod no_perm;
2+
3+
use poise::serenity_prelude;
4+
5+
pub async fn get_guild(
6+
ctx: crate::discord::commands::Context<'_>
7+
) -> serenity_prelude::PartialGuild {
8+
9+
ctx.http()
10+
.get_guild(
11+
crate::env::GUILD_ID
12+
.as_str()
13+
.parse()
14+
.unwrap()
15+
)
16+
.await
17+
.unwrap()
18+
}
19+
20+
fn get_role<'a>(
21+
guild: &'a serenity_prelude::PartialGuild
22+
) -> &'a serenity_prelude::Role {
23+
24+
guild
25+
.roles
26+
.get(
27+
&crate::env::ROLE_ID
28+
.as_str()
29+
.parse()
30+
.unwrap()
31+
)
32+
.unwrap()
33+
}

src/discord/utils/no_perm.rs

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
use poise::serenity_prelude;
2+
3+
// check if there is permission or not
4+
// returns true if user has role (which is what determines the permissions)
5+
// returns false if user doesn't have the role (unauthorized)
6+
pub async fn check_perms(
7+
ctx: crate::discord::commands::Context<'_>,
8+
user: &poise::serenity_prelude::User
9+
) -> bool {
10+
11+
let guild: serenity_prelude::PartialGuild = crate::discord::utils::get_guild(ctx).await;
12+
13+
let role: &serenity_prelude::Role =
14+
&crate::discord::utils::get_role(
15+
&guild
16+
);
17+
18+
if !user
19+
.has_role(
20+
ctx.http(),
21+
&guild,
22+
role
23+
)
24+
.await
25+
.unwrap()
26+
{
27+
28+
return false;
29+
}
30+
31+
true
32+
}
33+
34+
// Send no permission message
35+
pub async fn send_no_perm(
36+
ctx: crate::discord::commands::Context<'_>
37+
) -> Result<
38+
(),
39+
crate::discord::commands::Error
40+
> {
41+
42+
ctx
43+
.send(
44+
poise::CreateReply::default()
45+
.embed(
46+
poise::serenity_prelude::CreateEmbed::new()
47+
.title("Permission denied")
48+
.description("You are not allowed to perform this action.")
49+
.color(0xFF0000)
50+
)
51+
.ephemeral(true)
52+
).await?;
53+
54+
Ok(())
55+
}
56+
57+
pub async fn check_and_send_no_perm(
58+
ctx: crate::discord::commands::Context<'_>,
59+
user: &poise::serenity_prelude::User
60+
) -> Result<
61+
bool,
62+
crate::discord::commands::Error
63+
> {
64+
65+
if !check_perms(ctx, user).await {
66+
67+
send_no_perm(ctx).await?;
68+
69+
return Ok(false);
70+
}
71+
72+
Ok(true)
73+
}

0 commit comments

Comments
 (0)