mirror of
https://github.com/jech/galene.git
synced 2024-12-26 09:15:46 +01:00
Add low-level support for managing wildcard user.
This commit is contained in:
parent
f0ebf4d63c
commit
d29d14da16
3 changed files with 106 additions and 50 deletions
|
@ -602,31 +602,49 @@ func GetUsers(group string) ([]string, string, error) {
|
|||
return users, makeETag(desc.fileSize, desc.modTime), nil
|
||||
}
|
||||
|
||||
func GetSanitisedUser(group, username string) (UserDescription, string, error) {
|
||||
func GetSanitisedUser(group, username string, wildcard bool) (UserDescription, string, error) {
|
||||
if wildcard && username != "" {
|
||||
return UserDescription{}, "",
|
||||
errors.New("wildcard with username")
|
||||
}
|
||||
|
||||
desc, err := GetDescription(group)
|
||||
if err != nil {
|
||||
return UserDescription{}, "", err
|
||||
}
|
||||
|
||||
if desc.Users == nil {
|
||||
return UserDescription{}, "", os.ErrNotExist
|
||||
}
|
||||
var u UserDescription
|
||||
if wildcard {
|
||||
if desc.WildcardUser == nil {
|
||||
return UserDescription{}, "", os.ErrNotExist
|
||||
}
|
||||
u = *desc.WildcardUser
|
||||
} else {
|
||||
if desc.Users == nil {
|
||||
return UserDescription{}, "", os.ErrNotExist
|
||||
}
|
||||
|
||||
u, ok := desc.Users[username]
|
||||
if !ok {
|
||||
return UserDescription{}, "", os.ErrNotExist
|
||||
ok := false
|
||||
u, ok = desc.Users[username]
|
||||
if !ok {
|
||||
return UserDescription{}, "", os.ErrNotExist
|
||||
}
|
||||
}
|
||||
|
||||
u.Password = Password{}
|
||||
return u, makeETag(desc.fileSize, desc.modTime), nil
|
||||
}
|
||||
|
||||
func GetUserTag(group, username string) (string, error) {
|
||||
_, etag, err := GetSanitisedUser(group, username)
|
||||
func GetUserTag(group, username string, wildcard bool) (string, error) {
|
||||
_, etag, err := GetSanitisedUser(group, username, wildcard)
|
||||
return etag, err
|
||||
}
|
||||
|
||||
func DeleteUser(group, username, etag string) error {
|
||||
func DeleteUser(group, username string, wildcard bool, etag string) error {
|
||||
if wildcard && username != "" {
|
||||
return errors.New("wildcard with username")
|
||||
}
|
||||
|
||||
groups.mu.Lock()
|
||||
defer groups.mu.Unlock()
|
||||
|
||||
|
@ -634,13 +652,19 @@ func DeleteUser(group, username, etag string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if desc.Users == nil {
|
||||
return os.ErrNotExist
|
||||
}
|
||||
|
||||
_, ok := desc.Users[username]
|
||||
if !ok {
|
||||
return os.ErrNotExist
|
||||
if wildcard {
|
||||
if desc.WildcardUser == nil {
|
||||
return os.ErrNotExist
|
||||
}
|
||||
} else {
|
||||
if desc.Users == nil {
|
||||
return os.ErrNotExist
|
||||
}
|
||||
_, ok := desc.Users[username]
|
||||
if !ok {
|
||||
return os.ErrNotExist
|
||||
}
|
||||
}
|
||||
|
||||
oldetag := makeETag(desc.fileSize, desc.modTime)
|
||||
|
@ -648,14 +672,23 @@ func DeleteUser(group, username, etag string) error {
|
|||
return ErrTagMismatch
|
||||
}
|
||||
|
||||
delete(desc.Users, username)
|
||||
if wildcard {
|
||||
desc.WildcardUser = nil
|
||||
} else {
|
||||
delete(desc.Users, username)
|
||||
}
|
||||
|
||||
return rewriteDescriptionFile(desc.FileName, desc)
|
||||
}
|
||||
|
||||
func UpdateUser(group, username, etag string, user *UserDescription) error {
|
||||
func UpdateUser(group, username string, wildcard bool, etag string, user *UserDescription) error {
|
||||
if wildcard && username != "" {
|
||||
return errors.New("wildcard with username")
|
||||
}
|
||||
if user.Password.Type != "" || user.Password.Key != nil {
|
||||
return errors.New("user description is not sanitised")
|
||||
}
|
||||
|
||||
groups.mu.Lock()
|
||||
defer groups.mu.Unlock()
|
||||
|
||||
|
@ -663,11 +696,21 @@ func UpdateUser(group, username, etag string, user *UserDescription) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if desc.Users == nil {
|
||||
desc.Users = make(map[string]UserDescription)
|
||||
|
||||
var old UserDescription
|
||||
var ok bool
|
||||
if wildcard {
|
||||
if desc.WildcardUser != nil {
|
||||
ok = true
|
||||
old = *desc.WildcardUser
|
||||
}
|
||||
} else {
|
||||
if desc.Users == nil {
|
||||
desc.Users = make(map[string]UserDescription)
|
||||
}
|
||||
old, ok = desc.Users[username]
|
||||
}
|
||||
|
||||
old, ok := desc.Users[username]
|
||||
var oldetag string
|
||||
if ok {
|
||||
oldetag = makeETag(desc.fileSize, desc.modTime)
|
||||
|
@ -681,11 +724,20 @@ func UpdateUser(group, username, etag string, user *UserDescription) error {
|
|||
|
||||
newuser := *user
|
||||
newuser.Password = old.Password
|
||||
desc.Users[username] = newuser
|
||||
|
||||
if wildcard {
|
||||
desc.WildcardUser = &newuser
|
||||
} else {
|
||||
desc.Users[username] = newuser
|
||||
}
|
||||
return rewriteDescriptionFile(desc.FileName, desc)
|
||||
}
|
||||
|
||||
func SetUserPassword(group, username string, pw Password) error {
|
||||
func SetUserPassword(group, username string, wildcard bool, pw Password) error {
|
||||
if wildcard && username != "" {
|
||||
return errors.New("wildcard with username")
|
||||
}
|
||||
|
||||
groups.mu.Lock()
|
||||
defer groups.mu.Unlock()
|
||||
|
||||
|
@ -697,12 +749,19 @@ func SetUserPassword(group, username string, pw Password) error {
|
|||
return os.ErrNotExist
|
||||
}
|
||||
|
||||
user, ok := desc.Users[username]
|
||||
if !ok {
|
||||
return os.ErrNotExist
|
||||
}
|
||||
if wildcard {
|
||||
if desc.WildcardUser == nil {
|
||||
return os.ErrNotExist
|
||||
}
|
||||
desc.WildcardUser.Password = pw
|
||||
} else {
|
||||
user, ok := desc.Users[username]
|
||||
if !ok {
|
||||
return os.ErrNotExist
|
||||
}
|
||||
|
||||
user.Password = pw
|
||||
desc.Users[username] = user
|
||||
user.Password = pw
|
||||
desc.Users[username] = user
|
||||
}
|
||||
return rewriteDescriptionFile(desc.FileName, desc)
|
||||
}
|
||||
|
|
|
@ -255,27 +255,31 @@ func TestWritableGroups(t *testing.T) {
|
|||
nil, "Test", err, desc.AllowAnonymous,
|
||||
)
|
||||
}
|
||||
testUser(t, "jch", false)
|
||||
testUser(t, "", true)
|
||||
}
|
||||
|
||||
_, _, err = GetSanitisedUser("test", "jch")
|
||||
func testUser(t *testing.T, username string, wildcard bool) {
|
||||
_, _, err := GetSanitisedUser("test", username, wildcard)
|
||||
if !errors.Is(err, os.ErrNotExist) {
|
||||
t.Errorf("GetSanitisedUser: got %v, expected ErrNotExist", err)
|
||||
}
|
||||
|
||||
err = UpdateUser("test", "jch", "", &UserDescription{
|
||||
err = UpdateUser("test", username, wildcard, "", &UserDescription{
|
||||
Permissions: Permissions{name: "observe"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("UpdateUser: got %v", err)
|
||||
}
|
||||
|
||||
user, token, err := GetSanitisedUser("test", "jch")
|
||||
user, token, err := GetSanitisedUser("test", username, wildcard)
|
||||
if err != nil || token == "" || user.Permissions.name != "observe" {
|
||||
t.Errorf("GetDescription: got %v %v, expected %v %v",
|
||||
err, user.Permissions.name, nil, "observe",
|
||||
)
|
||||
}
|
||||
|
||||
err = UpdateUser("test", "jch", "", &UserDescription{
|
||||
err = UpdateUser("test", username, wildcard, "", &UserDescription{
|
||||
Permissions: Permissions{name: "present"},
|
||||
})
|
||||
if !errors.Is(err, ErrTagMismatch) {
|
||||
|
@ -283,7 +287,7 @@ func TestWritableGroups(t *testing.T) {
|
|||
err)
|
||||
}
|
||||
|
||||
err = UpdateUser("test", "jch", token, &UserDescription{
|
||||
err = UpdateUser("test", username, wildcard, token, &UserDescription{
|
||||
Permissions: Permissions{name: "present"},
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -291,20 +295,13 @@ func TestWritableGroups(t *testing.T) {
|
|||
}
|
||||
|
||||
pw := "pw"
|
||||
err = SetUserPassword("test", "jch", Password{
|
||||
err = SetUserPassword("test", username, wildcard, Password{
|
||||
Type: "plain",
|
||||
Key: &pw,
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("SetUserPassword: got %v", err)
|
||||
}
|
||||
|
||||
desc, err = GetDescription("test")
|
||||
if err != nil || *desc.Users["jch"].Password.Key != "pw" {
|
||||
t.Errorf("GetDescription: got %v %v, expected %v %v",
|
||||
err, desc.Users["jch"].Password.Key, nil, "pw",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubGroup(t *testing.T) {
|
||||
|
|
|
@ -297,7 +297,7 @@ func userHandler(w http.ResponseWriter, r *http.Request, g, user string) {
|
|||
}
|
||||
|
||||
if r.Method == "HEAD" || r.Method == "GET" {
|
||||
user, etag, err := group.GetSanitisedUser(g, user)
|
||||
user, etag, err := group.GetSanitisedUser(g, user, false)
|
||||
if err != nil {
|
||||
httpError(w, err)
|
||||
return
|
||||
|
@ -310,7 +310,7 @@ func userHandler(w http.ResponseWriter, r *http.Request, g, user string) {
|
|||
sendJSON(w, r, user)
|
||||
return
|
||||
} else if r.Method == "PUT" {
|
||||
etag, err := group.GetUserTag(g, user)
|
||||
etag, err := group.GetUserTag(g, user, false)
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
etag = ""
|
||||
err = nil
|
||||
|
@ -329,7 +329,7 @@ func userHandler(w http.ResponseWriter, r *http.Request, g, user string) {
|
|||
if done {
|
||||
return
|
||||
}
|
||||
err = group.UpdateUser(g, user, etag, &newdesc)
|
||||
err = group.UpdateUser(g, user, false, etag, &newdesc)
|
||||
if err != nil {
|
||||
httpError(w, err)
|
||||
return
|
||||
|
@ -341,7 +341,7 @@ func userHandler(w http.ResponseWriter, r *http.Request, g, user string) {
|
|||
}
|
||||
return
|
||||
} else if r.Method == "DELETE" {
|
||||
etag, err := group.GetUserTag(g, user)
|
||||
etag, err := group.GetUserTag(g, user, false)
|
||||
if err != nil {
|
||||
httpError(w, err)
|
||||
return
|
||||
|
@ -352,7 +352,7 @@ func userHandler(w http.ResponseWriter, r *http.Request, g, user string) {
|
|||
return
|
||||
}
|
||||
|
||||
err = group.DeleteUser(g, user, etag)
|
||||
err = group.DeleteUser(g, user, false, etag)
|
||||
if err != nil {
|
||||
httpError(w, err)
|
||||
return
|
||||
|
@ -375,7 +375,7 @@ func passwordHandler(w http.ResponseWriter, r *http.Request, g, user string) {
|
|||
if done {
|
||||
return
|
||||
}
|
||||
err := group.SetUserPassword(g, user, pw)
|
||||
err := group.SetUserPassword(g, user, false, pw)
|
||||
if err != nil {
|
||||
httpError(w, err)
|
||||
return
|
||||
|
@ -403,7 +403,7 @@ func passwordHandler(w http.ResponseWriter, r *http.Request, g, user string) {
|
|||
Salt: hex.EncodeToString(salt),
|
||||
Iterations: iterations,
|
||||
}
|
||||
err = group.SetUserPassword(g, user, pw)
|
||||
err = group.SetUserPassword(g, user, false, pw)
|
||||
if err != nil {
|
||||
httpError(w, err)
|
||||
return
|
||||
|
@ -411,7 +411,7 @@ func passwordHandler(w http.ResponseWriter, r *http.Request, g, user string) {
|
|||
w.WriteHeader(http.StatusNoContent)
|
||||
return
|
||||
} else if r.Method == "DELETE" {
|
||||
err := group.SetUserPassword(g, user, group.Password{})
|
||||
err := group.SetUserPassword(g, user, false, group.Password{})
|
||||
if err != nil {
|
||||
httpError(w, err)
|
||||
return
|
||||
|
|
Loading…
Reference in a new issue