fix author perms

This commit is contained in:
nora 2022-06-19 21:14:35 +02:00
parent d91ee43933
commit aa6e57b2fa
6 changed files with 87 additions and 46 deletions

1
Cargo.lock generated
View file

@ -219,6 +219,7 @@ dependencies = [
"serde_json", "serde_json",
"tokio", "tokio",
"tracing", "tracing",
"tracing-error",
"tracing-subscriber", "tracing-subscriber",
"tracing-tree", "tracing-tree",
] ]

View file

@ -16,3 +16,4 @@ serde = { version = "1.0.137", features = ["derive"] }
serde_json = "1.0.81" serde_json = "1.0.81"
poise = "0.2.2" poise = "0.2.2"
tracing-tree = "0.2.1" tracing-tree = "0.2.1"
tracing-error = "0.2.0"

View file

@ -5,7 +5,6 @@ a very funny discord bot
.env .env
``` ```
DISCORD_TOKEN=token DISCORD_TOKEN=token
APPLICATION_ID=uwu
RUST_LOG=DEBUG RUST_LOG=DEBUG
MONGO_URI=mongodb://localhost:27017 MONGO_URI=mongodb://localhost:27017
DB_NAME=court_bot DB_NAME=court_bot

View file

@ -8,7 +8,7 @@ use tracing::{debug, error, info};
use crate::{ use crate::{
lawsuit::{Lawsuit, LawsuitCtx}, lawsuit::{Lawsuit, LawsuitCtx},
model::SnowflakeId, model::SnowflakeId,
Mongo, Report, WrapErr, Context, Mongo, Report, WrapErr,
}; };
pub struct Handler { pub struct Handler {
@ -73,17 +73,23 @@ impl Handler {
} }
pub mod lawsuit { pub mod lawsuit {
use color_eyre::eyre::eyre;
use super::*; use super::*;
#[poise::command(slash_command, subcommands("create", "set_category", "close", "clear"))] #[poise::command(
pub async fn lawsuit(_: crate::Context<'_>) -> Result<()> { slash_command,
guild_only,
subcommands("create", "set_category", "close", "clear")
)]
pub async fn lawsuit(_: Context<'_>) -> Result<()> {
unreachable!() unreachable!()
} }
/// Einen neuen Gerichtsprozess erstellen /// Einen neuen Gerichtsprozess erstellen
#[poise::command(slash_command, required_permissions = "MANAGE_GUILD")] #[poise::command(slash_command, guild_only, required_permissions = "MANAGE_GUILD")]
async fn create( async fn create(
ctx: crate::Context<'_>, ctx: Context<'_>,
#[description = "Der Kläger"] plaintiff: User, #[description = "Der Kläger"] plaintiff: User,
#[description = "Der Angeklagte"] accused: User, #[description = "Der Angeklagte"] accused: User,
#[description = "Der Richter"] judge: User, #[description = "Der Richter"] judge: User,
@ -105,9 +111,9 @@ pub mod lawsuit {
} }
/// Die Rolle für Gefangene setzen /// Die Rolle für Gefangene setzen
#[poise::command(slash_command, required_permissions = "MANAGE_GUILD")] #[poise::command(slash_command, guild_only, required_permissions = "MANAGE_GUILD")]
async fn set_category( async fn set_category(
ctx: crate::Context<'_>, ctx: Context<'_>,
#[description = "Die Kategorie"] category: Channel, #[description = "Die Kategorie"] category: Channel,
) -> Result<()> { ) -> Result<()> {
lawsuit_set_category_impl(ctx, category) lawsuit_set_category_impl(ctx, category)
@ -116,25 +122,22 @@ pub mod lawsuit {
} }
/// Den Gerichtsprozess abschliessen und ein Urteil fällen /// Den Gerichtsprozess abschliessen und ein Urteil fällen
#[poise::command(slash_command, required_permissions = "MANAGE_GUILD")] #[poise::command(slash_command, guild_only, required_permissions = "MANAGE_GUILD")]
async fn close( async fn close(ctx: Context<'_>, #[description = "Das Urteil"] verdict: String) -> Result<()> {
ctx: crate::Context<'_>,
#[description = "Das Urteil"] verdict: String,
) -> Result<()> {
lawsuit_close_impl(ctx, verdict) lawsuit_close_impl(ctx, verdict)
.await .await
.wrap_err("lawsuit_close") .wrap_err("lawsuit_close")
} }
/// Alle Rechtsprozessdaten löschen /// Alle Rechtsprozessdaten löschen
#[poise::command(slash_command, required_permissions = "MANAGE_GUILD")] #[poise::command(slash_command, guild_only, required_permissions = "MANAGE_GUILD")]
async fn clear(ctx: crate::Context<'_>) -> Result<()> { async fn clear(ctx: Context<'_>) -> Result<()> {
lawsuit_clear_impl(ctx).await.wrap_err("lawsuit_clear") lawsuit_clear_impl(ctx).await.wrap_err("lawsuit_clear")
} }
#[tracing::instrument(skip(ctx))] #[tracing::instrument(skip(ctx))]
async fn lawsuit_create_impl( async fn lawsuit_create_impl(
ctx: crate::Context<'_>, ctx: Context<'_>,
plaintiff: User, plaintiff: User,
accused: User, accused: User,
judge: User, judge: User,
@ -174,14 +177,9 @@ pub mod lawsuit {
} }
#[tracing::instrument(skip(ctx))] #[tracing::instrument(skip(ctx))]
async fn lawsuit_set_category_impl(ctx: crate::Context<'_>, category: Channel) -> Result<()> { async fn lawsuit_set_category_impl(ctx: Context<'_>, category: Channel) -> Result<()> {
let guild_id = ctx.guild_id().wrap_err("guild_id not found")?; let guild_id = ctx.guild_id().wrap_err("guild_id not found")?;
//let channel = channel
// .id
// .to_channel(&ctx.http)
// .await
// .wrap_err("fetch category for set_category")?;
match category.category() { match category.category() {
Some(category) => { Some(category) => {
let id = category.id; let id = category.id;
@ -200,14 +198,23 @@ pub mod lawsuit {
} }
#[tracing::instrument(skip(ctx))] #[tracing::instrument(skip(ctx))]
async fn lawsuit_close_impl(ctx: crate::Context<'_>, verdict: String) -> Result<()> { async fn lawsuit_close_impl(ctx: Context<'_>, verdict: String) -> Result<()> {
let guild_id = ctx.guild_id().wrap_err("guild_id not found")?; let guild_id = ctx.guild_id().wrap_err("guild_id not found")?;
let member = ctx.author_member().await.wrap_err("member not found")?; let application_context = match ctx {
Context::Application(ctx) => ctx,
Context::Prefix(_) => return Err(eyre!("wrong context, cannot happen!")),
};
let member = application_context
.interaction
.member()
.wrap_err("member not found")?;
let permission_override = member let permission_override = member
.permissions .permissions
.wrap_err("permissions not found")? .map(|p| p.contains(Permissions::MANAGE_GUILD))
.contains(Permissions::MANAGE_GUILD); .unwrap_or(false);
let room_id = ctx.channel_id(); let room_id = ctx.channel_id();
let mongo_client = &ctx.data().mongo; let mongo_client = &ctx.data().mongo;
@ -269,7 +276,7 @@ pub mod lawsuit {
} }
#[tracing::instrument(skip(ctx))] #[tracing::instrument(skip(ctx))]
async fn lawsuit_clear_impl(ctx: crate::Context<'_>) -> Result<()> { async fn lawsuit_clear_impl(ctx: Context<'_>) -> Result<()> {
let guild_id = ctx.guild_id().wrap_err("guild_id not found")?; let guild_id = ctx.guild_id().wrap_err("guild_id not found")?;
ctx.data().mongo.delete_guild(guild_id.into()).await?; ctx.data().mongo.delete_guild(guild_id.into()).await?;
@ -280,27 +287,27 @@ pub mod lawsuit {
pub mod prison { pub mod prison {
use super::*; use super::*;
#[poise::command(
#[poise::command(slash_command, subcommands("set_role", "arrest", "release"))] slash_command,
pub async fn prison(_: crate::Context<'_>) -> Result<()> { guild_only,
subcommands("set_role", "arrest", "release")
)]
pub async fn prison(_: Context<'_>) -> Result<()> {
unreachable!() unreachable!()
} }
/// Die Rolle für Gefangene setzen /// Die Rolle für Gefangene setzen
#[poise::command(slash_command, required_permissions = "MANAGE_GUILD")] #[poise::command(slash_command, guild_only, required_permissions = "MANAGE_GUILD")]
async fn set_role( async fn set_role(ctx: Context<'_>, #[description = "Die Rolle"] role: Role) -> Result<()> {
ctx: crate::Context<'_>,
#[description = "Die Rolle"] role: Role,
) -> Result<()> {
prison_set_role_impl(ctx, role) prison_set_role_impl(ctx, role)
.await .await
.wrap_err("prison_set_role") .wrap_err("prison_set_role")
} }
/// Jemanden einsperren /// Jemanden einsperren
#[poise::command(slash_command, required_permissions = "MANAGE_GUILD")] #[poise::command(slash_command, guild_only, required_permissions = "MANAGE_GUILD")]
async fn arrest( async fn arrest(
ctx: crate::Context<'_>, ctx: Context<'_>,
#[description = "Die Person zum einsperren"] user: User, #[description = "Die Person zum einsperren"] user: User,
) -> Result<()> { ) -> Result<()> {
prison_arrest_impl(ctx, user) prison_arrest_impl(ctx, user)
@ -309,9 +316,9 @@ pub mod prison {
} }
/// Einen Gefangenen freilassen /// Einen Gefangenen freilassen
#[poise::command(slash_command, required_permissions = "MANAGE_GUILD")] #[poise::command(slash_command, guild_only, required_permissions = "MANAGE_GUILD")]
async fn release( async fn release(
ctx: crate::Context<'_>, ctx: Context<'_>,
#[description = "Die Person zum freilassen"] user: User, #[description = "Die Person zum freilassen"] user: User,
) -> Result<()> { ) -> Result<()> {
prison_release_impl(ctx, user) prison_release_impl(ctx, user)
@ -320,7 +327,7 @@ pub mod prison {
} }
#[tracing::instrument(skip(ctx))] #[tracing::instrument(skip(ctx))]
async fn prison_set_role_impl(ctx: crate::Context<'_>, role: Role) -> Result<()> { async fn prison_set_role_impl(ctx: Context<'_>, role: Role) -> Result<()> {
ctx.data() ctx.data()
.mongo .mongo
.set_prison_role( .set_prison_role(
@ -335,7 +342,7 @@ pub mod prison {
} }
#[tracing::instrument(skip(ctx))] #[tracing::instrument(skip(ctx))]
async fn prison_arrest_impl(ctx: crate::Context<'_>, user: User) -> Result<()> { async fn prison_arrest_impl(ctx: Context<'_>, user: User) -> Result<()> {
let mongo_client = &ctx.data().mongo; let mongo_client = &ctx.data().mongo;
let guild_id = ctx.guild_id().wrap_err("guild_id not found")?; let guild_id = ctx.guild_id().wrap_err("guild_id not found")?;
let http = &ctx.discord().http; let http = &ctx.discord().http;
@ -363,11 +370,14 @@ pub mod prison {
.add_role(http, role) .add_role(http, role)
.await .await
.wrap_err("add guild member role")?; .wrap_err("add guild member role")?;
ctx.say("isch igsperrt").await?;
Ok(()) Ok(())
} }
#[tracing::instrument(skip(ctx))] #[tracing::instrument(skip(ctx))]
async fn prison_release_impl(ctx: crate::Context<'_>, user: User) -> Result<()> { async fn prison_release_impl(ctx: Context<'_>, user: User) -> Result<()> {
let mongo_client = &ctx.data().mongo; let mongo_client = &ctx.data().mongo;
let guild_id = ctx.guild_id().wrap_err("guild_id not found")?; let guild_id = ctx.guild_id().wrap_err("guild_id not found")?;
let http = &ctx.discord().http; let http = &ctx.discord().http;

View file

@ -154,7 +154,9 @@ async fn hello(ctx: Context<'_>) -> Result<()> {
} }
fn setup_tracing(pretty: bool) { fn setup_tracing(pretty: bool) {
let registry = Registry::default().with(EnvFilter::from_default_env()); let registry = Registry::default()
.with(EnvFilter::from_default_env())
.with(tracing_error::ErrorLayer::default());
if pretty { if pretty {
let tree_layer = tracing_tree::HierarchicalLayer::new(2) let tree_layer = tracing_tree::HierarchicalLayer::new(2)

View file

@ -8,8 +8,8 @@ use color_eyre::Result;
use mongodb::{ use mongodb::{
bson, bson,
bson::{doc, Bson, Uuid}, bson::{doc, Bson, Uuid},
options::{ClientOptions, Credential, UpdateOptions}, options::{ClientOptions, Credential, IndexOptions, UpdateOptions},
Client, Collection, Database, Client, Collection, Database, IndexModel,
}; };
use poise::serenity::model::id::{ChannelId, GuildId, RoleId, UserId}; use poise::serenity::model::id::{ChannelId, GuildId, RoleId, UserId};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -114,6 +114,7 @@ pub struct Mongo {
} }
impl Mongo { impl Mongo {
#[tracing::instrument(skip(password))]
pub async fn connect( pub async fn connect(
uri: &str, uri: &str,
db_name: &str, db_name: &str,
@ -133,8 +134,35 @@ impl Mongo {
let client = Client::with_options(client_options).wrap_err("failed to create client")?; let client = Client::with_options(client_options).wrap_err("failed to create client")?;
let db = client.database(db_name); let db = client.database(db_name);
let mongo = Self { db };
Ok(Self { db }) info!("Creating indexes");
mongo
.state_coll()
.create_index(
IndexModel::builder()
.keys(doc! { "guild_id": 1 })
.options(IndexOptions::builder().name("state.guild_id".to_string()).build())
.build(),
None,
)
.await
.wrap_err("create state index")?;
mongo
.prison_coll()
.create_index(
IndexModel::builder()
.keys(doc! { "guild_id": 1, "user_id": 1 })
.options(IndexOptions::builder().name("prison.guild_id_user_id".to_string()).build())
.build(),
None,
)
.await
.wrap_err("create state index")?;
Ok(mongo)
} }
#[tracing::instrument(skip(self))] #[tracing::instrument(skip(self))]