mirror of
https://github.com/jech/galene.git
synced 2024-11-26 10:35:59 +01:00
24187430e8
We now distinguish between status, which is maintained by the server, and data, which is provided by the client. In addition to client data, we now support group data.
109 lines
2.4 KiB
Go
109 lines
2.4 KiB
Go
package group
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"errors"
|
|
"hash"
|
|
|
|
"golang.org/x/crypto/pbkdf2"
|
|
|
|
"github.com/jech/galene/conn"
|
|
)
|
|
|
|
type RawPassword struct {
|
|
Type string `json:"type,omitempty"`
|
|
Hash string `json:"hash,omitempty"`
|
|
Key string `json:"key"`
|
|
Salt string `json:"salt,omitempty"`
|
|
Iterations int `json:"iterations,omitempty"`
|
|
}
|
|
|
|
type Password RawPassword
|
|
|
|
func (p Password) Match(pw string) (bool, error) {
|
|
switch p.Type {
|
|
case "":
|
|
return p.Key == pw, nil
|
|
case "pbkdf2":
|
|
key, err := hex.DecodeString(p.Key)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
salt, err := hex.DecodeString(p.Salt)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
var h func() hash.Hash
|
|
switch p.Hash {
|
|
case "sha-256":
|
|
h = sha256.New
|
|
default:
|
|
return false, errors.New("unknown hash type")
|
|
}
|
|
theirKey := pbkdf2.Key(
|
|
[]byte(pw), salt, p.Iterations, len(key), h,
|
|
)
|
|
return bytes.Compare(key, theirKey) == 0, nil
|
|
default:
|
|
return false, errors.New("unknown password type")
|
|
}
|
|
}
|
|
|
|
func (p *Password) UnmarshalJSON(b []byte) error {
|
|
var k string
|
|
err := json.Unmarshal(b, &k)
|
|
if err == nil {
|
|
*p = Password{
|
|
Key: k,
|
|
}
|
|
return nil
|
|
}
|
|
var r RawPassword
|
|
err = json.Unmarshal(b, &r)
|
|
if err == nil {
|
|
*p = Password(r)
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (p Password) MarshalJSON() ([]byte, error) {
|
|
if p.Type == "" && p.Hash == "" && p.Salt == "" && p.Iterations == 0 {
|
|
return json.Marshal(p.Key)
|
|
}
|
|
return json.Marshal(RawPassword(p))
|
|
}
|
|
|
|
type ClientPattern struct {
|
|
Username string `json:"username,omitempty"`
|
|
Password *Password `json:"password,omitempty"`
|
|
}
|
|
|
|
type ClientPermissions struct {
|
|
Op bool `json:"op,omitempty"`
|
|
Present bool `json:"present,omitempty"`
|
|
Record bool `json:"record,omitempty"`
|
|
System bool `json:"system,omitempty"`
|
|
}
|
|
|
|
type ClientCredentials struct {
|
|
System bool
|
|
Username string
|
|
Password string
|
|
}
|
|
|
|
type Client interface {
|
|
Group() *Group
|
|
Id() string
|
|
Username() string
|
|
Permissions() ClientPermissions
|
|
SetPermissions(ClientPermissions)
|
|
Data() map[string]interface{}
|
|
PushConn(g *Group, id string, conn conn.Up, tracks []conn.UpTrack, replace string) error
|
|
RequestConns(target Client, g *Group, id string) error
|
|
Joined(group, kind string) error
|
|
PushClient(group, kind, id, username string, permissions ClientPermissions, data map[string]interface{}) error
|
|
Kick(id, user, message string) error
|
|
}
|