satellite/console: add create api key http endpoint

This change adds an endpoint to create new API key, similar to GraphQL mutation.

Issue:
https://github.com/storj/storj/issues/6139

Change-Id: I2b35d680fa8e019666c811ad3bdf16201e3b8946
This commit is contained in:
Vitalii 2023-08-07 15:45:25 +03:00 committed by Storj Robot
parent fa4f5a6ae9
commit f57bc81ce7
3 changed files with 67 additions and 0 deletions

View File

@ -6,9 +6,11 @@ package consoleapi
import (
"context"
"encoding/json"
"io"
"net/http"
"strconv"
"github.com/gorilla/mux"
"github.com/zeebo/errs"
"go.uber.org/zap"
@ -36,6 +38,55 @@ func NewAPIKeys(log *zap.Logger, service *console.Service) *APIKeys {
}
}
// CreateAPIKey creates new API key for given project.
func (keys *APIKeys) CreateAPIKey(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var err error
defer mon.Task()(&ctx)(&err)
var ok bool
var idParam string
if idParam, ok = mux.Vars(r)["projectID"]; !ok {
keys.serveJSONError(ctx, w, http.StatusBadRequest, errs.New("missing projectID route param"))
return
}
projectID, err := uuid.FromString(idParam)
if err != nil {
keys.serveJSONError(ctx, w, http.StatusBadRequest, err)
return
}
bodyBytes, err := io.ReadAll(r.Body)
if err != nil {
keys.serveJSONError(ctx, w, http.StatusBadRequest, err)
return
}
name := string(bodyBytes)
info, key, err := keys.service.CreateAPIKey(ctx, projectID, name)
if err != nil {
if console.ErrUnauthorized.Has(err) {
keys.serveJSONError(ctx, w, http.StatusUnauthorized, err)
return
}
keys.serveJSONError(ctx, w, http.StatusInternalServerError, err)
return
}
response := console.CreateAPIKeyResponse{
Key: key.Serialize(),
KeyInfo: info,
}
err = json.NewEncoder(w).Encode(response)
if err != nil {
keys.log.Error("failed to write json create api key response", zap.Error(ErrAPIKeysAPI.Wrap(err)))
}
}
// GetProjectAPIKeys returns paged API keys by project ID.
func (keys *APIKeys) GetProjectAPIKeys(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()

View File

@ -448,6 +448,21 @@ func TestAPIKeys(t *testing.T) {
require.NoError(t, json.Unmarshal([]byte(body), &projects))
require.Contains(t, body, "apiKeys")
}
{ // Post_Create_APIKey
var response console.CreateAPIKeyResponse
path := "/api-keys/create/" + test.defaultProjectID()
resp, body := test.request(http.MethodPost, path,
test.toJSON(map[string]interface{}{
"name": "testCreatedKey",
}))
require.Equal(t, http.StatusOK, resp.StatusCode)
err := json.Unmarshal([]byte(body), &response)
require.NoError(t, err)
require.Contains(t, body, "key")
require.Contains(t, body, "keyInfo")
require.NotNil(t, response.KeyInfo)
}
})
}

View File

@ -355,6 +355,7 @@ func NewServer(logger *zap.Logger, config Config, service *console.Service, oidc
apiKeysRouter := router.PathPrefix("/api/v0/api-keys").Subrouter()
apiKeysRouter.Use(server.withCORS)
apiKeysRouter.Use(server.withAuth)
apiKeysRouter.HandleFunc("/create/{projectID}", apiKeysController.CreateAPIKey).Methods(http.MethodPost, http.MethodOptions)
apiKeysRouter.HandleFunc("/list-paged", apiKeysController.GetProjectAPIKeys).Methods(http.MethodGet, http.MethodOptions)
apiKeysRouter.HandleFunc("/delete-by-name", apiKeysController.DeleteByNameAndProjectID).Methods(http.MethodDelete, http.MethodOptions)
apiKeysRouter.HandleFunc("/api-key-names", apiKeysController.GetAllAPIKeyNames).Methods(http.MethodGet, http.MethodOptions)