2020-06-03 17:37:51 +00:00
|
|
|
package secret
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
|
2021-03-30 18:10:02 +00:00
|
|
|
"github.com/influxdata/influxdb/v2/kit/platform"
|
|
|
|
"github.com/influxdata/influxdb/v2/kit/platform/errors"
|
|
|
|
|
2020-06-03 17:37:51 +00:00
|
|
|
"github.com/go-chi/chi"
|
|
|
|
"github.com/influxdata/influxdb/v2"
|
|
|
|
kithttp "github.com/influxdata/influxdb/v2/kit/transport/http"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
)
|
|
|
|
|
|
|
|
type handler struct {
|
|
|
|
log *zap.Logger
|
|
|
|
svc influxdb.SecretService
|
|
|
|
api *kithttp.API
|
|
|
|
|
|
|
|
idLookupKey string
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewHandler creates a new handler for the secret service
|
|
|
|
func NewHandler(log *zap.Logger, idLookupKey string, svc influxdb.SecretService) http.Handler {
|
|
|
|
h := &handler{
|
|
|
|
log: log,
|
|
|
|
svc: svc,
|
|
|
|
api: kithttp.NewAPI(kithttp.WithLog(log)),
|
|
|
|
|
|
|
|
idLookupKey: idLookupKey,
|
|
|
|
}
|
|
|
|
|
|
|
|
r := chi.NewRouter()
|
|
|
|
|
|
|
|
r.Get("/", h.handleGetSecrets)
|
|
|
|
r.Patch("/", h.handlePatchSecrets)
|
|
|
|
// TODO: this shouldn't be a post to delete
|
|
|
|
r.Post("/delete", h.handleDeleteSecrets)
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
|
|
|
// handleGetSecrets is the HTTP handler for the GET /api/v2/orgs/:id/secrets route.
|
|
|
|
func (h *handler) handleGetSecrets(w http.ResponseWriter, r *http.Request) {
|
|
|
|
orgID, err := h.decodeOrgID(r)
|
|
|
|
if err != nil {
|
|
|
|
h.api.Err(w, r, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
ks, err := h.svc.GetSecretKeys(r.Context(), orgID)
|
2021-03-30 18:10:02 +00:00
|
|
|
if err != nil && errors.ErrorCode(err) != errors.ENotFound {
|
2020-06-03 17:37:51 +00:00
|
|
|
h.api.Err(w, r, err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
h.api.Respond(w, r, http.StatusOK, newSecretsResponse(orgID, ks))
|
|
|
|
}
|
|
|
|
|
|
|
|
type secretsResponse struct {
|
|
|
|
Links map[string]string `json:"links"`
|
|
|
|
Secrets []string `json:"secrets"`
|
|
|
|
}
|
|
|
|
|
2021-03-30 18:10:02 +00:00
|
|
|
func newSecretsResponse(orgID platform.ID, ks []string) *secretsResponse {
|
2020-06-03 17:37:51 +00:00
|
|
|
if ks == nil {
|
|
|
|
ks = []string{}
|
|
|
|
}
|
|
|
|
return &secretsResponse{
|
|
|
|
Links: map[string]string{
|
|
|
|
"org": fmt.Sprintf("/api/v2/orgs/%s", orgID),
|
|
|
|
"self": fmt.Sprintf("/api/v2/orgs/%s/secrets", orgID),
|
|
|
|
},
|
|
|
|
Secrets: ks,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// handleGetPatchSecrets is the HTTP handler for the PATCH /api/v2/orgs/:id/secrets route.
|
|
|
|
func (h *handler) handlePatchSecrets(w http.ResponseWriter, r *http.Request) {
|
|
|
|
orgID, err := h.decodeOrgID(r)
|
|
|
|
if err != nil {
|
|
|
|
h.api.Err(w, r, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var secrets map[string]string
|
|
|
|
if err := h.api.DecodeJSON(r.Body, &secrets); err != nil {
|
|
|
|
h.api.Err(w, r, err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := h.svc.PatchSecrets(r.Context(), orgID, secrets); err != nil {
|
|
|
|
h.api.Err(w, r, err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
h.api.Respond(w, r, http.StatusNoContent, nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
type secretsDeleteBody struct {
|
|
|
|
Secrets []string `json:"secrets"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// handleDeleteSecrets is the HTTP handler for the DELETE /api/v2/orgs/:id/secrets route.
|
|
|
|
func (h *handler) handleDeleteSecrets(w http.ResponseWriter, r *http.Request) {
|
|
|
|
orgID, err := h.decodeOrgID(r)
|
|
|
|
if err != nil {
|
|
|
|
h.api.Err(w, r, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var reqBody secretsDeleteBody
|
|
|
|
|
|
|
|
if err := h.api.DecodeJSON(r.Body, &reqBody); err != nil {
|
|
|
|
h.api.Err(w, r, err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := h.svc.DeleteSecret(r.Context(), orgID, reqBody.Secrets...); err != nil {
|
|
|
|
h.api.Err(w, r, err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
h.api.Respond(w, r, http.StatusNoContent, nil)
|
|
|
|
}
|
|
|
|
|
2021-03-30 18:10:02 +00:00
|
|
|
func (h *handler) decodeOrgID(r *http.Request) (platform.ID, error) {
|
2020-06-03 17:37:51 +00:00
|
|
|
org := chi.URLParam(r, h.idLookupKey)
|
|
|
|
if org == "" {
|
2021-03-30 18:10:02 +00:00
|
|
|
return platform.InvalidID(), &errors.Error{
|
|
|
|
Code: errors.EInvalid,
|
2020-06-03 17:37:51 +00:00
|
|
|
Msg: "url missing id",
|
|
|
|
}
|
|
|
|
}
|
2021-03-30 18:10:02 +00:00
|
|
|
id, err := platform.IDFromString(org)
|
2020-06-03 17:37:51 +00:00
|
|
|
if err != nil {
|
2021-03-30 18:10:02 +00:00
|
|
|
return platform.InvalidID(), err
|
2020-06-03 17:37:51 +00:00
|
|
|
}
|
|
|
|
return *id, nil
|
|
|
|
}
|