satellite/console: add get project api keys http endpoint
This change adds an endpoint to get paged project API keys, similar to GraphQL query. Issue: https://github.com/storj/storj/issues/6138 Change-Id: I5dea9e4ac61e798cc8a2e56a2755d722c1b66bfa
This commit is contained in:
parent
a4f7f0634d
commit
256bd18120
@ -7,6 +7,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/zeebo/errs"
|
||||
"go.uber.org/zap"
|
||||
@ -35,7 +36,102 @@ func NewAPIKeys(log *zap.Logger, service *console.Service) *APIKeys {
|
||||
}
|
||||
}
|
||||
|
||||
// GetAllAPIKeyNames returns all api key names by project ID.
|
||||
// GetProjectAPIKeys returns paged API keys by project ID.
|
||||
func (keys *APIKeys) GetProjectAPIKeys(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
var err error
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
query := r.URL.Query()
|
||||
|
||||
projectIDParam := query.Get("projectID")
|
||||
if projectIDParam == "" {
|
||||
keys.serveJSONError(ctx, w, http.StatusBadRequest, errs.New("parameter 'projectID' can't be empty"))
|
||||
return
|
||||
}
|
||||
|
||||
projectID, err := uuid.FromString(projectIDParam)
|
||||
if err != nil {
|
||||
keys.serveJSONError(ctx, w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
limitParam := query.Get("limit")
|
||||
if limitParam == "" {
|
||||
keys.serveJSONError(ctx, w, http.StatusBadRequest, errs.New("parameter 'limit' can't be empty"))
|
||||
return
|
||||
}
|
||||
|
||||
limit, err := strconv.ParseUint(limitParam, 10, 32)
|
||||
if err != nil {
|
||||
keys.serveJSONError(ctx, w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
pageParam := query.Get("page")
|
||||
if pageParam == "" {
|
||||
keys.serveJSONError(ctx, w, http.StatusBadRequest, errs.New("parameter 'page' can't be empty"))
|
||||
return
|
||||
}
|
||||
|
||||
page, err := strconv.ParseUint(pageParam, 10, 32)
|
||||
if err != nil {
|
||||
keys.serveJSONError(ctx, w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
orderParam := query.Get("order")
|
||||
if orderParam == "" {
|
||||
keys.serveJSONError(ctx, w, http.StatusBadRequest, errs.New("parameter 'order' can't be empty"))
|
||||
return
|
||||
}
|
||||
|
||||
order, err := strconv.ParseUint(orderParam, 10, 32)
|
||||
if err != nil {
|
||||
keys.serveJSONError(ctx, w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
orderDirectionParam := query.Get("orderDirection")
|
||||
if orderDirectionParam == "" {
|
||||
keys.serveJSONError(ctx, w, http.StatusBadRequest, errs.New("parameter 'orderDirection' can't be empty"))
|
||||
return
|
||||
}
|
||||
|
||||
orderDirection, err := strconv.ParseUint(orderDirectionParam, 10, 32)
|
||||
if err != nil {
|
||||
keys.serveJSONError(ctx, w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
searchString := query.Get("search")
|
||||
|
||||
cursor := console.APIKeyCursor{
|
||||
Search: searchString,
|
||||
Limit: uint(limit),
|
||||
Page: uint(page),
|
||||
Order: console.APIKeyOrder(order),
|
||||
OrderDirection: console.OrderDirection(orderDirection),
|
||||
}
|
||||
|
||||
apiKeys, err := keys.service.GetAPIKeys(ctx, projectID, cursor)
|
||||
if err != nil {
|
||||
if console.ErrUnauthorized.Has(err) {
|
||||
keys.serveJSONError(ctx, w, http.StatusUnauthorized, err)
|
||||
return
|
||||
}
|
||||
|
||||
keys.serveJSONError(ctx, w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = json.NewEncoder(w).Encode(apiKeys)
|
||||
if err != nil {
|
||||
keys.log.Error("failed to write json all api keys response", zap.Error(ErrAPIKeysAPI.Wrap(err)))
|
||||
}
|
||||
}
|
||||
|
||||
// GetAllAPIKeyNames returns all API key names by project ID.
|
||||
func (keys *APIKeys) GetAllAPIKeyNames(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
var err error
|
||||
@ -70,7 +166,7 @@ func (keys *APIKeys) GetAllAPIKeyNames(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteByNameAndProjectID deletes specific api key by it's name and project ID.
|
||||
// DeleteByNameAndProjectID deletes specific API key by it's name and project ID.
|
||||
// ID here may be project.publicID or project.ID.
|
||||
func (keys *APIKeys) DeleteByNameAndProjectID(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"storj.io/common/testcontext"
|
||||
"storj.io/common/uuid"
|
||||
"storj.io/storj/private/testplanet"
|
||||
"storj.io/storj/satellite/console"
|
||||
"storj.io/storj/satellite/payments/storjscan/blockchaintest"
|
||||
)
|
||||
|
||||
@ -438,6 +439,15 @@ func TestAPIKeys(t *testing.T) {
|
||||
require.Contains(t, body, "apiKeysPage")
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
}
|
||||
|
||||
{ // Get_ProjectAPIKeys
|
||||
var projects console.APIKeyPage
|
||||
path := "/api-keys/list-paged?projectID=" + test.defaultProjectID() + "&search=''&limit=6&page=1&order=1&orderDirection=1"
|
||||
resp, body := test.request(http.MethodGet, path, nil)
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
require.NoError(t, json.Unmarshal([]byte(body), &projects))
|
||||
require.Contains(t, body, "apiKeys")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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("/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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user