Skip to content

Commit

Permalink
PMM-12251 API key migration.
Browse files Browse the repository at this point in the history
  • Loading branch information
JiriCtvrtka committed Nov 8, 2023
1 parent 4a59c23 commit ff44b1a
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
6 changes: 6 additions & 0 deletions pkg/services/serviceaccounts/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ func (api *ServiceAccountsAPI) RegisterAPIEndpoints() {
serviceAccountsRoute.Post("/:serviceAccountId/revert/:keyId", auth(middleware.ReqOrgAdmin,
accesscontrol.EvalPermission(serviceaccounts.ActionDelete, serviceaccounts.ScopeID)), routing.Wrap(api.RevertApiKey))
})

// @PERCONA
// current service account (works only with service account token auth). If you use API key then key will be automatically migrated into service account.
api.RouterRegister.Group("/api/auth/serviceaccount", func(serviceAccountsRoute routing.RouteRegister) {
serviceAccountsRoute.Get("/", routing.Wrap(api.CurrentServiceAcount))
})
}

// swagger:route POST /serviceaccounts service_accounts createServiceAccount
Expand Down
48 changes: 48 additions & 0 deletions pkg/services/serviceaccounts/api/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ type TokenDTO struct {
IsRevoked *bool `json:"isRevoked"`
}

type currentServiceAccount struct {
ServiceAccount *serviceaccounts.ServiceAccountProfileDTO
JustMigratedFromAPIKey bool
}

func hasExpired(expiration *int64) bool {
if expiration == nil {
return false
Expand Down Expand Up @@ -112,6 +117,49 @@ func (api *ServiceAccountsAPI) ListTokens(ctx *models.ReqContext) response.Respo
return response.JSON(http.StatusOK, result)
}

// @PERCONA
// swagger:route GET /auth/serviceaccount serviceaccounts currentServiceAccount
//
// # CurrentServiceAcount get current service account info
//
// Requires service account token authentication and that the authenticated user is at least reader.
//
// Responses:
// 200: currentServiceAccountResponse
// 400: badRequestError
// 401: unauthorisedError
// 403: forbiddenError
// 500: internalServerError
func (api *ServiceAccountsAPI) CurrentServiceAcount(ctx *models.ReqContext) response.Response {
apiKey := false
if !ctx.IsServiceAccount {
err := api.store.MigrateApiKeysToServiceAccounts(ctx.Req.Context(), ctx.OrgID)
if err != nil {
return response.Error(http.StatusBadRequest, "Auth method is not service token type", errors.New("failed to migrate API key to service account"))
}
apiKey = true
}

serviceAccount, err := api.store.RetrieveServiceAccount(ctx.Req.Context(), ctx.OrgID, ctx.UserID)
if err != nil {
switch {
case errors.Is(err, serviceaccounts.ErrServiceAccountNotFound):
return response.Error(http.StatusNotFound, "Failed to retrieve service account", err)
default:
return response.Error(http.StatusInternalServerError, "Failed to retrieve service account", err)
}
}

currentServiceAccount := currentServiceAccount{
ServiceAccount: serviceAccount,
}
if apiKey {
currentServiceAccount.JustMigratedFromAPIKey = true
}

return response.JSON(http.StatusOK, currentServiceAccount)
}

// swagger:route POST /serviceaccounts/{serviceAccountId}/tokens service_accounts createToken
//
// # CreateNewToken adds a token to a service account
Expand Down

0 comments on commit ff44b1a

Please sign in to comment.