1
Fork 0
mirror of https://github.com/jech/galene.git synced 2024-11-09 18:25:58 +01:00

Move password checking into group.go.

It used to be delegated to clients.
This commit is contained in:
Juliusz Chroboczek 2021-10-27 04:15:44 +02:00
parent 8135f6b91d
commit 869eb9b839
8 changed files with 60 additions and 97 deletions

View file

@ -59,10 +59,6 @@ func (client *Client) Username() string {
return "RECORDING" return "RECORDING"
} }
func (client *Client) Challenge(group string, cred group.ClientCredentials) bool {
return true
}
func (client *Client) SetPermissions(perms group.ClientPermissions) { func (client *Client) SetPermissions(perms group.ClientPermissions) {
return return
} }

View file

@ -56,7 +56,7 @@ func main() {
} }
e := json.NewEncoder(os.Stdout) e := json.NewEncoder(os.Stdout)
if username != "" { if username != "" {
creds := group.ClientCredentials{ creds := group.ClientPattern{
Username: username, Username: username,
Password: &p, Password: &p,
} }

View file

@ -76,7 +76,7 @@ func (p Password) MarshalJSON() ([]byte, error) {
return json.Marshal(RawPassword(p)) return json.Marshal(RawPassword(p))
} }
type ClientCredentials struct { type ClientPattern struct {
Username string `json:"username,omitempty"` Username string `json:"username,omitempty"`
Password *Password `json:"password,omitempty"` Password *Password `json:"password,omitempty"`
} }
@ -88,15 +88,16 @@ type ClientPermissions struct {
System bool `json:"system,omitempty"` System bool `json:"system,omitempty"`
} }
type Challengeable interface { type ClientCredentials struct {
Username() string System bool
Challenge(string, ClientCredentials) bool Username string
Password string
} }
type Client interface { type Client interface {
Group() *Group Group() *Group
Id() string Id() string
Challengeable Username() string
Permissions() ClientPermissions Permissions() ClientPermissions
SetPermissions(ClientPermissions) SetPermissions(ClientPermissions)
Status() map[string]interface{} Status() map[string]interface{}

View file

@ -525,7 +525,7 @@ func deleteUnlocked(g *Group) bool {
return true return true
} }
func AddClient(group string, c Client) (*Group, error) { func AddClient(group string, c Client, creds ClientCredentials) (*Group, error) {
g, err := Add(group, nil) g, err := Add(group, nil)
if err != nil { if err != nil {
return nil, err return nil, err
@ -537,7 +537,7 @@ func AddClient(group string, c Client) (*Group, error) {
clients := g.getClientsUnlocked(nil) clients := g.getClientsUnlocked(nil)
if !c.Permissions().System { if !c.Permissions().System {
perms, err := g.description.GetPermission(group, c) perms, err := g.description.GetPermission(group, creds)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -788,12 +788,16 @@ func (g *Group) GetChatHistory() []ChatHistoryEntry {
return h return h
} }
func matchClient(group string, c Challengeable, users []ClientCredentials) (bool, bool) { func matchClient(group string, creds ClientCredentials, users []ClientPattern) (bool, bool) {
matched := false matched := false
for _, u := range users { for _, u := range users {
if u.Username == c.Username() { if u.Username == creds.Username {
matched = true matched = true
if c.Challenge(group, u) { if u.Password == nil {
return true, true
}
m, _ := u.Password.Match(creds.Password)
if m {
return true, true return true, true
} }
} }
@ -804,7 +808,11 @@ func matchClient(group string, c Challengeable, users []ClientCredentials) (bool
for _, u := range users { for _, u := range users {
if u.Username == "" { if u.Username == "" {
if c.Challenge(group, u) { if u.Password == nil {
return true, true
}
m, _ := u.Password.Match(creds.Password)
if m {
return true, true return true, true
} }
} }
@ -865,13 +873,13 @@ type Description struct {
Autokick bool `json:"autokick,omitempty"` Autokick bool `json:"autokick,omitempty"`
// A list of logins for ops. // A list of logins for ops.
Op []ClientCredentials `json:"op,omitempty"` Op []ClientPattern `json:"op,omitempty"`
// A list of logins for presenters. // A list of logins for presenters.
Presenter []ClientCredentials `json:"presenter,omitempty"` Presenter []ClientPattern `json:"presenter,omitempty"`
// A list of logins for non-presenting users. // A list of logins for non-presenting users.
Other []ClientCredentials `json:"other,omitempty"` Other []ClientPattern `json:"other,omitempty"`
// Codec preferences. If empty, a suitable default is chosen in // Codec preferences. If empty, a suitable default is chosen in
// the APIFromNames function. // the APIFromNames function.
@ -970,12 +978,12 @@ func GetDescription(name string) (*Description, error) {
return &desc, nil return &desc, nil
} }
func (desc *Description) GetPermission(group string, c Challengeable) (ClientPermissions, error) { func (desc *Description) GetPermission(group string, creds ClientCredentials) (ClientPermissions, error) {
var p ClientPermissions var p ClientPermissions
if !desc.AllowAnonymous && c.Username() == "" { if !desc.AllowAnonymous && creds.Username == "" {
return p, ErrAnonymousNotAuthorised return p, ErrAnonymousNotAuthorised
} }
if found, good := matchClient(group, c, desc.Op); found { if found, good := matchClient(group, creds, desc.Op); found {
if good { if good {
p.Op = true p.Op = true
p.Present = true p.Present = true
@ -986,14 +994,14 @@ func (desc *Description) GetPermission(group string, c Challengeable) (ClientPer
} }
return p, ErrNotAuthorised return p, ErrNotAuthorised
} }
if found, good := matchClient(group, c, desc.Presenter); found { if found, good := matchClient(group, creds, desc.Presenter); found {
if good { if good {
p.Present = true p.Present = true
return p, nil return p, nil
} }
return p, ErrNotAuthorised return p, ErrNotAuthorised
} }
if found, good := matchClient(group, c, desc.Other); found { if found, good := matchClient(group, creds, desc.Other); found {
if good { if good {
return p, nil return p, nil
} }

View file

@ -136,56 +136,36 @@ func TestDescriptionJSON(t *testing.T) {
} }
} }
type testClient struct { var badClients = []ClientCredentials{
username string {Username: "jch", Password: "foo"},
password string {Username: "john", Password: "foo"},
{Username: "james", Password: "foo"},
} }
func (c testClient) Username() string { type credPerm struct {
return c.username c ClientCredentials
}
func (c testClient) Challenge(g string, creds ClientCredentials) bool {
if creds.Password == nil {
return true
}
m, err := creds.Password.Match(c.password)
if err != nil {
return false
}
return m
}
type testClientPerm struct {
c testClient
p ClientPermissions p ClientPermissions
} }
var badClients = []testClient{ var goodClients = []credPerm{
testClient{"jch", "foo"},
testClient{"john", "foo"},
testClient{"james", "foo"},
}
var goodClients = []testClientPerm{
{ {
testClient{"jch", "topsecret"}, ClientCredentials{Username: "jch", Password: "topsecret"},
ClientPermissions{Op: true, Present: true}, ClientPermissions{Op: true, Present: true},
}, },
{ {
testClient{"john", "secret"}, ClientCredentials{Username: "john", Password: "secret"},
ClientPermissions{Present: true}, ClientPermissions{Present: true},
}, },
{ {
testClient{"john", "secret2"}, ClientCredentials{Username: "john", Password: "secret2"},
ClientPermissions{Present: true}, ClientPermissions{Present: true},
}, },
{ {
testClient{"james", "secret3"}, ClientCredentials{Username: "james", Password: "secret3"},
ClientPermissions{}, ClientPermissions{},
}, },
{ {
testClient{"paul", "secret3"}, ClientCredentials{Username: "paul", Password: "secret3"},
ClientPermissions{}, ClientPermissions{},
}, },
} }
@ -198,7 +178,7 @@ func TestPermissions(t *testing.T) {
} }
for _, c := range badClients { for _, c := range badClients {
t.Run("bad "+c.Username(), func(t *testing.T) { t.Run("bad "+c.Username, func(t *testing.T) {
p, err := d.GetPermission("test", c) p, err := d.GetPermission("test", c)
if err != ErrNotAuthorised { if err != ErrNotAuthorised {
t.Errorf("GetPermission %v: %v %v", c, err, p) t.Errorf("GetPermission %v: %v %v", c, err, p)
@ -207,7 +187,7 @@ func TestPermissions(t *testing.T) {
} }
for _, cp := range goodClients { for _, cp := range goodClients {
t.Run("good "+cp.c.Username(), func(t *testing.T) { t.Run("good "+cp.c.Username, func(t *testing.T) {
p, err := d.GetPermission("test", cp.c) p, err := d.GetPermission("test", cp.c)
if err != nil { if err != nil {
t.Errorf("GetPermission %v: %v", cp.c, err) t.Errorf("GetPermission %v: %v", cp.c, err)

View file

@ -37,4 +37,3 @@ func TestDownTrackAtomics(t *testing.T) {
t.Errorf("Expected %v, got %v", info, info2) t.Errorf("Expected %v, got %v", info, info2)
} }
} }

View file

@ -56,7 +56,6 @@ type webClient struct {
group *group.Group group *group.Group
id string id string
username string username string
password string
permissions group.ClientPermissions permissions group.ClientPermissions
status map[string]interface{} status map[string]interface{}
requested map[string][]string requested map[string][]string
@ -83,18 +82,6 @@ func (c *webClient) Username() string {
return c.username return c.username
} }
func (c *webClient) Challenge(group string, creds group.ClientCredentials) bool {
if creds.Password == nil {
return true
}
m, err := creds.Password.Match(c.password)
if err != nil {
log.Printf("Password match: %v", err)
return false
}
return m
}
func (c *webClient) Permissions() group.ClientPermissions { func (c *webClient) Permissions() group.ClientPermissions {
return c.permissions return c.permissions
} }
@ -1343,8 +1330,12 @@ func handleClientMessage(c *webClient, m clientMessage) error {
return group.ProtocolError("cannot join multiple groups") return group.ProtocolError("cannot join multiple groups")
} }
c.username = m.Username c.username = m.Username
c.password = m.Password g, err := group.AddClient(m.Group, c,
g, err := group.AddClient(m.Group, c) group.ClientCredentials{
Username: m.Username,
Password: m.Password,
},
)
if err != nil { if err != nil {
var s string var s string
if os.IsNotExist(err) { if os.IsNotExist(err) {
@ -1583,7 +1574,11 @@ func handleClientMessage(c *webClient, m clientMessage) error {
} }
} }
disk := diskwriter.New(g) disk := diskwriter.New(g)
_, err := group.AddClient(g.Name(), disk) _, err := group.AddClient(g.Name(), disk,
group.ClientCredentials{
System: true,
},
)
if err != nil { if err != nil {
disk.Close() disk.Close()
return c.error(err) return c.error(err)

View file

@ -534,27 +534,6 @@ func handleGroupAction(w http.ResponseWriter, r *http.Request, group string) {
} }
} }
type httpClient struct {
username string
password string
}
func (c httpClient) Username() string {
return c.username
}
func (c httpClient) Challenge(group string, creds group.ClientCredentials) bool {
if creds.Password == nil {
return true
}
m, err := creds.Password.Match(c.password)
if err != nil {
log.Printf("Password match: %v", err)
return false
}
return m
}
func checkGroupPermissions(w http.ResponseWriter, r *http.Request, groupname string) bool { func checkGroupPermissions(w http.ResponseWriter, r *http.Request, groupname string) bool {
desc, err := group.GetDescription(groupname) desc, err := group.GetDescription(groupname)
if err != nil { if err != nil {
@ -566,7 +545,12 @@ func checkGroupPermissions(w http.ResponseWriter, r *http.Request, groupname str
return false return false
} }
p, err := desc.GetPermission(groupname, httpClient{user, pass}) p, err := desc.GetPermission(groupname,
group.ClientCredentials{
Username: user,
Password: pass,
},
)
if err != nil || !p.Record { if err != nil || !p.Record {
if err == group.ErrNotAuthorised { if err == group.ErrNotAuthorised {
time.Sleep(200 * time.Millisecond) time.Sleep(200 * time.Millisecond)