Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

payload validation #187

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 20 additions & 1 deletion discord/application_command_create.go
@@ -1,6 +1,9 @@
package discord

import "github.com/disgoorg/disgo/json"
import (
"github.com/disgoorg/disgo/json"
"github.com/disgoorg/validate"
)

type ApplicationCommandCreate interface {
json.Marshaler
Expand All @@ -19,6 +22,15 @@ type SlashCommandCreate struct {
DMPermission bool `json:"dm_permission"`
}

func (c SlashCommandCreate) Validate() error {
return validate.Validate(
validate.Value(c.Name, validate.Required[string], validate.StringRange(1, ApplicationCommandNameMaxLength)),
validate.Value(c.Description, validate.Required[string], validate.StringRange(1, ApplicationCommandDescriptionMaxLength)),
validate.Value(c.Options, validate.SliceMaxLen[ApplicationCommandOption](ApplicationCommandMaxOptions)),
validate.Slice(c.Options),
)
}

func (c SlashCommandCreate) MarshalJSON() ([]byte, error) {
type slashCommandCreate SlashCommandCreate
return json.Marshal(struct {
Expand Down Expand Up @@ -95,3 +107,10 @@ func (c MessageCommandCreate) CommandName() string {
}

func (MessageCommandCreate) applicationCommandCreate() {}

const (
ApplicationCommandNameMaxLength = 32
ApplicationCommandDescriptionMaxLength = 100

ApplicationCommandMaxOptions = 25
)
216 changes: 179 additions & 37 deletions discord/application_command_option.go
Expand Up @@ -2,8 +2,10 @@ package discord

import (
"fmt"
"math"

"github.com/disgoorg/disgo/json"
"github.com/disgoorg/validate"
)

// ApplicationCommandOptionType specifies the type of the arguments used in ApplicationCommand.Options
Expand All @@ -26,9 +28,12 @@ const (

type ApplicationCommandOption interface {
json.Marshaler
validate.Validator
Type() ApplicationCommandOptionType
OptionName() string
OptionNameLocalizations() map[Locale]string
OptionDescription() string
OptionDescriptionLocalizations() map[Locale]string
applicationCommandOption()
}

Expand Down Expand Up @@ -165,10 +170,26 @@ func (o ApplicationCommandOptionSubCommand) OptionName() string {
return o.Name
}

func (o ApplicationCommandOptionSubCommand) OptionNameLocalizations() map[Locale]string {
return o.NameLocalizations
}

func (o ApplicationCommandOptionSubCommand) OptionDescription() string {
return o.Description
}

func (o ApplicationCommandOptionSubCommand) OptionDescriptionLocalizations() map[Locale]string {
return o.DescriptionLocalizations
}

func (o ApplicationCommandOptionSubCommand) Validate() error {
return validate.Validate(
applicationCommandOptionValidator(o),
validate.Value(o.Options, validate.SliceMaxLen[ApplicationCommandOption](ApplicationCommandMaxOptions)),
validate.Slice(o.Options),
)
}

func (ApplicationCommandOptionSubCommand) applicationCommandOption() {}
func (ApplicationCommandOptionSubCommand) Type() ApplicationCommandOptionType {
return ApplicationCommandOptionTypeSubCommand
Expand Down Expand Up @@ -199,10 +220,26 @@ func (o ApplicationCommandOptionSubCommandGroup) OptionName() string {
return o.Name
}

func (o ApplicationCommandOptionSubCommandGroup) OptionNameLocalizations() map[Locale]string {
return o.NameLocalizations
}

func (o ApplicationCommandOptionSubCommandGroup) OptionDescription() string {
return o.Description
}

func (o ApplicationCommandOptionSubCommandGroup) OptionDescriptionLocalizations() map[Locale]string {
return o.DescriptionLocalizations
}

func (o ApplicationCommandOptionSubCommandGroup) Validate() error {
return validate.Validate(
applicationCommandOptionValidator(o),
validate.Value(o.Options, validate.SliceNoneNil[ApplicationCommandOptionSubCommand], validate.SliceMaxLen[ApplicationCommandOptionSubCommand](ApplicationCommandMaxOptions)),
validate.Slice(o.Options),
)
}

func (ApplicationCommandOptionSubCommandGroup) applicationCommandOption() {}
func (ApplicationCommandOptionSubCommandGroup) Type() ApplicationCommandOptionType {
return ApplicationCommandOptionTypeSubCommandGroup
Expand Down Expand Up @@ -237,10 +274,22 @@ func (o ApplicationCommandOptionString) OptionName() string {
return o.Name
}

func (o ApplicationCommandOptionString) OptionNameLocalizations() map[Locale]string {
return o.NameLocalizations
}

func (o ApplicationCommandOptionString) OptionDescription() string {
return o.Description
}

func (o ApplicationCommandOptionString) OptionDescriptionLocalizations() map[Locale]string {
return o.DescriptionLocalizations
}

func (o ApplicationCommandOptionString) Validate() error {
return applicationCommandOptionValidator(o).Validate()
}

func (ApplicationCommandOptionString) applicationCommandOption() {}
func (ApplicationCommandOptionString) Type() ApplicationCommandOptionType {
return ApplicationCommandOptionTypeString
Expand Down Expand Up @@ -275,10 +324,25 @@ func (o ApplicationCommandOptionInt) OptionName() string {
return o.Name
}

func (o ApplicationCommandOptionInt) OptionNameLocalizations() map[Locale]string {
return o.NameLocalizations
}

func (o ApplicationCommandOptionInt) OptionDescription() string {
return o.Description
}

func (o ApplicationCommandOptionInt) OptionDescriptionLocalizations() map[Locale]string {
return o.DescriptionLocalizations
}

func (o ApplicationCommandOptionInt) Validate() error {
return validate.Validate(
applicationCommandOptionValidator(o),
validate.Value(o.MinValue, validate.NumberRangePtr[int](0, math.MaxInt32)),
)
}

func (ApplicationCommandOptionInt) applicationCommandOption() {}
func (ApplicationCommandOptionInt) Type() ApplicationCommandOptionType {
return ApplicationCommandOptionTypeInt
Expand Down Expand Up @@ -309,10 +373,22 @@ func (o ApplicationCommandOptionBool) OptionName() string {
return o.Name
}

func (o ApplicationCommandOptionBool) OptionNameLocalizations() map[Locale]string {
return o.NameLocalizations
}

func (o ApplicationCommandOptionBool) OptionDescription() string {
return o.Description
}

func (o ApplicationCommandOptionBool) OptionDescriptionLocalizations() map[Locale]string {
return o.DescriptionLocalizations
}

func (o ApplicationCommandOptionBool) Validate() error {
return applicationCommandOptionValidator(o).Validate()
}

func (ApplicationCommandOptionBool) applicationCommandOption() {}
func (ApplicationCommandOptionBool) Type() ApplicationCommandOptionType {
return ApplicationCommandOptionTypeBool
Expand Down Expand Up @@ -343,10 +419,22 @@ func (o ApplicationCommandOptionUser) OptionName() string {
return o.Name
}

func (o ApplicationCommandOptionUser) OptionNameLocalizations() map[Locale]string {
return o.NameLocalizations
}

func (o ApplicationCommandOptionUser) OptionDescription() string {
return o.Description
}

func (o ApplicationCommandOptionUser) OptionDescriptionLocalizations() map[Locale]string {
return o.DescriptionLocalizations
}

func (o ApplicationCommandOptionUser) Validate() error {
return applicationCommandOptionValidator(o).Validate()
}

func (ApplicationCommandOptionUser) applicationCommandOption() {}
func (ApplicationCommandOptionUser) Type() ApplicationCommandOptionType {
return ApplicationCommandOptionTypeUser
Expand Down Expand Up @@ -378,8 +466,20 @@ func (o ApplicationCommandOptionChannel) OptionName() string {
return o.Name
}

func (o ApplicationCommandOptionChannel) OptionNameLocalizations() map[Locale]string {
return o.NameLocalizations
}

func (o ApplicationCommandOptionChannel) OptionDescription() string {
return o.Name
return o.Description
}

func (o ApplicationCommandOptionChannel) OptionDescriptionLocalizations() map[Locale]string {
return o.DescriptionLocalizations
}

func (o ApplicationCommandOptionChannel) Validate() error {
return applicationCommandOptionValidator(o).Validate()
}

func (ApplicationCommandOptionChannel) applicationCommandOption() {}
Expand Down Expand Up @@ -412,8 +512,20 @@ func (o ApplicationCommandOptionRole) OptionName() string {
return o.Name
}

func (o ApplicationCommandOptionRole) OptionNameLocalizations() map[Locale]string {
return o.NameLocalizations
}

func (o ApplicationCommandOptionRole) OptionDescription() string {
return o.Name
return o.Description
}

func (o ApplicationCommandOptionRole) OptionDescriptionLocalizations() map[Locale]string {
return o.DescriptionLocalizations
}

func (o ApplicationCommandOptionRole) Validate() error {
return applicationCommandOptionValidator(o).Validate()
}

func (ApplicationCommandOptionRole) applicationCommandOption() {}
Expand Down Expand Up @@ -446,8 +558,20 @@ func (o ApplicationCommandOptionMentionable) OptionName() string {
return o.Name
}

func (o ApplicationCommandOptionMentionable) OptionNameLocalizations() map[Locale]string {
return o.NameLocalizations
}

func (o ApplicationCommandOptionMentionable) OptionDescription() string {
return o.Name
return o.Description
}

func (o ApplicationCommandOptionMentionable) OptionDescriptionLocalizations() map[Locale]string {
return o.DescriptionLocalizations
}

func (o ApplicationCommandOptionMentionable) Validate() error {
return applicationCommandOptionValidator(o).Validate()
}

func (ApplicationCommandOptionMentionable) applicationCommandOption() {}
Expand Down Expand Up @@ -484,49 +608,31 @@ func (o ApplicationCommandOptionFloat) OptionName() string {
return o.Name
}

func (o ApplicationCommandOptionFloat) OptionDescription() string {
return o.Name
}

func (ApplicationCommandOptionFloat) applicationCommandOption() {}
func (ApplicationCommandOptionFloat) Type() ApplicationCommandOptionType {
return ApplicationCommandOptionTypeFloat
func (o ApplicationCommandOptionFloat) OptionNameLocalizations() map[Locale]string {
return o.NameLocalizations
}

type ApplicationCommandOptionChoice interface {
applicationCommandOptionChoice()
func (o ApplicationCommandOptionFloat) OptionDescription() string {
return o.Description
}

var _ ApplicationCommandOptionChoice = (*ApplicationCommandOptionChoiceInt)(nil)

type ApplicationCommandOptionChoiceInt struct {
Name string `json:"name"`
NameLocalizations map[Locale]string `json:"name_localizations,omitempty"`
Value int `json:"value"`
func (o ApplicationCommandOptionFloat) OptionDescriptionLocalizations() map[Locale]string {
return o.DescriptionLocalizations
}

func (ApplicationCommandOptionChoiceInt) applicationCommandOptionChoice() {}

var _ ApplicationCommandOptionChoice = (*ApplicationCommandOptionChoiceString)(nil)

type ApplicationCommandOptionChoiceString struct {
Name string `json:"name"`
NameLocalizations map[Locale]string `json:"name_localizations,omitempty"`
Value string `json:"value"`
func (o ApplicationCommandOptionFloat) Validate() error {
return validate.Validate(
applicationCommandOptionValidator(o),
validate.Value(o.Choices, validate.SliceNoneNil[ApplicationCommandOptionChoiceFloat], validate.SliceMaxLen[ApplicationCommandOptionChoiceFloat](ApplicationCommandOptionMaxChoices)),
validate.Slice(o.Choices),
)
}

func (ApplicationCommandOptionChoiceString) applicationCommandOptionChoice() {}

var _ ApplicationCommandOptionChoice = (*ApplicationCommandOptionChoiceInt)(nil)

type ApplicationCommandOptionChoiceFloat struct {
Name string `json:"name"`
NameLocalizations map[Locale]string `json:"name_localizations,omitempty"`
Value float64 `json:"value"`
func (ApplicationCommandOptionFloat) applicationCommandOption() {}
func (ApplicationCommandOptionFloat) Type() ApplicationCommandOptionType {
return ApplicationCommandOptionTypeFloat
}

func (ApplicationCommandOptionChoiceFloat) applicationCommandOptionChoice() {}

type ApplicationCommandOptionAttachment struct {
Name string `json:"name"`
NameLocalizations map[Locale]string `json:"name_localizations,omitempty"`
Expand All @@ -550,11 +656,47 @@ func (o ApplicationCommandOptionAttachment) OptionName() string {
return o.Name
}

func (o ApplicationCommandOptionAttachment) OptionNameLocalizations() map[Locale]string {
return o.NameLocalizations
}

func (o ApplicationCommandOptionAttachment) OptionDescription() string {
return o.Name
return o.Description
}

func (o ApplicationCommandOptionAttachment) OptionDescriptionLocalizations() map[Locale]string {
return o.DescriptionLocalizations
}

func (o ApplicationCommandOptionAttachment) Validate() error {
return applicationCommandOptionValidator(o).Validate()
}

func (ApplicationCommandOptionAttachment) applicationCommandOption() {}
func (ApplicationCommandOptionAttachment) Type() ApplicationCommandOptionType {
return ApplicationCommandOptionTypeAttachment
}

func applicationCommandOptionValidator(o ApplicationCommandOption) validate.Validator {
return validate.Combine(
validate.Value(o.OptionName(), validate.Required[string], validate.StringRange(1, ApplicationCommandOptionNameMaxLength)),
validate.Map(o.OptionNameLocalizations(), validateLocalizations(1, ApplicationCommandOptionNameMaxLength)),
validate.Value(o.OptionDescription(), validate.Required[string], validate.StringRange(1, ApplicationCommandOptionDescriptionMaxLength)),
validate.Map(o.OptionDescriptionLocalizations(), validateLocalizations(1, ApplicationCommandOptionDescriptionMaxLength)),
)
}

func validateLocalizations(valueMinLength int, valueMaxLength int) validate.MapValidateFunc[Locale, string] {
return func(k Locale, v string) error {
return validate.Validate(
validate.Value(k, validate.EnumInMapKeys(Locales)),
validate.Value(v, validate.Required[string], validate.StringRange(valueMinLength, valueMaxLength)),
)
}
}

const (
ApplicationCommandOptionNameMaxLength = 32
ApplicationCommandOptionDescriptionMaxLength = 100
ApplicationCommandOptionMaxChoices = 25
)