2 * Copyright 2018 Intel Corporation, Inc
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 "github.com/gorilla/mux"
24 smsbackend "sms/backend"
28 // handler stores two interface implementations that implement
29 // the backend functionality
31 secretBackend smsbackend.SecretBackend
32 loginBackend smsbackend.LoginBackend
35 // createSecretDomainHandler creates a secret domain with a name provided
36 func (h handler) createSecretDomainHandler(w http.ResponseWriter, r *http.Request) {
37 var d smsbackend.SecretDomain
39 err := json.NewDecoder(r.Body).Decode(&d)
41 smslogger.WriteError(err.Error())
42 http.Error(w, err.Error(), http.StatusBadRequest)
46 dom, err := h.secretBackend.CreateSecretDomain(d.Name)
48 smslogger.WriteError(err.Error())
49 http.Error(w, err.Error(), http.StatusInternalServerError)
53 jdata, err := json.Marshal(dom)
55 smslogger.WriteError(err.Error())
56 http.Error(w, err.Error(), http.StatusInternalServerError)
60 w.Header().Set("Content-Type", "application/json")
61 w.WriteHeader(http.StatusCreated)
65 // deleteSecretDomainHandler deletes a secret domain with the name provided
66 func (h handler) deleteSecretDomainHandler(w http.ResponseWriter, r *http.Request) {
68 domName := vars["domName"]
70 err := h.secretBackend.DeleteSecretDomain(domName)
72 smslogger.WriteError(err.Error())
73 http.Error(w, err.Error(), http.StatusInternalServerError)
77 w.WriteHeader(http.StatusNoContent)
80 // createSecretHandler handles creation of secrets on a given domain name
81 func (h handler) createSecretHandler(w http.ResponseWriter, r *http.Request) {
82 // Get domain name from URL
84 domName := vars["domName"]
86 // Get secrets to be stored from body
87 var b smsbackend.Secret
88 err := json.NewDecoder(r.Body).Decode(&b)
90 smslogger.WriteError(err.Error())
91 http.Error(w, err.Error(), http.StatusBadRequest)
95 err = h.secretBackend.CreateSecret(domName, b)
97 smslogger.WriteError(err.Error())
98 http.Error(w, err.Error(), http.StatusInternalServerError)
102 w.WriteHeader(http.StatusCreated)
105 // getSecretHandler handles reading a secret by given domain name and secret name
106 func (h handler) getSecretHandler(w http.ResponseWriter, r *http.Request) {
108 domName := vars["domName"]
109 secName := vars["secretName"]
111 sec, err := h.secretBackend.GetSecret(domName, secName)
113 smslogger.WriteError(err.Error())
114 http.Error(w, err.Error(), http.StatusInternalServerError)
118 jdata, err := json.Marshal(sec)
120 smslogger.WriteError(err.Error())
121 http.Error(w, err.Error(), http.StatusInternalServerError)
125 w.Header().Set("Content-Type", "application/json")
129 // listSecretHandler handles listing all secrets under a particular domain name
130 func (h handler) listSecretHandler(w http.ResponseWriter, r *http.Request) {
132 domName := vars["domName"]
134 sec, err := h.secretBackend.ListSecret(domName)
136 smslogger.WriteError(err.Error())
137 http.Error(w, err.Error(), http.StatusInternalServerError)
141 jdata, err := json.Marshal(sec)
143 smslogger.WriteError(err.Error())
144 http.Error(w, err.Error(), http.StatusInternalServerError)
148 w.Header().Set("Content-Type", "application/json")
152 // deleteSecretHandler handles deleting a secret by given domain name and secret name
153 func (h handler) deleteSecretHandler(w http.ResponseWriter, r *http.Request) {
155 domName := vars["domName"]
156 secName := vars["secretName"]
158 err := h.secretBackend.DeleteSecret(domName, secName)
160 smslogger.WriteError(err.Error())
161 http.Error(w, err.Error(), http.StatusInternalServerError)
166 // struct that tracks various status items for SMS and backend
167 type backendStatus struct {
168 Seal bool `json:"sealstatus"`
171 // statusHandler returns information related to SMS and SMS backend services
172 func (h handler) statusHandler(w http.ResponseWriter, r *http.Request) {
173 s, err := h.secretBackend.GetStatus()
175 smslogger.WriteError(err.Error())
176 http.Error(w, err.Error(), http.StatusInternalServerError)
180 status := backendStatus{Seal: s}
181 jdata, err := json.Marshal(status)
183 smslogger.WriteError(err.Error())
184 http.Error(w, err.Error(), http.StatusInternalServerError)
188 w.Header().Set("Content-Type", "application/json")
192 // loginHandler handles login via password and username
193 func (h handler) loginHandler(w http.ResponseWriter, r *http.Request) {
197 // unsealHandler is a pass through that sends requests from quorum client
199 func (h handler) unsealHandler(w http.ResponseWriter, r *http.Request) {
200 // Get shards to be used for unseal
201 type unsealStruct struct {
202 UnsealShard string `json:"unsealshard"`
206 decoder := json.NewDecoder(r.Body)
207 decoder.DisallowUnknownFields()
208 err := decoder.Decode(&inp)
210 smslogger.WriteError(err.Error())
211 http.Error(w, "Bad input JSON", http.StatusBadRequest)
215 err = h.secretBackend.Unseal(inp.UnsealShard)
217 smslogger.WriteError(err.Error())
218 http.Error(w, err.Error(), http.StatusInternalServerError)
223 // CreateRouter returns an http.Handler for the registered URLs
224 // Takes an interface implementation as input
225 func CreateRouter(b smsbackend.SecretBackend) http.Handler {
226 h := handler{secretBackend: b}
228 // Create a new mux to handle URL endpoints
229 router := mux.NewRouter()
231 router.HandleFunc("/v1/sms/login", h.loginHandler).Methods("POST")
233 // Initialization APIs which will be used by quorum client
234 // to unseal and to provide root token to sms service
235 router.HandleFunc("/v1/sms/status", h.statusHandler).Methods("GET")
236 router.HandleFunc("/v1/sms/unseal", h.unsealHandler).Methods("POST")
238 router.HandleFunc("/v1/sms/domain", h.createSecretDomainHandler).Methods("POST")
239 router.HandleFunc("/v1/sms/domain/{domName}", h.deleteSecretDomainHandler).Methods("DELETE")
241 router.HandleFunc("/v1/sms/domain/{domName}/secret", h.createSecretHandler).Methods("POST")
242 router.HandleFunc("/v1/sms/domain/{domName}/secret", h.listSecretHandler).Methods("GET")
243 router.HandleFunc("/v1/sms/domain/{domName}/secret/{secretName}", h.getSecretHandler).Methods("GET")
244 router.HandleFunc("/v1/sms/domain/{domName}/secret/{secretName}", h.deleteSecretHandler).Methods("DELETE")