added the ability to assign multiple plugin administrators

This commit is contained in:
Дмитрий Пиченикин 2026-02-19 16:21:52 +03:00
parent 754304e4ca
commit 7c976233a7
6 changed files with 53 additions and 45 deletions

View File

@ -172,7 +172,7 @@ func (p *Plugin) getTypes(w http.ResponseWriter, r *http.Request, userID string)
resp := GetTypesResponse{
Types: result,
CanCreateType: canCreateType(u, p.badgeAdminUserID, false),
CanCreateType: canCreateType(u, p.badgeAdminUserIDs, false),
}
b, _ := json.Marshal(resp)
@ -225,7 +225,7 @@ func (p *Plugin) apiCreateBadge(w http.ResponseWriter, r *http.Request, userID s
return
}
if !canCreateBadge(user, p.badgeAdminUserID, t) {
if !canCreateBadge(user, p.badgeAdminUserIDs, t) {
p.writeAPIError(w, &APIErrorResponse{
ID: "no_permission", Message: "No permission to create badge of this type", StatusCode: http.StatusForbidden,
})
@ -281,7 +281,7 @@ func (p *Plugin) apiCreateType(w http.ResponseWriter, r *http.Request, userID st
return
}
if !canCreateType(user, p.badgeAdminUserID, false) {
if !canCreateType(user, p.badgeAdminUserIDs, false) {
p.writeAPIError(w, &APIErrorResponse{
ID: "no_permission", Message: "No permission to create type", StatusCode: http.StatusForbidden,
})
@ -350,7 +350,7 @@ func (p *Plugin) apiUpdateBadge(w http.ResponseWriter, r *http.Request, userID s
return
}
if !canEditBadge(user, p.badgeAdminUserID, badge) {
if !canEditBadge(user, p.badgeAdminUserIDs, badge) {
p.writeAPIError(w, &APIErrorResponse{
ID: "no_permission", Message: "No permission to edit this badge", StatusCode: http.StatusForbidden,
})
@ -420,7 +420,7 @@ func (p *Plugin) apiDeleteBadge(w http.ResponseWriter, r *http.Request, userID s
return
}
if !canEditBadge(user, p.badgeAdminUserID, badge) {
if !canEditBadge(user, p.badgeAdminUserIDs, badge) {
p.writeAPIError(w, &APIErrorResponse{
ID: "no_permission", Message: "No permission to delete this badge", StatusCode: http.StatusForbidden,
})
@ -470,7 +470,7 @@ func (p *Plugin) apiDeleteType(w http.ResponseWriter, r *http.Request, userID st
return
}
if !canEditType(user, p.badgeAdminUserID, t) {
if !canEditType(user, p.badgeAdminUserIDs, t) {
p.writeAPIError(w, &APIErrorResponse{
ID: "no_permission", Message: "No permission to delete this type", StatusCode: http.StatusForbidden,
})
@ -550,7 +550,7 @@ func (p *Plugin) dialogCreateBadge(w http.ResponseWriter, r *http.Request, userI
return
}
if !canCreateBadge(user, p.badgeAdminUserID, t) {
if !canCreateBadge(user, p.badgeAdminUserIDs, t) {
dialogError(w, T("badges.api.no_permissions_create_badge", "У вас нет прав на создание этого значка"), nil)
return
}
@ -586,7 +586,7 @@ func (p *Plugin) dialogCreateType(w http.ResponseWriter, r *http.Request, userID
}
T := p.getT(u.Locale)
if !canCreateType(u, p.badgeAdminUserID, false) {
if !canCreateType(u, p.badgeAdminUserIDs, false) {
dialogError(w, T("badges.api.no_permissions_create_type", "У вас нет прав на создание типа"), nil)
return
}
@ -684,7 +684,7 @@ func (p *Plugin) dialogSelectType(w http.ResponseWriter, r *http.Request, userID
}
T := p.getT(u.Locale)
if !canEditType(u, p.badgeAdminUserID, t) {
if !canEditType(u, p.badgeAdminUserIDs, t) {
dialogError(w, T("badges.api.cannot_edit_type", "Вы не можете редактировать этот тип"), nil)
return
}
@ -723,7 +723,7 @@ func (p *Plugin) dialogEditType(w http.ResponseWriter, r *http.Request, userID s
return
}
if !canEditType(u, p.badgeAdminUserID, originalType) {
if !canEditType(u, p.badgeAdminUserIDs, originalType) {
dialogError(w, T("badges.api.no_permissions_edit_type", "У вас нет прав на редактирование этого типа"), nil)
return
}
@ -828,7 +828,7 @@ func (p *Plugin) dialogSelectBadge(w http.ResponseWriter, r *http.Request, userI
}
T := p.getT(u.Locale)
if !canEditBadge(u, p.badgeAdminUserID, b) {
if !canEditBadge(u, p.badgeAdminUserIDs, b) {
dialogError(w, T("badges.api.cannot_edit_badge", "Вы не можете редактировать этот значок"), nil)
return
}
@ -867,7 +867,7 @@ func (p *Plugin) dialogEditBadge(w http.ResponseWriter, r *http.Request, userID
return
}
if !canEditBadge(u, p.badgeAdminUserID, originalBadge) {
if !canEditBadge(u, p.badgeAdminUserIDs, originalBadge) {
dialogError(w, T("badges.api.no_permissions_edit_badge", "У вас нет прав на редактирование этого значка"), nil)
return
}
@ -970,7 +970,7 @@ func (p *Plugin) dialogGrant(w http.ResponseWriter, r *http.Request, userID stri
return
}
if !canGrantBadge(granter, p.badgeAdminUserID, badge, badgeType) {
if !canGrantBadge(granter, p.badgeAdminUserIDs, badge, badgeType) {
dialogError(w, T("badges.api.no_permissions_grant", "У вас нет прав на выдачу этого значка"), nil)
return
}
@ -1030,7 +1030,7 @@ func (p *Plugin) dialogCreateSubscription(w http.ResponseWriter, r *http.Request
}
T := p.getT(u.Locale)
if !canCreateSubscription(u, p.badgeAdminUserID, req.ChannelId) {
if !canCreateSubscription(u, p.badgeAdminUserIDs, req.ChannelId) {
dialogError(w, T("badges.api.cannot_create_subscription", "Вы не можете создать подписку"), nil)
return
}
@ -1070,7 +1070,7 @@ func (p *Plugin) dialogDeleteSubscription(w http.ResponseWriter, r *http.Request
}
T := p.getT(u.Locale)
if !canCreateSubscription(u, p.badgeAdminUserID, req.ChannelId) {
if !canCreateSubscription(u, p.badgeAdminUserIDs, req.ChannelId) {
dialogError(w, T("badges.api.cannot_delete_subscription", "Вы не можете удалить подписку"), nil)
return
}
@ -1162,7 +1162,7 @@ func (p *Plugin) grantBadge(w http.ResponseWriter, r *http.Request, pluginID str
return
}
if !canGrantBadge(granter, p.badgeAdminUserID, badge, badgeType) {
if !canGrantBadge(granter, p.badgeAdminUserIDs, badge, badgeType) {
p.writeAPIError(w, &APIErrorResponse{
ID: "cannot grant badge",
Message: "you have no permissions to grant this badge",

View File

@ -271,7 +271,7 @@ func (p *Plugin) runEditBadge(args []string, extra *model.CommandArgs) (bool, *m
return commandError(err.Error())
}
if !canEditBadge(u, p.badgeAdminUserID, badge) {
if !canEditBadge(u, p.badgeAdminUserIDs, badge) {
return commandError(T("badges.error.cannot_edit_badge", "У вас нет прав на редактирование этого значка"))
}
@ -359,7 +359,7 @@ func (p *Plugin) runEditType(args []string, extra *model.CommandArgs) (bool, *mo
}
T := p.getT(u.Locale)
if !canCreateType(u, p.badgeAdminUserID, false) {
if !canCreateType(u, p.badgeAdminUserIDs, false) {
return commandError(T("badges.error.no_permissions_edit_type", "У вас нет прав на редактирование типа значков."))
}
@ -379,7 +379,7 @@ func (p *Plugin) runEditType(args []string, extra *model.CommandArgs) (bool, *mo
return commandError(err.Error())
}
if !canEditType(u, p.badgeAdminUserID, typeDefinition) {
if !canEditType(u, p.badgeAdminUserIDs, typeDefinition) {
return commandError(T("badges.error.cannot_edit_type", "У вас нет прав на редактирование этого типа"))
}
@ -493,7 +493,7 @@ func (p *Plugin) runCreateType(args []string, extra *model.CommandArgs) (bool, *
}
T := p.getT(u.Locale)
if !canCreateType(u, p.badgeAdminUserID, false) {
if !canCreateType(u, p.badgeAdminUserIDs, false) {
return commandError(T("badges.error.no_permissions_create_type", "У вас нет прав на создание типа значков."))
}
@ -582,7 +582,7 @@ func (p *Plugin) runGrant(args []string, extra *model.CommandArgs) (bool, *model
return commandError(err.Error())
}
if !canGrantBadge(granter, p.badgeAdminUserID, badge, badgeType) {
if !canGrantBadge(granter, p.badgeAdminUserIDs, badge, badgeType) {
return commandError(T("badges.error.no_permissions_grant", "У вас нет прав на выдачу этого значка"))
}
@ -755,7 +755,7 @@ func (p *Plugin) runCreateSubscription(args []string, extra *model.CommandArgs)
}
T := p.getT(actingUser.Locale)
if !canCreateSubscription(actingUser, p.badgeAdminUserID, extra.ChannelId) {
if !canCreateSubscription(actingUser, p.badgeAdminUserIDs, extra.ChannelId) {
return commandError(T("badges.error.cannot_create_subscription", "Вы не можете создавать подписки"))
}
@ -818,7 +818,7 @@ func (p *Plugin) runDeleteSubscription(args []string, extra *model.CommandArgs)
}
T := p.getT(actingUser.Locale)
if !canCreateSubscription(actingUser, p.badgeAdminUserID, extra.ChannelId) {
if !canCreateSubscription(actingUser, p.badgeAdminUserIDs, extra.ChannelId) {
return commandError(T("badges.error.cannot_create_subscription", "Вы не можете создавать подписки"))
}

View File

@ -2,6 +2,7 @@ package main
import (
"reflect"
"strings"
"github.com/pkg/errors"
)
@ -78,13 +79,20 @@ func (p *Plugin) OnConfigurationChange() error {
return errors.Wrap(err, "failed to load plugin configuration")
}
p.badgeAdminUserID = ""
p.badgeAdminUserIDs = make(map[string]bool)
if configuration.BadgesAdmin != "" {
u, err := p.API.GetUserByUsername(configuration.BadgesAdmin)
if err != nil {
return errors.Wrap(err, "cannot get badge admin user")
for username := range strings.SplitSeq(configuration.BadgesAdmin, ",") {
username = strings.TrimSpace(username)
if username == "" {
continue
}
u, err := p.API.GetUserByUsername(username)
if err != nil {
p.API.LogWarn("Cannot find badge admin user", "username", username, "error", err.Error())
continue
}
p.badgeAdminUserIDs[u.Id] = true
}
p.badgeAdminUserID = u.Id
}
p.setConfiguration(configuration)

View File

@ -28,7 +28,7 @@ type Plugin struct {
BotUserID string
store Store
router *mux.Router
badgeAdminUserID string
badgeAdminUserIDs map[string]bool
i18nBundle *i18n.Bundle
}

View File

@ -23,7 +23,7 @@ func (p *Plugin) filterGrantBadges(user *model.User) ([]*badgesmodel.Badge, erro
p.mm.Log.Debug("Badge with missing type", "badge", b)
continue
}
if canGrantBadge(user, p.badgeAdminUserID, b, badgeType) {
if canGrantBadge(user, p.badgeAdminUserIDs, b, badgeType) {
out = append(out, b)
}
}
@ -39,7 +39,7 @@ func (p *Plugin) filterCreateBadgeTypes(user *model.User) (badgesmodel.BadgeType
out := badgesmodel.BadgeTypeList{}
for _, t := range types {
if canCreateBadge(user, p.badgeAdminUserID, t) {
if canCreateBadge(user, p.badgeAdminUserIDs, t) {
out = append(out, t)
}
}
@ -55,7 +55,7 @@ func (p *Plugin) filterEditTypes(user *model.User) (badgesmodel.BadgeTypeList, e
out := badgesmodel.BadgeTypeList{}
for _, t := range types {
if canEditType(user, p.badgeAdminUserID, t) {
if canEditType(user, p.badgeAdminUserIDs, t) {
out = append(out, t)
}
}
@ -71,7 +71,7 @@ func (p *Plugin) filterEditBadges(user *model.User) ([]*badgesmodel.Badge, error
out := []*badgesmodel.Badge{}
for _, b := range bb {
if canEditBadge(user, p.badgeAdminUserID, b) {
if canEditBadge(user, p.badgeAdminUserIDs, b) {
out = append(out, b)
}
}

View File

@ -23,8 +23,8 @@ func areRolesAllowed(userRoles []string, allowedRoles map[string]bool) bool {
return false
}
func canGrantBadge(user *model.User, badgeAdminID string, badge *badgesmodel.Badge, badgeType *badgesmodel.BadgeTypeDefinition) bool {
if badgeAdminID != "" && user.Id == badgeAdminID {
func canGrantBadge(user *model.User, badgeAdminIDs map[string]bool, badge *badgesmodel.Badge, badgeType *badgesmodel.BadgeTypeDefinition) bool {
if badgeAdminIDs[user.Id] {
return true
}
@ -57,8 +57,8 @@ func canGrantBadge(user *model.User, badgeAdminID string, badge *badgesmodel.Bad
return badgeType.CanGrant.Everyone
}
func canCreateBadge(user *model.User, badgeAdminID string, badgeType *badgesmodel.BadgeTypeDefinition) bool {
if badgeAdminID != "" && user.Id == badgeAdminID {
func canCreateBadge(user *model.User, badgeAdminIDs map[string]bool, badgeType *badgesmodel.BadgeTypeDefinition) bool {
if badgeAdminIDs[user.Id] {
return true
}
@ -87,36 +87,36 @@ func canCreateBadge(user *model.User, badgeAdminID string, badgeType *badgesmode
return badgeType.CanCreate.Everyone
}
func canEditType(user *model.User, badgeAdminID string, badgeType *badgesmodel.BadgeTypeDefinition) bool {
if badgeAdminID != "" && user.Id == badgeAdminID {
func canEditType(user *model.User, badgeAdminIDs map[string]bool, badgeType *badgesmodel.BadgeTypeDefinition) bool {
if badgeAdminIDs[user.Id] {
return true
}
return user.IsSystemAdmin()
}
func canEditBadge(user *model.User, badgeAdminID string, badge *badgesmodel.Badge) bool {
if badgeAdminID != "" && user.Id == badgeAdminID {
func canEditBadge(user *model.User, badgeAdminIDs map[string]bool, badge *badgesmodel.Badge) bool {
if badgeAdminIDs[user.Id] {
return true
}
return user.IsSystemAdmin() || user.Id == badge.CreatedBy
}
func canCreateType(user *model.User, badgeAdminID string, isPlugin bool) bool {
func canCreateType(user *model.User, badgeAdminIDs map[string]bool, isPlugin bool) bool {
if isPlugin {
return true
}
if badgeAdminID != "" && user.Id == badgeAdminID {
if badgeAdminIDs[user.Id] {
return true
}
return user.IsSystemAdmin()
}
func canCreateSubscription(user *model.User, badgeAdminID string, channelID string) bool {
if badgeAdminID != "" && user.Id == badgeAdminID {
func canCreateSubscription(user *model.User, badgeAdminIDs map[string]bool, channelID string) bool {
if badgeAdminIDs[user.Id] {
return true
}