diff --git a/discord/ctf.go b/discord/ctf.go index 16ab39e..0a5b797 100644 --- a/discord/ctf.go +++ b/discord/ctf.go @@ -40,6 +40,7 @@ func (s *Server) handleCommandNewCTF(event *handler.CommandEvent) error { _, err = event.CreateFollowupMessage(discord.NewMessageCreateBuilder(). SetEmbeds(discord.NewEmbedBuilder(). SetColor(ColorBlurple). + SetTitle(":white_check_mark: Confirm creation"). SetDescriptionf("Would you like to create a new CTF named `%s`?", ctfName). Build()). SetEphemeral(true). @@ -101,10 +102,11 @@ func (s *Server) handleCommandDeleteCTF(event *handler.CommandEvent) error { ctfName := ctf.Name() - err = event.CreateMessage(discord.NewMessageCreateBuilder(). + _, err = event.CreateFollowupMessage(discord.NewMessageCreateBuilder(). SetEmbeds(discord.NewEmbedBuilder(). - SetColor(ColorRed). - SetDescriptionf("Would you like to delete `%s`? There's no undo.", ctfName). + SetColor(ColorFuchsia). + SetTitle(":warning: Confirm deletion"). + SetDescriptionf("Are you sure you want to delete `%s`? There's no undo.", ctfName). Build()). SetEphemeral(true). AddActionRow( diff --git a/discord/discord.go b/discord/discord.go index 2d0d084..9889d34 100644 --- a/discord/discord.go +++ b/discord/discord.go @@ -17,7 +17,7 @@ func Error(event CreateFollowupMessager, err error) error { code, message := havcebot.ErrorCode(err), havcebot.ErrorMessage(err) if code == havcebot.EINTERNAL { - event.Client().Logger().Error("Internal server error", code, message) + event.Client().Logger().Error("Internal server error", code, err) } // Print user message to response. @@ -29,7 +29,7 @@ func Error(event CreateFollowupMessager, err error) error { // messageError is a utility that builds and outputs a embed. func messageEmbedError(message string) discord.Embed { return discord.NewEmbedBuilder(). - SetTitlef(":warning: There was an error while handling your request."). + SetTitlef(":octagonal_sign: There was an error while handling your request."). SetColor(ColorRed). SetDescriptionf(message). SetField(0, "Message", message, true).Build() diff --git a/discord/middlewares.go b/discord/middlewares.go index 66a342a..7824c0f 100644 --- a/discord/middlewares.go +++ b/discord/middlewares.go @@ -6,25 +6,38 @@ import ( "github.com/disgoorg/disgo/discord" "github.com/disgoorg/disgo/events" "github.com/disgoorg/disgo/handler" + "github.com/disgoorg/disgo/handler/middleware" + "github.com/havce/havcebot" ) // AdminOnly restricts access to the routes to Administrators only. var AdminOnly handler.Middleware = func(next handler.Handler) handler.Handler { return func(e *events.InteractionCreate) error { if e.Member().Permissions.Has(discord.PermissionAdministrator) { - return next(e) + return middleware.Defer(discord.InteractionTypeComponent, false, true)( + middleware.Defer(discord.InteractionTypeApplicationCommand, false, true)(next), + )(e) } - return e.Respond(discord.InteractionResponseTypeCreateMessage, + _ = e.Respond(discord.InteractionResponseTypeCreateMessage, discord.NewMessageCreateBuilder(). SetEphemeral(true). SetEmbeds(messageEmbedError("You're not authorized to run this command.")).Build()) + + return havcebot.Errorf(havcebot.EUNAUTHORIZED, "You're not authorized to run this command.") } } func (s *Server) MustBeInsideCTFAndAdmin(next handler.Handler) handler.Handler { return func(e *events.InteractionCreate) error { - return AdminOnly(s.MustBeInsideCTF(next))(e) + if !e.Member().Permissions.Has(discord.PermissionAdministrator) { + _ = e.Respond(discord.InteractionResponseTypeCreateMessage, + discord.NewMessageCreateBuilder(). + SetEphemeral(true). + SetEmbeds(messageEmbedError("You're not authorized to run this command.")).Build()) + return havcebot.Errorf(havcebot.EUNAUTHORIZED, "You're not authorized to run this command.") + } + return s.MustBeInsideCTF(next)(e) } } @@ -46,6 +59,8 @@ func (s *Server) MustBeInsideCTF(next handler.Handler) handler.Handler { return err } - return next(e) + return middleware.Defer(discord.InteractionTypeComponent, false, true)( + middleware.Defer(discord.InteractionTypeApplicationCommand, false, true)(next), + )(e) } } diff --git a/discord/server.go b/discord/server.go index d304932..4119632 100644 --- a/discord/server.go +++ b/discord/server.go @@ -40,27 +40,24 @@ func NewServer() *Server { // order of evaluation is important. It isn't super clean, but it works. s.router.Group(func(r handler.Router) { r.Use(AdminOnly) - r.Use(middleware.Defer(discord.InteractionTypeApplicationCommand, false, true)) - r.Use(middleware.Defer(discord.InteractionTypeComponent, false, true)) - r.Command("/new", s.handleCommandNewCTF) r.Component("/new/{ctf}/create", s.handleCreateCTF) - r.Command("/close", s.handleUpdateCanJoin(false)) - r.Command("/open", s.handleUpdateCanJoin(true)) r.Command("/vote", s.handleInfoCTF(true)) }) + // Admin only routes and must be under a registered CTF. s.router.Group(func(r handler.Router) { r.Use(s.MustBeInsideCTFAndAdmin) r.Command("/delete", s.handleCommandDeleteCTF) r.Component("/delete/really", s.handleDeleteCTF) + r.Command("/close", s.handleUpdateCanJoin(false)) + r.Command("/open", s.handleUpdateCanJoin(true)) }) - // These routes must be hit while inside of a CTF. + // These routes must be hit while inside of a CTF, but don't + // require any admin priviledge. s.router.Group(func(r handler.Router) { r.Use(s.MustBeInsideCTF) - r.Use(middleware.Defer(discord.InteractionTypeApplicationCommand, false, true)) - r.Use(middleware.Defer(discord.InteractionTypeComponent, false, true)) r.Component("/join/{ctf}", s.handleJoinCTF) r.Command("/flag", s.handleFlag(false)) @@ -68,7 +65,8 @@ func NewServer() *Server { r.Command("/chal", s.handleNewChal) }) - // These routes can be use by anyone. They won't create any public message. + // These routes can be used by anyone. + // They won't create any public message. s.router.Group(func(r handler.Router) { r.Use(middleware.Defer(discord.InteractionTypeApplicationCommand, false, true)) r.Use(middleware.Defer(discord.InteractionTypeComponent, false, true))