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

Minor refactoring in api.go.

This commit is contained in:
Juliusz Chroboczek 2024-05-03 20:11:36 +02:00
parent a12331ee09
commit f5279022ce

View file

@ -63,6 +63,50 @@ func checkPasswordAdmin(w http.ResponseWriter, r *http.Request, groupname, user
return false return false
} }
func sendJSON(w http.ResponseWriter, r *http.Request, v any) {
w.Header().Set("content-type", "application/json")
if r.Method == "HEAD" {
return
}
e := json.NewEncoder(w)
e.Encode(v)
}
func getText(w http.ResponseWriter, r *http.Request) ([]byte, bool) {
ctype := parseContentType(r.Header.Get("Content-Type"))
if !strings.EqualFold(ctype, "text/plain") {
http.Error(w, "unsupported content type",
http.StatusUnsupportedMediaType)
return nil, true
}
body, err := io.ReadAll(http.MaxBytesReader(w, r.Body, 4096))
if err != nil {
httpError(w, err)
return nil, true
}
return body, false
}
func getJSON(w http.ResponseWriter, r *http.Request, v any) bool {
ctype := parseContentType(r.Header.Get("Content-Type"))
if !strings.EqualFold(ctype, "application/json") {
http.Error(w, "unsupported content type",
http.StatusUnsupportedMediaType)
return true
}
d := json.NewDecoder(r.Body)
err := d.Decode(v)
if err != nil {
httpError(w, err)
return true
}
return false
}
func apiHandler(w http.ResponseWriter, r *http.Request) { func apiHandler(w http.ResponseWriter, r *http.Request) {
if !strings.HasPrefix(r.URL.Path, "/galene-api/") { if !strings.HasPrefix(r.URL.Path, "/galene-api/") {
http.NotFound(w, r) http.NotFound(w, r)
@ -78,15 +122,8 @@ func apiHandler(w http.ResponseWriter, r *http.Request) {
methodNotAllowed(w, "HEAD", "GET") methodNotAllowed(w, "HEAD", "GET")
return return
} }
w.Header().Set("content-type", "application/json")
w.Header().Set("cache-control", "no-cache") w.Header().Set("cache-control", "no-cache")
if r.Method == "HEAD" { sendJSON(w, r, stats.GetGroups())
return
}
ss := stats.GetGroups()
e := json.NewEncoder(w)
e.Encode(ss)
return return
} else if first == "/v0" && kind == ".groups" { } else if first == "/v0" && kind == ".groups" {
apiGroupHandler(w, r, rest) apiGroupHandler(w, r, rest)
@ -117,12 +154,7 @@ func apiGroupHandler(w http.ResponseWriter, r *http.Request, pth string) {
httpError(w, err) httpError(w, err)
return return
} }
w.Header().Set("content-type", "application/json") sendJSON(w, r, groups)
if r.Method == "HEAD" {
return
}
e := json.NewEncoder(w)
e.Encode(groups)
return return
} }
@ -164,13 +196,7 @@ func apiGroupHandler(w http.ResponseWriter, r *http.Request, pth string) {
return return
} }
w.Header().Set("content-type", "application/json") sendJSON(w, r, desc)
if r.Method == "HEAD" {
return
}
e := json.NewEncoder(w)
e.Encode(desc)
return return
} else if r.Method == "PUT" { } else if r.Method == "PUT" {
etag, err := group.GetDescriptionTag(g) etag, err := group.GetDescriptionTag(g)
@ -187,19 +213,9 @@ func apiGroupHandler(w http.ResponseWriter, r *http.Request, pth string) {
return return
} }
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 newdesc group.Description var newdesc group.Description
err = d.Decode(&newdesc) done = getJSON(w, r, &newdesc)
if err != nil { if done {
httpError(w, err)
return return
} }
err = group.UpdateDescription(g, etag, &newdesc) err = group.UpdateDescription(g, etag, &newdesc)
@ -255,17 +271,12 @@ func usersHandler(w http.ResponseWriter, r *http.Request, g, pth string) {
httpError(w, err) httpError(w, err)
return return
} }
w.Header().Set("content-type", "application/json")
w.Header().Set("etag", etag) w.Header().Set("etag", etag)
done := checkPreconditions(w, r, etag) done := checkPreconditions(w, r, etag)
if done { if done {
return return
} }
if r.Method == "HEAD" { sendJSON(w, r, users)
return
}
e := json.NewEncoder(w)
e.Encode(users)
return return
} }
@ -292,17 +303,12 @@ func usersHandler(w http.ResponseWriter, r *http.Request, g, pth string) {
httpError(w, err) httpError(w, err)
return return
} }
w.Header().Set("content-type", "application/json")
w.Header().Set("etag", etag) w.Header().Set("etag", etag)
done := checkPreconditions(w, r, etag) done := checkPreconditions(w, r, etag)
if done { if done {
return return
} }
if r.Method == "HEAD" { sendJSON(w, r, user)
return
}
e := json.NewEncoder(w)
e.Encode(user)
return return
} else if r.Method == "PUT" { } else if r.Method == "PUT" {
etag, err := group.GetUserTag(g, username) etag, err := group.GetUserTag(g, username)
@ -319,17 +325,9 @@ func usersHandler(w http.ResponseWriter, r *http.Request, g, pth string) {
return return
} }
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 newdesc group.UserDescription var newdesc group.UserDescription
err = d.Decode(&newdesc) done = getJSON(w, r, &newdesc)
if err != nil { if done {
httpError(w, err)
return return
} }
err = group.UpdateUser(g, username, etag, &newdesc) err = group.UpdateUser(g, username, etag, &newdesc)
@ -373,20 +371,12 @@ func passwordHandler(w http.ResponseWriter, r *http.Request, g, user string) {
} }
if r.Method == "PUT" { 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 pw group.Password var pw group.Password
err := d.Decode(&pw) done := getJSON(w, r, &pw)
if err != nil { if done {
httpError(w, err)
return return
} }
err = group.SetUserPassword(g, user, pw) err := group.SetUserPassword(g, user, pw)
if err != nil { if err != nil {
httpError(w, err) httpError(w, err)
return return
@ -394,20 +384,12 @@ func passwordHandler(w http.ResponseWriter, r *http.Request, g, user string) {
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)
return return
} else if r.Method == "POST" { } else if r.Method == "POST" {
ctype := parseContentType(r.Header.Get("Content-Type")) body, done := getText(w, r)
if !strings.EqualFold(ctype, "text/plain") { if done {
http.Error(w, "unsupported content type",
http.StatusUnsupportedMediaType)
return
}
body, err := io.ReadAll(http.MaxBytesReader(w, r.Body, 4096))
if err != nil {
httpError(w, err)
return return
} }
salt := make([]byte, 8) salt := make([]byte, 8)
_, err = rand.Read(salt) _, err := rand.Read(salt)
if err != nil { if err != nil {
httpError(w, err) httpError(w, err)
return return
@ -449,20 +431,12 @@ func fallbackUsersHandler(w http.ResponseWriter, r *http.Request, g string) {
} }
if r.Method == "PUT" { 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 var users []group.UserDescription
err := d.Decode(&users) done := getJSON(w, r, &users)
if err != nil { if done {
httpError(w, err)
return return
} }
err = group.SetFallbackUsers(g, users) err := group.SetFallbackUsers(g, users)
if err != nil { if err != nil {
httpError(w, err) httpError(w, err)
return return
@ -493,6 +467,7 @@ func keysHandler(w http.ResponseWriter, r *http.Request, g string) {
} }
if r.Method == "PUT" { if r.Method == "PUT" {
// cannot use getJSON due to the weird content-type
ctype := parseContentType(r.Header.Get("Content-Type")) ctype := parseContentType(r.Header.Get("Content-Type"))
if !strings.EqualFold(ctype, "application/jwk-set+json") { if !strings.EqualFold(ctype, "application/jwk-set+json") {
http.Error(w, "unsupported content type", http.Error(w, "unsupported content type",
@ -546,28 +521,16 @@ func tokensHandler(w http.ResponseWriter, r *http.Request, g, pth string) {
if etag != "" { if etag != "" {
w.Header().Set("etag", etag) w.Header().Set("etag", etag)
} }
if r.Method == "HEAD" {
return
}
toknames := make([]string, len(tokens)) toknames := make([]string, len(tokens))
for i, t := range tokens { for i, t := range tokens {
toknames[i] = t.Token toknames[i] = t.Token
} }
e := json.NewEncoder(w) sendJSON(w, r, toknames)
e.Encode(toknames)
return return
} else if r.Method == "POST" { } else if r.Method == "POST" {
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 newtoken token.Stateful var newtoken token.Stateful
err := d.Decode(&newtoken) done := getJSON(w, r, &newtoken)
if err != nil { if done {
httpError(w, err)
return return
} }
if newtoken.Token != "" || newtoken.Group != "" { if newtoken.Token != "" || newtoken.Group != "" {
@ -608,17 +571,12 @@ func tokensHandler(w http.ResponseWriter, r *http.Request, g, pth string) {
http.NotFound(w, r) http.NotFound(w, r)
return return
} }
w.Header().Set("content-type", "application/json")
w.Header().Set("etag", etag) w.Header().Set("etag", etag)
done := checkPreconditions(w, r, etag) done := checkPreconditions(w, r, etag)
if done { if done {
return return
} }
if r.Method == "HEAD" { sendJSON(w, r, t)
return
}
e := json.NewEncoder(w)
e.Encode(t)
return return
} else if r.Method == "PUT" { } else if r.Method == "PUT" {
old, etag, err := token.Get(t) old, etag, err := token.Get(t)
@ -640,17 +598,9 @@ func tokensHandler(w http.ResponseWriter, r *http.Request, g, pth string) {
return return
} }
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 newtoken token.Stateful var newtoken token.Stateful
err = d.Decode(&newtoken) done = getJSON(w, r, &newtoken)
if err != nil { if done {
httpError(w, err)
return return
} }
if newtoken.Group != g { if newtoken.Group != g {