cscsysbot/plugins/club/club.go

124 lines
3.5 KiB
Go

package club
import (
"crypto/tls"
"fmt"
"strconv"
"strings"
"sort"
"git.uwaterloo.ca/csc/cscsysbot/utils"
"github.com/go-chat-bot/bot"
"gopkg.in/ldap.v2"
)
const (
ldapServer = "ldap-master.csclub.uwaterloo.ca"
)
type ByTerm []string
func (s ByTerm) Len() int {
return len(s)
}
func (s ByTerm) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s ByTerm) Less(i, j int) bool {
a := s[i]
b := s[j]
ya, _ := strconv.ParseInt(a[1:5], 10, 32)
yb, _ := strconv.ParseInt(b[1:5], 10, 32)
if (ya == yb) {
// w, s, f (happens to be in reverse order)
return a[0] > b[0]
}
return ya < yb
}
func club(command *bot.Cmd) (string, error) {
var lines []string
if len(command.Args) != 1 {
return "An invalid number of arguments was provided. Usage is: !club userid", nil
}
authorized, _ := utils.SyscomNicks()
if (!utils.InList(authorized, command.User.Nick)) {
return "Sorry, you are not authorized to request membership information from me.", nil
}
l, err := ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", ldapServer, 636), &tls.Config{
ServerName: ldapServer,
})
if err != nil {
return "", err
}
defer l.Close()
req := ldap.NewSearchRequest("ou=People,dc=csclub,dc=uwaterloo,dc=ca", ldap.ScopeWholeSubtree,
ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(&(uid=%s)(objectClass=club))", command.Args[0]),
[]string{"*"}, nil)
res, err := l.Search(req)
if err != nil {
return "", err
}
if len(res.Entries) == 0 {
lines = append(lines, fmt.Sprintf("No clubs matched userid %q", command.Args[0]))
} else {
entry := res.Entries[0]
lines = append(lines, fmt.Sprintf("Club: %s (%s) -- %s",
entry.GetAttributeValue("uid"),
entry.GetAttributeValue("uidNumber"),
entry.GetAttributeValue("cn")))
lines = append(lines, fmt.Sprintf("Login Shell: %s, Home Directory: %s", entry.GetAttributeValue("loginShell"), entry.GetAttributeValue("homeDirectory")))
}
// Get members
req = ldap.NewSearchRequest("ou=Group,dc=csclub,dc=uwaterloo,dc=ca", ldap.ScopeWholeSubtree,
ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(&(cn=%s)(objectClass=posixGroup))", command.Args[0]),
[]string{"*"}, nil)
res, err = l.Search(req)
if err != nil {
return "", err
}
if len(res.Entries) == 0 {
lines = append(lines, fmt.Sprintf("No groups matched name %q", command.Args[0]))
} else {
entry := res.Entries[0]
lines = append(lines, fmt.Sprintf("Group: %s (%s)", entry.GetAttributeValue("cn"), entry.GetAttributeValue("gidNumber")))
members := entry.GetAttributeValues("uniqueMember")
memberUids := make([]string, len(members))
for i, member := range members {
memberUids[i] = strings.Replace(strings.Replace(member, "uid=", "", -1), ",ou=People,dc=csclub,dc=uwaterloo,dc=ca", "", -1)
}
smemberUids := sort.StringSlice(memberUids[0:])
sort.Sort(smemberUids)
lines = append(lines, fmt.Sprintf("Members: %s", strings.Join(smemberUids, ", ")))
}
return strings.Join(lines, "\n"), nil
}
func init() {
bot.RegisterCommand(
"club",
"Prints club information",
"userid",
club)
}