github.com/go-kivik/kivik/v4@v4.3.2/x/server/config.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 // use this file except in compliance with the License. You may obtain a copy of 3 // the License at 4 // 5 // http://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 // License for the specific language governing permissions and limitations under 11 // the License. 12 13 //go:build !js 14 15 package server 16 17 import ( 18 "encoding/json" 19 "fmt" 20 "net/http" 21 22 "github.com/go-chi/chi/v5" 23 "gitlab.com/flimzy/httpe" 24 25 internal "github.com/go-kivik/kivik/v4/int/errors" 26 "github.com/go-kivik/kivik/v4/x/server/config" 27 ) 28 29 const nodeLocal = "_local" 30 31 func (s *Server) allConfig() httpe.HandlerWithError { 32 return httpe.HandlerWithErrorFunc(func(w http.ResponseWriter, r *http.Request) error { 33 if node := chi.URLParam(r, "node-name"); node != nodeLocal { 34 return &internal.Error{Status: http.StatusNotFound, Message: fmt.Sprintf("no such node: %s", node)} 35 } 36 conf, err := s.config.All(r.Context()) 37 if err != nil { 38 return err 39 } 40 return serveJSON(w, http.StatusOK, conf) 41 }) 42 } 43 44 func (s *Server) configSection() httpe.HandlerWithError { 45 return httpe.HandlerWithErrorFunc(func(w http.ResponseWriter, r *http.Request) error { 46 if node := chi.URLParam(r, "node-name"); node != nodeLocal { 47 return &internal.Error{Status: http.StatusNotFound, Message: fmt.Sprintf("no such node: %s", node)} 48 } 49 section, err := s.config.Section(r.Context(), chi.URLParam(r, "section")) 50 if err != nil { 51 return err 52 } 53 return serveJSON(w, http.StatusOK, section) 54 }) 55 } 56 57 func (s *Server) configKey() httpe.HandlerWithError { 58 return httpe.HandlerWithErrorFunc(func(w http.ResponseWriter, r *http.Request) error { 59 if node := chi.URLParam(r, "node-name"); node != nodeLocal { 60 return &internal.Error{Status: http.StatusNotFound, Message: fmt.Sprintf("no such node: %s", node)} 61 } 62 key, err := s.config.Key(r.Context(), chi.URLParam(r, "section"), chi.URLParam(r, "key")) 63 if err != nil { 64 return err 65 } 66 return serveJSON(w, http.StatusOK, key) 67 }) 68 } 69 70 func (s *Server) reloadConfig() httpe.HandlerWithError { 71 return httpe.HandlerWithErrorFunc(func(w http.ResponseWriter, r *http.Request) error { 72 if node := chi.URLParam(r, "node-name"); node != nodeLocal { 73 return &internal.Error{Status: http.StatusNotFound, Message: fmt.Sprintf("no such node: %s", node)} 74 } 75 if err := s.config.Reload(r.Context()); err != nil { 76 return err 77 } 78 return serveJSON(w, http.StatusOK, map[string]bool{"ok": true}) 79 }) 80 } 81 82 func (s *Server) setConfigKey() httpe.HandlerWithError { 83 return httpe.HandlerWithErrorFunc(func(w http.ResponseWriter, r *http.Request) error { 84 if node := chi.URLParam(r, "node-name"); node != nodeLocal { 85 return &internal.Error{Status: http.StatusNotFound, Message: fmt.Sprintf("no such node: %s", node)} 86 } 87 confWriter, ok := s.config.(config.Writer) 88 if !ok { 89 return &internal.Error{Status: http.StatusMethodNotAllowed, Message: "configuration is read-only"} 90 } 91 var newValue string 92 if err := json.NewDecoder(r.Body).Decode(&newValue); err != nil { 93 return &internal.Error{Status: http.StatusBadRequest, Err: err} 94 } 95 oldValue, err := confWriter.SetKey(r.Context(), chi.URLParam(r, "section"), chi.URLParam(r, "key"), newValue) 96 if err != nil { 97 return err 98 } 99 return serveJSON(w, http.StatusOK, oldValue) 100 }) 101 } 102 103 func (s *Server) deleteConfigKey() httpe.HandlerWithError { 104 return httpe.HandlerWithErrorFunc(func(w http.ResponseWriter, r *http.Request) error { 105 if node := chi.URLParam(r, "node-name"); node != nodeLocal { 106 return &internal.Error{Status: http.StatusNotFound, Message: fmt.Sprintf("no such node: %s", node)} 107 } 108 confWriter, ok := s.config.(config.Writer) 109 if !ok { 110 return &internal.Error{Status: http.StatusMethodNotAllowed, Message: "configuration is read-only"} 111 } 112 oldValue, err := confWriter.Delete(r.Context(), chi.URLParam(r, "section"), chi.URLParam(r, "key")) 113 if err != nil { 114 return err 115 } 116 return serveJSON(w, http.StatusOK, oldValue) 117 }) 118 }