888 lines
24 KiB
Go
888 lines
24 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/larkox/mattermost-plugin-badges/badgesmodel"
|
|
commandparser "github.com/larkox/mattermost-plugin-badges/server/command_parser"
|
|
"github.com/mattermost/mattermost-server/v5/model"
|
|
"github.com/mattermost/mattermost-server/v5/plugin"
|
|
"github.com/spf13/pflag"
|
|
)
|
|
|
|
func getHelp() string {
|
|
return `Available Commands:
|
|
`
|
|
}
|
|
|
|
func (p *Plugin) getCommand() *model.Command {
|
|
return &model.Command{
|
|
Trigger: "badges",
|
|
DisplayName: "Badges Bot",
|
|
Description: "Badges",
|
|
AutoComplete: true,
|
|
AutoCompleteDesc: "Available commands:",
|
|
AutoCompleteHint: "[command]",
|
|
AutocompleteData: p.getAutocompleteData(),
|
|
}
|
|
}
|
|
|
|
func (p *Plugin) postCommandResponse(args *model.CommandArgs, text string) {
|
|
post := &model.Post{
|
|
UserId: p.BotUserID,
|
|
ChannelId: args.ChannelId,
|
|
Message: text,
|
|
}
|
|
p.mm.Post.SendEphemeralPost(args.UserId, post)
|
|
}
|
|
|
|
func commandError(text string) (bool, *model.CommandResponse, error) {
|
|
return true, &model.CommandResponse{}, errors.New(text)
|
|
}
|
|
|
|
// ExecuteCommand executes a given command and returns a command response.
|
|
func (p *Plugin) ExecuteCommand(c *plugin.Context, args *model.CommandArgs) (*model.CommandResponse, *model.AppError) {
|
|
stringArgs := commandparser.Parse(args.Command)
|
|
lengthOfArgs := len(stringArgs)
|
|
restOfArgs := []string{}
|
|
|
|
var handler func([]string, *model.CommandArgs) (bool, *model.CommandResponse, error)
|
|
if lengthOfArgs == 1 {
|
|
p.postCommandResponse(args, getHelp())
|
|
return &model.CommandResponse{}, nil
|
|
}
|
|
command := stringArgs[1]
|
|
if lengthOfArgs > 2 {
|
|
restOfArgs = stringArgs[2:]
|
|
}
|
|
switch command {
|
|
case "test-clean":
|
|
handler = p.runClean
|
|
case "grant":
|
|
handler = p.runGrant
|
|
case "edit":
|
|
handler = p.runEdit
|
|
case "create":
|
|
handler = p.runCreate
|
|
case "subscription":
|
|
handler = p.runSubscription
|
|
default:
|
|
p.postCommandResponse(args, getHelp())
|
|
return &model.CommandResponse{}, nil
|
|
}
|
|
isUserError, resp, err := handler(restOfArgs, args)
|
|
if err != nil {
|
|
if isUserError {
|
|
p.postCommandResponse(args, fmt.Sprintf("__Error: %s__", err.Error()))
|
|
} else {
|
|
p.mm.Log.Error(err.Error())
|
|
p.postCommandResponse(args, "An unknown error occurred. Please talk to your system administrator for help.")
|
|
}
|
|
}
|
|
|
|
if resp != nil {
|
|
return resp, nil
|
|
}
|
|
|
|
return &model.CommandResponse{}, nil
|
|
}
|
|
|
|
func (p *Plugin) runClean(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) {
|
|
user, err := p.mm.User.Get(extra.UserId)
|
|
if err != nil {
|
|
return false, &model.CommandResponse{Text: "Cannot get user."}, nil
|
|
}
|
|
if !user.IsSystemAdmin() {
|
|
return false, &model.CommandResponse{Text: "Only a system admin can clean the badges database."}, nil
|
|
}
|
|
_ = p.mm.KV.DeleteAll()
|
|
return false, &model.CommandResponse{Text: "Clean"}, nil
|
|
}
|
|
|
|
func (p *Plugin) runCreate(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) {
|
|
lengthOfArgs := len(args)
|
|
restOfArgs := []string{}
|
|
var handler func([]string, *model.CommandArgs) (bool, *model.CommandResponse, error)
|
|
if lengthOfArgs == 0 {
|
|
return false, &model.CommandResponse{Text: "Specify what you want to create."}, nil
|
|
}
|
|
command := args[0]
|
|
if lengthOfArgs > 1 {
|
|
restOfArgs = args[1:]
|
|
}
|
|
switch command {
|
|
case "badge":
|
|
handler = p.runCreateBadge
|
|
case "type":
|
|
handler = p.runCreateType
|
|
default:
|
|
return false, &model.CommandResponse{Text: "You can create either badge or type"}, nil
|
|
}
|
|
|
|
return handler(restOfArgs, extra)
|
|
}
|
|
|
|
func (p *Plugin) runCreateBadge(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) {
|
|
u, err := p.mm.User.Get(extra.UserId)
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
typeSuggestions, err := p.filterCreateBadgeTypes(u)
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
typeOptions := []*model.PostActionOptions{}
|
|
for _, typeSuggestion := range typeSuggestions {
|
|
id := string(typeSuggestion.ID)
|
|
typeOptions = append(typeOptions, &model.PostActionOptions{Text: typeSuggestion.Name, Value: id})
|
|
}
|
|
|
|
if len(typeOptions) == 0 {
|
|
return commandError("You cannot create badges from any type.")
|
|
}
|
|
|
|
err = p.mm.Frontend.OpenInteractiveDialog(model.OpenDialogRequest{
|
|
TriggerId: extra.TriggerId,
|
|
URL: p.getDialogURL() + DialogPathCreateBadge,
|
|
Dialog: model.Dialog{
|
|
Title: "Create badge",
|
|
SubmitLabel: "Create",
|
|
Elements: []model.DialogElement{
|
|
{
|
|
DisplayName: "Name",
|
|
Type: "text",
|
|
Name: DialogFieldBadgeName,
|
|
MaxLength: badgesmodel.NameMaxLength,
|
|
},
|
|
{
|
|
DisplayName: "Description",
|
|
Type: "text",
|
|
Name: DialogFieldBadgeDescription,
|
|
MaxLength: badgesmodel.DescriptionMaxLength,
|
|
},
|
|
{
|
|
DisplayName: "Image",
|
|
Type: "text",
|
|
Name: DialogFieldBadgeImage,
|
|
HelpText: "Insert a emoticon name",
|
|
},
|
|
{
|
|
DisplayName: "Type",
|
|
Type: "select",
|
|
Name: DialogFieldBadgeType,
|
|
Options: typeOptions,
|
|
},
|
|
{
|
|
DisplayName: "Multiple",
|
|
Type: "bool",
|
|
Name: DialogFieldBadgeMultiple,
|
|
HelpText: "Whether the badge can be granted multiple times",
|
|
Optional: true,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
return false, &model.CommandResponse{}, nil
|
|
}
|
|
|
|
func (p *Plugin) runEdit(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) {
|
|
lengthOfArgs := len(args)
|
|
restOfArgs := []string{}
|
|
var handler func([]string, *model.CommandArgs) (bool, *model.CommandResponse, error)
|
|
if lengthOfArgs == 0 {
|
|
return false, &model.CommandResponse{Text: "Specify what you want to create."}, nil
|
|
}
|
|
command := args[0]
|
|
if lengthOfArgs > 1 {
|
|
restOfArgs = args[1:]
|
|
}
|
|
switch command {
|
|
case "badge":
|
|
handler = p.runEditBadge
|
|
case "type":
|
|
handler = p.runEditType
|
|
default:
|
|
return false, &model.CommandResponse{Text: "You can create either badge or type"}, nil
|
|
}
|
|
|
|
return handler(restOfArgs, extra)
|
|
}
|
|
|
|
func (p *Plugin) runEditBadge(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) {
|
|
u, err := p.mm.User.Get(extra.UserId)
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
var badgeIDStr string
|
|
fs := pflag.NewFlagSet("", pflag.ContinueOnError)
|
|
fs.StringVar(&badgeIDStr, "id", "", "ID of the badge")
|
|
if err = fs.Parse(args); err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
if badgeIDStr == "" {
|
|
return commandError("You must set the badge ID")
|
|
}
|
|
|
|
badge, err := p.store.GetBadge(badgesmodel.BadgeID(badgeIDStr))
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
if !canEditBadge(u, p.badgeAdminUserID, badge) {
|
|
return commandError("you cannot edit this badge")
|
|
}
|
|
|
|
typeSuggestions, err := p.filterCreateBadgeTypes(u)
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
typeOptions := []*model.PostActionOptions{}
|
|
for _, typeSuggestion := range typeSuggestions {
|
|
id := string(typeSuggestion.ID)
|
|
typeOptions = append(typeOptions, &model.PostActionOptions{Text: typeSuggestion.Name, Value: id})
|
|
}
|
|
|
|
if len(typeOptions) == 0 {
|
|
return commandError("You cannot create badges from any type.")
|
|
}
|
|
|
|
err = p.mm.Frontend.OpenInteractiveDialog(model.OpenDialogRequest{
|
|
TriggerId: extra.TriggerId,
|
|
URL: p.getDialogURL() + DialogPathEditBadge,
|
|
Dialog: model.Dialog{
|
|
Title: "Create badge",
|
|
SubmitLabel: "Edit",
|
|
State: string(badge.ID),
|
|
Elements: []model.DialogElement{
|
|
{
|
|
DisplayName: "Name",
|
|
Type: "text",
|
|
Name: DialogFieldBadgeName,
|
|
MaxLength: badgesmodel.NameMaxLength,
|
|
Default: badge.Name,
|
|
},
|
|
{
|
|
DisplayName: "Description",
|
|
Type: "text",
|
|
Name: DialogFieldBadgeDescription,
|
|
MaxLength: badgesmodel.DescriptionMaxLength,
|
|
Default: badge.Description,
|
|
},
|
|
{
|
|
DisplayName: "Image",
|
|
Type: "text",
|
|
Name: DialogFieldBadgeImage,
|
|
HelpText: "Insert a emoticon name",
|
|
Default: badge.Image,
|
|
},
|
|
{
|
|
DisplayName: "Type",
|
|
Type: "select",
|
|
Name: DialogFieldBadgeType,
|
|
Options: typeOptions,
|
|
Default: string(badge.Type),
|
|
},
|
|
{
|
|
DisplayName: "Multiple",
|
|
Type: "bool",
|
|
Name: DialogFieldBadgeMultiple,
|
|
HelpText: "Whether the badge can be granted multiple times",
|
|
Optional: true,
|
|
Default: getBooleanString(badge.Multiple),
|
|
},
|
|
{
|
|
DisplayName: "Delete badge",
|
|
Type: "bool",
|
|
Name: DialogFieldBadgeDelete,
|
|
HelpText: "WARNING: Checking this will remove this badge permanently.",
|
|
Optional: true,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
return false, &model.CommandResponse{}, nil
|
|
}
|
|
|
|
func (p *Plugin) runEditType(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) {
|
|
u, err := p.mm.User.Get(extra.UserId)
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
if !canCreateType(u, p.badgeAdminUserID, false) {
|
|
return commandError("You have no permissions to edit a badge type.")
|
|
}
|
|
|
|
var badgeTypeStr string
|
|
fs := pflag.NewFlagSet("", pflag.ContinueOnError)
|
|
fs.StringVar(&badgeTypeStr, "type", "", "ID of the type")
|
|
if err = fs.Parse(args); err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
if badgeTypeStr == "" {
|
|
return commandError("You must provide a type id")
|
|
}
|
|
|
|
typeDefinition, err := p.store.GetType(badgesmodel.BadgeType(badgeTypeStr))
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
if !canEditType(u, p.badgeAdminUserID, typeDefinition) {
|
|
return commandError("you cannot edit this type")
|
|
}
|
|
|
|
canGrantAllowList := ""
|
|
for uID, allowed := range typeDefinition.CanGrant.AllowList {
|
|
if !allowed {
|
|
continue
|
|
}
|
|
var allowedUser *model.User
|
|
allowedUser, err = p.mm.User.Get(uID)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if canGrantAllowList == "" {
|
|
canGrantAllowList += allowedUser.Username
|
|
continue
|
|
}
|
|
|
|
canGrantAllowList += ", " + allowedUser.Username
|
|
}
|
|
|
|
canCreateAllowList := ""
|
|
for uID, allowed := range typeDefinition.CanCreate.AllowList {
|
|
if !allowed {
|
|
continue
|
|
}
|
|
var allowedUser *model.User
|
|
allowedUser, err = p.mm.User.Get(uID)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if canCreateAllowList == "" {
|
|
canCreateAllowList += allowedUser.Username
|
|
continue
|
|
}
|
|
|
|
canCreateAllowList += ", " + allowedUser.Username
|
|
}
|
|
|
|
err = p.mm.Frontend.OpenInteractiveDialog(model.OpenDialogRequest{
|
|
TriggerId: extra.TriggerId,
|
|
URL: p.getDialogURL() + DialogPathEditType,
|
|
Dialog: model.Dialog{
|
|
Title: "Edit type",
|
|
SubmitLabel: "Edit",
|
|
State: badgeTypeStr,
|
|
Elements: []model.DialogElement{
|
|
{
|
|
DisplayName: "Name",
|
|
Type: "text",
|
|
Name: DialogFieldTypeName,
|
|
MaxLength: badgesmodel.NameMaxLength,
|
|
Default: typeDefinition.Name,
|
|
},
|
|
{
|
|
DisplayName: "Everyone can create badge",
|
|
Type: "bool",
|
|
Name: DialogFieldTypeEveryoneCanCreate,
|
|
HelpText: "Whether any user can create a badge of this type",
|
|
Optional: true,
|
|
Default: getBooleanString(typeDefinition.CanCreate.Everyone),
|
|
},
|
|
{
|
|
DisplayName: "Can create allowlist",
|
|
Type: "text",
|
|
Name: DialogFieldTypeAllowlistCanCreate,
|
|
HelpText: "Fill the usernames separated by comma (,) of the people that can create badges of this type.",
|
|
Placeholder: "user-1, user-2, user-3",
|
|
Optional: true,
|
|
Default: canCreateAllowList,
|
|
},
|
|
{
|
|
DisplayName: "Everyone can grant badge",
|
|
Type: "bool",
|
|
Name: DialogFieldTypeEveryoneCanGrant,
|
|
HelpText: "Whether any user can grant a badge of this type",
|
|
Optional: true,
|
|
Default: getBooleanString(typeDefinition.CanGrant.Everyone),
|
|
},
|
|
{
|
|
DisplayName: "Can grant allowlist",
|
|
Type: "text",
|
|
Name: DialogFieldTypeAllowlistCanGrant,
|
|
HelpText: "Fill the usernames separated by comma (,) of the people that can grant badges of this type.",
|
|
Placeholder: "user-1, user-2, user-3",
|
|
Optional: true,
|
|
Default: canGrantAllowList,
|
|
},
|
|
{
|
|
DisplayName: "Remove type",
|
|
Type: "bool",
|
|
Name: DialogFieldTypeDelete,
|
|
HelpText: "WARNING: checking this will remove this type and all associated badges permanently.",
|
|
Optional: true,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
return false, &model.CommandResponse{}, nil
|
|
}
|
|
|
|
func (p *Plugin) runCreateType(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) {
|
|
u, err := p.mm.User.Get(extra.UserId)
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
if !canCreateType(u, p.badgeAdminUserID, false) {
|
|
return commandError("You have no permissions to create a badge type.")
|
|
}
|
|
|
|
err = p.mm.Frontend.OpenInteractiveDialog(model.OpenDialogRequest{
|
|
TriggerId: extra.TriggerId,
|
|
URL: p.getDialogURL() + DialogPathCreateType,
|
|
Dialog: model.Dialog{
|
|
Title: "Create type",
|
|
SubmitLabel: "Create",
|
|
Elements: []model.DialogElement{
|
|
{
|
|
DisplayName: "Name",
|
|
Type: "text",
|
|
Name: DialogFieldTypeName,
|
|
MaxLength: badgesmodel.NameMaxLength,
|
|
},
|
|
{
|
|
DisplayName: "Everyone can create badge",
|
|
Type: "bool",
|
|
Name: DialogFieldTypeEveryoneCanCreate,
|
|
HelpText: "Whether any user can create a badge of this type",
|
|
Optional: true,
|
|
},
|
|
{
|
|
DisplayName: "Can create allowlist",
|
|
Type: "text",
|
|
Name: DialogFieldTypeAllowlistCanCreate,
|
|
HelpText: "Fill the usernames separated by comma (,) of the people that can create badges of this type.",
|
|
Placeholder: "user-1, user-2, user-3",
|
|
Optional: true,
|
|
},
|
|
{
|
|
DisplayName: "Everyone can grant badge",
|
|
Type: "bool",
|
|
Name: DialogFieldTypeEveryoneCanGrant,
|
|
HelpText: "Whether any user can grant a badge of this type",
|
|
Optional: true,
|
|
},
|
|
{
|
|
DisplayName: "Can grant allowlist",
|
|
Type: "text",
|
|
Name: DialogFieldTypeAllowlistCanGrant,
|
|
HelpText: "Fill the usernames separated by comma (,) of the people that can grant badges of this type.",
|
|
Placeholder: "user-1, user-2, user-3",
|
|
Optional: true,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
return false, &model.CommandResponse{}, nil
|
|
}
|
|
|
|
func (p *Plugin) runGrant(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) {
|
|
badgeStr := ""
|
|
username := ""
|
|
fs := pflag.NewFlagSet("", pflag.ContinueOnError)
|
|
fs.StringVar(&badgeStr, "badge", "", "ID of the badge")
|
|
fs.StringVar(&username, "user", "", "Username to grant to")
|
|
if err := fs.Parse(args); err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
if username != "" && badgeStr != "" {
|
|
if username[0] == '@' {
|
|
username = username[1:]
|
|
}
|
|
|
|
granter, err := p.mm.User.Get(extra.UserId)
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
badge, err := p.store.GetBadge(badgesmodel.BadgeID(badgeStr))
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
badgeType, err := p.store.GetType(badge.Type)
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
if !canGrantBadge(granter, p.badgeAdminUserID, badge, badgeType) {
|
|
return commandError("you have no permissions to grant this badge")
|
|
}
|
|
|
|
user, err := p.mm.User.GetByUsername(username)
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
shouldNotify, err := p.store.GrantBadge(badgesmodel.BadgeID(badgeStr), user.Id, extra.UserId, "")
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
if shouldNotify {
|
|
p.notifyGrant(badgesmodel.BadgeID(badgeStr), extra.UserId, user, false, "", "")
|
|
}
|
|
|
|
p.postCommandResponse(extra, "Granted")
|
|
return false, &model.CommandResponse{}, nil
|
|
}
|
|
|
|
elements := []model.DialogElement{}
|
|
|
|
stateText := ""
|
|
introductionText := ""
|
|
if username != "" {
|
|
if username[0] == '@' {
|
|
username = username[1:]
|
|
}
|
|
|
|
user, err := p.mm.User.GetByUsername(username)
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
introductionText = "Grant badge to @" + username
|
|
stateText = user.Id
|
|
}
|
|
|
|
if stateText == "" {
|
|
elements = append(elements, model.DialogElement{
|
|
DisplayName: "User",
|
|
Type: "select",
|
|
Name: DialogFieldUser,
|
|
DataSource: "users",
|
|
})
|
|
}
|
|
|
|
actingUser, err := p.mm.User.Get(extra.UserId)
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
options := []*model.PostActionOptions{}
|
|
grantableBadges, err := p.filterGrantBadges(actingUser)
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
for _, badge := range grantableBadges {
|
|
options = append(options, &model.PostActionOptions{Text: badge.Name, Value: string(badge.ID)})
|
|
}
|
|
|
|
badgeElement := model.DialogElement{
|
|
DisplayName: "Badge",
|
|
Type: "select",
|
|
Name: DialogFieldBadge,
|
|
Options: options,
|
|
}
|
|
|
|
if badgeStr != "" {
|
|
found := false
|
|
for _, badge := range grantableBadges {
|
|
if badgeStr == string(badge.ID) {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !found {
|
|
return commandError("You cannot grant that badge")
|
|
}
|
|
|
|
badgeElement.Default = badgeStr
|
|
}
|
|
|
|
elements = append(elements, badgeElement)
|
|
|
|
elements = append(elements, model.DialogElement{
|
|
DisplayName: "Reason",
|
|
Name: DialogFieldGrantReason,
|
|
Optional: true,
|
|
HelpText: "Reason why you are granting this badge. This will be seen by the user, and wherever this grant notification is shown (e.g. subscriptions).",
|
|
Type: "text",
|
|
})
|
|
|
|
elements = append(elements, model.DialogElement{
|
|
DisplayName: "Notify on this channel",
|
|
Name: DialogFieldNotifyHere,
|
|
Type: "bool",
|
|
HelpText: "If you mark this, the bot will send a message to this channel notifying that you granted this badge to this person.",
|
|
Optional: true,
|
|
})
|
|
|
|
err = p.mm.Frontend.OpenInteractiveDialog(model.OpenDialogRequest{
|
|
TriggerId: extra.TriggerId,
|
|
URL: p.getDialogURL() + DialogPathGrant,
|
|
Dialog: model.Dialog{
|
|
Title: "Grant badge",
|
|
IntroductionText: introductionText,
|
|
SubmitLabel: "Grant",
|
|
Elements: elements,
|
|
State: stateText,
|
|
},
|
|
})
|
|
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
return false, &model.CommandResponse{}, nil
|
|
}
|
|
|
|
func (p *Plugin) runSubscription(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) {
|
|
lengthOfArgs := len(args)
|
|
restOfArgs := []string{}
|
|
var handler func([]string, *model.CommandArgs) (bool, *model.CommandResponse, error)
|
|
if lengthOfArgs == 0 {
|
|
return false, &model.CommandResponse{Text: "Specify what you want to do."}, nil
|
|
}
|
|
command := args[0]
|
|
if lengthOfArgs > 1 {
|
|
restOfArgs = args[1:]
|
|
}
|
|
switch command {
|
|
case "create":
|
|
handler = p.runCreateSubscription
|
|
case "remove":
|
|
handler = p.runDeleteSubscription
|
|
default:
|
|
return false, &model.CommandResponse{Text: "You can either create or delete subscriptions"}, nil
|
|
}
|
|
|
|
return handler(restOfArgs, extra)
|
|
}
|
|
|
|
func (p *Plugin) runCreateSubscription(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) {
|
|
typeStr := ""
|
|
fs := pflag.NewFlagSet("", pflag.ContinueOnError)
|
|
fs.StringVar(&typeStr, "type", "", "ID of the badge")
|
|
if err := fs.Parse(args); err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
actingUser, err := p.mm.User.Get(extra.UserId)
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
if !canCreateSubscription(actingUser, p.badgeAdminUserID, extra.ChannelId) {
|
|
return commandError("You cannot create subscriptions")
|
|
}
|
|
|
|
if typeStr != "" {
|
|
|
|
err = p.store.AddSubscription(badgesmodel.BadgeType(typeStr), extra.ChannelId)
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
p.postCommandResponse(extra, "Granted")
|
|
return false, &model.CommandResponse{}, nil
|
|
}
|
|
|
|
options := []*model.PostActionOptions{}
|
|
typesDefinitions, err := p.filterEditTypes(actingUser)
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
for _, typeDefinition := range typesDefinitions {
|
|
options = append(options, &model.PostActionOptions{Text: typeDefinition.Name, Value: string(typeDefinition.ID)})
|
|
}
|
|
|
|
err = p.mm.Frontend.OpenInteractiveDialog(model.OpenDialogRequest{
|
|
TriggerId: extra.TriggerId,
|
|
URL: p.getDialogURL() + DialogPathCreateSubscription,
|
|
Dialog: model.Dialog{
|
|
Title: "Create subscription",
|
|
IntroductionText: "Introduce the badge type you want to subscribe to this channel.",
|
|
SubmitLabel: "Add",
|
|
Elements: []model.DialogElement{
|
|
{
|
|
DisplayName: "Type",
|
|
Type: "select",
|
|
Name: DialogFieldBadgeType,
|
|
Options: options,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
return false, &model.CommandResponse{}, nil
|
|
}
|
|
|
|
func (p *Plugin) runDeleteSubscription(args []string, extra *model.CommandArgs) (bool, *model.CommandResponse, error) {
|
|
typeStr := ""
|
|
fs := pflag.NewFlagSet("", pflag.ContinueOnError)
|
|
fs.StringVar(&typeStr, "type", "", "ID of the badge")
|
|
if err := fs.Parse(args); err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
actingUser, err := p.mm.User.Get(extra.UserId)
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
if !canCreateSubscription(actingUser, p.badgeAdminUserID, extra.ChannelId) {
|
|
return commandError("You cannot create subscriptions")
|
|
}
|
|
|
|
if typeStr != "" {
|
|
err = p.store.RemoveSubscriptions(badgesmodel.BadgeType(typeStr), extra.ChannelId)
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
p.postCommandResponse(extra, "Removed")
|
|
return false, &model.CommandResponse{}, nil
|
|
}
|
|
|
|
options := []*model.PostActionOptions{}
|
|
typesDefinitions, err := p.store.GetChannelSubscriptions(extra.ChannelId)
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
for _, typeDefinition := range typesDefinitions {
|
|
options = append(options, &model.PostActionOptions{Text: typeDefinition.Name, Value: string(typeDefinition.ID)})
|
|
}
|
|
|
|
err = p.mm.Frontend.OpenInteractiveDialog(model.OpenDialogRequest{
|
|
TriggerId: extra.TriggerId,
|
|
URL: p.getDialogURL() + DialogPathDeleteSubscription,
|
|
Dialog: model.Dialog{
|
|
Title: "Delete subscription",
|
|
IntroductionText: "Introduce the badge type you want to remove from this channel.",
|
|
SubmitLabel: "Remove",
|
|
Elements: []model.DialogElement{
|
|
{
|
|
DisplayName: "Type",
|
|
Type: "select",
|
|
Name: DialogFieldBadgeType,
|
|
Options: options,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
if err != nil {
|
|
return commandError(err.Error())
|
|
}
|
|
|
|
return false, &model.CommandResponse{}, nil
|
|
}
|
|
|
|
func (p *Plugin) getAutocompleteData() *model.AutocompleteData {
|
|
badges := model.NewAutocompleteData("badges", "[command]", "Available commands: grant")
|
|
|
|
grant := model.NewAutocompleteData("grant", "--user @username --badge id", "Grant a badge to a user")
|
|
grant.AddNamedDynamicListArgument("badge", "--badge badgeID", getAutocompletePath(AutocompletePathBadgeSuggestions), true)
|
|
grant.AddNamedTextArgument("user", "User to grant the badge to", "--user @username", "", true)
|
|
badges.AddCommand(grant)
|
|
|
|
create := model.NewAutocompleteData("create", "badge | type", "Create a badge or a type")
|
|
|
|
badge := model.NewAutocompleteData(
|
|
"badge",
|
|
"",
|
|
"Create a badge",
|
|
)
|
|
create.AddCommand(badge)
|
|
|
|
createType := model.NewAutocompleteData(
|
|
"type",
|
|
"",
|
|
"Create a badge type",
|
|
)
|
|
create.AddCommand(createType)
|
|
|
|
badges.AddCommand(create)
|
|
|
|
edit := model.NewAutocompleteData("edit", "badge | type", "Edit a badge or a type")
|
|
|
|
editBadge := model.NewAutocompleteData(
|
|
"badge",
|
|
"",
|
|
"Edit a badge",
|
|
)
|
|
editBadge.AddNamedDynamicListArgument("id", "--id badgeID", getAutocompletePath(AutocompletePathEditBadgeSuggestions), true)
|
|
edit.AddCommand(editBadge)
|
|
|
|
editType := model.NewAutocompleteData(
|
|
"type",
|
|
"",
|
|
"Edit a badge type",
|
|
)
|
|
editType.AddNamedDynamicListArgument("type", "--type typeID", getAutocompletePath(AutocompletePathEditTypeSuggestions), true)
|
|
edit.AddCommand(editType)
|
|
|
|
badges.AddCommand(edit)
|
|
|
|
subscription := model.NewAutocompleteData("subscription", "create | remove", "Manage this channel subscriptions")
|
|
|
|
createSubscription := model.NewAutocompleteData(
|
|
"create",
|
|
"",
|
|
"Create a subscription",
|
|
)
|
|
subscription.AddCommand(createSubscription)
|
|
|
|
deleteSubscription := model.NewAutocompleteData(
|
|
"remove",
|
|
"",
|
|
"Remove a subscription",
|
|
)
|
|
subscription.AddCommand(deleteSubscription)
|
|
|
|
badges.AddCommand(subscription)
|
|
|
|
return badges
|
|
}
|
|
|
|
func getAutocompletePath(path string) string {
|
|
return "plugins/" + manifest.Id + AutocompletePath + path
|
|
}
|