From 3e21f25dfdbbcf003a28ab5a6c31b58bc6cc4e49 Mon Sep 17 00:00:00 2001 From: Dot-Rar Date: Mon, 20 Apr 2020 22:46:01 +0100 Subject: [PATCH] admin role checking --- app/http/endpoints/manage/settings.go | 5 +- go.mod | 1 + utils/permissionutils.go | 86 ++++++++++++++++++++++----- 3 files changed, 74 insertions(+), 18 deletions(-) diff --git a/app/http/endpoints/manage/settings.go b/app/http/endpoints/manage/settings.go index bdab4c0..6093b62 100644 --- a/app/http/endpoints/manage/settings.go +++ b/app/http/endpoints/manage/settings.go @@ -31,15 +31,12 @@ func SettingsHandler(ctx *gin.Context) { } // Check the bot is in the guild - _, isInGuild := cache.Instance.GetGuild(guildId, false) + guild, isInGuild := cache.Instance.GetGuild(guildId, false) if !isInGuild { ctx.Redirect(302, fmt.Sprintf("https://invite.ticketsbot.net/?guild_id=%s&disable_guild_select=true&response_type=code&scope=bot%%20identify&redirect_uri=%s", guildIdStr, config.Conf.Server.BaseUrl)) return } - // Get object for selected guild - guild, _ := cache.Instance.GetGuild(guildId, false) - // Verify the user has permissions to be here isAdmin := make(chan bool) go utils.IsAdmin(guild, userId, isAdmin) diff --git a/go.mod b/go.mod index 9a02c48..7856fe2 100644 --- a/go.mod +++ b/go.mod @@ -21,4 +21,5 @@ require ( github.com/pkg/errors v0.9.1 github.com/robfig/go-cache v0.0.0-20130306151617-9fc39e0dbf62 github.com/rxdn/gdl v0.0.0-20200417164852-76b2d3c847c1 + golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a // indirect ) diff --git a/utils/permissionutils.go b/utils/permissionutils.go index 487a5b7..1f07b9c 100644 --- a/utils/permissionutils.go +++ b/utils/permissionutils.go @@ -1,14 +1,19 @@ package utils import ( + "context" + "errors" "github.com/TicketsBot/GoPanel/config" "github.com/TicketsBot/GoPanel/database/table" "github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/rpc/ratelimit" + "github.com/apex/log" "github.com/rxdn/gdl/objects/guild" "github.com/rxdn/gdl/permission" "github.com/rxdn/gdl/rest" + "golang.org/x/sync/errgroup" "strconv" + "sync" ) func IsAdmin(g guild.Guild, userId uint64, res chan bool) { @@ -24,29 +29,28 @@ func IsAdmin(g guild.Guild, userId uint64, res chan bool) { res <- true } - if permission.HasPermissionRaw(g.Permissions, permission.Administrator) { - res <- true + userRoles, _ := getRoles(g.Id, userId) + + // check if user has administrator permission + if hasAdministratorPermission(g.Id, userRoles) { + res <- true } adminRolesChan := make(chan []uint64) go table.GetAdminRoles(g.Id, adminRolesChan) - adminRoles := <- adminRolesChan + adminRoles := <-adminRolesChan - userRoles, found := getRoles(g.Id, userId) - - hasAdminRole := false - if found { - for _, userRole := range userRoles { - for _, adminRole := range adminRoles { - if userRole == adminRole { - hasAdminRole = true - break - } + hasTicketAdminRole := false + for _, userRole := range userRoles { + for _, adminRole := range adminRoles { + if userRole == adminRole { + hasTicketAdminRole = true + break } } } - if hasAdminRole { + if hasTicketAdminRole { res <- true } @@ -68,3 +72,57 @@ func getRoles(guildId, userId uint64) ([]uint64, bool) { return member.Roles, true } + +func hasAdministratorPermission(guildId uint64, roles []uint64) bool { + var lock sync.Mutex + var hasAdministrator bool + + group, _ := errgroup.WithContext(context.Background()) + for _, roleId := range roles { + group.Go(func() error { + roleHasAdmin, err := roleHasAdministrator(guildId, roleId) + if err != nil { + return err + } + + if roleHasAdmin { + lock.Lock() + hasAdministrator = true + lock.Unlock() + } + + return nil + }) + } + + if err := group.Wait(); err != nil { + return false + } + + return hasAdministrator +} + +func roleHasAdministrator(guildId, roleId uint64) (bool, error) { + role, found := cache.Instance.GetRole(roleId) + if !found { + roles, err := rest.GetGuildRoles(config.Conf.Bot.Token, ratelimit.Ratelimiter, guildId) + if err != nil { + log.Error(err.Error()) + return false, err + } + + go cache.Instance.StoreRoles(roles, guildId) + for _, r := range roles { + if r.Id == roleId { + role = r + found = true + break + } + } + if !found { + return false, errors.New("role does not exist") + } + } + + return permission.HasPermissionRaw(role.Permissions, permission.Administrator), nil +}