diff --git a/handlers.go b/handlers.go index eec82e0..b159955 100644 --- a/handlers.go +++ b/handlers.go @@ -44,20 +44,11 @@ func (b *bot) chatHandler(m chat1.MsgSummary) { } // then check if this is the root command if isRootCommand(m.Content.Text.Body, b.cmd(), b.k.Username) { - b.handleMeeting(m) - return - } - // then check sub-command variants - // meet - if hasCommandPrefix(m.Content.Text.Body, b.cmd(), b.k.Username, "meet") { - b.handleMeeting(m) - return - } - // feedback - if hasCommandPrefix(m.Content.Text.Body, b.cmd(), b.k.Username, "feedback") { - b.handleFeedback(m) + b.checkPermissionAndExecute("reader", m, b.handleMeeting) return } + + // then check help and welcome (non-permissions) // help if hasCommandPrefix(m.Content.Text.Body, b.cmd(), b.k.Username, "help") { b.handleWelcome(m.ConvID) @@ -68,9 +59,21 @@ func (b *bot) chatHandler(m chat1.MsgSummary) { b.handleWelcome(m.ConvID) return } + + // then check sub-command variants (permissions) + // meet + if hasCommandPrefix(m.Content.Text.Body, b.cmd(), b.k.Username, "meet") { + b.checkPermissionAndExecute("reader", m, b.handleMeeting) + return + } + // feedback + if hasCommandPrefix(m.Content.Text.Body, b.cmd(), b.k.Username, "feedback") { + b.checkPermissionAndExecute("reader", m, b.handleFeedback) + return + } // config commands if hasCommandPrefix(m.Content.Text.Body, b.cmd(), b.k.Username, "config") { - b.handleConfigCommand(m) + b.checkPermissionAndExecute("admin", m, b.handleConfigCommand) return } } diff --git a/permissions.go b/permissions.go new file mode 100644 index 0000000..ab107f4 --- /dev/null +++ b/permissions.go @@ -0,0 +1,90 @@ +package main + +import ( + "strings" + + "samhofi.us/x/keybase/types/chat1" +) + +// checkPermissionAndExecute will check the minimum required role for the permission and execute the handler function if allowed +func (b *bot) checkPermissionAndExecute(requiredRole string, m chat1.MsgSummary, f func(chat1.MsgSummary)) { + // get the members of the conversation + b.debug("Executing permissions check") + // currently this doesn't work due to a keybase bug + // the workaround is to check the general channel the old way + //conversation, err := b.k.ListMembersOfConversation(m.ConvID) + + // **** + channel := chat1.ChatChannel{ + Name: m.Channel.Name, + MembersType: m.Channel.MembersType, + TopicName: "general", + } + conversation, err := b.k.ListMembersOfChannel(channel) + /// **** + + if err != nil { + eid := b.logError(err) + b.k.ReactByConvID(m.ConvID, m.Id, "Error ID %s", eid) + return + } + // create a map of valid roles, according to @dxb struc + memberTypes := make(map[string]struct{}) + memberTypes["owner"] = struct{}{} + memberTypes["admin"] = struct{}{} + memberTypes["writer"] = struct{}{} + memberTypes["reader"] = struct{}{} + + // if the role is not in the map, its an invalid role + if _, ok := memberTypes[strings.ToLower(requiredRole)]; !ok { + // the role passed was not valid, so bail + b.log("ERROR: %s is not a valid permissions level", requiredRole) + return + } + + // then descend permissions from top down + for _, member := range conversation.Members.Owners { + if strings.ToLower(member.Username) == strings.ToLower(m.Sender.Username) { + f(m) + return + } + b.debug("no") + } + // if the required role was owner, return and don't evaluate the rest + if strings.ToLower(requiredRole) == "owner" { + b.debug("user does not have required permission of: owner") + return + } + // admins + for _, member := range conversation.Members.Admins { + if strings.ToLower(member.Username) == strings.ToLower(m.Sender.Username) { + f(m) + return + } + } + if strings.ToLower(requiredRole) == "admin" { + b.debug("user does not have required permission of: admin") + return + } + // writers + for _, member := range conversation.Members.Writers { + if strings.ToLower(member.Username) == strings.ToLower(m.Sender.Username) { + f(m) + return + } + } + if strings.ToLower(requiredRole) == "writer" { + b.debug("user does not have required permission of: writer") + return + } + // readers + for _, member := range conversation.Members.Readers { + if strings.ToLower(member.Username) == strings.ToLower(m.Sender.Username) { + f(m) + return + } + } + // just return - restricted bots shouldn't be able to run commands + b.debug("user does not have required permission of: reader") + return +}