mirror of
https://github.com/jech/galene.git
synced 2024-11-26 02:25:58 +01:00
Implement subgroups.
This commit is contained in:
parent
dcfd071ea0
commit
29bd67cc22
2 changed files with 64 additions and 21 deletions
2
README
2
README
|
@ -119,6 +119,8 @@ fields, all of which are optional.
|
||||||
kept (default 14400, i.e. 4 hours);
|
kept (default 14400, i.e. 4 hours);
|
||||||
- `allow-recording`: if true, then recording is allowed in this group;
|
- `allow-recording`: if true, then recording is allowed in this group;
|
||||||
- `allow-anonymous`: if true, then users may connect with an empty username.
|
- `allow-anonymous`: if true, then users may connect with an empty username.
|
||||||
|
- `allow-subgroups`: if true, then subgroups of the form `group/subgroup`
|
||||||
|
are automatically created when accessed.
|
||||||
- `redirect`: if set, then attempts to join the group will be redirected
|
- `redirect`: if set, then attempts to join the group will be redirected
|
||||||
to the given URL; most other fields are ignored in this case.
|
to the given URL; most other fields are ignored in this case.
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -198,16 +199,7 @@ func Add(name string, desc *description) (*Group, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if g.dead || time.Since(g.description.loadTime) > 5*time.Second {
|
if g.dead || time.Since(g.description.loadTime) > 5*time.Second {
|
||||||
changed, err := descriptionChanged(name, g.description)
|
if descriptionChanged(name, g.description) {
|
||||||
if err != nil {
|
|
||||||
if !os.IsNotExist(err) {
|
|
||||||
log.Printf("Reading group %v: %v", name, err)
|
|
||||||
}
|
|
||||||
g.dead = true
|
|
||||||
delGroupUnlocked(name)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if changed {
|
|
||||||
desc, err := GetDescription(name)
|
desc, err := GetDescription(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
|
@ -478,6 +470,7 @@ func matchUser(user ClientCredentials, users []ClientCredentials) (bool, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type description struct {
|
type description struct {
|
||||||
|
fileName string `json:"-"`
|
||||||
loadTime time.Time `json:"-"`
|
loadTime time.Time `json:"-"`
|
||||||
modTime time.Time `json:"-"`
|
modTime time.Time `json:"-"`
|
||||||
fileSize int64 `json:"-"`
|
fileSize int64 `json:"-"`
|
||||||
|
@ -485,27 +478,65 @@ type description struct {
|
||||||
Redirect string `json:"redirect,omitempty"`
|
Redirect string `json:"redirect,omitempty"`
|
||||||
Public bool `json:"public,omitempty"`
|
Public bool `json:"public,omitempty"`
|
||||||
MaxClients int `json:"max-clients,omitempty"`
|
MaxClients int `json:"max-clients,omitempty"`
|
||||||
MaxHistoryAge int `json:"max-history-age",omitempty`
|
MaxHistoryAge int `json:"max-history-age,omitempty"`
|
||||||
AllowAnonymous bool `json:"allow-anonymous,omitempty"`
|
AllowAnonymous bool `json:"allow-anonymous,omitempty"`
|
||||||
AllowRecording bool `json:"allow-recording,omitempty"`
|
AllowRecording bool `json:"allow-recording,omitempty"`
|
||||||
|
AllowSubgroups bool `json:"allow-subgroups,omitempty"`
|
||||||
Op []ClientCredentials `json:"op,omitempty"`
|
Op []ClientCredentials `json:"op,omitempty"`
|
||||||
Presenter []ClientCredentials `json:"presenter,omitempty"`
|
Presenter []ClientCredentials `json:"presenter,omitempty"`
|
||||||
Other []ClientCredentials `json:"other,omitempty"`
|
Other []ClientCredentials `json:"other,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func descriptionChanged(name string, old *description) (bool, error) {
|
func openDescriptionFile(name string) (*os.File, string, bool, error) {
|
||||||
fi, err := os.Stat(filepath.Join(Directory, name+".json"))
|
isParent := false
|
||||||
if err != nil {
|
for name != "" {
|
||||||
return false, err
|
fileName := filepath.Join(
|
||||||
|
Directory, path.Clean("/"+name)+".json",
|
||||||
|
)
|
||||||
|
r, err := os.Open(fileName)
|
||||||
|
if !os.IsNotExist(err) {
|
||||||
|
return r, fileName, isParent, err
|
||||||
}
|
}
|
||||||
if fi.Size() != old.fileSize || fi.ModTime() != old.modTime {
|
isParent = true
|
||||||
return true, err
|
name, _ = path.Split(name)
|
||||||
|
name = strings.TrimRight(name, "/")
|
||||||
}
|
}
|
||||||
return false, err
|
return nil, "", false, os.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
|
func statDescriptionFile(name string) (os.FileInfo, string, bool, error) {
|
||||||
|
isParent := false
|
||||||
|
for name != "" {
|
||||||
|
fileName := filepath.Join(
|
||||||
|
Directory, path.Clean("/"+name)+".json",
|
||||||
|
)
|
||||||
|
fi, err := os.Stat(fileName)
|
||||||
|
if !os.IsNotExist(err) {
|
||||||
|
return fi, fileName, isParent, err
|
||||||
|
}
|
||||||
|
isParent = true
|
||||||
|
name, _ = path.Split(name)
|
||||||
|
name = strings.TrimRight(name, "/")
|
||||||
|
}
|
||||||
|
return nil, "", false, os.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
|
// descriptionChanged returns true if a group's description may have
|
||||||
|
// changed since it was last read.
|
||||||
|
func descriptionChanged(name string, desc *description) bool {
|
||||||
|
fi, fileName, _, err := statDescriptionFile(name)
|
||||||
|
if err != nil || fileName != desc.fileName {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if fi.Size() != desc.fileSize || fi.ModTime() != desc.modTime {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDescription(name string) (*description, error) {
|
func GetDescription(name string) (*description, error) {
|
||||||
r, err := os.Open(filepath.Join(Directory, name+".json"))
|
r, fileName, isParent, err := openDescriptionFile(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -517,15 +548,25 @@ func GetDescription(name string) (*description, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
desc.fileSize = fi.Size()
|
|
||||||
desc.modTime = fi.ModTime()
|
|
||||||
|
|
||||||
d := json.NewDecoder(r)
|
d := json.NewDecoder(r)
|
||||||
err = d.Decode(&desc)
|
err = d.Decode(&desc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if isParent {
|
||||||
|
if !desc.AllowSubgroups {
|
||||||
|
return nil, os.ErrNotExist
|
||||||
|
}
|
||||||
|
desc.Public = false
|
||||||
|
desc.Description = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
desc.fileName = fileName
|
||||||
|
desc.fileSize = fi.Size()
|
||||||
|
desc.modTime = fi.ModTime()
|
||||||
desc.loadTime = time.Now()
|
desc.loadTime = time.Now()
|
||||||
|
|
||||||
return &desc, nil
|
return &desc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue