wip: data source permissions hooks

This commit is contained in:
Torkel Ödegaard
2018-10-01 15:38:55 +02:00
parent d2464812eb
commit b3c78f1265
6 changed files with 55 additions and 63 deletions

View File

@@ -234,13 +234,13 @@ func (hs *HTTPServer) registerRoutes() {
datasourceRoute.Get("/", Wrap(GetDataSources))
datasourceRoute.Post("/", quota("data_source"), bind(m.AddDataSourceCommand{}), Wrap(AddDataSource))
datasourceRoute.Put("/:id", bind(m.UpdateDataSourceCommand{}), Wrap(UpdateDataSource))
datasourceRoute.Delete("/:id", Wrap(DeleteDataSourceByID))
datasourceRoute.Delete("/:id", Wrap(DeleteDataSourceById))
datasourceRoute.Delete("/name/:name", Wrap(DeleteDataSourceByName))
datasourceRoute.Get("/:id", Wrap(GetDataSourceByID))
datasourceRoute.Get("/:id", Wrap(GetDataSourceById))
datasourceRoute.Get("/name/:name", Wrap(GetDataSourceByName))
}, reqOrgAdmin)
apiRoute.Get("/datasources/id/:name", Wrap(GetDataSourceIDByName), reqSignedIn)
apiRoute.Get("/datasources/id/:name", Wrap(GetDataSourceIdByName), reqSignedIn)
apiRoute.Get("/plugins", Wrap(GetPluginList))
apiRoute.Get("/plugins/:pluginId/settings", Wrap(GetPluginSettingByID))

View File

@@ -20,8 +20,8 @@ func GetDataSources(c *m.ReqContext) Response {
result := make(dtos.DataSourceList, 0)
for _, ds := range query.Result {
dsItem := dtos.DataSourceListItemDTO{
Id: ds.Id,
OrgId: ds.OrgId,
Id: ds.Id,
Name: ds.Name,
Url: ds.Url,
Type: ds.Type,
@@ -49,7 +49,27 @@ func GetDataSources(c *m.ReqContext) Response {
return JSON(200, &result)
}
func GetDataSourceByID(c *m.ReqContext) Response {
func hasRequiredDatasourcePermission(dsId int64, permission m.DataSourcePermissionType, user *m.SignedInUser) Response {
query := m.HasRequiredDataSourcePermissionQuery{
Id: dsId,
User: user,
RequiredPermission: permission,
}
if err := bus.Dispatch(&query); err != nil {
if err == bus.ErrHandlerNotFound {
return nil
}
if err == m.ErrDataSourceAccessDenied {
return Error(403, err.Error(), nil)
}
return Error(500, "Failed to check data source permissions", err)
}
return nil
}
func GetDataSourceById(c *m.ReqContext) Response {
query := m.GetDataSourceByIdQuery{
Id: c.ParamsInt64(":id"),
OrgId: c.OrgId,
@@ -68,14 +88,14 @@ func GetDataSourceByID(c *m.ReqContext) Response {
return JSON(200, &dtos)
}
func DeleteDataSourceByID(c *m.ReqContext) Response {
func DeleteDataSourceById(c *m.ReqContext) Response {
id := c.ParamsInt64(":id")
if id <= 0 {
return Error(400, "Missing valid datasource id", nil)
}
ds, err := getRawDataSourceByID(id, c.OrgId)
ds, err := getRawDataSourceById(id, c.OrgId)
if err != nil {
return Error(400, "Failed to delete datasource", nil)
}
@@ -186,7 +206,7 @@ func fillWithSecureJSONData(cmd *m.UpdateDataSourceCommand) error {
return nil
}
ds, err := getRawDataSourceByID(cmd.Id, cmd.OrgId)
ds, err := getRawDataSourceById(cmd.Id, cmd.OrgId)
if err != nil {
return err
}
@@ -206,7 +226,7 @@ func fillWithSecureJSONData(cmd *m.UpdateDataSourceCommand) error {
return nil
}
func getRawDataSourceByID(id int64, orgID int64) (*m.DataSource, error) {
func getRawDataSourceById(id int64, orgID int64) (*m.DataSource, error) {
query := m.GetDataSourceByIdQuery{
Id: id,
OrgId: orgID,
@@ -236,7 +256,7 @@ func GetDataSourceByName(c *m.ReqContext) Response {
}
// Get /api/datasources/id/:name
func GetDataSourceIDByName(c *m.ReqContext) Response {
func GetDataSourceIdByName(c *m.ReqContext) Response {
query := m.GetDataSourceByNameQuery{Name: c.Params(":name"), OrgId: c.OrgId}
if err := bus.Dispatch(&query); err != nil {

View File

@@ -32,7 +32,6 @@ import (
_ "github.com/grafana/grafana/pkg/plugins"
_ "github.com/grafana/grafana/pkg/services/alerting"
_ "github.com/grafana/grafana/pkg/services/cleanup"
_ "github.com/grafana/grafana/pkg/services/datasources"
_ "github.com/grafana/grafana/pkg/services/notifications"
_ "github.com/grafana/grafana/pkg/services/provisioning"
_ "github.com/grafana/grafana/pkg/services/rendering"

View File

@@ -29,6 +29,7 @@ var (
ErrDataSourceNameExists = errors.New("Data source with same name already exists")
ErrDataSourceUpdatingOldVersion = errors.New("Trying to update old version of datasource")
ErrDatasourceIsReadOnly = errors.New("Data source is readonly. Can only be updated from configuration.")
ErrDataSourceAccessDenied = errors.New("Data source access denied")
)
type DsAccess string
@@ -165,6 +166,7 @@ type DeleteDataSourceByNameCommand struct {
type GetDataSourcesQuery struct {
OrgId int64
User *SignedInUser
Result []*DataSource
}
@@ -185,6 +187,26 @@ type GetDataSourceByNameQuery struct {
}
// ---------------------
// EVENTS
type DataSourceCreatedEvent struct {
// Permissions
// ---------------------
type DataSourcePermissionType int
const (
DsPermissionQuery DataSourcePermissionType = 1 << iota
DsPermissionAdmin
)
func (p DataSourcePermissionType) String() string {
names := map[int]string{
int(DsPermissionQuery): "Query",
int(DsPermissionAdmin): "Admin",
}
return names[int(p)]
}
type HasRequiredDataSourcePermissionQuery struct {
Id int64
User *SignedInUser
RequiredPermission DataSourcePermissionType
}

View File

@@ -1,50 +0,0 @@
package datasources
import (
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/registry"
"github.com/grafana/grafana/pkg/setting"
)
type DataSourceService interface {
GetById(id int64, user *models.SignedInUser) (*models.DataSource, error)
}
type DataSourceServiceImpl struct {
log log.Logger
Cfg *setting.Cfg `inject:""`
Guardian DataSourceGuardian `inject:""`
}
func init() {
registry.RegisterService(&DataSourceServiceImpl{})
registry.RegisterService(&DataSourceGuardianNoop{})
}
func (srv *DataSourceServiceImpl) Init() error {
srv.log = log.New("datasources")
srv.log.Info("hello", "guardian", srv.Guardian.GetPermission(0, nil))
return nil
}
func (srv *DataSourceServiceImpl) GetById(id int64, user *models.SignedInUser) {
// check cache
// Get by id from db
// check permissions
}
type DataSourceGuardian interface {
GetPermission(id int64, user *models.SignedInUser) bool
}
type DataSourceGuardianNoop struct {
}
func (dsg *DataSourceGuardianNoop) Init() error {
return nil
}
func (dsg *DataSourceGuardianNoop) GetPermission(id int64, user *models.SignedInUser) bool {
return false
}

View File

@@ -27,6 +27,7 @@ func GetDataSourceById(query *m.GetDataSourceByIdQuery) error {
datasource := m.DataSource{OrgId: query.OrgId, Id: query.Id}
has, err := x.Get(&datasource)
if err != nil {
return err
}