Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
b5c53aae
Unverified
Commit
b5c53aae
authored
Jun 04, 2018
by
David
Committed by
GitHub
Jun 04, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #12108 from grafana/davkal/12001-explore-permissions
Restrict Explore UI to Editor and Admin roles
parents
574e92e1
0c45ee63
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
36 additions
and
8 deletions
+36
-8
pkg/api/api.go
+3
-0
pkg/api/index.go
+1
-1
public/app/core/services/keybindingSrv.ts
+4
-1
public/app/features/panel/metrics_panel_ctrl.ts
+5
-3
public/app/features/panel/specs/metrics_panel_ctrl.jest.ts
+2
-1
public/app/routes/ReactContainer.tsx
+18
-2
public/app/routes/routes.ts
+1
-0
public/test/specs/helpers.ts
+2
-0
No files found.
pkg/api/api.go
View file @
b5c53aae
...
@@ -77,6 +77,9 @@ func (hs *HTTPServer) registerRoutes() {
...
@@ -77,6 +77,9 @@ func (hs *HTTPServer) registerRoutes() {
r
.
Get
(
"/dashboards/"
,
reqSignedIn
,
Index
)
r
.
Get
(
"/dashboards/"
,
reqSignedIn
,
Index
)
r
.
Get
(
"/dashboards/*"
,
reqSignedIn
,
Index
)
r
.
Get
(
"/dashboards/*"
,
reqSignedIn
,
Index
)
r
.
Get
(
"/explore/"
,
reqEditorRole
,
Index
)
r
.
Get
(
"/explore/*"
,
reqEditorRole
,
Index
)
r
.
Get
(
"/playlists/"
,
reqSignedIn
,
Index
)
r
.
Get
(
"/playlists/"
,
reqSignedIn
,
Index
)
r
.
Get
(
"/playlists/*"
,
reqSignedIn
,
Index
)
r
.
Get
(
"/playlists/*"
,
reqSignedIn
,
Index
)
r
.
Get
(
"/alerting/"
,
reqSignedIn
,
Index
)
r
.
Get
(
"/alerting/"
,
reqSignedIn
,
Index
)
...
...
pkg/api/index.go
View file @
b5c53aae
...
@@ -128,7 +128,7 @@ func setIndexViewData(c *m.ReqContext) (*dtos.IndexViewData, error) {
...
@@ -128,7 +128,7 @@ func setIndexViewData(c *m.ReqContext) (*dtos.IndexViewData, error) {
Children
:
dashboardChildNavs
,
Children
:
dashboardChildNavs
,
})
})
if
setting
.
ExploreEnabled
{
if
setting
.
ExploreEnabled
&&
(
c
.
OrgRole
==
m
.
ROLE_ADMIN
||
c
.
OrgRole
==
m
.
ROLE_EDITOR
)
{
data
.
NavTree
=
append
(
data
.
NavTree
,
&
dtos
.
NavLink
{
data
.
NavTree
=
append
(
data
.
NavTree
,
&
dtos
.
NavLink
{
Text
:
"Explore"
,
Text
:
"Explore"
,
Id
:
"explore"
,
Id
:
"explore"
,
...
...
public/app/core/services/keybindingSrv.ts
View file @
b5c53aae
...
@@ -14,7 +14,7 @@ export class KeybindingSrv {
...
@@ -14,7 +14,7 @@ export class KeybindingSrv {
timepickerOpen
=
false
;
timepickerOpen
=
false
;
/** @ngInject */
/** @ngInject */
constructor
(
private
$rootScope
,
private
$location
,
private
datasourceSrv
,
private
timeSrv
)
{
constructor
(
private
$rootScope
,
private
$location
,
private
datasourceSrv
,
private
timeSrv
,
private
contextSrv
)
{
// clear out all shortcuts on route change
// clear out all shortcuts on route change
$rootScope
.
$on
(
'$routeChangeSuccess'
,
()
=>
{
$rootScope
.
$on
(
'$routeChangeSuccess'
,
()
=>
{
Mousetrap
.
reset
();
Mousetrap
.
reset
();
...
@@ -177,6 +177,8 @@ export class KeybindingSrv {
...
@@ -177,6 +177,8 @@ export class KeybindingSrv {
}
}
});
});
// jump to explore if permissions allow
if
(
this
.
contextSrv
.
isEditor
)
{
this
.
bind
(
'x'
,
async
()
=>
{
this
.
bind
(
'x'
,
async
()
=>
{
if
(
dashboard
.
meta
.
focusPanelId
)
{
if
(
dashboard
.
meta
.
focusPanelId
)
{
const
panel
=
dashboard
.
getPanelById
(
dashboard
.
meta
.
focusPanelId
);
const
panel
=
dashboard
.
getPanelById
(
dashboard
.
meta
.
focusPanelId
);
...
@@ -192,6 +194,7 @@ export class KeybindingSrv {
...
@@ -192,6 +194,7 @@ export class KeybindingSrv {
}
}
}
}
});
});
}
// delete panel
// delete panel
this
.
bind
(
'p r'
,
()
=>
{
this
.
bind
(
'p r'
,
()
=>
{
...
...
public/app/features/panel/metrics_panel_ctrl.ts
View file @
b5c53aae
import
config
from
'app/core/config'
;
import
$
from
'jquery'
;
import
$
from
'jquery'
;
import
_
from
'lodash'
;
import
_
from
'lodash'
;
import
config
from
'app/core/config'
;
import
kbn
from
'app/core/utils/kbn'
;
import
kbn
from
'app/core/utils/kbn'
;
import
{
PanelCtrl
}
from
'app/features/panel/panel_ctrl'
;
import
{
PanelCtrl
}
from
'app/features/panel/panel_ctrl'
;
import
*
as
rangeUtil
from
'app/core/utils/rangeutil'
;
import
*
as
rangeUtil
from
'app/core/utils/rangeutil'
;
import
*
as
dateMath
from
'app/core/utils/datemath'
;
import
*
as
dateMath
from
'app/core/utils/datemath'
;
import
{
encodePathComponent
}
from
'app/core/utils/location_util'
;
import
{
encodePathComponent
}
from
'app/core/utils/location_util'
;
...
@@ -16,6 +16,7 @@ class MetricsPanelCtrl extends PanelCtrl {
...
@@ -16,6 +16,7 @@ class MetricsPanelCtrl extends PanelCtrl {
datasourceName
:
any
;
datasourceName
:
any
;
$q
:
any
;
$q
:
any
;
$timeout
:
any
;
$timeout
:
any
;
contextSrv
:
any
;
datasourceSrv
:
any
;
datasourceSrv
:
any
;
timeSrv
:
any
;
timeSrv
:
any
;
templateSrv
:
any
;
templateSrv
:
any
;
...
@@ -37,6 +38,7 @@ class MetricsPanelCtrl extends PanelCtrl {
...
@@ -37,6 +38,7 @@ class MetricsPanelCtrl extends PanelCtrl {
// make metrics tab the default
// make metrics tab the default
this
.
editorTabIndex
=
1
;
this
.
editorTabIndex
=
1
;
this
.
$q
=
$injector
.
get
(
'$q'
);
this
.
$q
=
$injector
.
get
(
'$q'
);
this
.
contextSrv
=
$injector
.
get
(
'contextSrv'
);
this
.
datasourceSrv
=
$injector
.
get
(
'datasourceSrv'
);
this
.
datasourceSrv
=
$injector
.
get
(
'datasourceSrv'
);
this
.
timeSrv
=
$injector
.
get
(
'timeSrv'
);
this
.
timeSrv
=
$injector
.
get
(
'timeSrv'
);
this
.
templateSrv
=
$injector
.
get
(
'templateSrv'
);
this
.
templateSrv
=
$injector
.
get
(
'templateSrv'
);
...
@@ -312,7 +314,7 @@ class MetricsPanelCtrl extends PanelCtrl {
...
@@ -312,7 +314,7 @@ class MetricsPanelCtrl extends PanelCtrl {
getAdditionalMenuItems
()
{
getAdditionalMenuItems
()
{
const
items
=
[];
const
items
=
[];
if
(
this
.
datasource
&&
this
.
datasource
.
supportsExplore
)
{
if
(
this
.
contextSrv
.
isEditor
&&
this
.
datasource
&&
this
.
datasource
.
supportsExplore
)
{
items
.
push
({
items
.
push
({
text
:
'Explore'
,
text
:
'Explore'
,
click
:
'ctrl.explore();'
,
click
:
'ctrl.explore();'
,
...
...
public/app/features/panel/specs/metrics_panel_ctrl.jest.ts
View file @
b5c53aae
...
@@ -24,8 +24,9 @@ describe('MetricsPanelCtrl', () => {
...
@@ -24,8 +24,9 @@ describe('MetricsPanelCtrl', () => {
});
});
});
});
describe
(
'and has datasource set that supports explore'
,
()
=>
{
describe
(
'and has datasource set that supports explore
and user has powers
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
ctrl
.
contextSrv
=
{
isEditor
:
true
};
ctrl
.
datasource
=
{
supportsExplore
:
true
};
ctrl
.
datasource
=
{
supportsExplore
:
true
};
additionalItems
=
ctrl
.
getAdditionalMenuItems
();
additionalItems
=
ctrl
.
getAdditionalMenuItems
();
});
});
...
...
public/app/routes/ReactContainer.tsx
View file @
b5c53aae
...
@@ -6,6 +6,7 @@ import coreModule from 'app/core/core_module';
...
@@ -6,6 +6,7 @@ import coreModule from 'app/core/core_module';
import
{
store
}
from
'app/stores/store'
;
import
{
store
}
from
'app/stores/store'
;
import
{
BackendSrv
}
from
'app/core/services/backend_srv'
;
import
{
BackendSrv
}
from
'app/core/services/backend_srv'
;
import
{
DatasourceSrv
}
from
'app/features/plugins/datasource_srv'
;
import
{
DatasourceSrv
}
from
'app/features/plugins/datasource_srv'
;
import
{
ContextSrv
}
from
'app/core/services/context_srv'
;
function
WrapInProvider
(
store
,
Component
,
props
)
{
function
WrapInProvider
(
store
,
Component
,
props
)
{
return
(
return
(
...
@@ -16,16 +17,31 @@ function WrapInProvider(store, Component, props) {
...
@@ -16,16 +17,31 @@ function WrapInProvider(store, Component, props) {
}
}
/** @ngInject */
/** @ngInject */
export
function
reactContainer
(
$route
,
$location
,
backendSrv
:
BackendSrv
,
datasourceSrv
:
DatasourceSrv
)
{
export
function
reactContainer
(
$route
,
$location
,
backendSrv
:
BackendSrv
,
datasourceSrv
:
DatasourceSrv
,
contextSrv
:
ContextSrv
)
{
return
{
return
{
restrict
:
'E'
,
restrict
:
'E'
,
template
:
''
,
template
:
''
,
link
(
scope
,
elem
)
{
link
(
scope
,
elem
)
{
let
component
=
$route
.
current
.
locals
.
component
;
// Check permissions for this component
const
{
roles
}
=
$route
.
current
.
locals
;
if
(
roles
&&
roles
.
length
)
{
if
(
!
roles
.
some
(
r
=>
contextSrv
.
hasRole
(
r
)))
{
$location
.
url
(
'/'
);
}
}
let
{
component
}
=
$route
.
current
.
locals
;
// Dynamic imports return whole module, need to extract default export
// Dynamic imports return whole module, need to extract default export
if
(
component
.
default
)
{
if
(
component
.
default
)
{
component
=
component
.
default
;
component
=
component
.
default
;
}
}
const
props
=
{
const
props
=
{
backendSrv
:
backendSrv
,
backendSrv
:
backendSrv
,
datasourceSrv
:
datasourceSrv
,
datasourceSrv
:
datasourceSrv
,
...
...
public/app/routes/routes.ts
View file @
b5c53aae
...
@@ -113,6 +113,7 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
...
@@ -113,6 +113,7 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
.
when
(
'/explore/:initial?'
,
{
.
when
(
'/explore/:initial?'
,
{
template
:
'<react-container />'
,
template
:
'<react-container />'
,
resolve
:
{
resolve
:
{
roles
:
()
=>
[
'Editor'
,
'Admin'
],
component
:
()
=>
import
(
/* webpackChunkName: "explore" */
'app/containers/Explore/Wrapper'
),
component
:
()
=>
import
(
/* webpackChunkName: "explore" */
'app/containers/Explore/Wrapper'
),
},
},
})
})
...
...
public/test/specs/helpers.ts
View file @
b5c53aae
...
@@ -11,6 +11,7 @@ export function ControllerTestContext() {
...
@@ -11,6 +11,7 @@ export function ControllerTestContext() {
this
.
$element
=
{};
this
.
$element
=
{};
this
.
$sanitize
=
{};
this
.
$sanitize
=
{};
this
.
annotationsSrv
=
{};
this
.
annotationsSrv
=
{};
this
.
contextSrv
=
{};
this
.
timeSrv
=
new
TimeSrvStub
();
this
.
timeSrv
=
new
TimeSrvStub
();
this
.
templateSrv
=
new
TemplateSrvStub
();
this
.
templateSrv
=
new
TemplateSrvStub
();
this
.
datasourceSrv
=
{
this
.
datasourceSrv
=
{
...
@@ -27,6 +28,7 @@ export function ControllerTestContext() {
...
@@ -27,6 +28,7 @@ export function ControllerTestContext() {
this
.
providePhase
=
function
(
mocks
)
{
this
.
providePhase
=
function
(
mocks
)
{
return
angularMocks
.
module
(
function
(
$provide
)
{
return
angularMocks
.
module
(
function
(
$provide
)
{
$provide
.
value
(
'contextSrv'
,
self
.
contextSrv
);
$provide
.
value
(
'datasourceSrv'
,
self
.
datasourceSrv
);
$provide
.
value
(
'datasourceSrv'
,
self
.
datasourceSrv
);
$provide
.
value
(
'annotationsSrv'
,
self
.
annotationsSrv
);
$provide
.
value
(
'annotationsSrv'
,
self
.
annotationsSrv
);
$provide
.
value
(
'timeSrv'
,
self
.
timeSrv
);
$provide
.
value
(
'timeSrv'
,
self
.
timeSrv
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment