mirror of
https://github.com/grafana/grafana.git
synced 2024-11-26 19:00:54 -06:00
Accesscontrol: list tokens for service account (#43809)
* Add list tokens endpoint * Update api.go Co-authored-by: J Guerreiro <joao.guerreiro@grafana.com>
This commit is contained in:
parent
449c608ef1
commit
6ae7b0c3b2
@ -5,6 +5,8 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/middleware"
|
||||
@ -49,6 +51,7 @@ func (api *ServiceAccountsAPI) RegisterAPIEndpoints(
|
||||
serviceAccountsRoute.Delete("/:serviceAccountId", auth(middleware.ReqOrgAdmin, accesscontrol.EvalPermission(serviceaccounts.ActionDelete, serviceaccounts.ScopeID)), routing.Wrap(api.DeleteServiceAccount))
|
||||
serviceAccountsRoute.Get("/upgrade", auth(middleware.ReqOrgAdmin, accesscontrol.EvalPermission(serviceaccounts.ActionCreate, serviceaccounts.ScopeID)), routing.Wrap(api.UpgradeServiceAccounts))
|
||||
serviceAccountsRoute.Post("/", auth(middleware.ReqOrgAdmin, accesscontrol.EvalPermission(serviceaccounts.ActionCreate, serviceaccounts.ScopeID)), routing.Wrap(api.CreateServiceAccount))
|
||||
serviceAccountsRoute.Get("/:serviceAccountId/tokens", auth(middleware.ReqOrgAdmin, accesscontrol.EvalPermission(serviceaccounts.ActionRead, serviceaccounts.ScopeID)), routing.Wrap(api.ListTokens))
|
||||
})
|
||||
}
|
||||
|
||||
@ -89,6 +92,33 @@ func (api *ServiceAccountsAPI) UpgradeServiceAccounts(ctx *models.ReqContext) re
|
||||
}
|
||||
}
|
||||
|
||||
func (api *ServiceAccountsAPI) ListTokens(ctx *models.ReqContext) response.Response {
|
||||
saID, err := strconv.ParseInt(web.Params(ctx.Req)[":serviceAccountId"], 10, 64)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusBadRequest, "serviceAccountId is invalid", err)
|
||||
}
|
||||
if saTokens, err := api.store.ListTokens(ctx.Req.Context(), ctx.OrgId, saID); err == nil {
|
||||
result := make([]*models.ApiKeyDTO, len(saTokens))
|
||||
for i, t := range saTokens {
|
||||
var expiration *time.Time = nil
|
||||
if t.Expires != nil {
|
||||
v := time.Unix(*t.Expires, 0)
|
||||
expiration = &v
|
||||
}
|
||||
result[i] = &models.ApiKeyDTO{
|
||||
Id: t.Id,
|
||||
Name: t.Name,
|
||||
Role: t.Role,
|
||||
Expiration: expiration,
|
||||
}
|
||||
}
|
||||
|
||||
return response.JSON(200, result)
|
||||
} else {
|
||||
return response.Error(500, "Internal server error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (api *ServiceAccountsAPI) ListServiceAccounts(ctx *models.ReqContext) response.Response {
|
||||
serviceAccounts, err := api.store.ListServiceAccounts(ctx.Req.Context(), ctx.OrgId)
|
||||
if err != nil {
|
||||
|
@ -1,14 +1,17 @@
|
||||
package database
|
||||
|
||||
//nolint:goimports
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/serviceaccounts"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
type ServiceAccountsStoreImpl struct {
|
||||
@ -85,6 +88,21 @@ func (s *ServiceAccountsStoreImpl) UpgradeServiceAccounts(ctx context.Context) e
|
||||
return nil
|
||||
}
|
||||
|
||||
//nolint:gosimple
|
||||
func (s *ServiceAccountsStoreImpl) ListTokens(ctx context.Context, orgID int64, serviceAccount int64) ([]*models.ApiKey, error) {
|
||||
result := make([]*models.ApiKey, 0)
|
||||
err := s.sqlStore.WithDbSession(ctx, func(dbSession *sqlstore.DBSession) error {
|
||||
var sess *xorm.Session
|
||||
|
||||
sess = dbSession.Limit(100, 0).
|
||||
Join("inner", "user", "user.id = api_key.service_account_id").
|
||||
Where("user.org_id=? AND user.id=? AND ( expires IS NULL or expires >= ?)", orgID, serviceAccount, time.Now().Unix()).
|
||||
Asc("name")
|
||||
|
||||
return sess.Find(&result)
|
||||
})
|
||||
return result, err
|
||||
}
|
||||
func (s *ServiceAccountsStoreImpl) ListServiceAccounts(ctx context.Context, orgID int64) ([]*models.OrgUserDTO, error) {
|
||||
query := models.GetOrgUsersQuery{OrgId: orgID, IsServiceAccount: true}
|
||||
err := s.sqlStore.GetOrgUsers(ctx, &query)
|
||||
|
@ -17,4 +17,5 @@ type Store interface {
|
||||
ListServiceAccounts(ctx context.Context, orgID int64) ([]*models.OrgUserDTO, error)
|
||||
DeleteServiceAccount(ctx context.Context, orgID, serviceAccountID int64) error
|
||||
UpgradeServiceAccounts(ctx context.Context) error
|
||||
ListTokens(ctx context.Context, orgID int64, serviceAccount int64) ([]*models.ApiKey, error)
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ type Calls struct {
|
||||
ListServiceAccounts []interface{}
|
||||
DeleteServiceAccount []interface{}
|
||||
UpgradeServiceAccounts []interface{}
|
||||
ListTokens []interface{}
|
||||
}
|
||||
|
||||
type ServiceAccountsStoreMock struct {
|
||||
@ -79,10 +80,14 @@ func (s *ServiceAccountsStoreMock) DeleteServiceAccount(ctx context.Context, org
|
||||
}
|
||||
|
||||
func (s *ServiceAccountsStoreMock) UpgradeServiceAccounts(ctx context.Context) error {
|
||||
s.Calls.DeleteServiceAccount = append(s.Calls.UpgradeServiceAccounts, []interface{}{ctx})
|
||||
s.Calls.UpgradeServiceAccounts = append(s.Calls.UpgradeServiceAccounts, []interface{}{ctx})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ServiceAccountsStoreMock) ListTokens(ctx context.Context, orgID int64, serviceAccount int64) ([]*models.ApiKey, error) {
|
||||
s.Calls.ListTokens = append(s.Calls.ListTokens, []interface{}{ctx, orgID, serviceAccount})
|
||||
return nil, nil
|
||||
}
|
||||
func (s *ServiceAccountsStoreMock) ListServiceAccounts(ctx context.Context, orgID int64) ([]*models.OrgUserDTO, error) {
|
||||
s.Calls.ListServiceAccounts = append(s.Calls.ListServiceAccounts, []interface{}{ctx, orgID})
|
||||
return nil, nil
|
||||
|
@ -8,14 +8,15 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/search"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/searchstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
Loading…
Reference in New Issue
Block a user