mirror of
https://github.com/mumble-voip/grumble.git
synced 2025-12-19 21:59:59 -08:00
190 lines
4.3 KiB
Go
190 lines
4.3 KiB
Go
package main
|
|
|
|
import (
|
|
"json"
|
|
"os"
|
|
"compress/zlib"
|
|
)
|
|
|
|
type jsonServer struct {
|
|
Id int "id"
|
|
MaxUsers int "max_user"
|
|
Channels []jsonChannel "channels"
|
|
}
|
|
|
|
type jsonChannel struct {
|
|
Id int "id"
|
|
Name string "name"
|
|
ParentId int "parent_id"
|
|
Position int64 "position"
|
|
InheritACL bool "inherit_acl"
|
|
ACL []jsonACL "acl"
|
|
Groups []jsonGroup "groups"
|
|
Description string "description"
|
|
DescriptionHash []byte "description_hash"
|
|
}
|
|
|
|
type jsonACL struct {
|
|
UserId int "user_id"
|
|
Group string "group"
|
|
ApplyHere bool "apply_here"
|
|
ApplySubs bool "apply_subs"
|
|
Allow uint32 "allow"
|
|
Deny uint32 "deny"
|
|
}
|
|
|
|
type jsonGroup struct {
|
|
Name string "name"
|
|
Inherit bool "inherit"
|
|
Inheritable bool "inheritable"
|
|
Add []int "add"
|
|
Remove []int "remove"
|
|
}
|
|
|
|
// Marshal a server into a JSON object
|
|
func (server *Server) MarshalJSON() (buf []byte, err os.Error) {
|
|
obj := make(map[string]interface{})
|
|
obj["id"] = server.Id
|
|
obj["max_user"] = server.MaxUsers
|
|
|
|
channels := []interface{}{}
|
|
for _, c := range server.Channels {
|
|
channels = append(channels, c)
|
|
}
|
|
obj["channels"] = channels
|
|
|
|
return json.Marshal(obj)
|
|
}
|
|
|
|
// Marshal a Channel into a JSON object
|
|
func (channel *Channel) MarshalJSON() (buf []byte, err os.Error) {
|
|
obj := make(map[string]interface{})
|
|
|
|
obj["id"] = channel.Id
|
|
obj["name"] = channel.Name
|
|
if channel.parent != nil {
|
|
obj["parent_id"] = channel.parent.Id
|
|
} else {
|
|
obj["parent_id"] = -1
|
|
}
|
|
|
|
obj["position"] = channel.Position
|
|
obj["inherit_acl"] = channel.InheritACL
|
|
obj["description"] = channel.Description
|
|
obj["description_hash"] = channel.DescriptionHash
|
|
|
|
obj["acl"] = channel.ACL
|
|
|
|
groups := []*Group{}
|
|
for _, grp := range channel.Groups {
|
|
groups = append(groups, grp)
|
|
}
|
|
obj["groups"] = groups
|
|
links := []int{}
|
|
for cid, _ := range channel.Links {
|
|
links = append(links, cid)
|
|
}
|
|
|
|
return json.Marshal(obj)
|
|
}
|
|
|
|
func (acl *ChannelACL) MarshalJSON() (buf []byte, err os.Error) {
|
|
obj := make(map[string]interface{})
|
|
obj["user_id"] = acl.UserId
|
|
obj["group"] = acl.Group
|
|
obj["apply_here"] = acl.ApplyHere
|
|
obj["apply_subs"] = acl.ApplySubs
|
|
obj["allow"] = acl.Allow
|
|
obj["deny"] = acl.Deny
|
|
|
|
return json.Marshal(obj)
|
|
}
|
|
|
|
func (group *Group) MarshalJSON() (buf []byte, err os.Error) {
|
|
obj := make(map[string]interface{})
|
|
obj["name"] = group.Name
|
|
obj["inherit"] = group.Inherit
|
|
obj["inheritable"] = group.Inheritable
|
|
obj["add"] = group.AddUsers()
|
|
obj["remove"] = group.RemoveUsers()
|
|
|
|
return json.Marshal(obj)
|
|
}
|
|
|
|
// Create a new Server from a Grumble zlib-compressed JSON description
|
|
func NewServerFromGrumbleDesc(filename string) (s *Server, err os.Error) {
|
|
descFile, err := os.Open(filename)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer descFile.Close()
|
|
|
|
zr, err := zlib.NewReader(descFile)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
srv := new(jsonServer)
|
|
decoder := json.NewDecoder(zr)
|
|
decoder.Decode(&srv)
|
|
|
|
s, err = NewServer(int64(srv.Id), "", int(DefaultPort+srv.Id-1))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Add all channels, but don't hook up parent/child relationships
|
|
// until all of them are loaded.
|
|
for _, jc := range srv.Channels {
|
|
c := NewChannel(jc.Id, jc.Name)
|
|
c.Position = int(jc.Position)
|
|
c.InheritACL = jc.InheritACL
|
|
c.Description = jc.Description
|
|
c.DescriptionHash = jc.DescriptionHash
|
|
|
|
for _, jacl := range jc.ACL {
|
|
acl := NewChannelACL(c)
|
|
acl.ApplyHere = jacl.ApplyHere
|
|
acl.ApplySubs = jacl.ApplySubs
|
|
acl.UserId = jacl.UserId
|
|
acl.Group = jacl.Group
|
|
acl.Deny = Permission(jacl.Deny)
|
|
acl.Allow = Permission(jacl.Allow)
|
|
c.ACL = append(c.ACL, acl)
|
|
}
|
|
for _, jgrp := range jc.Groups {
|
|
g := NewGroup(c, jgrp.Name)
|
|
g.Inherit = jgrp.Inherit
|
|
g.Inheritable = jgrp.Inheritable
|
|
for _, uid := range jgrp.Add {
|
|
g.Add[uid] = true
|
|
}
|
|
for _, uid := range jgrp.Remove {
|
|
g.Remove[uid] = true
|
|
}
|
|
c.Groups[g.Name] = g
|
|
}
|
|
|
|
s.Channels[c.Id] = c
|
|
}
|
|
|
|
// Hook up children with their parents.
|
|
for _, jc := range srv.Channels {
|
|
if jc.Id == 0 {
|
|
continue
|
|
}
|
|
childChan, exists := s.Channels[jc.Id]
|
|
if !exists {
|
|
return nil, os.NewError("Non-existant child channel")
|
|
}
|
|
parentChan, exists := s.Channels[jc.ParentId]
|
|
if !exists {
|
|
return nil, os.NewError("Non-existant parent channel")
|
|
}
|
|
parentChan.AddChild(childChan)
|
|
}
|
|
|
|
s.root = s.Channels[0]
|
|
|
|
return s, nil
|
|
}
|