Selaa lähdekoodia

wip: data source permissions hooks

Torkel Ödegaard 7 vuotta sitten
vanhempi
commit
b3c78f1265

+ 3 - 3
pkg/api/api.go

@@ -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))

+ 27 - 7
pkg/api/datasources.go

@@ -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 {

+ 0 - 1
pkg/cmd/grafana-server/server.go

@@ -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"

+ 24 - 2
pkg/models/datasource.go

@@ -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
 }

+ 0 - 50
pkg/services/datasources/datasource_service.go

@@ -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
-}

+ 1 - 0
pkg/services/sqlstore/datasource.go

@@ -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
 	}