mirror of
https://github.com/jech/galene.git
synced 2024-11-22 08:35:57 +01:00
Implement FallbackUsers in API.
This commit is contained in:
parent
31a18bcf44
commit
7673a95b05
4 changed files with 80 additions and 0 deletions
|
@ -55,6 +55,14 @@ on-disk format but without any user definitions or cryptographic keys.
|
||||||
Allowed methods are HEAD, GET, PUT and DELETE. The only accepted
|
Allowed methods are HEAD, GET, PUT and DELETE. The only accepted
|
||||||
content-type is `application/json`.
|
content-type is `application/json`.
|
||||||
|
|
||||||
|
### Fallback users
|
||||||
|
|
||||||
|
/galene-api/0/.groups/groupname/.fallback-users
|
||||||
|
|
||||||
|
Contains fallback user descriptions, in the same format as the
|
||||||
|
`fallbackUsers` field of the on-disk format. Allowed methods are PUT and
|
||||||
|
DELETE. The only accepted content-type is `application/json`.
|
||||||
|
|
||||||
### Authentication keys
|
### Authentication keys
|
||||||
|
|
||||||
/galene-api/0/.groups/groupname/.keys
|
/galene-api/0/.groups/groupname/.keys
|
||||||
|
|
|
@ -540,6 +540,18 @@ func GetDescriptionNames() ([]string, error) {
|
||||||
return names, err
|
return names, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetFallbackUsers(group string, users []UserDescription) error {
|
||||||
|
groups.mu.Lock()
|
||||||
|
defer groups.mu.Unlock()
|
||||||
|
|
||||||
|
desc, err := readDescription(group, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
desc.FallbackUsers = users
|
||||||
|
return rewriteDescriptionFile(desc.FileName, desc)
|
||||||
|
}
|
||||||
|
|
||||||
func SetKeys(group string, keys []map[string]any) error {
|
func SetKeys(group string, keys []map[string]any) error {
|
||||||
groups.mu.Lock()
|
groups.mu.Lock()
|
||||||
defer groups.mu.Unlock()
|
defer groups.mu.Unlock()
|
||||||
|
|
|
@ -128,6 +128,9 @@ func apiGroupHandler(w http.ResponseWriter, r *http.Request, pth string) {
|
||||||
if kind == ".users" {
|
if kind == ".users" {
|
||||||
apiUserHandler(w, r, g, rest)
|
apiUserHandler(w, r, g, rest)
|
||||||
return
|
return
|
||||||
|
} else if kind == ".fallback-users" && rest == "" {
|
||||||
|
fallbackUsersHandler(w, r, g)
|
||||||
|
return
|
||||||
} else if kind == ".keys" && rest == "" {
|
} else if kind == ".keys" && rest == "" {
|
||||||
keysHandler(w, r, g)
|
keysHandler(w, r, g)
|
||||||
return
|
return
|
||||||
|
@ -433,6 +436,46 @@ func passwordHandler(w http.ResponseWriter, r *http.Request, g, user string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fallbackUsersHandler(w http.ResponseWriter, r *http.Request, g string) {
|
||||||
|
if !checkAdmin(w, r) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.Method == "PUT" {
|
||||||
|
ctype := parseContentType(r.Header.Get("Content-Type"))
|
||||||
|
if !strings.EqualFold(ctype, "application/json") {
|
||||||
|
http.Error(w, "unsupported content type",
|
||||||
|
http.StatusUnsupportedMediaType)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
d := json.NewDecoder(r.Body)
|
||||||
|
var users []group.UserDescription
|
||||||
|
err := d.Decode(&users)
|
||||||
|
if err != nil {
|
||||||
|
httpError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = group.SetFallbackUsers(g, users)
|
||||||
|
if err != nil {
|
||||||
|
httpError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
return
|
||||||
|
} else if r.Method == "DELETE" {
|
||||||
|
err := group.SetFallbackUsers(g, nil)
|
||||||
|
if err != nil {
|
||||||
|
httpError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
methodNotAllowed(w, "PUT", "DELETE")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
type jwkset = struct {
|
type jwkset = struct {
|
||||||
Keys []map[string]any `json:"keys"`
|
Keys []map[string]any `json:"keys"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,6 +168,13 @@ func TestApi(t *testing.T) {
|
||||||
t.Errorf("Get groups: %v %#v", err, s)
|
t.Errorf("Get groups: %v %#v", err, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resp, err = do("PUT", "/galene-api/0/.groups/test/.fallback-users",
|
||||||
|
"application/json", "", "",
|
||||||
|
`[{"password": "topsecret"}]`)
|
||||||
|
if err != nil || resp.StatusCode != http.StatusNoContent {
|
||||||
|
t.Errorf("Set fallback users: %v %v", err, resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
resp, err = do("PUT", "/galene-api/0/.groups/test/.keys",
|
resp, err = do("PUT", "/galene-api/0/.groups/test/.keys",
|
||||||
"application/jwk-set+json", "", "",
|
"application/jwk-set+json", "", "",
|
||||||
`{"keys": [{
|
`{"keys": [{
|
||||||
|
@ -261,10 +268,20 @@ func TestApi(t *testing.T) {
|
||||||
t.Errorf("Users (after delete): %#v", desc.Users)
|
t.Errorf("Users (after delete): %#v", desc.Users)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(desc.FallbackUsers) != 1 {
|
||||||
|
t.Errorf("Keys: %v", len(desc.AuthKeys))
|
||||||
|
}
|
||||||
|
|
||||||
if len(desc.AuthKeys) != 1 {
|
if len(desc.AuthKeys) != 1 {
|
||||||
t.Errorf("Keys: %v", len(desc.AuthKeys))
|
t.Errorf("Keys: %v", len(desc.AuthKeys))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resp, err = do("DELETE", "/galene-api/0/.groups/test/.fallback-users",
|
||||||
|
"", "", "", "")
|
||||||
|
if err != nil || resp.StatusCode != http.StatusNoContent {
|
||||||
|
t.Errorf("Delete fallback users: %v %v", err, resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
resp, err = do("DELETE", "/galene-api/0/.groups/test/.keys",
|
resp, err = do("DELETE", "/galene-api/0/.groups/test/.keys",
|
||||||
"", "", "", "")
|
"", "", "", "")
|
||||||
if err != nil || resp.StatusCode != http.StatusNoContent {
|
if err != nil || resp.StatusCode != http.StatusNoContent {
|
||||||
|
|
Loading…
Reference in a new issue