mirror of
https://github.com/jech/galene.git
synced 2024-11-09 18:25:58 +01:00
Export and document group.Description.
This is useful for people writing administrative interfaces.
This commit is contained in:
parent
81050184eb
commit
189dfb4abe
2 changed files with 76 additions and 35 deletions
|
@ -66,7 +66,7 @@ type Group struct {
|
||||||
name string
|
name string
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
description *description
|
description *Description
|
||||||
locked *string
|
locked *string
|
||||||
clients map[string]Client
|
clients map[string]Client
|
||||||
history []ChatHistoryEntry
|
history []ChatHistoryEntry
|
||||||
|
@ -266,7 +266,7 @@ func APIFromNames(names []string) *webrtc.API {
|
||||||
return APIFromCodecs(codecs)
|
return APIFromCodecs(codecs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Add(name string, desc *description) (*Group, error) {
|
func Add(name string, desc *Description) (*Group, error) {
|
||||||
if name == "" || strings.HasSuffix(name, "/") {
|
if name == "" || strings.HasSuffix(name, "/") {
|
||||||
return nil, UserError("illegal group name")
|
return nil, UserError("illegal group name")
|
||||||
}
|
}
|
||||||
|
@ -698,31 +698,72 @@ func matchClient(group string, c Challengeable, users []ClientCredentials) (bool
|
||||||
return false, false
|
return false, false
|
||||||
}
|
}
|
||||||
|
|
||||||
type description struct {
|
// Type Description represents a group description together with some
|
||||||
fileName string `json:"-"`
|
// metadata about the JSON file it was deserialised from.
|
||||||
modTime time.Time `json:"-"`
|
type Description struct {
|
||||||
fileSize int64 `json:"-"`
|
// The file this was deserialised from. This is not necessarily
|
||||||
Description string `json:"description,omitempty"`
|
// the name of the group, for example in case of a subgroup.
|
||||||
Contact string `json:"contact,omitempty"`
|
FileName string `json:"-"`
|
||||||
Comment string `json:"comment,omitempty"`
|
|
||||||
Redirect string `json:"redirect,omitempty"`
|
// The modtime and size of the file. These are used to detect
|
||||||
Public bool `json:"public,omitempty"`
|
// when a file has changed on disk.
|
||||||
MaxClients int `json:"max-clients,omitempty"`
|
modTime time.Time `json:"-"`
|
||||||
MaxHistoryAge int `json:"max-history-age,omitempty"`
|
fileSize int64 `json:"-"`
|
||||||
AllowAnonymous bool `json:"allow-anonymous,omitempty"`
|
|
||||||
AllowRecording bool `json:"allow-recording,omitempty"`
|
// A user-readable description of the group.
|
||||||
AllowSubgroups bool `json:"allow-subgroups,omitempty"`
|
Description string `json:"description,omitempty"`
|
||||||
Autolock bool `json:"autolock,omitempty"`
|
|
||||||
Autokick bool `json:"autokick,omitempty"`
|
// A user-readable contact, typically an e-mail address.
|
||||||
Op []ClientCredentials `json:"op,omitempty"`
|
Contact string `json:"contact,omitempty"`
|
||||||
Presenter []ClientCredentials `json:"presenter,omitempty"`
|
|
||||||
Other []ClientCredentials `json:"other,omitempty"`
|
// A user-readable comment. Ignored by the server.
|
||||||
Codecs []string `json:"codecs,omitempty"`
|
Comment string `json:"comment,omitempty"`
|
||||||
|
|
||||||
|
// Whether to display the group on the landing page.
|
||||||
|
Public bool `json:"public,omitempty"`
|
||||||
|
|
||||||
|
// A URL to redirect the group to. If this is not empty, most
|
||||||
|
// other fields are ignored.
|
||||||
|
Redirect string `json:"redirect,omitempty"`
|
||||||
|
|
||||||
|
// The maximum number of simultaneous clients. Unlimited if 0.
|
||||||
|
MaxClients int `json:"max-clients,omitempty"`
|
||||||
|
|
||||||
|
// The time for which history entries are kept.
|
||||||
|
MaxHistoryAge int `json:"max-history-age,omitempty"`
|
||||||
|
|
||||||
|
// Whether users are allowed to log in with an empty username.
|
||||||
|
AllowAnonymous bool `json:"allow-anonymous,omitempty"`
|
||||||
|
|
||||||
|
// Whether recording is allowed.
|
||||||
|
AllowRecording bool `json:"allow-recording,omitempty"`
|
||||||
|
|
||||||
|
// Whether subgroups are created on the fly.
|
||||||
|
AllowSubgroups bool `json:"allow-subgroups,omitempty"`
|
||||||
|
|
||||||
|
// Whether to lock the group when the last op logs out.
|
||||||
|
Autolock bool `json:"autolock,omitempty"`
|
||||||
|
|
||||||
|
// Whether to kick all users when the last op logs out.
|
||||||
|
Autokick bool `json:"autokick,omitempty"`
|
||||||
|
|
||||||
|
// A list of logins for ops.
|
||||||
|
Op []ClientCredentials `json:"op,omitempty"`
|
||||||
|
|
||||||
|
// A list of logins for presenters.
|
||||||
|
Presenter []ClientCredentials `json:"presenter,omitempty"`
|
||||||
|
|
||||||
|
// A list of logins for non-presenting users.
|
||||||
|
Other []ClientCredentials `json:"other,omitempty"`
|
||||||
|
|
||||||
|
// Codec preferences. If empty, a suitable default is chosen in
|
||||||
|
// the APIFromNames function.
|
||||||
|
Codecs []string `json:"codecs,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const DefaultMaxHistoryAge = 4 * time.Hour
|
const DefaultMaxHistoryAge = 4 * time.Hour
|
||||||
|
|
||||||
func maxHistoryAge(desc *description) time.Duration {
|
func maxHistoryAge(desc *Description) time.Duration {
|
||||||
if desc.MaxHistoryAge != 0 {
|
if desc.MaxHistoryAge != 0 {
|
||||||
return time.Duration(desc.MaxHistoryAge) * time.Second
|
return time.Duration(desc.MaxHistoryAge) * time.Second
|
||||||
}
|
}
|
||||||
|
@ -765,9 +806,9 @@ func statDescriptionFile(name string) (os.FileInfo, string, bool, error) {
|
||||||
|
|
||||||
// descriptionChanged returns true if a group's description may have
|
// descriptionChanged returns true if a group's description may have
|
||||||
// changed since it was last read.
|
// changed since it was last read.
|
||||||
func descriptionChanged(name string, desc *description) bool {
|
func descriptionChanged(name string, desc *Description) bool {
|
||||||
fi, fileName, _, err := statDescriptionFile(name)
|
fi, fileName, _, err := statDescriptionFile(name)
|
||||||
if err != nil || fileName != desc.fileName {
|
if err != nil || fileName != desc.FileName {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -777,14 +818,14 @@ func descriptionChanged(name string, desc *description) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDescription(name string) (*description, error) {
|
func GetDescription(name string) (*Description, error) {
|
||||||
r, fileName, isParent, err := openDescriptionFile(name)
|
r, fileName, isParent, err := openDescriptionFile(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer r.Close()
|
defer r.Close()
|
||||||
|
|
||||||
var desc description
|
var desc Description
|
||||||
|
|
||||||
fi, err := r.Stat()
|
fi, err := r.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -805,14 +846,14 @@ func GetDescription(name string) (*description, error) {
|
||||||
desc.Description = ""
|
desc.Description = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
desc.fileName = fileName
|
desc.FileName = fileName
|
||||||
desc.fileSize = fi.Size()
|
desc.fileSize = fi.Size()
|
||||||
desc.modTime = fi.ModTime()
|
desc.modTime = fi.ModTime()
|
||||||
|
|
||||||
return &desc, nil
|
return &desc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (desc *description) GetPermission(group string, c Challengeable) (ClientPermissions, error) {
|
func (desc *Description) GetPermission(group string, c Challengeable) (ClientPermissions, error) {
|
||||||
var p ClientPermissions
|
var p ClientPermissions
|
||||||
if !desc.AllowAnonymous && c.Username() == "" {
|
if !desc.AllowAnonymous && c.Username() == "" {
|
||||||
return p, UserError("anonymous users not allowed in this group, please choose a username")
|
return p, UserError("anonymous users not allowed in this group, please choose a username")
|
||||||
|
|
|
@ -10,8 +10,8 @@ import (
|
||||||
|
|
||||||
func TestGroup(t *testing.T) {
|
func TestGroup(t *testing.T) {
|
||||||
groups.groups = nil
|
groups.groups = nil
|
||||||
Add("group", &description{})
|
Add("group", &Description{})
|
||||||
Add("group/subgroup", &description{Public: true})
|
Add("group/subgroup", &Description{Public: true})
|
||||||
if len(groups.groups) != 2 {
|
if len(groups.groups) != 2 {
|
||||||
t.Errorf("Expected 2, got %v", len(groups.groups))
|
t.Errorf("Expected 2, got %v", len(groups.groups))
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ func TestJSTime(t *testing.T) {
|
||||||
|
|
||||||
func TestChatHistory(t *testing.T) {
|
func TestChatHistory(t *testing.T) {
|
||||||
g := Group{
|
g := Group{
|
||||||
description: &description{},
|
description: &Description{},
|
||||||
}
|
}
|
||||||
for i := 0; i < 2*maxChatHistory; i++ {
|
for i := 0; i < 2*maxChatHistory; i++ {
|
||||||
g.AddToChatHistory("id", "user", ToJSTime(time.Now()), "",
|
g.AddToChatHistory("id", "user", ToJSTime(time.Now()), "",
|
||||||
|
@ -132,7 +132,7 @@ var descJSON = `
|
||||||
}`
|
}`
|
||||||
|
|
||||||
func TestDescriptionJSON(t *testing.T) {
|
func TestDescriptionJSON(t *testing.T) {
|
||||||
var d description
|
var d Description
|
||||||
err := json.Unmarshal([]byte(descJSON), &d)
|
err := json.Unmarshal([]byte(descJSON), &d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unmarshal: %v", err)
|
t.Fatalf("unmarshal: %v", err)
|
||||||
|
@ -143,7 +143,7 @@ func TestDescriptionJSON(t *testing.T) {
|
||||||
t.Fatalf("marshal: %v", err)
|
t.Fatalf("marshal: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var ddd description
|
var ddd Description
|
||||||
err = json.Unmarshal([]byte(dd), &ddd)
|
err = json.Unmarshal([]byte(dd), &ddd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unmarshal: %v", err)
|
t.Fatalf("unmarshal: %v", err)
|
||||||
|
@ -209,7 +209,7 @@ var goodClients = []testClientPerm{
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPermissions(t *testing.T) {
|
func TestPermissions(t *testing.T) {
|
||||||
var d description
|
var d Description
|
||||||
err := json.Unmarshal([]byte(descJSON), &d)
|
err := json.Unmarshal([]byte(descJSON), &d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unmarshal: %v", err)
|
t.Fatalf("unmarshal: %v", err)
|
||||||
|
|
Loading…
Reference in a new issue