Started reworking skaldctl. Give room status along with room name.
This commit is contained in:
+45
-2
@@ -18,6 +18,13 @@ import (
|
||||
var ErrTagMismatch = errors.New("tag mismatch")
|
||||
var ErrDescriptionsNotWritable = &NotAuthorisedError{}
|
||||
var ErrUnknownPermission = errors.New("unknown permission")
|
||||
var localAdministration bool
|
||||
|
||||
// SetLocalAdministration allows a local administration tool to update hall
|
||||
// files without enabling writes through the server's HTTP API.
|
||||
func SetLocalAdministration(enabled bool) {
|
||||
localAdministration = enabled
|
||||
}
|
||||
|
||||
type Permissions struct {
|
||||
// non-empty for a named permissions set
|
||||
@@ -338,6 +345,9 @@ func makeETag(fileSize int64, modTime time.Time) string {
|
||||
// DeleteDescription deletes a description (and therefore persistently
|
||||
// deletes a hall) but only if it matches a given ETag.
|
||||
func DeleteDescription(name, etag string) error {
|
||||
if !validHallName(name) {
|
||||
return UserError("illegal hall name")
|
||||
}
|
||||
halls.mu.Lock()
|
||||
defer halls.mu.Unlock()
|
||||
|
||||
@@ -357,7 +367,22 @@ func UpdateDescription(name, etag string, desc *Description) error {
|
||||
if desc.Users != nil || desc.WildcardUser != nil || desc.AuthKeys != nil {
|
||||
return errors.New("description is not sanitised")
|
||||
}
|
||||
return updateDescription(name, etag, desc, true)
|
||||
}
|
||||
|
||||
// WriteDescription writes a full hall description from a local administration
|
||||
// tool. It is not available to the server's HTTP API.
|
||||
func WriteDescription(name, etag string, desc *Description) error {
|
||||
if !localAdministration {
|
||||
return ErrDescriptionsNotWritable
|
||||
}
|
||||
return updateDescription(name, etag, desc, false)
|
||||
}
|
||||
|
||||
func updateDescription(name, etag string, desc *Description, preserveSecrets bool) error {
|
||||
if !validHallName(name) {
|
||||
return UserError("illegal hall name")
|
||||
}
|
||||
halls.mu.Lock()
|
||||
defer halls.mu.Unlock()
|
||||
|
||||
@@ -381,7 +406,7 @@ func UpdateDescription(name, etag string, desc *Description) error {
|
||||
}
|
||||
|
||||
newdesc := *desc
|
||||
if old != nil {
|
||||
if old != nil && preserveSecrets {
|
||||
newdesc.Users = old.Users
|
||||
newdesc.WildcardUser = old.WildcardUser
|
||||
newdesc.AuthKeys = old.AuthKeys
|
||||
@@ -395,7 +420,7 @@ func rewriteDescriptionFile(filename string, desc *Description) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !conf.WritableHalls {
|
||||
if !conf.WritableHalls && !localAdministration {
|
||||
return ErrDescriptionsNotWritable
|
||||
}
|
||||
|
||||
@@ -657,9 +682,15 @@ func GetUserTag(hall, username string, wildcard bool) (string, error) {
|
||||
}
|
||||
|
||||
func DeleteUser(hall, username string, wildcard bool, etag string) error {
|
||||
if !validHallName(hall) {
|
||||
return UserError("illegal hall name")
|
||||
}
|
||||
if wildcard && username != "" {
|
||||
return errors.New("wildcard with username")
|
||||
}
|
||||
if !wildcard && !validUsername(username) {
|
||||
return UserError("illegal username")
|
||||
}
|
||||
|
||||
halls.mu.Lock()
|
||||
defer halls.mu.Unlock()
|
||||
@@ -698,9 +729,15 @@ func DeleteUser(hall, username string, wildcard bool, etag string) error {
|
||||
}
|
||||
|
||||
func UpdateUser(hall, username string, wildcard bool, etag string, user *UserDescription) error {
|
||||
if !validHallName(hall) {
|
||||
return UserError("illegal hall name")
|
||||
}
|
||||
if wildcard && username != "" {
|
||||
return errors.New("wildcard with username")
|
||||
}
|
||||
if !wildcard && !validUsername(username) {
|
||||
return UserError("illegal username")
|
||||
}
|
||||
if user.Password.Type != "" || user.Password.Key != nil {
|
||||
return errors.New("user description is not sanitised")
|
||||
}
|
||||
@@ -750,9 +787,15 @@ func UpdateUser(hall, username string, wildcard bool, etag string, user *UserDes
|
||||
}
|
||||
|
||||
func SetUserPassword(hall, username string, wildcard bool, pw Password) error {
|
||||
if !validHallName(hall) {
|
||||
return UserError("illegal hall name")
|
||||
}
|
||||
if wildcard && username != "" {
|
||||
return errors.New("wildcard with username")
|
||||
}
|
||||
if !wildcard && !validUsername(username) {
|
||||
return UserError("illegal username")
|
||||
}
|
||||
|
||||
halls.mu.Lock()
|
||||
defer halls.mu.Unlock()
|
||||
|
||||
@@ -263,6 +263,44 @@ func TestWritableHalls(t *testing.T) {
|
||||
testUser(t, "", true)
|
||||
}
|
||||
|
||||
func TestLocalAdministrationWritesFullDescription(t *testing.T) {
|
||||
err := setupTest(t.TempDir(), t.TempDir(), false)
|
||||
if err != nil {
|
||||
t.Fatalf("setupTest: %v", err)
|
||||
}
|
||||
SetLocalAdministration(true)
|
||||
defer SetLocalAdministration(false)
|
||||
|
||||
permissions, err := NewPermissions("op")
|
||||
if err != nil {
|
||||
t.Fatalf("NewPermissions: %v", err)
|
||||
}
|
||||
pw := "secret"
|
||||
err = WriteDescription("test", "", &Description{
|
||||
Autolock: true,
|
||||
Users: map[string]UserDescription{
|
||||
"Username": {
|
||||
Password: Password{
|
||||
Type: "plain",
|
||||
Key: &pw,
|
||||
},
|
||||
Permissions: permissions,
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("WriteDescription: %v", err)
|
||||
}
|
||||
|
||||
desc, err := GetDescription("test")
|
||||
if err != nil {
|
||||
t.Fatalf("GetDescription: %v", err)
|
||||
}
|
||||
if !desc.Autolock || desc.Users["Username"].Permissions.String() != "op" {
|
||||
t.Fatalf("description = %#v", desc)
|
||||
}
|
||||
}
|
||||
|
||||
func testUser(t *testing.T, username string, wildcard bool) {
|
||||
_, _, err := GetSanitisedUser("test", username, wildcard)
|
||||
if !errors.Is(err, os.ErrNotExist) {
|
||||
|
||||
@@ -405,6 +405,11 @@ func validHallName(name string) bool {
|
||||
return s == "/"+name
|
||||
}
|
||||
|
||||
// ValidHallName reports whether name is safe to use as a hall name.
|
||||
func ValidHallName(name string) bool {
|
||||
return validHallName(name)
|
||||
}
|
||||
|
||||
func add(name string, desc *Description) (*Hall, []Client, error) {
|
||||
if !validHallName(name) {
|
||||
return nil, nil, UserError("illegal hall name")
|
||||
@@ -1034,6 +1039,11 @@ func validUsername(username string) bool {
|
||||
return username != "" && validHallName(username)
|
||||
}
|
||||
|
||||
// ValidUsername reports whether username is safe to use as a login name.
|
||||
func ValidUsername(username string) bool {
|
||||
return validUsername(username)
|
||||
}
|
||||
|
||||
// called locked
|
||||
func (g *Hall) getPermission(creds ClientCredentials) (string, []string, error) {
|
||||
desc := g.description
|
||||
@@ -1097,6 +1107,7 @@ type Status struct {
|
||||
AuthServer string `json:"authServer,omitempty"`
|
||||
AuthPortal string `json:"authPortal,omitempty"`
|
||||
Locked bool `json:"locked,omitempty"`
|
||||
Recording bool `json:"recording,omitempty"`
|
||||
ClientCount *int `json:"clientCount,omitempty"`
|
||||
CanChangePassword bool `json:"canChangePassword,omitempty"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user