Access control: Pass access control metadata for api keys (#48445)

* Move ApiKeyDTO to dtos package

* Add access control filter to api keys

* pass user in GetApiKeysQuery

* Add api key metadata to DTO

* Remove scope all requirement from get api keys endpoint

* Handle api key access control metadata in frondend
This commit is contained in:
Karl Persson
2022-04-29 15:30:24 +02:00
committed by GitHub
parent e9a2a06651
commit 6c6137f45a
13 changed files with 123 additions and 39 deletions
+1 -1
View File
@@ -278,7 +278,7 @@ func (hs *HTTPServer) registerRoutes() {
// auth api keys
apiRoute.Group("/auth/keys", func(keysRoute routing.RouteRegister) {
apikeyIDScope := ac.Scope("apikeys", "id", ac.Parameter(":id"))
keysRoute.Get("/", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionAPIKeyRead, ac.ScopeAPIKeysAll)), routing.Wrap(hs.GetAPIKeys))
keysRoute.Get("/", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionAPIKeyRead)), routing.Wrap(hs.GetAPIKeys))
keysRoute.Post("/", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionAPIKeyCreate)), quota("api_key"), routing.Wrap(hs.AddAPIKey))
keysRoute.Delete("/:id", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionAPIKeyDelete, apikeyIDScope)), routing.Wrap(hs.DeleteAPIKey))
})
+12 -3
View File
@@ -15,20 +15,22 @@ import (
// GetAPIKeys returns a list of API keys
func (hs *HTTPServer) GetAPIKeys(c *models.ReqContext) response.Response {
query := models.GetApiKeysQuery{OrgId: c.OrgId, IncludeExpired: c.QueryBool("includeExpired")}
query := models.GetApiKeysQuery{OrgId: c.OrgId, User: c.SignedInUser, IncludeExpired: c.QueryBool("includeExpired")}
if err := hs.SQLStore.GetAPIKeys(c.Req.Context(), &query); err != nil {
return response.Error(500, "Failed to list api keys", err)
}
result := make([]*models.ApiKeyDTO, len(query.Result))
ids := map[string]bool{}
result := make([]*dtos.ApiKeyDTO, len(query.Result))
for i, t := range query.Result {
ids[strconv.FormatInt(t.Id, 10)] = true
var expiration *time.Time = nil
if t.Expires != nil {
v := time.Unix(*t.Expires, 0)
expiration = &v
}
result[i] = &models.ApiKeyDTO{
result[i] = &dtos.ApiKeyDTO{
Id: t.Id,
Name: t.Name,
Role: t.Role,
@@ -36,6 +38,13 @@ func (hs *HTTPServer) GetAPIKeys(c *models.ReqContext) response.Response {
}
}
metadata := hs.getMultiAccessControlMetadata(c, c.OrgId, "apikeys:id", ids)
if len(metadata) > 0 {
for _, key := range result {
key.AccessControl = metadata[strconv.FormatInt(key.Id, 10)]
}
}
return response.JSON(http.StatusOK, result)
}
+1 -1
View File
@@ -70,7 +70,7 @@ type DeleteAPIkeyParams struct {
type GetAPIkeyResponse struct {
// The response message
// in: body
Body []*models.ApiKeyDTO `json:"body"`
Body []*dtos.ApiKeyDTO `json:"body"`
}
// swagger:response postAPIkeyResponse
+15
View File
@@ -1,7 +1,22 @@
package dtos
import (
"time"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
)
type NewApiKeyResult struct {
ID int64 `json:"id"`
Name string `json:"name"`
Key string `json:"key"`
}
type ApiKeyDTO struct {
Id int64 `json:"id"`
Name string `json:"name"`
Role models.RoleType `json:"role"`
Expiration *time.Time `json:"expiration,omitempty"`
AccessControl accesscontrol.Metadata `json:"accessControl,omitempty"`
}