From ebd17adecf22fa5daa03f4d907e2b03f6627d54f Mon Sep 17 00:00:00 2001 From: Mihai Doarna Date: Thu, 5 Sep 2024 13:10:24 +0300 Subject: [PATCH] API keys: Return 410 Gone status from POST /auth/keys endpoint (#92965) * return 410 Gone status from POST /auth/keys endpoint * generate swagger * remove postAPIkeyResponse * re-generate swagger * remove docs for api key creation endpoint --- docs/sources/developers/http_api/auth.md | 38 ++---------------------- pkg/api/apikey.go | 20 +++++-------- pkg/api/swagger_responses.go | 5 ++++ public/api-enterprise-spec.json | 12 ++++---- public/api-merged.json | 16 +++++----- public/openapi3.json | 24 +++++++-------- 6 files changed, 40 insertions(+), 75 deletions(-) diff --git a/docs/sources/developers/http_api/auth.md b/docs/sources/developers/http_api/auth.md index 71b1b5c491f..2f3dd915dcb 100644 --- a/docs/sources/developers/http_api/auth.md +++ b/docs/sources/developers/http_api/auth.md @@ -89,47 +89,13 @@ Endpoint is obsolete and has been moved to [Grafana service account API]({{< rel `POST /api/auth/keys` -**Required permissions** - -See note in the [introduction]({{< ref "#authentication-api" >}}) for an explanation. - -| Action | Scope | -| ---------------- | ----- | -| `apikeys:create` | n/a | - -**Example Request**: - -```http -POST /api/auth/keys HTTP/1.1 -Accept: application/json -Content-Type: application/json -Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk - -{ - "name": "mykey", - "role": "Admin", - "secondsToLive": 86400 -} -``` - -JSON Body schema: - -- **name** – The key name -- **role** – Sets the access level/Grafana Role for the key. Can be one of the following values: `None`, `Viewer`, `Editor` or `Admin`. -- **secondsToLive** – Sets the key expiration in seconds. It is optional. If it is a positive number an expiration date for the key is set. If it is null, zero or is omitted completely (unless `api_key_max_seconds_to_live` configuration option is set) the key will never expire. - -Error statuses: - -- **400** – `api_key_max_seconds_to_live` is set but no `secondsToLive` is specified or `secondsToLive` is greater than this value. -- **500** – The key was unable to be stored in the database. - **Example Response**: ```http -HTTP/1.1 301 +HTTP/1.1 410 Content-Type: application/json -"" +{"message":"this endpoint has been removed, please use POST /api/serviceaccounts and POST /api/serviceaccounts/{id}/tokens instead"} ``` ## Delete API Key diff --git a/pkg/api/apikey.go b/pkg/api/apikey.go index bab21403f55..ea2fe9c1e34 100644 --- a/pkg/api/apikey.go +++ b/pkg/api/apikey.go @@ -113,15 +113,16 @@ func (hs *HTTPServer) DeleteAPIKey(c *contextmodel.ReqContext) response.Response // see: https://grafana.com/docs/grafana/next/administration/service-accounts/migrate-api-keys/. // // Responses: -// 301: statusMovedPermanently +// 410: goneError func (hs *HTTPServer) AddAPIKey(c *contextmodel.ReqContext) response.Response { - // Set the Location header to the new URL hs.log.Warn("Obsolete and Permanently moved API endpoint called", "path", c.Req.URL.Path) - c.Context.Resp.Header().Set("Location", "/api/serviceaccounts/tokens") - // Respond with a 301 Moved Permanently status code - // the Location header is enough for clients to know where to go next. - return response.JSON(http.StatusMovedPermanently, nil) + // Respond with a 410 Gone status code + return response.Error( + http.StatusGone, + "this endpoint has been removed, please use POST /api/serviceaccounts and POST /api/serviceaccounts/{id}/tokens instead", + nil, + ) } // swagger:parameters getAPIkeys @@ -146,10 +147,3 @@ type GetAPIkeyResponse struct { // in: body Body []*dtos.ApiKeyDTO `json:"body"` } - -// swagger:response postAPIkeyResponse -type PostAPIkeyResponse struct { - // The response message - // in: body - Body dtos.NewApiKeyResult `json:"body"` -} diff --git a/pkg/api/swagger_responses.go b/pkg/api/swagger_responses.go index 5f422b90eff..4b529ca4112 100644 --- a/pkg/api/swagger_responses.go +++ b/pkg/api/swagger_responses.go @@ -77,6 +77,11 @@ type InternalServerError GenericError // swagger:response unauthorisedError type UnauthorizedError GenericError +// GoneError is returned when the requested endpoint was removed. +// +// swagger:response goneError +type GoneError GenericError + // AcceptedResponse // // swagger:response acceptedResponse diff --git a/public/api-enterprise-spec.json b/public/api-enterprise-spec.json index 06396ffc779..cfcba3e9b58 100644 --- a/public/api-enterprise-spec.json +++ b/public/api-enterprise-spec.json @@ -9439,6 +9439,12 @@ } } }, + "goneError": { + "description": "GoneError is returned when the requested endpoint was removed.", + "schema": { + "$ref": "#/definitions/ErrorResponseBody" + } + }, "helpFlagResponse": { "description": "", "schema": { @@ -9623,12 +9629,6 @@ "$ref": "#/definitions/SuccessResponseBody" } }, - "postAPIkeyResponse": { - "description": "", - "schema": { - "$ref": "#/definitions/NewApiKeyResult" - } - }, "postAnnotationResponse": { "description": "", "schema": { diff --git a/public/api-merged.json b/public/api-merged.json index 8d6476bd4d8..2c9c7078edd 100644 --- a/public/api-merged.json +++ b/public/api-merged.json @@ -2226,8 +2226,8 @@ "operationId": "addAPIkey", "deprecated": true, "responses": { - "301": { - "$ref": "#/responses/statusMovedPermanently" + "410": { + "$ref": "#/responses/goneError" } } } @@ -23806,6 +23806,12 @@ } } }, + "goneError": { + "description": "GoneError is returned when the requested endpoint was removed.", + "schema": { + "$ref": "#/definitions/ErrorResponseBody" + } + }, "helpFlagResponse": { "description": "(empty)", "schema": { @@ -23990,12 +23996,6 @@ "$ref": "#/definitions/SuccessResponseBody" } }, - "postAPIkeyResponse": { - "description": "(empty)", - "schema": { - "$ref": "#/definitions/NewApiKeyResult" - } - }, "postAnnotationResponse": { "description": "(empty)", "schema": { diff --git a/public/openapi3.json b/public/openapi3.json index 309ce67bff5..6ef714a02a4 100644 --- a/public/openapi3.json +++ b/public/openapi3.json @@ -1372,6 +1372,16 @@ }, "description": "(empty)" }, + "goneError": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseBody" + } + } + }, + "description": "GoneError is returned when the requested endpoint was removed." + }, "helpFlagResponse": { "content": { "application/json": { @@ -1628,16 +1638,6 @@ }, "description": "An OKResponse is returned if the request was successful." }, - "postAPIkeyResponse": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NewApiKeyResult" - } - } - }, - "description": "(empty)" - }, "postAnnotationResponse": { "content": { "application/json": { @@ -15392,8 +15392,8 @@ "description": "Will return details of the created API key.", "operationId": "addAPIkey", "responses": { - "301": { - "$ref": "#/components/responses/statusMovedPermanently" + "410": { + "$ref": "#/components/responses/goneError" } }, "summary": "Creates an API key.",