Skip to content

Commit 314fffe

Browse files
committed
Merge branch 'data-source-instance-to-react' into datasource-dashboards-to-react
2 parents 176c857 + b7b0ce0 commit 314fffe

File tree

20 files changed

+434
-35
lines changed

20 files changed

+434
-35
lines changed

pkg/api/api.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,13 +234,13 @@ func (hs *HTTPServer) registerRoutes() {
234234
datasourceRoute.Get("/", Wrap(GetDataSources))
235235
datasourceRoute.Post("/", quota("data_source"), bind(m.AddDataSourceCommand{}), Wrap(AddDataSource))
236236
datasourceRoute.Put("/:id", bind(m.UpdateDataSourceCommand{}), Wrap(UpdateDataSource))
237-
datasourceRoute.Delete("/:id", Wrap(DeleteDataSourceByID))
237+
datasourceRoute.Delete("/:id", Wrap(DeleteDataSourceById))
238238
datasourceRoute.Delete("/name/:name", Wrap(DeleteDataSourceByName))
239-
datasourceRoute.Get("/:id", Wrap(GetDataSourceByID))
239+
datasourceRoute.Get("/:id", Wrap(GetDataSourceById))
240240
datasourceRoute.Get("/name/:name", Wrap(GetDataSourceByName))
241241
}, reqOrgAdmin)
242242

243-
apiRoute.Get("/datasources/id/:name", Wrap(GetDataSourceIDByName), reqSignedIn)
243+
apiRoute.Get("/datasources/id/:name", Wrap(GetDataSourceIdByName), reqSignedIn)
244244

245245
apiRoute.Get("/plugins", Wrap(GetPluginList))
246246
apiRoute.Get("/plugins/:pluginId/settings", Wrap(GetPluginSettingByID))

pkg/api/dataproxy.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package api
22

33
import (
44
"fmt"
5+
"github.com/pkg/errors"
56
"time"
67

78
"github.com/grafana/grafana/pkg/api/pluginproxy"
@@ -14,6 +15,20 @@ import (
1415
const HeaderNameNoBackendCache = "X-Grafana-NoCache"
1516

1617
func (hs *HTTPServer) getDatasourceFromCache(id int64, c *m.ReqContext) (*m.DataSource, error) {
18+
userPermissionsQuery := m.GetDataSourcePermissionsForUserQuery{
19+
User: c.SignedInUser,
20+
}
21+
if err := bus.Dispatch(&userPermissionsQuery); err != nil {
22+
if err != bus.ErrHandlerNotFound {
23+
return nil, err
24+
}
25+
} else {
26+
permissionType, exists := userPermissionsQuery.Result[id]
27+
if exists && permissionType != m.DsPermissionQuery {
28+
return nil, errors.New("User not allowed to access datasource")
29+
}
30+
}
31+
1732
nocache := c.Req.Header.Get(HeaderNameNoBackendCache) == "true"
1833
cacheKey := fmt.Sprintf("ds-%d", id)
1934

@@ -38,7 +53,9 @@ func (hs *HTTPServer) getDatasourceFromCache(id int64, c *m.ReqContext) (*m.Data
3853
func (hs *HTTPServer) ProxyDataSourceRequest(c *m.ReqContext) {
3954
c.TimeRequest(metrics.M_DataSource_ProxyReq_Timer)
4055

41-
ds, err := hs.getDatasourceFromCache(c.ParamsInt64(":id"), c)
56+
dsId := c.ParamsInt64(":id")
57+
ds, err := hs.getDatasourceFromCache(dsId, c)
58+
4259
if err != nil {
4360
c.JsonApiErr(500, "Unable to load datasource meta data", err)
4461
return

pkg/api/datasources.go

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,27 @@ func GetDataSources(c *m.ReqContext) Response {
1717
return Error(500, "Failed to query datasources", err)
1818
}
1919

20+
dsFilterQuery := m.DatasourcesPermissionFilterQuery{
21+
User: c.SignedInUser,
22+
Datasources: query.Result,
23+
}
24+
25+
var datasources []*m.DataSource
26+
if err := bus.Dispatch(&dsFilterQuery); err != nil {
27+
if err != bus.ErrHandlerNotFound {
28+
return Error(500, "Could not get datasources", err)
29+
}
30+
31+
datasources = query.Result
32+
} else {
33+
datasources = dsFilterQuery.Result
34+
}
35+
2036
result := make(dtos.DataSourceList, 0)
21-
for _, ds := range query.Result {
37+
for _, ds := range datasources {
2238
dsItem := dtos.DataSourceListItemDTO{
23-
Id: ds.Id,
2439
OrgId: ds.OrgId,
40+
Id: ds.Id,
2541
Name: ds.Name,
2642
Url: ds.Url,
2743
Type: ds.Type,
@@ -49,7 +65,7 @@ func GetDataSources(c *m.ReqContext) Response {
4965
return JSON(200, &result)
5066
}
5167

52-
func GetDataSourceByID(c *m.ReqContext) Response {
68+
func GetDataSourceById(c *m.ReqContext) Response {
5369
query := m.GetDataSourceByIdQuery{
5470
Id: c.ParamsInt64(":id"),
5571
OrgId: c.OrgId,
@@ -68,14 +84,14 @@ func GetDataSourceByID(c *m.ReqContext) Response {
6884
return JSON(200, &dtos)
6985
}
7086

71-
func DeleteDataSourceByID(c *m.ReqContext) Response {
87+
func DeleteDataSourceById(c *m.ReqContext) Response {
7288
id := c.ParamsInt64(":id")
7389

7490
if id <= 0 {
7591
return Error(400, "Missing valid datasource id", nil)
7692
}
7793

78-
ds, err := getRawDataSourceByID(id, c.OrgId)
94+
ds, err := getRawDataSourceById(id, c.OrgId)
7995
if err != nil {
8096
return Error(400, "Failed to delete datasource", nil)
8197
}
@@ -186,7 +202,7 @@ func fillWithSecureJSONData(cmd *m.UpdateDataSourceCommand) error {
186202
return nil
187203
}
188204

189-
ds, err := getRawDataSourceByID(cmd.Id, cmd.OrgId)
205+
ds, err := getRawDataSourceById(cmd.Id, cmd.OrgId)
190206
if err != nil {
191207
return err
192208
}
@@ -206,7 +222,7 @@ func fillWithSecureJSONData(cmd *m.UpdateDataSourceCommand) error {
206222
return nil
207223
}
208224

209-
func getRawDataSourceByID(id int64, orgID int64) (*m.DataSource, error) {
225+
func getRawDataSourceById(id int64, orgID int64) (*m.DataSource, error) {
210226
query := m.GetDataSourceByIdQuery{
211227
Id: id,
212228
OrgId: orgID,
@@ -236,7 +252,7 @@ func GetDataSourceByName(c *m.ReqContext) Response {
236252
}
237253

238254
// Get /api/datasources/id/:name
239-
func GetDataSourceIDByName(c *m.ReqContext) Response {
255+
func GetDataSourceIdByName(c *m.ReqContext) Response {
240256
query := m.GetDataSourceByNameQuery{Name: c.Params(":name"), OrgId: c.OrgId}
241257

242258
if err := bus.Dispatch(&query); err != nil {

pkg/api/frontendsettings.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,20 @@ func getFrontendSettingsMap(c *m.ReqContext) (map[string]interface{}, error) {
2222
return nil, err
2323
}
2424

25-
orgDataSources = query.Result
25+
dsFilterQuery := m.DatasourcesPermissionFilterQuery{
26+
User: c.SignedInUser,
27+
Datasources: query.Result,
28+
}
29+
30+
if err := bus.Dispatch(&dsFilterQuery); err != nil {
31+
if err != bus.ErrHandlerNotFound {
32+
return nil, err
33+
}
34+
35+
orgDataSources = query.Result
36+
} else {
37+
orgDataSources = dsFilterQuery.Result
38+
}
2639
}
2740

2841
datasources := make(map[string]interface{})

pkg/models/datasource.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ var (
3030
ErrDataSourceNameExists = errors.New("Data source with same name already exists")
3131
ErrDataSourceUpdatingOldVersion = errors.New("Trying to update old version of datasource")
3232
ErrDatasourceIsReadOnly = errors.New("Data source is readonly. Can only be updated from configuration.")
33+
ErrDataSourceAccessDenied = errors.New("Data source access denied")
3334
)
3435

3536
type DsAccess string
@@ -167,6 +168,7 @@ type DeleteDataSourceByNameCommand struct {
167168

168169
type GetDataSourcesQuery struct {
169170
OrgId int64
171+
User *SignedInUser
170172
Result []*DataSource
171173
}
172174

@@ -187,6 +189,37 @@ type GetDataSourceByNameQuery struct {
187189
}
188190

189191
// ---------------------
190-
// EVENTS
191-
type DataSourceCreatedEvent struct {
192+
// Permissions
193+
// ---------------------
194+
195+
type DsPermissionType int
196+
197+
const (
198+
DsPermissionQuery DsPermissionType = 1 << iota
199+
DsPermissionNoAccess
200+
)
201+
202+
func (p DsPermissionType) String() string {
203+
names := map[int]string{
204+
int(DsPermissionQuery): "Query",
205+
int(DsPermissionNoAccess): "No Access",
206+
}
207+
return names[int(p)]
208+
}
209+
210+
type HasRequiredDataSourcePermissionQuery struct {
211+
Id int64
212+
User *SignedInUser
213+
RequiredPermission DsPermissionType
214+
}
215+
216+
type GetDataSourcePermissionsForUserQuery struct {
217+
User *SignedInUser
218+
Result map[int64]DsPermissionType
219+
}
220+
221+
type DatasourcesPermissionFilterQuery struct {
222+
User *SignedInUser
223+
Datasources []*DataSource
224+
Result []*DataSource
192225
}

pkg/services/sqlstore/datasource.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ func GetDataSourceById(query *m.GetDataSourceByIdQuery) error {
2727

2828
datasource := m.DataSource{OrgId: query.OrgId, Id: query.Id}
2929
has, err := x.Get(&datasource)
30+
3031
if err != nil {
3132
return err
3233
}

pkg/services/sqlstore/sqlstore.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ type SqlStore struct {
5353
dbCfg DatabaseConfig
5454
engine *xorm.Engine
5555
log log.Logger
56+
Dialect migrator.Dialect
5657
skipEnsureAdmin bool
5758
}
5859

@@ -125,10 +126,12 @@ func (ss *SqlStore) Init() error {
125126
}
126127

127128
ss.engine = engine
129+
ss.Dialect = migrator.NewDialect(ss.engine)
128130

129131
// temporarily still set global var
130132
x = engine
131-
dialect = migrator.NewDialect(x)
133+
dialect = ss.Dialect
134+
132135
migrator := migrator.NewMigrator(x)
133136
migrations.AddMigrations(migrator)
134137

@@ -347,7 +350,11 @@ func InitTestDB(t *testing.T) *SqlStore {
347350
t.Fatalf("Failed to init test database: %v", err)
348351
}
349352

350-
dialect = migrator.NewDialect(engine)
353+
sqlstore.Dialect = migrator.NewDialect(engine)
354+
355+
// temp global var until we get rid of global vars
356+
dialect = sqlstore.Dialect
357+
351358
if err := dialect.CleanDB(); err != nil {
352359
t.Fatalf("Failed to clean test db %v", err)
353360
}

public/app/core/components/PermissionList/AddPermission.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ export interface Props {
1818
}
1919

2020
class AddPermissions extends Component<Props, NewDashboardAclItem> {
21+
static defaultProps = {
22+
showPermissionLevels: true,
23+
};
24+
2125
constructor(props) {
2226
super(props);
2327
this.state = this.getCleanState();

public/app/core/components/Picker/DescriptionPicker.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@ export interface Props {
2222
const getSelectedOption = (optionsWithDesc, value) => optionsWithDesc.find(option => option.value === value);
2323

2424
class DescriptionPicker extends Component<Props, any> {
25-
constructor(props) {
26-
super(props);
27-
}
28-
2925
render() {
3026
const { optionsWithDesc, onSelected, disabled, className, value } = this.props;
3127
const selectedOption = getSelectedOption(optionsWithDesc, value);

0 commit comments

Comments
 (0)