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
8d7fa644
Unverified
Commit
8d7fa644
authored
Mar 23, 2018
by
Carl Bergquist
Committed by
GitHub
Mar 23, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #11352 from digineo/golint
Make golint happier
parents
7b141280
0a415c50
Hide whitespace changes
Inline
Side-by-side
Showing
44 changed files
with
554 additions
and
547 deletions
+554
-547
pkg/api/alerting.go
+36
-36
pkg/api/annotations.go
+30
-30
pkg/api/annotations_test.go
+4
-4
pkg/api/api.go
+6
-6
pkg/api/apikey.go
+7
-7
pkg/api/common.go
+13
-9
pkg/api/dashboard.go
+36
-36
pkg/api/dashboard_permission.go
+8
-8
pkg/api/dashboard_snapshot.go
+8
-8
pkg/api/dashboard_test.go
+3
-3
pkg/api/dataproxy.go
+2
-2
pkg/api/datasources.go
+28
-28
pkg/api/dtos/prefs.go
+2
-2
pkg/api/folder.go
+13
-13
pkg/api/folder_permission.go
+10
-10
pkg/api/folder_permission_test.go
+5
-5
pkg/api/folder_test.go
+9
-9
pkg/api/http_server.go
+10
-10
pkg/api/login.go
+4
-4
pkg/api/metrics.go
+11
-11
pkg/api/org.go
+22
-22
pkg/api/org_invite.go
+26
-26
pkg/api/org_users.go
+14
-14
pkg/api/password.go
+8
-8
pkg/api/playlist.go
+15
-15
pkg/api/playlist_play.go
+5
-5
pkg/api/pluginproxy/ds_proxy.go
+14
-14
pkg/api/pluginproxy/ds_proxy_test.go
+8
-8
pkg/api/pluginproxy/pluginproxy.go
+9
-9
pkg/api/plugins.go
+15
-15
pkg/api/preferences.go
+8
-8
pkg/api/quota.go
+14
-14
pkg/api/signup.go
+13
-13
pkg/api/stars.go
+7
-7
pkg/api/team.go
+14
-14
pkg/api/team_members.go
+10
-10
pkg/api/user.go
+33
-33
pkg/cmd/grafana-server/server.go
+1
-1
pkg/middleware/auth_proxy.go
+52
-49
pkg/middleware/dashboard_redirect.go
+5
-5
pkg/middleware/dashboard_redirect_test.go
+1
-1
pkg/middleware/render_auth.go
+7
-7
pkg/services/dashboards/folder_service.go
+4
-4
pkg/services/dashboards/folder_service_test.go
+4
-4
No files found.
pkg/api/alerting.go
View file @
8d7fa644
...
...
@@ -29,7 +29,7 @@ func GetAlertStatesForDashboard(c *m.ReqContext) Response {
dashboardID
:=
c
.
QueryInt64
(
"dashboardId"
)
if
dashboardID
==
0
{
return
Api
Error
(
400
,
"Missing query parameter dashboardId"
,
nil
)
return
Error
(
400
,
"Missing query parameter dashboardId"
,
nil
)
}
query
:=
m
.
GetAlertStatesForDashboardQuery
{
...
...
@@ -38,10 +38,10 @@ func GetAlertStatesForDashboard(c *m.ReqContext) Response {
}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to fetch alert states"
,
err
)
return
Error
(
500
,
"Failed to fetch alert states"
,
err
)
}
return
J
son
(
200
,
query
.
Result
)
return
J
SON
(
200
,
query
.
Result
)
}
// GET /api/alerts
...
...
@@ -60,20 +60,20 @@ func GetAlerts(c *m.ReqContext) Response {
}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
Api
Error
(
500
,
"List alerts failed"
,
err
)
return
Error
(
500
,
"List alerts failed"
,
err
)
}
for
_
,
alert
:=
range
query
.
Result
{
alert
.
Url
=
m
.
GetDashboardUrl
(
alert
.
DashboardUid
,
alert
.
DashboardSlug
)
}
return
J
son
(
200
,
query
.
Result
)
return
J
SON
(
200
,
query
.
Result
)
}
// POST /api/alerts/test
func
AlertTest
(
c
*
m
.
ReqContext
,
dto
dtos
.
AlertTestCommand
)
Response
{
if
_
,
idErr
:=
dto
.
Dashboard
.
Get
(
"id"
)
.
Int64
();
idErr
!=
nil
{
return
Api
Error
(
400
,
"The dashboard needs to be saved at least once before you can test an alert rule"
,
nil
)
return
Error
(
400
,
"The dashboard needs to be saved at least once before you can test an alert rule"
,
nil
)
}
backendCmd
:=
alerting
.
AlertTestCommand
{
...
...
@@ -84,9 +84,9 @@ func AlertTest(c *m.ReqContext, dto dtos.AlertTestCommand) Response {
if
err
:=
bus
.
Dispatch
(
&
backendCmd
);
err
!=
nil
{
if
validationErr
,
ok
:=
err
.
(
alerting
.
ValidationError
);
ok
{
return
Api
Error
(
422
,
validationErr
.
Error
(),
nil
)
return
Error
(
422
,
validationErr
.
Error
(),
nil
)
}
return
Api
Error
(
500
,
"Failed to test rule"
,
err
)
return
Error
(
500
,
"Failed to test rule"
,
err
)
}
res
:=
backendCmd
.
Result
...
...
@@ -109,7 +109,7 @@ func AlertTest(c *m.ReqContext, dto dtos.AlertTestCommand) Response {
dtoRes
.
TimeMs
=
fmt
.
Sprintf
(
"%1.3fms"
,
res
.
GetDurationMs
())
return
J
son
(
200
,
dtoRes
)
return
J
SON
(
200
,
dtoRes
)
}
// GET /api/alerts/:id
...
...
@@ -118,21 +118,21 @@ func GetAlert(c *m.ReqContext) Response {
query
:=
m
.
GetAlertByIdQuery
{
Id
:
id
}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
Api
Error
(
500
,
"List alerts failed"
,
err
)
return
Error
(
500
,
"List alerts failed"
,
err
)
}
return
J
son
(
200
,
&
query
.
Result
)
return
J
SON
(
200
,
&
query
.
Result
)
}
func
GetAlertNotifiers
(
c
*
m
.
ReqContext
)
Response
{
return
J
son
(
200
,
alerting
.
GetNotifiers
())
return
J
SON
(
200
,
alerting
.
GetNotifiers
())
}
func
GetAlertNotifications
(
c
*
m
.
ReqContext
)
Response
{
query
:=
&
m
.
GetAllAlertNotificationsQuery
{
OrgId
:
c
.
OrgId
}
if
err
:=
bus
.
Dispatch
(
query
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to get alert notifications"
,
err
)
return
Error
(
500
,
"Failed to get alert notifications"
,
err
)
}
result
:=
make
([]
*
dtos
.
AlertNotification
,
0
)
...
...
@@ -148,7 +148,7 @@ func GetAlertNotifications(c *m.ReqContext) Response {
})
}
return
J
son
(
200
,
result
)
return
J
SON
(
200
,
result
)
}
func
GetAlertNotificationByID
(
c
*
m
.
ReqContext
)
Response
{
...
...
@@ -158,30 +158,30 @@ func GetAlertNotificationByID(c *m.ReqContext) Response {
}
if
err
:=
bus
.
Dispatch
(
query
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to get alert notifications"
,
err
)
return
Error
(
500
,
"Failed to get alert notifications"
,
err
)
}
return
J
son
(
200
,
query
.
Result
)
return
J
SON
(
200
,
query
.
Result
)
}
func
CreateAlertNotification
(
c
*
m
.
ReqContext
,
cmd
m
.
CreateAlertNotificationCommand
)
Response
{
cmd
.
OrgId
=
c
.
OrgId
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to create alert notification"
,
err
)
return
Error
(
500
,
"Failed to create alert notification"
,
err
)
}
return
J
son
(
200
,
cmd
.
Result
)
return
J
SON
(
200
,
cmd
.
Result
)
}
func
UpdateAlertNotification
(
c
*
m
.
ReqContext
,
cmd
m
.
UpdateAlertNotificationCommand
)
Response
{
cmd
.
OrgId
=
c
.
OrgId
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to update alert notification"
,
err
)
return
Error
(
500
,
"Failed to update alert notification"
,
err
)
}
return
J
son
(
200
,
cmd
.
Result
)
return
J
SON
(
200
,
cmd
.
Result
)
}
func
DeleteAlertNotification
(
c
*
m
.
ReqContext
)
Response
{
...
...
@@ -191,10 +191,10 @@ func DeleteAlertNotification(c *m.ReqContext) Response {
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to delete alert notification"
,
err
)
return
Error
(
500
,
"Failed to delete alert notification"
,
err
)
}
return
Api
Success
(
"Notification deleted"
)
return
Success
(
"Notification deleted"
)
}
//POST /api/alert-notifications/test
...
...
@@ -207,41 +207,41 @@ func NotificationTest(c *m.ReqContext, dto dtos.NotificationTestCommand) Respons
if
err
:=
bus
.
Dispatch
(
cmd
);
err
!=
nil
{
if
err
==
m
.
ErrSmtpNotEnabled
{
return
Api
Error
(
412
,
err
.
Error
(),
err
)
return
Error
(
412
,
err
.
Error
(),
err
)
}
return
Api
Error
(
500
,
"Failed to send alert notifications"
,
err
)
return
Error
(
500
,
"Failed to send alert notifications"
,
err
)
}
return
Api
Success
(
"Test notification sent"
)
return
Success
(
"Test notification sent"
)
}
//POST /api/alerts/:alertId/pause
func
PauseAlert
(
c
*
m
.
ReqContext
,
dto
dtos
.
PauseAlertCommand
)
Response
{
alertI
d
:=
c
.
ParamsInt64
(
"alertId"
)
alertI
D
:=
c
.
ParamsInt64
(
"alertId"
)
query
:=
m
.
GetAlertByIdQuery
{
Id
:
alertI
d
}
query
:=
m
.
GetAlertByIdQuery
{
Id
:
alertI
D
}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
Api
Error
(
500
,
"Get Alert failed"
,
err
)
return
Error
(
500
,
"Get Alert failed"
,
err
)
}
guardian
:=
guardian
.
New
(
query
.
Result
.
DashboardId
,
c
.
OrgId
,
c
.
SignedInUser
)
if
canEdit
,
err
:=
guardian
.
CanEdit
();
err
!=
nil
||
!
canEdit
{
if
err
!=
nil
{
return
Api
Error
(
500
,
"Error while checking permissions for Alert"
,
err
)
return
Error
(
500
,
"Error while checking permissions for Alert"
,
err
)
}
return
Api
Error
(
403
,
"Access denied to this dashboard and alert"
,
nil
)
return
Error
(
403
,
"Access denied to this dashboard and alert"
,
nil
)
}
cmd
:=
m
.
PauseAlertCommand
{
OrgId
:
c
.
OrgId
,
AlertIds
:
[]
int64
{
alertI
d
},
AlertIds
:
[]
int64
{
alertI
D
},
Paused
:
dto
.
Paused
,
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
""
,
err
)
return
Error
(
500
,
""
,
err
)
}
var
response
m
.
AlertStateType
=
m
.
AlertStatePending
...
...
@@ -252,12 +252,12 @@ func PauseAlert(c *m.ReqContext, dto dtos.PauseAlertCommand) Response {
}
result
:=
map
[
string
]
interface
{}{
"alertId"
:
alertI
d
,
"alertId"
:
alertI
D
,
"state"
:
response
,
"message"
:
"Alert "
+
pausedState
,
}
return
J
son
(
200
,
result
)
return
J
SON
(
200
,
result
)
}
//POST /api/admin/pause-all-alerts
...
...
@@ -267,7 +267,7 @@ func PauseAllAlerts(c *m.ReqContext, dto dtos.PauseAllAlertsCommand) Response {
}
if
err
:=
bus
.
Dispatch
(
&
updateCmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to pause alerts"
,
err
)
return
Error
(
500
,
"Failed to pause alerts"
,
err
)
}
var
response
m
.
AlertStateType
=
m
.
AlertStatePending
...
...
@@ -283,5 +283,5 @@ func PauseAllAlerts(c *m.ReqContext, dto dtos.PauseAllAlertsCommand) Response {
"alertsAffected"
:
updateCmd
.
ResultCount
,
}
return
J
son
(
200
,
result
)
return
J
SON
(
200
,
result
)
}
pkg/api/annotations.go
View file @
8d7fa644
...
...
@@ -30,7 +30,7 @@ func GetAnnotations(c *m.ReqContext) Response {
items
,
err
:=
repo
.
Find
(
query
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to get annotations"
,
err
)
return
Error
(
500
,
"Failed to get annotations"
,
err
)
}
for
_
,
item
:=
range
items
{
...
...
@@ -40,7 +40,7 @@ func GetAnnotations(c *m.ReqContext) Response {
item
.
Time
=
item
.
Time
*
1000
}
return
J
son
(
200
,
items
)
return
J
SON
(
200
,
items
)
}
type
CreateAnnotationError
struct
{
...
...
@@ -60,7 +60,7 @@ func PostAnnotation(c *m.ReqContext, cmd dtos.PostAnnotationsCmd) Response {
if
cmd
.
Text
==
""
{
err
:=
&
CreateAnnotationError
{
"text field should not be empty"
}
return
Api
Error
(
500
,
"Failed to save annotation"
,
err
)
return
Error
(
500
,
"Failed to save annotation"
,
err
)
}
item
:=
annotations
.
Item
{
...
...
@@ -79,7 +79,7 @@ func PostAnnotation(c *m.ReqContext, cmd dtos.PostAnnotationsCmd) Response {
}
if
err
:=
repo
.
Save
(
&
item
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to save annotation"
,
err
)
return
Error
(
500
,
"Failed to save annotation"
,
err
)
}
startID
:=
item
.
Id
...
...
@@ -93,24 +93,24 @@ func PostAnnotation(c *m.ReqContext, cmd dtos.PostAnnotationsCmd) Response {
}
if
err
:=
repo
.
Update
(
&
item
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed set regionId on annotation"
,
err
)
return
Error
(
500
,
"Failed set regionId on annotation"
,
err
)
}
item
.
Id
=
0
item
.
Epoch
=
cmd
.
TimeEnd
/
1000
if
err
:=
repo
.
Save
(
&
item
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed save annotation for region end time"
,
err
)
return
Error
(
500
,
"Failed save annotation for region end time"
,
err
)
}
return
J
son
(
200
,
util
.
DynMap
{
return
J
SON
(
200
,
util
.
DynMap
{
"message"
:
"Annotation added"
,
"id"
:
startID
,
"endId"
:
item
.
Id
,
})
}
return
J
son
(
200
,
util
.
DynMap
{
return
J
SON
(
200
,
util
.
DynMap
{
"message"
:
"Annotation added"
,
"id"
:
startID
,
})
...
...
@@ -129,7 +129,7 @@ func PostGraphiteAnnotation(c *m.ReqContext, cmd dtos.PostGraphiteAnnotationsCmd
if
cmd
.
What
==
""
{
err
:=
&
CreateAnnotationError
{
"what field should not be empty"
}
return
Api
Error
(
500
,
"Failed to save Graphite annotation"
,
err
)
return
Error
(
500
,
"Failed to save Graphite annotation"
,
err
)
}
if
cmd
.
When
==
0
{
...
...
@@ -152,12 +152,12 @@ func PostGraphiteAnnotation(c *m.ReqContext, cmd dtos.PostGraphiteAnnotationsCmd
tagsArray
=
append
(
tagsArray
,
tagStr
)
}
else
{
err
:=
&
CreateAnnotationError
{
"tag should be a string"
}
return
Api
Error
(
500
,
"Failed to save Graphite annotation"
,
err
)
return
Error
(
500
,
"Failed to save Graphite annotation"
,
err
)
}
}
default
:
err
:=
&
CreateAnnotationError
{
"unsupported tags format"
}
return
Api
Error
(
500
,
"Failed to save Graphite annotation"
,
err
)
return
Error
(
500
,
"Failed to save Graphite annotation"
,
err
)
}
item
:=
annotations
.
Item
{
...
...
@@ -169,10 +169,10 @@ func PostGraphiteAnnotation(c *m.ReqContext, cmd dtos.PostGraphiteAnnotationsCmd
}
if
err
:=
repo
.
Save
(
&
item
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to save Graphite annotation"
,
err
)
return
Error
(
500
,
"Failed to save Graphite annotation"
,
err
)
}
return
J
son
(
200
,
util
.
DynMap
{
return
J
SON
(
200
,
util
.
DynMap
{
"message"
:
"Graphite annotation added"
,
"id"
:
item
.
Id
,
})
...
...
@@ -197,7 +197,7 @@ func UpdateAnnotation(c *m.ReqContext, cmd dtos.UpdateAnnotationsCmd) Response {
}
if
err
:=
repo
.
Update
(
&
item
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to update annotation"
,
err
)
return
Error
(
500
,
"Failed to update annotation"
,
err
)
}
if
cmd
.
IsRegion
{
...
...
@@ -210,11 +210,11 @@ func UpdateAnnotation(c *m.ReqContext, cmd dtos.UpdateAnnotationsCmd) Response {
itemRight
.
Id
=
0
if
err
:=
repo
.
Update
(
&
itemRight
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to update annotation for region end time"
,
err
)
return
Error
(
500
,
"Failed to update annotation for region end time"
,
err
)
}
}
return
Api
Success
(
"Annotation updated"
)
return
Success
(
"Annotation updated"
)
}
func
DeleteAnnotations
(
c
*
m
.
ReqContext
,
cmd
dtos
.
DeleteAnnotationsCmd
)
Response
{
...
...
@@ -227,29 +227,29 @@ func DeleteAnnotations(c *m.ReqContext, cmd dtos.DeleteAnnotationsCmd) Response
})
if
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to delete annotations"
,
err
)
return
Error
(
500
,
"Failed to delete annotations"
,
err
)
}
return
Api
Success
(
"Annotations deleted"
)
return
Success
(
"Annotations deleted"
)
}
func
DeleteAnnotationByI
d
(
c
*
m
.
ReqContext
)
Response
{
func
DeleteAnnotationByI
D
(
c
*
m
.
ReqContext
)
Response
{
repo
:=
annotations
.
GetRepository
()
annotationI
d
:=
c
.
ParamsInt64
(
":annotationId"
)
annotationI
D
:=
c
.
ParamsInt64
(
":annotationId"
)
if
resp
:=
canSave
(
c
,
repo
,
annotationI
d
);
resp
!=
nil
{
if
resp
:=
canSave
(
c
,
repo
,
annotationI
D
);
resp
!=
nil
{
return
resp
}
err
:=
repo
.
Delete
(
&
annotations
.
DeleteParams
{
Id
:
annotationI
d
,
Id
:
annotationI
D
,
})
if
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to delete annotation"
,
err
)
return
Error
(
500
,
"Failed to delete annotation"
,
err
)
}
return
Api
Success
(
"Annotation deleted"
)
return
Success
(
"Annotation deleted"
)
}
func
DeleteAnnotationRegion
(
c
*
m
.
ReqContext
)
Response
{
...
...
@@ -265,10 +265,10 @@ func DeleteAnnotationRegion(c *m.ReqContext) Response {
})
if
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to delete annotation region"
,
err
)
return
Error
(
500
,
"Failed to delete annotation region"
,
err
)
}
return
Api
Success
(
"Annotation region deleted"
)
return
Success
(
"Annotation region deleted"
)
}
func
canSaveByDashboardID
(
c
*
m
.
ReqContext
,
dashboardID
int64
)
(
bool
,
error
)
{
...
...
@@ -286,11 +286,11 @@ func canSaveByDashboardID(c *m.ReqContext, dashboardID int64) (bool, error) {
return
true
,
nil
}
func
canSave
(
c
*
m
.
ReqContext
,
repo
annotations
.
Repository
,
annotationI
d
int64
)
Response
{
items
,
err
:=
repo
.
Find
(
&
annotations
.
ItemQuery
{
AnnotationId
:
annotationI
d
,
OrgId
:
c
.
OrgId
})
func
canSave
(
c
*
m
.
ReqContext
,
repo
annotations
.
Repository
,
annotationI
D
int64
)
Response
{
items
,
err
:=
repo
.
Find
(
&
annotations
.
ItemQuery
{
AnnotationId
:
annotationI
D
,
OrgId
:
c
.
OrgId
})
if
err
!=
nil
||
len
(
items
)
==
0
{
return
Api
Error
(
500
,
"Could not find annotation to update"
,
err
)
return
Error
(
500
,
"Could not find annotation to update"
,
err
)
}
dashboardID
:=
items
[
0
]
.
DashboardId
...
...
@@ -306,7 +306,7 @@ func canSaveByRegionID(c *m.ReqContext, repo annotations.Repository, regionID in
items
,
err
:=
repo
.
Find
(
&
annotations
.
ItemQuery
{
RegionId
:
regionID
,
OrgId
:
c
.
OrgId
})
if
err
!=
nil
||
len
(
items
)
==
0
{
return
Api
Error
(
500
,
"Could not find annotation to update"
,
err
)
return
Error
(
500
,
"Could not find annotation to update"
,
err
)
}
dashboardID
:=
items
[
0
]
.
DashboardId
...
...
pkg/api/annotations_test.go
View file @
8d7fa644
...
...
@@ -41,7 +41,7 @@ func TestAnnotationsApiEndpoint(t *testing.T) {
})
loggedInUserScenarioWithRole
(
"When calling DELETE on"
,
"DELETE"
,
"/api/annotations/1"
,
"/api/annotations/:annotationId"
,
role
,
func
(
sc
*
scenarioContext
)
{
sc
.
handlerFunc
=
DeleteAnnotationByI
d
sc
.
handlerFunc
=
DeleteAnnotationByI
D
sc
.
fakeReqWithParams
(
"DELETE"
,
sc
.
url
,
map
[
string
]
string
{})
.
exec
()
So
(
sc
.
resp
.
Code
,
ShouldEqual
,
403
)
})
...
...
@@ -68,7 +68,7 @@ func TestAnnotationsApiEndpoint(t *testing.T) {
})
loggedInUserScenarioWithRole
(
"When calling DELETE on"
,
"DELETE"
,
"/api/annotations/1"
,
"/api/annotations/:annotationId"
,
role
,
func
(
sc
*
scenarioContext
)
{
sc
.
handlerFunc
=
DeleteAnnotationByI
d
sc
.
handlerFunc
=
DeleteAnnotationByI
D
sc
.
fakeReqWithParams
(
"DELETE"
,
sc
.
url
,
map
[
string
]
string
{})
.
exec
()
So
(
sc
.
resp
.
Code
,
ShouldEqual
,
200
)
})
...
...
@@ -132,7 +132,7 @@ func TestAnnotationsApiEndpoint(t *testing.T) {
})
loggedInUserScenarioWithRole
(
"When calling DELETE on"
,
"DELETE"
,
"/api/annotations/1"
,
"/api/annotations/:annotationId"
,
role
,
func
(
sc
*
scenarioContext
)
{
sc
.
handlerFunc
=
DeleteAnnotationByI
d
sc
.
handlerFunc
=
DeleteAnnotationByI
D
sc
.
fakeReqWithParams
(
"DELETE"
,
sc
.
url
,
map
[
string
]
string
{})
.
exec
()
So
(
sc
.
resp
.
Code
,
ShouldEqual
,
403
)
})
...
...
@@ -159,7 +159,7 @@ func TestAnnotationsApiEndpoint(t *testing.T) {
})
loggedInUserScenarioWithRole
(
"When calling DELETE on"
,
"DELETE"
,
"/api/annotations/1"
,
"/api/annotations/:annotationId"
,
role
,
func
(
sc
*
scenarioContext
)
{
sc
.
handlerFunc
=
DeleteAnnotationByI
d
sc
.
handlerFunc
=
DeleteAnnotationByI
D
sc
.
fakeReqWithParams
(
"DELETE"
,
sc
.
url
,
map
[
string
]
string
{})
.
exec
()
So
(
sc
.
resp
.
Code
,
ShouldEqual
,
200
)
})
...
...
pkg/api/api.go
View file @
8d7fa644
...
...
@@ -9,14 +9,14 @@ import (
)
// Register adds http routes
func
(
hs
*
H
ttp
Server
)
registerRoutes
()
{
func
(
hs
*
H
TTP
Server
)
registerRoutes
()
{
macaronR
:=
hs
.
macaron
reqSignedIn
:=
middleware
.
Auth
(
&
middleware
.
AuthOptions
{
ReqSignedIn
:
true
})
reqGrafanaAdmin
:=
middleware
.
Auth
(
&
middleware
.
AuthOptions
{
ReqSignedIn
:
true
,
ReqGrafanaAdmin
:
true
})
reqEditorRole
:=
middleware
.
RoleAuth
(
m
.
ROLE_EDITOR
,
m
.
ROLE_ADMIN
)
reqOrgAdmin
:=
middleware
.
RoleAuth
(
m
.
ROLE_ADMIN
)
redirectFromLegacyDashboardU
rl
:=
middleware
.
RedirectFromLegacyDashboardURL
()
redirectFromLegacyDashboardSoloU
rl
:=
middleware
.
RedirectFromLegacyDashboardSoloUrl
()
redirectFromLegacyDashboardU
RL
:=
middleware
.
RedirectFromLegacyDashboardURL
()
redirectFromLegacyDashboardSoloU
RL
:=
middleware
.
RedirectFromLegacyDashboardSoloURL
()
quota
:=
middleware
.
Quota
bind
:=
binding
.
Bind
...
...
@@ -67,11 +67,11 @@ func (hs *HttpServer) registerRoutes() {
r
.
Get
(
"/d/:uid/:slug"
,
reqSignedIn
,
Index
)
r
.
Get
(
"/d/:uid"
,
reqSignedIn
,
Index
)
r
.
Get
(
"/dashboard/db/:slug"
,
reqSignedIn
,
redirectFromLegacyDashboardU
rl
,
Index
)
r
.
Get
(
"/dashboard/db/:slug"
,
reqSignedIn
,
redirectFromLegacyDashboardU
RL
,
Index
)
r
.
Get
(
"/dashboard/script/*"
,
reqSignedIn
,
Index
)
r
.
Get
(
"/dashboard-solo/snapshot/*"
,
Index
)
r
.
Get
(
"/d-solo/:uid/:slug"
,
reqSignedIn
,
Index
)
r
.
Get
(
"/dashboard-solo/db/:slug"
,
reqSignedIn
,
redirectFromLegacyDashboardSoloU
rl
,
Index
)
r
.
Get
(
"/dashboard-solo/db/:slug"
,
reqSignedIn
,
redirectFromLegacyDashboardSoloU
RL
,
Index
)
r
.
Get
(
"/dashboard-solo/script/*"
,
reqSignedIn
,
Index
)
r
.
Get
(
"/import/dashboard"
,
reqSignedIn
,
Index
)
r
.
Get
(
"/dashboards/"
,
reqSignedIn
,
Index
)
...
...
@@ -341,7 +341,7 @@ func (hs *HttpServer) registerRoutes() {
apiRoute
.
Group
(
"/annotations"
,
func
(
annotationsRoute
RouteRegister
)
{
annotationsRoute
.
Post
(
"/"
,
bind
(
dtos
.
PostAnnotationsCmd
{}),
wrap
(
PostAnnotation
))
annotationsRoute
.
Delete
(
"/:annotationId"
,
wrap
(
DeleteAnnotationByI
d
))
annotationsRoute
.
Delete
(
"/:annotationId"
,
wrap
(
DeleteAnnotationByI
D
))
annotationsRoute
.
Put
(
"/:annotationId"
,
bind
(
dtos
.
UpdateAnnotationsCmd
{}),
wrap
(
UpdateAnnotation
))
annotationsRoute
.
Delete
(
"/region/:regionId"
,
wrap
(
DeleteAnnotationRegion
))
annotationsRoute
.
Post
(
"/graphite"
,
reqEditorRole
,
bind
(
dtos
.
PostGraphiteAnnotationsCmd
{}),
wrap
(
PostGraphiteAnnotation
))
...
...
pkg/api/apikey.go
View file @
8d7fa644
...
...
@@ -11,7 +11,7 @@ func GetAPIKeys(c *m.ReqContext) Response {
query
:=
m
.
GetApiKeysQuery
{
OrgId
:
c
.
OrgId
}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to list api keys"
,
err
)
return
Error
(
500
,
"Failed to list api keys"
,
err
)
}
result
:=
make
([]
*
m
.
ApiKeyDTO
,
len
(
query
.
Result
))
...
...
@@ -23,7 +23,7 @@ func GetAPIKeys(c *m.ReqContext) Response {
}
}
return
J
son
(
200
,
result
)
return
J
SON
(
200
,
result
)
}
func
DeleteAPIKey
(
c
*
m
.
ReqContext
)
Response
{
...
...
@@ -33,15 +33,15 @@ func DeleteAPIKey(c *m.ReqContext) Response {
err
:=
bus
.
Dispatch
(
cmd
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to delete API key"
,
err
)
return
Error
(
500
,
"Failed to delete API key"
,
err
)
}
return
Api
Success
(
"API key deleted"
)
return
Success
(
"API key deleted"
)
}
func
AddAPIKey
(
c
*
m
.
ReqContext
,
cmd
m
.
AddApiKeyCommand
)
Response
{
if
!
cmd
.
Role
.
IsValid
()
{
return
Api
Error
(
400
,
"Invalid role specified"
,
nil
)
return
Error
(
400
,
"Invalid role specified"
,
nil
)
}
cmd
.
OrgId
=
c
.
OrgId
...
...
@@ -50,12 +50,12 @@ func AddAPIKey(c *m.ReqContext, cmd m.AddApiKeyCommand) Response {
cmd
.
Key
=
newKeyInfo
.
HashedKey
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to add API key"
,
err
)
return
Error
(
500
,
"Failed to add API key"
,
err
)
}
result
:=
&
dtos
.
NewApiKeyResult
{
Name
:
cmd
.
Result
.
Name
,
Key
:
newKeyInfo
.
ClientSecret
}
return
J
son
(
200
,
result
)
return
J
SON
(
200
,
result
)
}
pkg/api/common.go
View file @
8d7fa644
...
...
@@ -11,10 +11,10 @@ import (
var
(
NotFound
=
func
()
Response
{
return
Api
Error
(
404
,
"Not found"
,
nil
)
return
Error
(
404
,
"Not found"
,
nil
)
}
ServerError
=
func
(
err
error
)
Response
{
return
Api
Error
(
500
,
"Server error"
,
err
)
return
Error
(
500
,
"Server error"
,
err
)
}
)
...
...
@@ -67,22 +67,25 @@ func (r *NormalResponse) Header(key, value string) *NormalResponse {
return
r
}
//
functions to create responses
//
Empty create an empty response
func
Empty
(
status
int
)
*
NormalResponse
{
return
Respond
(
status
,
nil
)
}
func
Json
(
status
int
,
body
interface
{})
*
NormalResponse
{
// JSON create a JSON response
func
JSON
(
status
int
,
body
interface
{})
*
NormalResponse
{
return
Respond
(
status
,
body
)
.
Header
(
"Content-Type"
,
"application/json"
)
}
func
ApiSuccess
(
message
string
)
*
NormalResponse
{
// Success create a successful response
func
Success
(
message
string
)
*
NormalResponse
{
resp
:=
make
(
map
[
string
]
interface
{})
resp
[
"message"
]
=
message
return
J
son
(
200
,
resp
)
return
J
SON
(
200
,
resp
)
}
func
ApiError
(
status
int
,
message
string
,
err
error
)
*
NormalResponse
{
// Error create a erroneous response
func
Error
(
status
int
,
message
string
,
err
error
)
*
NormalResponse
{
data
:=
make
(
map
[
string
]
interface
{})
switch
status
{
...
...
@@ -102,7 +105,7 @@ func ApiError(status int, message string, err error) *NormalResponse {
}
}
resp
:=
J
son
(
status
,
data
)
resp
:=
J
SON
(
status
,
data
)
if
err
!=
nil
{
resp
.
errMessage
=
message
...
...
@@ -112,6 +115,7 @@ func ApiError(status int, message string, err error) *NormalResponse {
return
resp
}
// Respond create a response
func
Respond
(
status
int
,
body
interface
{})
*
NormalResponse
{
var
b
[]
byte
var
err
error
...
...
@@ -122,7 +126,7 @@ func Respond(status int, body interface{}) *NormalResponse {
b
=
[]
byte
(
t
)
default
:
if
b
,
err
=
json
.
Marshal
(
body
);
err
!=
nil
{
return
Api
Error
(
500
,
"body json marshal"
,
err
)
return
Error
(
500
,
"body json marshal"
,
err
)
}
}
return
&
NormalResponse
{
...
...
pkg/api/dashboard.go
View file @
8d7fa644
...
...
@@ -37,10 +37,10 @@ func isDashboardStarredByUser(c *m.ReqContext, dashID int64) (bool, error) {
func
dashboardGuardianResponse
(
err
error
)
Response
{
if
err
!=
nil
{
return
Api
Error
(
500
,
"Error while checking dashboard permissions"
,
err
)
return
Error
(
500
,
"Error while checking dashboard permissions"
,
err
)
}
return
Api
Error
(
403
,
"Access denied to this dashboard"
,
nil
)
return
Error
(
403
,
"Access denied to this dashboard"
,
nil
)
}
func
GetDashboard
(
c
*
m
.
ReqContext
)
Response
{
...
...
@@ -60,7 +60,7 @@ func GetDashboard(c *m.ReqContext) Response {
isStarred
,
err
:=
isDashboardStarredByUser
(
c
,
dash
.
Id
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"Error while checking if dashboard was starred by user"
,
err
)
return
Error
(
500
,
"Error while checking if dashboard was starred by user"
,
err
)
}
// Finding creator and last updater of the dashboard
...
...
@@ -96,7 +96,7 @@ func GetDashboard(c *m.ReqContext) Response {
if
dash
.
FolderId
>
0
{
query
:=
m
.
GetDashboardQuery
{
Id
:
dash
.
FolderId
,
OrgId
:
c
.
OrgId
}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
Api
Error
(
500
,
"Dashboard folder could not be read"
,
err
)
return
Error
(
500
,
"Dashboard folder could not be read"
,
err
)
}
meta
.
FolderTitle
=
query
.
Result
.
Title
meta
.
FolderUrl
=
query
.
Result
.
GetUrl
()
...
...
@@ -111,7 +111,7 @@ func GetDashboard(c *m.ReqContext) Response {
}
c
.
TimeRequest
(
metrics
.
M_Api_Dashboard_Get
)
return
J
son
(
200
,
dto
)
return
J
SON
(
200
,
dto
)
}
func
getUserLogin
(
userID
int64
)
string
{
...
...
@@ -133,7 +133,7 @@ func getDashboardHelper(orgID int64, slug string, id int64, uid string) (*m.Dash
}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
nil
,
Api
Error
(
404
,
"Dashboard not found"
,
err
)
return
nil
,
Error
(
404
,
"Dashboard not found"
,
err
)
}
return
query
.
Result
,
nil
...
...
@@ -143,11 +143,11 @@ func DeleteDashboard(c *m.ReqContext) Response {
query
:=
m
.
GetDashboardsBySlugQuery
{
OrgId
:
c
.
OrgId
,
Slug
:
c
.
Params
(
":slug"
)}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to retrieve dashboards by slug"
,
err
)
return
Error
(
500
,
"Failed to retrieve dashboards by slug"
,
err
)
}
if
len
(
query
.
Result
)
>
1
{
return
J
son
(
412
,
util
.
DynMap
{
"status"
:
"multiple-slugs-exists"
,
"message"
:
m
.
ErrDashboardsWithSameSlugExists
.
Error
()})
return
J
SON
(
412
,
util
.
DynMap
{
"status"
:
"multiple-slugs-exists"
,
"message"
:
m
.
ErrDashboardsWithSameSlugExists
.
Error
()})
}
dash
,
rsp
:=
getDashboardHelper
(
c
.
OrgId
,
c
.
Params
(
":slug"
),
0
,
""
)
...
...
@@ -162,10 +162,10 @@ func DeleteDashboard(c *m.ReqContext) Response {
cmd
:=
m
.
DeleteDashboardCommand
{
OrgId
:
c
.
OrgId
,
Id
:
dash
.
Id
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to delete dashboard"
,
err
)
return
Error
(
500
,
"Failed to delete dashboard"
,
err
)
}
return
J
son
(
200
,
util
.
DynMap
{
return
J
SON
(
200
,
util
.
DynMap
{
"title"
:
dash
.
Title
,
"message"
:
fmt
.
Sprintf
(
"Dashboard %s deleted"
,
dash
.
Title
),
})
...
...
@@ -184,10 +184,10 @@ func DeleteDashboardByUID(c *m.ReqContext) Response {
cmd
:=
m
.
DeleteDashboardCommand
{
OrgId
:
c
.
OrgId
,
Id
:
dash
.
Id
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to delete dashboard"
,
err
)
return
Error
(
500
,
"Failed to delete dashboard"
,
err
)
}
return
J
son
(
200
,
util
.
DynMap
{
return
J
SON
(
200
,
util
.
DynMap
{
"title"
:
dash
.
Title
,
"message"
:
fmt
.
Sprintf
(
"Dashboard %s deleted"
,
dash
.
Title
),
})
...
...
@@ -202,10 +202,10 @@ func PostDashboard(c *m.ReqContext, cmd m.SaveDashboardCommand) Response {
if
dash
.
Id
==
0
&&
dash
.
Uid
==
""
{
limitReached
,
err
:=
quota
.
QuotaReached
(
c
,
"dashboard"
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"failed to get quota"
,
err
)
return
Error
(
500
,
"failed to get quota"
,
err
)
}
if
limitReached
{
return
Api
Error
(
403
,
"Quota reached"
,
nil
)
return
Error
(
403
,
"Quota reached"
,
nil
)
}
}
...
...
@@ -229,23 +229,23 @@ func PostDashboard(c *m.ReqContext, cmd m.SaveDashboardCommand) Response {
err
==
m
.
ErrFolderNotFound
||
err
==
m
.
ErrDashboardFolderCannotHaveParent
||
err
==
m
.
ErrDashboardFolderNameExists
{
return
Api
Error
(
400
,
err
.
Error
(),
nil
)
return
Error
(
400
,
err
.
Error
(),
nil
)
}
if
err
==
m
.
ErrDashboardUpdateAccessDenied
{
return
Api
Error
(
403
,
err
.
Error
(),
err
)
return
Error
(
403
,
err
.
Error
(),
err
)
}
if
err
==
m
.
ErrDashboardContainsInvalidAlertData
{
return
Api
Error
(
500
,
"Invalid alert data. Cannot save dashboard"
,
err
)
return
Error
(
500
,
"Invalid alert data. Cannot save dashboard"
,
err
)
}
if
err
!=
nil
{
if
err
==
m
.
ErrDashboardWithSameNameInFolderExists
{
return
J
son
(
412
,
util
.
DynMap
{
"status"
:
"name-exists"
,
"message"
:
err
.
Error
()})
return
J
SON
(
412
,
util
.
DynMap
{
"status"
:
"name-exists"
,
"message"
:
err
.
Error
()})
}
if
err
==
m
.
ErrDashboardVersionMismatch
{
return
J
son
(
412
,
util
.
DynMap
{
"status"
:
"version-mismatch"
,
"message"
:
err
.
Error
()})
return
J
SON
(
412
,
util
.
DynMap
{
"status"
:
"version-mismatch"
,
"message"
:
err
.
Error
()})
}
if
pluginErr
,
ok
:=
err
.
(
m
.
UpdatePluginDashboardError
);
ok
{
message
:=
"The dashboard belongs to plugin "
+
pluginErr
.
PluginId
+
"."
...
...
@@ -253,20 +253,20 @@ func PostDashboard(c *m.ReqContext, cmd m.SaveDashboardCommand) Response {
if
pluginDef
,
exist
:=
plugins
.
Plugins
[
pluginErr
.
PluginId
];
exist
{
message
=
"The dashboard belongs to plugin "
+
pluginDef
.
Name
+
"."
}
return
J
son
(
412
,
util
.
DynMap
{
"status"
:
"plugin-dashboard"
,
"message"
:
message
})
return
J
SON
(
412
,
util
.
DynMap
{
"status"
:
"plugin-dashboard"
,
"message"
:
message
})
}
if
err
==
m
.
ErrDashboardNotFound
{
return
J
son
(
404
,
util
.
DynMap
{
"status"
:
"not-found"
,
"message"
:
err
.
Error
()})
return
J
SON
(
404
,
util
.
DynMap
{
"status"
:
"not-found"
,
"message"
:
err
.
Error
()})
}
return
Api
Error
(
500
,
"Failed to save dashboard"
,
err
)
return
Error
(
500
,
"Failed to save dashboard"
,
err
)
}
if
err
==
m
.
ErrDashboardFailedToUpdateAlertData
{
return
Api
Error
(
500
,
"Invalid alert data. Cannot save dashboard"
,
err
)
return
Error
(
500
,
"Invalid alert data. Cannot save dashboard"
,
err
)
}
c
.
TimeRequest
(
metrics
.
M_Api_Dashboard_Save
)
return
J
son
(
200
,
util
.
DynMap
{
return
J
SON
(
200
,
util
.
DynMap
{
"status"
:
"success"
,
"slug"
:
dashboard
.
Slug
,
"version"
:
dashboard
.
Version
,
...
...
@@ -279,7 +279,7 @@ func PostDashboard(c *m.ReqContext, cmd m.SaveDashboardCommand) Response {
func
GetHomeDashboard
(
c
*
m
.
ReqContext
)
Response
{
prefsQuery
:=
m
.
GetPreferencesWithDefaultsQuery
{
OrgId
:
c
.
OrgId
,
UserId
:
c
.
UserId
}
if
err
:=
bus
.
Dispatch
(
&
prefsQuery
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to get preferences"
,
err
)
return
Error
(
500
,
"Failed to get preferences"
,
err
)
}
if
prefsQuery
.
Result
.
HomeDashboardId
!=
0
{
...
...
@@ -288,7 +288,7 @@ func GetHomeDashboard(c *m.ReqContext) Response {
if
err
==
nil
{
url
:=
m
.
GetDashboardUrl
(
slugQuery
.
Result
.
Uid
,
slugQuery
.
Result
.
Slug
)
dashRedirect
:=
dtos
.
DashboardRedirect
{
RedirectUri
:
url
}
return
J
son
(
200
,
&
dashRedirect
)
return
J
SON
(
200
,
&
dashRedirect
)
}
log
.
Warn
(
"Failed to get slug from database, %s"
,
err
.
Error
())
}
...
...
@@ -296,7 +296,7 @@ func GetHomeDashboard(c *m.ReqContext) Response {
filePath
:=
path
.
Join
(
setting
.
StaticRootPath
,
"dashboards/home.json"
)
file
,
err
:=
os
.
Open
(
filePath
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to load home dashboard"
,
err
)
return
Error
(
500
,
"Failed to load home dashboard"
,
err
)
}
dash
:=
dtos
.
DashboardFullWithMeta
{}
...
...
@@ -306,14 +306,14 @@ func GetHomeDashboard(c *m.ReqContext) Response {
jsonParser
:=
json
.
NewDecoder
(
file
)
if
err
:=
jsonParser
.
Decode
(
&
dash
.
Dashboard
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to load home dashboard"
,
err
)
return
Error
(
500
,
"Failed to load home dashboard"
,
err
)
}
if
c
.
HasUserRole
(
m
.
ROLE_ADMIN
)
&&
!
c
.
HasHelpFlag
(
m
.
HelpFlagGettingStartedPanelDismissed
)
{
addGettingStartedPanelToHomeDashboard
(
dash
.
Dashboard
)
}
return
J
son
(
200
,
&
dash
)
return
J
SON
(
200
,
&
dash
)
}
func
addGettingStartedPanelToHomeDashboard
(
dash
*
simplejson
.
Json
)
{
...
...
@@ -351,7 +351,7 @@ func GetDashboardVersions(c *m.ReqContext) Response {
}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
Api
Error
(
404
,
fmt
.
Sprintf
(
"No versions found for dashboardId %d"
,
dashID
),
err
)
return
Error
(
404
,
fmt
.
Sprintf
(
"No versions found for dashboardId %d"
,
dashID
),
err
)
}
for
_
,
version
:=
range
query
.
Result
{
...
...
@@ -370,7 +370,7 @@ func GetDashboardVersions(c *m.ReqContext) Response {
}
}
return
J
son
(
200
,
query
.
Result
)
return
J
SON
(
200
,
query
.
Result
)
}
// GetDashboardVersion returns the dashboard version with the given ID.
...
...
@@ -389,7 +389,7 @@ func GetDashboardVersion(c *m.ReqContext) Response {
}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
Api
Error
(
500
,
fmt
.
Sprintf
(
"Dashboard version %d not found for dashboardId %d"
,
query
.
Version
,
dashID
),
err
)
return
Error
(
500
,
fmt
.
Sprintf
(
"Dashboard version %d not found for dashboardId %d"
,
query
.
Version
,
dashID
),
err
)
}
creator
:=
"Anonymous"
...
...
@@ -402,7 +402,7 @@ func GetDashboardVersion(c *m.ReqContext) Response {
CreatedBy
:
creator
,
}
return
J
son
(
200
,
dashVersionMeta
)
return
J
SON
(
200
,
dashVersionMeta
)
}
// POST /api/dashboards/calculate-diff performs diffs on two dashboards
...
...
@@ -438,9 +438,9 @@ func CalculateDashboardDiff(c *m.ReqContext, apiOptions dtos.CalculateDiffOption
result
,
err
:=
dashdiffs
.
CalculateDiff
(
&
options
)
if
err
!=
nil
{
if
err
==
m
.
ErrDashboardVersionNotFound
{
return
Api
Error
(
404
,
"Dashboard version not found"
,
err
)
return
Error
(
404
,
"Dashboard version not found"
,
err
)
}
return
Api
Error
(
500
,
"Unable to compute diff"
,
err
)
return
Error
(
500
,
"Unable to compute diff"
,
err
)
}
if
options
.
DiffType
==
dashdiffs
.
DiffDelta
{
...
...
@@ -464,7 +464,7 @@ func RestoreDashboardVersion(c *m.ReqContext, apiCmd dtos.RestoreDashboardVersio
versionQuery
:=
m
.
GetDashboardVersionQuery
{
DashboardId
:
dash
.
Id
,
Version
:
apiCmd
.
Version
,
OrgId
:
c
.
OrgId
}
if
err
:=
bus
.
Dispatch
(
&
versionQuery
);
err
!=
nil
{
return
Api
Error
(
404
,
"Dashboard version not found"
,
nil
)
return
Error
(
404
,
"Dashboard version not found"
,
nil
)
}
version
:=
versionQuery
.
Result
...
...
pkg/api/dashboard_permission.go
View file @
8d7fa644
...
...
@@ -25,7 +25,7 @@ func GetDashboardPermissionList(c *m.ReqContext) Response {
acl
,
err
:=
g
.
GetAcl
()
if
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to get dashboard permissions"
,
err
)
return
Error
(
500
,
"Failed to get dashboard permissions"
,
err
)
}
for
_
,
perm
:=
range
acl
{
...
...
@@ -34,7 +34,7 @@ func GetDashboardPermissionList(c *m.ReqContext) Response {
}
}
return
J
son
(
200
,
acl
)
return
J
SON
(
200
,
acl
)
}
func
UpdateDashboardPermissions
(
c
*
m
.
ReqContext
,
apiCmd
dtos
.
UpdateDashboardAclCommand
)
Response
{
...
...
@@ -70,21 +70,21 @@ func UpdateDashboardPermissions(c *m.ReqContext, apiCmd dtos.UpdateDashboardAclC
if
err
!=
nil
{
if
err
==
guardian
.
ErrGuardianPermissionExists
||
err
==
guardian
.
ErrGuardianOverride
{
return
Api
Error
(
400
,
err
.
Error
(),
err
)
return
Error
(
400
,
err
.
Error
(),
err
)
}
return
Api
Error
(
500
,
"Error while checking dashboard permissions"
,
err
)
return
Error
(
500
,
"Error while checking dashboard permissions"
,
err
)
}
return
Api
Error
(
403
,
"Cannot remove own admin permission for a folder"
,
nil
)
return
Error
(
403
,
"Cannot remove own admin permission for a folder"
,
nil
)
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
if
err
==
m
.
ErrDashboardAclInfoMissing
||
err
==
m
.
ErrDashboardPermissionDashboardEmpty
{
return
Api
Error
(
409
,
err
.
Error
(),
err
)
return
Error
(
409
,
err
.
Error
(),
err
)
}
return
Api
Error
(
500
,
"Failed to create permission"
,
err
)
return
Error
(
500
,
"Failed to create permission"
,
err
)
}
return
Api
Success
(
"Dashboard permissions updated"
)
return
Success
(
"Dashboard permissions updated"
)
}
pkg/api/dashboard_snapshot.go
View file @
8d7fa644
...
...
@@ -99,11 +99,11 @@ func DeleteDashboardSnapshot(c *m.ReqContext) Response {
err
:=
bus
.
Dispatch
(
query
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to get dashboard snapshot"
,
err
)
return
Error
(
500
,
"Failed to get dashboard snapshot"
,
err
)
}
if
query
.
Result
==
nil
{
return
Api
Error
(
404
,
"Failed to get dashboard snapshot"
,
nil
)
return
Error
(
404
,
"Failed to get dashboard snapshot"
,
nil
)
}
dashboard
:=
query
.
Result
.
Dashboard
dashboardID
:=
dashboard
.
Get
(
"id"
)
.
MustInt64
()
...
...
@@ -111,20 +111,20 @@ func DeleteDashboardSnapshot(c *m.ReqContext) Response {
guardian
:=
guardian
.
New
(
dashboardID
,
c
.
OrgId
,
c
.
SignedInUser
)
canEdit
,
err
:=
guardian
.
CanEdit
()
if
err
!=
nil
{
return
Api
Error
(
500
,
"Error while checking permissions for snapshot"
,
err
)
return
Error
(
500
,
"Error while checking permissions for snapshot"
,
err
)
}
if
!
canEdit
&&
query
.
Result
.
UserId
!=
c
.
SignedInUser
.
UserId
{
return
Api
Error
(
403
,
"Access denied to this snapshot"
,
nil
)
return
Error
(
403
,
"Access denied to this snapshot"
,
nil
)
}
cmd
:=
&
m
.
DeleteDashboardSnapshotCommand
{
DeleteKey
:
key
}
if
err
:=
bus
.
Dispatch
(
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to delete dashboard snapshot"
,
err
)
return
Error
(
500
,
"Failed to delete dashboard snapshot"
,
err
)
}
return
J
son
(
200
,
util
.
DynMap
{
"message"
:
"Snapshot deleted. It might take an hour before it's cleared from a CDN cache."
})
return
J
SON
(
200
,
util
.
DynMap
{
"message"
:
"Snapshot deleted. It might take an hour before it's cleared from a CDN cache."
})
}
// GET /api/dashboard/snapshots
...
...
@@ -145,7 +145,7 @@ func SearchDashboardSnapshots(c *m.ReqContext) Response {
err
:=
bus
.
Dispatch
(
&
searchQuery
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"Search failed"
,
err
)
return
Error
(
500
,
"Search failed"
,
err
)
}
dtos
:=
make
([]
*
m
.
DashboardSnapshotDTO
,
len
(
searchQuery
.
Result
))
...
...
@@ -165,5 +165,5 @@ func SearchDashboardSnapshots(c *m.ReqContext) Response {
}
}
return
J
son
(
200
,
dtos
)
return
J
SON
(
200
,
dtos
)
}
pkg/api/dashboard_test.go
View file @
8d7fa644
...
...
@@ -638,7 +638,7 @@ func TestDashboardApiEndpoint(t *testing.T) {
Convey
(
"Should result in 412 Precondition failed"
,
func
()
{
So
(
sc
.
resp
.
Code
,
ShouldEqual
,
412
)
result
:=
sc
.
ToJ
son
()
result
:=
sc
.
ToJ
SON
()
So
(
result
.
Get
(
"status"
)
.
MustString
(),
ShouldEqual
,
"multiple-slugs-exists"
)
So
(
result
.
Get
(
"message"
)
.
MustString
(),
ShouldEqual
,
m
.
ErrDashboardsWithSameSlugExists
.
Error
())
})
...
...
@@ -686,7 +686,7 @@ func TestDashboardApiEndpoint(t *testing.T) {
})
Convey
(
"It should return correct response data"
,
func
()
{
result
:=
sc
.
ToJ
son
()
result
:=
sc
.
ToJ
SON
()
So
(
result
.
Get
(
"status"
)
.
MustString
(),
ShouldEqual
,
"success"
)
So
(
result
.
Get
(
"id"
)
.
MustInt64
(),
ShouldEqual
,
2
)
So
(
result
.
Get
(
"uid"
)
.
MustString
(),
ShouldEqual
,
"uid"
)
...
...
@@ -903,7 +903,7 @@ func postDiffScenario(desc string, url string, routePattern string, cmd dtos.Cal
})
}
func
(
sc
*
scenarioContext
)
ToJ
son
()
*
simplejson
.
Json
{
func
(
sc
*
scenarioContext
)
ToJ
SON
()
*
simplejson
.
Json
{
var
result
*
simplejson
.
Json
err
:=
json
.
NewDecoder
(
sc
.
resp
.
Body
)
.
Decode
(
&
result
)
So
(
err
,
ShouldBeNil
)
...
...
pkg/api/dataproxy.go
View file @
8d7fa644
...
...
@@ -13,7 +13,7 @@ import (
const
HeaderNameNoBackendCache
=
"X-Grafana-NoCache"
func
(
hs
*
H
ttp
Server
)
getDatasourceByID
(
id
int64
,
orgID
int64
,
nocache
bool
)
(
*
m
.
DataSource
,
error
)
{
func
(
hs
*
H
TTP
Server
)
getDatasourceByID
(
id
int64
,
orgID
int64
,
nocache
bool
)
(
*
m
.
DataSource
,
error
)
{
cacheKey
:=
fmt
.
Sprintf
(
"ds-%d"
,
id
)
if
!
nocache
{
...
...
@@ -34,7 +34,7 @@ func (hs *HttpServer) getDatasourceByID(id int64, orgID int64, nocache bool) (*m
return
query
.
Result
,
nil
}
func
(
hs
*
H
ttp
Server
)
ProxyDataSourceRequest
(
c
*
m
.
ReqContext
)
{
func
(
hs
*
H
TTP
Server
)
ProxyDataSourceRequest
(
c
*
m
.
ReqContext
)
{
c
.
TimeRequest
(
metrics
.
M_DataSource_ProxyReq_Timer
)
nocache
:=
c
.
Req
.
Header
.
Get
(
HeaderNameNoBackendCache
)
==
"true"
...
...
pkg/api/datasources.go
View file @
8d7fa644
...
...
@@ -14,7 +14,7 @@ func GetDataSources(c *m.ReqContext) Response {
query
:=
m
.
GetDataSourcesQuery
{
OrgId
:
c
.
OrgId
}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to query datasources"
,
err
)
return
Error
(
500
,
"Failed to query datasources"
,
err
)
}
result
:=
make
(
dtos
.
DataSourceList
,
0
)
...
...
@@ -46,7 +46,7 @@ func GetDataSources(c *m.ReqContext) Response {
sort
.
Sort
(
result
)
return
J
son
(
200
,
&
result
)
return
J
SON
(
200
,
&
result
)
}
func
GetDataSourceByID
(
c
*
m
.
ReqContext
)
Response
{
...
...
@@ -57,66 +57,66 @@ func GetDataSourceByID(c *m.ReqContext) Response {
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
if
err
==
m
.
ErrDataSourceNotFound
{
return
Api
Error
(
404
,
"Data source not found"
,
nil
)
return
Error
(
404
,
"Data source not found"
,
nil
)
}
return
Api
Error
(
500
,
"Failed to query datasources"
,
err
)
return
Error
(
500
,
"Failed to query datasources"
,
err
)
}
ds
:=
query
.
Result
dtos
:=
convertModelToDtos
(
ds
)
return
J
son
(
200
,
&
dtos
)
return
J
SON
(
200
,
&
dtos
)
}
func
DeleteDataSourceByID
(
c
*
m
.
ReqContext
)
Response
{
id
:=
c
.
ParamsInt64
(
":id"
)
if
id
<=
0
{
return
Api
Error
(
400
,
"Missing valid datasource id"
,
nil
)
return
Error
(
400
,
"Missing valid datasource id"
,
nil
)
}
ds
,
err
:=
getRawDataSourceByID
(
id
,
c
.
OrgId
)
if
err
!=
nil
{
return
Api
Error
(
400
,
"Failed to delete datasource"
,
nil
)
return
Error
(
400
,
"Failed to delete datasource"
,
nil
)
}
if
ds
.
ReadOnly
{
return
Api
Error
(
403
,
"Cannot delete read-only data source"
,
nil
)
return
Error
(
403
,
"Cannot delete read-only data source"
,
nil
)
}
cmd
:=
&
m
.
DeleteDataSourceByIdCommand
{
Id
:
id
,
OrgId
:
c
.
OrgId
}
err
=
bus
.
Dispatch
(
cmd
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to delete datasource"
,
err
)
return
Error
(
500
,
"Failed to delete datasource"
,
err
)
}
return
Api
Success
(
"Data source deleted"
)
return
Success
(
"Data source deleted"
)
}
func
DeleteDataSourceByName
(
c
*
m
.
ReqContext
)
Response
{
name
:=
c
.
Params
(
":name"
)
if
name
==
""
{
return
Api
Error
(
400
,
"Missing valid datasource name"
,
nil
)
return
Error
(
400
,
"Missing valid datasource name"
,
nil
)
}
getCmd
:=
&
m
.
GetDataSourceByNameQuery
{
Name
:
name
,
OrgId
:
c
.
OrgId
}
if
err
:=
bus
.
Dispatch
(
getCmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to delete datasource"
,
err
)
return
Error
(
500
,
"Failed to delete datasource"
,
err
)
}
if
getCmd
.
Result
.
ReadOnly
{
return
Api
Error
(
403
,
"Cannot delete read-only data source"
,
nil
)
return
Error
(
403
,
"Cannot delete read-only data source"
,
nil
)
}
cmd
:=
&
m
.
DeleteDataSourceByNameCommand
{
Name
:
name
,
OrgId
:
c
.
OrgId
}
err
:=
bus
.
Dispatch
(
cmd
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to delete datasource"
,
err
)
return
Error
(
500
,
"Failed to delete datasource"
,
err
)
}
return
Api
Success
(
"Data source deleted"
)
return
Success
(
"Data source deleted"
)
}
func
AddDataSource
(
c
*
m
.
ReqContext
,
cmd
m
.
AddDataSourceCommand
)
Response
{
...
...
@@ -124,14 +124,14 @@ func AddDataSource(c *m.ReqContext, cmd m.AddDataSourceCommand) Response {
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
if
err
==
m
.
ErrDataSourceNameExists
{
return
Api
Error
(
409
,
err
.
Error
(),
err
)
return
Error
(
409
,
err
.
Error
(),
err
)
}
return
Api
Error
(
500
,
"Failed to add datasource"
,
err
)
return
Error
(
500
,
"Failed to add datasource"
,
err
)
}
ds
:=
convertModelToDtos
(
cmd
.
Result
)
return
J
son
(
200
,
util
.
DynMap
{
return
J
SON
(
200
,
util
.
DynMap
{
"message"
:
"Datasource added"
,
"id"
:
cmd
.
Result
.
Id
,
"name"
:
cmd
.
Result
.
Name
,
...
...
@@ -145,18 +145,18 @@ func UpdateDataSource(c *m.ReqContext, cmd m.UpdateDataSourceCommand) Response {
err
:=
fillWithSecureJSONData
(
&
cmd
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to update datasource"
,
err
)
return
Error
(
500
,
"Failed to update datasource"
,
err
)
}
err
=
bus
.
Dispatch
(
&
cmd
)
if
err
!=
nil
{
if
err
==
m
.
ErrDataSourceUpdatingOldVersion
{
return
Api
Error
(
500
,
"Failed to update datasource. Reload new version and try again"
,
err
)
return
Error
(
500
,
"Failed to update datasource. Reload new version and try again"
,
err
)
}
return
Api
Error
(
500
,
"Failed to update datasource"
,
err
)
return
Error
(
500
,
"Failed to update datasource"
,
err
)
}
ds
:=
convertModelToDtos
(
cmd
.
Result
)
return
J
son
(
200
,
util
.
DynMap
{
return
J
SON
(
200
,
util
.
DynMap
{
"message"
:
"Datasource updated"
,
"id"
:
cmd
.
Id
,
"name"
:
cmd
.
Name
,
...
...
@@ -208,14 +208,14 @@ func GetDataSourceByName(c *m.ReqContext) Response {
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
if
err
==
m
.
ErrDataSourceNotFound
{
return
Api
Error
(
404
,
"Data source not found"
,
nil
)
return
Error
(
404
,
"Data source not found"
,
nil
)
}
return
Api
Error
(
500
,
"Failed to query datasources"
,
err
)
return
Error
(
500
,
"Failed to query datasources"
,
err
)
}
dtos
:=
convertModelToDtos
(
query
.
Result
)
dtos
.
ReadOnly
=
true
return
J
son
(
200
,
&
dtos
)
return
J
SON
(
200
,
&
dtos
)
}
// Get /api/datasources/id/:name
...
...
@@ -224,9 +224,9 @@ func GetDataSourceIDByName(c *m.ReqContext) Response {
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
if
err
==
m
.
ErrDataSourceNotFound
{
return
Api
Error
(
404
,
"Data source not found"
,
nil
)
return
Error
(
404
,
"Data source not found"
,
nil
)
}
return
Api
Error
(
500
,
"Failed to query datasources"
,
err
)
return
Error
(
500
,
"Failed to query datasources"
,
err
)
}
ds
:=
query
.
Result
...
...
@@ -234,7 +234,7 @@ func GetDataSourceIDByName(c *m.ReqContext) Response {
Id
:
ds
.
Id
,
}
return
J
son
(
200
,
&
dtos
)
return
J
SON
(
200
,
&
dtos
)
}
func
convertModelToDtos
(
ds
*
m
.
DataSource
)
dtos
.
DataSource
{
...
...
pkg/api/dtos/prefs.go
View file @
8d7fa644
...
...
@@ -2,12 +2,12 @@ package dtos
type
Prefs
struct
{
Theme
string
`json:"theme"`
HomeDashboardI
d
int64
`json:"homeDashboardId"`
HomeDashboardI
D
int64
`json:"homeDashboardId"`
Timezone
string
`json:"timezone"`
}
type
UpdatePrefsCmd
struct
{
Theme
string
`json:"theme"`
HomeDashboardI
d
int64
`json:"homeDashboardId"`
HomeDashboardI
D
int64
`json:"homeDashboardId"`
Timezone
string
`json:"timezone"`
}
pkg/api/folder.go
View file @
8d7fa644
...
...
@@ -28,30 +28,30 @@ func GetFolders(c *m.ReqContext) Response {
})
}
return
J
son
(
200
,
result
)
return
J
SON
(
200
,
result
)
}
func
GetFolderByUID
(
c
*
m
.
ReqContext
)
Response
{
s
:=
dashboards
.
NewFolderService
(
c
.
OrgId
,
c
.
SignedInUser
)
folder
,
err
:=
s
.
GetFolderByU
id
(
c
.
Params
(
":uid"
))
folder
,
err
:=
s
.
GetFolderByU
ID
(
c
.
Params
(
":uid"
))
if
err
!=
nil
{
return
toFolderError
(
err
)
}
g
:=
guardian
.
New
(
folder
.
Id
,
c
.
OrgId
,
c
.
SignedInUser
)
return
J
son
(
200
,
toFolderDto
(
g
,
folder
))
return
J
SON
(
200
,
toFolderDto
(
g
,
folder
))
}
func
GetFolderByID
(
c
*
m
.
ReqContext
)
Response
{
s
:=
dashboards
.
NewFolderService
(
c
.
OrgId
,
c
.
SignedInUser
)
folder
,
err
:=
s
.
GetFolderByI
d
(
c
.
ParamsInt64
(
":id"
))
folder
,
err
:=
s
.
GetFolderByI
D
(
c
.
ParamsInt64
(
":id"
))
if
err
!=
nil
{
return
toFolderError
(
err
)
}
g
:=
guardian
.
New
(
folder
.
Id
,
c
.
OrgId
,
c
.
SignedInUser
)
return
J
son
(
200
,
toFolderDto
(
g
,
folder
))
return
J
SON
(
200
,
toFolderDto
(
g
,
folder
))
}
func
CreateFolder
(
c
*
m
.
ReqContext
,
cmd
m
.
CreateFolderCommand
)
Response
{
...
...
@@ -62,7 +62,7 @@ func CreateFolder(c *m.ReqContext, cmd m.CreateFolderCommand) Response {
}
g
:=
guardian
.
New
(
cmd
.
Result
.
Id
,
c
.
OrgId
,
c
.
SignedInUser
)
return
J
son
(
200
,
toFolderDto
(
g
,
cmd
.
Result
))
return
J
SON
(
200
,
toFolderDto
(
g
,
cmd
.
Result
))
}
func
UpdateFolder
(
c
*
m
.
ReqContext
,
cmd
m
.
UpdateFolderCommand
)
Response
{
...
...
@@ -73,7 +73,7 @@ func UpdateFolder(c *m.ReqContext, cmd m.UpdateFolderCommand) Response {
}
g
:=
guardian
.
New
(
cmd
.
Result
.
Id
,
c
.
OrgId
,
c
.
SignedInUser
)
return
J
son
(
200
,
toFolderDto
(
g
,
cmd
.
Result
))
return
J
SON
(
200
,
toFolderDto
(
g
,
cmd
.
Result
))
}
func
DeleteFolder
(
c
*
m
.
ReqContext
)
Response
{
...
...
@@ -83,7 +83,7 @@ func DeleteFolder(c *m.ReqContext) Response {
return
toFolderError
(
err
)
}
return
J
son
(
200
,
util
.
DynMap
{
return
J
SON
(
200
,
util
.
DynMap
{
"title"
:
f
.
Title
,
"message"
:
fmt
.
Sprintf
(
"Folder %s deleted"
,
f
.
Title
),
})
...
...
@@ -127,20 +127,20 @@ func toFolderError(err error) Response {
err
==
m
.
ErrDashboardTypeMismatch
||
err
==
m
.
ErrDashboardInvalidUid
||
err
==
m
.
ErrDashboardUidToLong
{
return
Api
Error
(
400
,
err
.
Error
(),
nil
)
return
Error
(
400
,
err
.
Error
(),
nil
)
}
if
err
==
m
.
ErrFolderAccessDenied
{
return
Api
Error
(
403
,
"Access denied"
,
err
)
return
Error
(
403
,
"Access denied"
,
err
)
}
if
err
==
m
.
ErrFolderNotFound
{
return
J
son
(
404
,
util
.
DynMap
{
"status"
:
"not-found"
,
"message"
:
m
.
ErrFolderNotFound
.
Error
()})
return
J
SON
(
404
,
util
.
DynMap
{
"status"
:
"not-found"
,
"message"
:
m
.
ErrFolderNotFound
.
Error
()})
}
if
err
==
m
.
ErrFolderVersionMismatch
{
return
J
son
(
412
,
util
.
DynMap
{
"status"
:
"version-mismatch"
,
"message"
:
m
.
ErrFolderVersionMismatch
.
Error
()})
return
J
SON
(
412
,
util
.
DynMap
{
"status"
:
"version-mismatch"
,
"message"
:
m
.
ErrFolderVersionMismatch
.
Error
()})
}
return
Api
Error
(
500
,
"Folder API error"
,
err
)
return
Error
(
500
,
"Folder API error"
,
err
)
}
pkg/api/folder_permission.go
View file @
8d7fa644
...
...
@@ -12,7 +12,7 @@ import (
func
GetFolderPermissionList
(
c
*
m
.
ReqContext
)
Response
{
s
:=
dashboards
.
NewFolderService
(
c
.
OrgId
,
c
.
SignedInUser
)
folder
,
err
:=
s
.
GetFolderByU
id
(
c
.
Params
(
":uid"
))
folder
,
err
:=
s
.
GetFolderByU
ID
(
c
.
Params
(
":uid"
))
if
err
!=
nil
{
return
toFolderError
(
err
)
...
...
@@ -26,7 +26,7 @@ func GetFolderPermissionList(c *m.ReqContext) Response {
acl
,
err
:=
g
.
GetAcl
()
if
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to get folder permissions"
,
err
)
return
Error
(
500
,
"Failed to get folder permissions"
,
err
)
}
for
_
,
perm
:=
range
acl
{
...
...
@@ -38,12 +38,12 @@ func GetFolderPermissionList(c *m.ReqContext) Response {
}
}
return
J
son
(
200
,
acl
)
return
J
SON
(
200
,
acl
)
}
func
UpdateFolderPermissions
(
c
*
m
.
ReqContext
,
apiCmd
dtos
.
UpdateDashboardAclCommand
)
Response
{
s
:=
dashboards
.
NewFolderService
(
c
.
OrgId
,
c
.
SignedInUser
)
folder
,
err
:=
s
.
GetFolderByU
id
(
c
.
Params
(
":uid"
))
folder
,
err
:=
s
.
GetFolderByU
ID
(
c
.
Params
(
":uid"
))
if
err
!=
nil
{
return
toFolderError
(
err
)
...
...
@@ -79,13 +79,13 @@ func UpdateFolderPermissions(c *m.ReqContext, apiCmd dtos.UpdateDashboardAclComm
if
err
!=
nil
{
if
err
==
guardian
.
ErrGuardianPermissionExists
||
err
==
guardian
.
ErrGuardianOverride
{
return
Api
Error
(
400
,
err
.
Error
(),
err
)
return
Error
(
400
,
err
.
Error
(),
err
)
}
return
Api
Error
(
500
,
"Error while checking folder permissions"
,
err
)
return
Error
(
500
,
"Error while checking folder permissions"
,
err
)
}
return
Api
Error
(
403
,
"Cannot remove own admin permission for a folder"
,
nil
)
return
Error
(
403
,
"Cannot remove own admin permission for a folder"
,
nil
)
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
...
...
@@ -97,11 +97,11 @@ func UpdateFolderPermissions(c *m.ReqContext, apiCmd dtos.UpdateDashboardAclComm
}
if
err
==
m
.
ErrFolderAclInfoMissing
||
err
==
m
.
ErrFolderPermissionFolderEmpty
{
return
Api
Error
(
409
,
err
.
Error
(),
err
)
return
Error
(
409
,
err
.
Error
(),
err
)
}
return
Api
Error
(
500
,
"Failed to create permission"
,
err
)
return
Error
(
500
,
"Failed to create permission"
,
err
)
}
return
Api
Success
(
"Folder permissions updated"
)
return
Success
(
"Folder permissions updated"
)
}
pkg/api/folder_permission_test.go
View file @
8d7fa644
...
...
@@ -17,7 +17,7 @@ func TestFolderPermissionApiEndpoint(t *testing.T) {
Convey
(
"Folder permissions test"
,
t
,
func
()
{
Convey
(
"Given folder not exists"
,
func
()
{
mock
:=
&
fakeFolderService
{
GetFolderByU
id
Error
:
m
.
ErrFolderNotFound
,
GetFolderByU
ID
Error
:
m
.
ErrFolderNotFound
,
}
origNewFolderService
:=
dashboards
.
NewFolderService
...
...
@@ -49,7 +49,7 @@ func TestFolderPermissionApiEndpoint(t *testing.T) {
guardian
.
MockDashboardGuardian
(
&
guardian
.
FakeDashboardGuardian
{
CanAdminValue
:
false
})
mock
:=
&
fakeFolderService
{
GetFolderByU
id
Result
:
&
m
.
Folder
{
GetFolderByU
ID
Result
:
&
m
.
Folder
{
Id
:
1
,
Uid
:
"uid"
,
Title
:
"Folder"
,
...
...
@@ -96,7 +96,7 @@ func TestFolderPermissionApiEndpoint(t *testing.T) {
})
mock
:=
&
fakeFolderService
{
GetFolderByU
id
Result
:
&
m
.
Folder
{
GetFolderByU
ID
Result
:
&
m
.
Folder
{
Id
:
1
,
Uid
:
"uid"
,
Title
:
"Folder"
,
...
...
@@ -142,7 +142,7 @@ func TestFolderPermissionApiEndpoint(t *testing.T) {
})
mock
:=
&
fakeFolderService
{
GetFolderByU
id
Result
:
&
m
.
Folder
{
GetFolderByU
ID
Result
:
&
m
.
Folder
{
Id
:
1
,
Uid
:
"uid"
,
Title
:
"Folder"
,
...
...
@@ -178,7 +178,7 @@ func TestFolderPermissionApiEndpoint(t *testing.T) {
)
mock
:=
&
fakeFolderService
{
GetFolderByU
id
Result
:
&
m
.
Folder
{
GetFolderByU
ID
Result
:
&
m
.
Folder
{
Id
:
1
,
Uid
:
"uid"
,
Title
:
"Folder"
,
...
...
pkg/api/folder_test.go
View file @
8d7fa644
...
...
@@ -204,10 +204,10 @@ func updateFolderScenario(desc string, url string, routePattern string, mock *fa
type
fakeFolderService
struct
{
GetFoldersResult
[]
*
m
.
Folder
GetFoldersError
error
GetFolderByU
id
Result
*
m
.
Folder
GetFolderByU
id
Error
error
GetFolderByI
d
Result
*
m
.
Folder
GetFolderByI
d
Error
error
GetFolderByU
ID
Result
*
m
.
Folder
GetFolderByU
ID
Error
error
GetFolderByI
D
Result
*
m
.
Folder
GetFolderByI
D
Error
error
CreateFolderResult
*
m
.
Folder
CreateFolderError
error
UpdateFolderResult
*
m
.
Folder
...
...
@@ -221,12 +221,12 @@ func (s *fakeFolderService) GetFolders(limit int) ([]*m.Folder, error) {
return
s
.
GetFoldersResult
,
s
.
GetFoldersError
}
func
(
s
*
fakeFolderService
)
GetFolderByI
d
(
id
int64
)
(
*
m
.
Folder
,
error
)
{
return
s
.
GetFolderByI
dResult
,
s
.
GetFolderById
Error
func
(
s
*
fakeFolderService
)
GetFolderByI
D
(
id
int64
)
(
*
m
.
Folder
,
error
)
{
return
s
.
GetFolderByI
DResult
,
s
.
GetFolderByID
Error
}
func
(
s
*
fakeFolderService
)
GetFolderByU
id
(
uid
string
)
(
*
m
.
Folder
,
error
)
{
return
s
.
GetFolderByU
idResult
,
s
.
GetFolderByUid
Error
func
(
s
*
fakeFolderService
)
GetFolderByU
ID
(
uid
string
)
(
*
m
.
Folder
,
error
)
{
return
s
.
GetFolderByU
IDResult
,
s
.
GetFolderByUID
Error
}
func
(
s
*
fakeFolderService
)
CreateFolder
(
cmd
*
m
.
CreateFolderCommand
)
error
{
...
...
@@ -234,7 +234,7 @@ func (s *fakeFolderService) CreateFolder(cmd *m.CreateFolderCommand) error {
return
s
.
CreateFolderError
}
func
(
s
*
fakeFolderService
)
UpdateFolder
(
existingU
id
string
,
cmd
*
m
.
UpdateFolderCommand
)
error
{
func
(
s
*
fakeFolderService
)
UpdateFolder
(
existingU
ID
string
,
cmd
*
m
.
UpdateFolderCommand
)
error
{
cmd
.
Result
=
s
.
UpdateFolderResult
return
s
.
UpdateFolderError
}
...
...
pkg/api/http_server.go
View file @
8d7fa644
...
...
@@ -29,7 +29,7 @@ import (
"github.com/grafana/grafana/pkg/setting"
)
type
H
ttp
Server
struct
{
type
H
TTP
Server
struct
{
log
log
.
Logger
macaron
*
macaron
.
Macaron
context
context
.
Context
...
...
@@ -39,14 +39,14 @@ type HttpServer struct {
httpSrv
*
http
.
Server
}
func
NewHTTPServer
()
*
H
ttp
Server
{
return
&
H
ttp
Server
{
func
NewHTTPServer
()
*
H
TTP
Server
{
return
&
H
TTP
Server
{
log
:
log
.
New
(
"http.server"
),
cache
:
gocache
.
New
(
5
*
time
.
Minute
,
10
*
time
.
Minute
),
}
}
func
(
hs
*
H
ttp
Server
)
Start
(
ctx
context
.
Context
)
error
{
func
(
hs
*
H
TTP
Server
)
Start
(
ctx
context
.
Context
)
error
{
var
err
error
hs
.
context
=
ctx
...
...
@@ -93,13 +93,13 @@ func (hs *HttpServer) Start(ctx context.Context) error {
return
err
}
func
(
hs
*
H
ttp
Server
)
Shutdown
(
ctx
context
.
Context
)
error
{
func
(
hs
*
H
TTP
Server
)
Shutdown
(
ctx
context
.
Context
)
error
{
err
:=
hs
.
httpSrv
.
Shutdown
(
ctx
)
hs
.
log
.
Info
(
"Stopped HTTP server"
)
return
err
}
func
(
hs
*
H
ttp
Server
)
listenAndServeTLS
(
certfile
,
keyfile
string
)
error
{
func
(
hs
*
H
TTP
Server
)
listenAndServeTLS
(
certfile
,
keyfile
string
)
error
{
if
certfile
==
""
{
return
fmt
.
Errorf
(
"cert_file cannot be empty when using HTTPS"
)
}
...
...
@@ -141,7 +141,7 @@ func (hs *HttpServer) listenAndServeTLS(certfile, keyfile string) error {
return
hs
.
httpSrv
.
ListenAndServeTLS
(
setting
.
CertFile
,
setting
.
KeyFile
)
}
func
(
hs
*
H
ttp
Server
)
newMacaron
()
*
macaron
.
Macaron
{
func
(
hs
*
H
TTP
Server
)
newMacaron
()
*
macaron
.
Macaron
{
macaron
.
Env
=
setting
.
Env
m
:=
macaron
.
New
()
...
...
@@ -188,7 +188,7 @@ func (hs *HttpServer) newMacaron() *macaron.Macaron {
return
m
}
func
(
hs
*
H
ttp
Server
)
metricsEndpoint
(
ctx
*
macaron
.
Context
)
{
func
(
hs
*
H
TTP
Server
)
metricsEndpoint
(
ctx
*
macaron
.
Context
)
{
if
ctx
.
Req
.
Method
!=
"GET"
||
ctx
.
Req
.
URL
.
Path
!=
"/metrics"
{
return
}
...
...
@@ -197,7 +197,7 @@ func (hs *HttpServer) metricsEndpoint(ctx *macaron.Context) {
ServeHTTP
(
ctx
.
Resp
,
ctx
.
Req
.
Request
)
}
func
(
hs
*
H
ttp
Server
)
healthHandler
(
ctx
*
macaron
.
Context
)
{
func
(
hs
*
H
TTP
Server
)
healthHandler
(
ctx
*
macaron
.
Context
)
{
notHeadOrGet
:=
ctx
.
Req
.
Method
!=
http
.
MethodGet
&&
ctx
.
Req
.
Method
!=
http
.
MethodHead
if
notHeadOrGet
||
ctx
.
Req
.
URL
.
Path
!=
"/api/health"
{
return
...
...
@@ -221,7 +221,7 @@ func (hs *HttpServer) healthHandler(ctx *macaron.Context) {
ctx
.
Resp
.
Write
(
dataBytes
)
}
func
(
hs
*
H
ttp
Server
)
mapStatic
(
m
*
macaron
.
Macaron
,
rootDir
string
,
dir
string
,
prefix
string
)
{
func
(
hs
*
H
TTP
Server
)
mapStatic
(
m
*
macaron
.
Macaron
,
rootDir
string
,
dir
string
,
prefix
string
)
{
headers
:=
func
(
c
*
macaron
.
Context
)
{
c
.
Resp
.
Header
()
.
Set
(
"Cache-Control"
,
"public, max-age=3600"
)
}
...
...
pkg/api/login.go
View file @
8d7fa644
...
...
@@ -98,7 +98,7 @@ func LoginAPIPing(c *m.ReqContext) {
func
LoginPost
(
c
*
m
.
ReqContext
,
cmd
dtos
.
LoginCommand
)
Response
{
if
setting
.
DisableLoginForm
{
return
Api
Error
(
401
,
"Login is disabled"
,
nil
)
return
Error
(
401
,
"Login is disabled"
,
nil
)
}
authQuery
:=
login
.
LoginUserQuery
{
...
...
@@ -109,10 +109,10 @@ func LoginPost(c *m.ReqContext, cmd dtos.LoginCommand) Response {
if
err
:=
bus
.
Dispatch
(
&
authQuery
);
err
!=
nil
{
if
err
==
login
.
ErrInvalidCredentials
||
err
==
login
.
ErrTooManyLoginAttempts
{
return
Api
Error
(
401
,
"Invalid username or password"
,
err
)
return
Error
(
401
,
"Invalid username or password"
,
err
)
}
return
Api
Error
(
500
,
"Error while trying to authenticate user"
,
err
)
return
Error
(
500
,
"Error while trying to authenticate user"
,
err
)
}
user
:=
authQuery
.
User
...
...
@@ -130,7 +130,7 @@ func LoginPost(c *m.ReqContext, cmd dtos.LoginCommand) Response {
metrics
.
M_Api_Login_Post
.
Inc
()
return
J
son
(
200
,
result
)
return
J
SON
(
200
,
result
)
}
func
loginUserWithUser
(
user
*
m
.
User
,
c
*
m
.
ReqContext
)
{
...
...
pkg/api/metrics.go
View file @
8d7fa644
...
...
@@ -17,17 +17,17 @@ func QueryMetrics(c *m.ReqContext, reqDto dtos.MetricRequest) Response {
timeRange
:=
tsdb
.
NewTimeRange
(
reqDto
.
From
,
reqDto
.
To
)
if
len
(
reqDto
.
Queries
)
==
0
{
return
Api
Error
(
400
,
"No queries found in query"
,
nil
)
return
Error
(
400
,
"No queries found in query"
,
nil
)
}
dsID
,
err
:=
reqDto
.
Queries
[
0
]
.
Get
(
"datasourceId"
)
.
Int64
()
if
err
!=
nil
{
return
Api
Error
(
400
,
"Query missing datasourceId"
,
nil
)
return
Error
(
400
,
"Query missing datasourceId"
,
nil
)
}
dsQuery
:=
m
.
GetDataSourceByIdQuery
{
Id
:
dsID
,
OrgId
:
c
.
OrgId
}
if
err
:=
bus
.
Dispatch
(
&
dsQuery
);
err
!=
nil
{
return
Api
Error
(
500
,
"failed to fetch data source"
,
err
)
return
Error
(
500
,
"failed to fetch data source"
,
err
)
}
request
:=
&
tsdb
.
TsdbQuery
{
TimeRange
:
timeRange
}
...
...
@@ -44,7 +44,7 @@ func QueryMetrics(c *m.ReqContext, reqDto dtos.MetricRequest) Response {
resp
,
err
:=
tsdb
.
HandleRequest
(
context
.
Background
(),
dsQuery
.
Result
,
request
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"Metric request error"
,
err
)
return
Error
(
500
,
"Metric request error"
,
err
)
}
statusCode
:=
200
...
...
@@ -56,7 +56,7 @@ func QueryMetrics(c *m.ReqContext, reqDto dtos.MetricRequest) Response {
}
}
return
J
son
(
statusCode
,
&
resp
)
return
J
SON
(
statusCode
,
&
resp
)
}
// GET /api/tsdb/testdata/scenarios
...
...
@@ -72,22 +72,22 @@ func GetTestDataScenarios(c *m.ReqContext) Response {
})
}
return
J
son
(
200
,
&
result
)
return
J
SON
(
200
,
&
result
)
}
// Genereates a index out of range error
func
GenerateError
(
c
*
m
.
ReqContext
)
Response
{
var
array
[]
string
return
J
son
(
200
,
array
[
20
])
return
J
SON
(
200
,
array
[
20
])
}
// GET /api/tsdb/testdata/gensql
func
GenerateSQLTestData
(
c
*
m
.
ReqContext
)
Response
{
if
err
:=
bus
.
Dispatch
(
&
m
.
InsertSqlTestDataCommand
{});
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to insert test data"
,
err
)
return
Error
(
500
,
"Failed to insert test data"
,
err
)
}
return
J
son
(
200
,
&
util
.
DynMap
{
"message"
:
"OK"
})
return
J
SON
(
200
,
&
util
.
DynMap
{
"message"
:
"OK"
})
}
// GET /api/tsdb/testdata/random-walk
...
...
@@ -111,8 +111,8 @@ func GetTestDataRandomWalk(c *m.ReqContext) Response {
resp
,
err
:=
tsdb
.
HandleRequest
(
context
.
Background
(),
dsInfo
,
request
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"Metric request error"
,
err
)
return
Error
(
500
,
"Metric request error"
,
err
)
}
return
J
son
(
200
,
&
resp
)
return
J
SON
(
200
,
&
resp
)
}
pkg/api/org.go
View file @
8d7fa644
...
...
@@ -24,10 +24,10 @@ func GetOrgByName(c *m.ReqContext) Response {
query
:=
m
.
GetOrgByNameQuery
{
Name
:
c
.
Params
(
":name"
)}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
if
err
==
m
.
ErrOrgNotFound
{
return
Api
Error
(
404
,
"Organization not found"
,
err
)
return
Error
(
404
,
"Organization not found"
,
err
)
}
return
Api
Error
(
500
,
"Failed to get organization"
,
err
)
return
Error
(
500
,
"Failed to get organization"
,
err
)
}
org
:=
query
.
Result
result
:=
m
.
OrgDetailsDTO
{
...
...
@@ -43,18 +43,18 @@ func GetOrgByName(c *m.ReqContext) Response {
},
}
return
J
son
(
200
,
&
result
)
return
J
SON
(
200
,
&
result
)
}
func
getOrgHelper
(
orgI
d
int64
)
Response
{
query
:=
m
.
GetOrgByIdQuery
{
Id
:
orgI
d
}
func
getOrgHelper
(
orgI
D
int64
)
Response
{
query
:=
m
.
GetOrgByIdQuery
{
Id
:
orgI
D
}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
if
err
==
m
.
ErrOrgNotFound
{
return
Api
Error
(
404
,
"Organization not found"
,
err
)
return
Error
(
404
,
"Organization not found"
,
err
)
}
return
Api
Error
(
500
,
"Failed to get organization"
,
err
)
return
Error
(
500
,
"Failed to get organization"
,
err
)
}
org
:=
query
.
Result
...
...
@@ -71,26 +71,26 @@ func getOrgHelper(orgId int64) Response {
},
}
return
J
son
(
200
,
&
result
)
return
J
SON
(
200
,
&
result
)
}
// POST /api/orgs
func
CreateOrg
(
c
*
m
.
ReqContext
,
cmd
m
.
CreateOrgCommand
)
Response
{
if
!
c
.
IsSignedIn
||
(
!
setting
.
AllowUserOrgCreate
&&
!
c
.
IsGrafanaAdmin
)
{
return
Api
Error
(
403
,
"Access denied"
,
nil
)
return
Error
(
403
,
"Access denied"
,
nil
)
}
cmd
.
UserId
=
c
.
UserId
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
if
err
==
m
.
ErrOrgNameTaken
{
return
Api
Error
(
409
,
"Organization name taken"
,
err
)
return
Error
(
409
,
"Organization name taken"
,
err
)
}
return
Api
Error
(
500
,
"Failed to create organization"
,
err
)
return
Error
(
500
,
"Failed to create organization"
,
err
)
}
metrics
.
M_Api_Org_Create
.
Inc
()
return
J
son
(
200
,
&
util
.
DynMap
{
return
J
SON
(
200
,
&
util
.
DynMap
{
"orgId"
:
cmd
.
Result
.
Id
,
"message"
:
"Organization created"
,
})
...
...
@@ -110,12 +110,12 @@ func updateOrgHelper(form dtos.UpdateOrgForm, orgID int64) Response {
cmd
:=
m
.
UpdateOrgCommand
{
Name
:
form
.
Name
,
OrgId
:
orgID
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
if
err
==
m
.
ErrOrgNameTaken
{
return
Api
Error
(
400
,
"Organization name taken"
,
err
)
return
Error
(
400
,
"Organization name taken"
,
err
)
}
return
Api
Error
(
500
,
"Failed to update organization"
,
err
)
return
Error
(
500
,
"Failed to update organization"
,
err
)
}
return
Api
Success
(
"Organization updated"
)
return
Success
(
"Organization updated"
)
}
// PUT /api/org/address
...
...
@@ -142,21 +142,21 @@ func updateOrgAddressHelper(form dtos.UpdateOrgAddressForm, orgID int64) Respons
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to update org address"
,
err
)
return
Error
(
500
,
"Failed to update org address"
,
err
)
}
return
Api
Success
(
"Address updated"
)
return
Success
(
"Address updated"
)
}
// GET /api/orgs/:orgId
func
DeleteOrgByID
(
c
*
m
.
ReqContext
)
Response
{
if
err
:=
bus
.
Dispatch
(
&
m
.
DeleteOrgCommand
{
Id
:
c
.
ParamsInt64
(
":orgId"
)});
err
!=
nil
{
if
err
==
m
.
ErrOrgNotFound
{
return
Api
Error
(
404
,
"Failed to delete organization. ID not found"
,
nil
)
return
Error
(
404
,
"Failed to delete organization. ID not found"
,
nil
)
}
return
Api
Error
(
500
,
"Failed to update organization"
,
err
)
return
Error
(
500
,
"Failed to update organization"
,
err
)
}
return
Api
Success
(
"Organization deleted"
)
return
Success
(
"Organization deleted"
)
}
func
SearchOrgs
(
c
*
m
.
ReqContext
)
Response
{
...
...
@@ -168,8 +168,8 @@ func SearchOrgs(c *m.ReqContext) Response {
}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to search orgs"
,
err
)
return
Error
(
500
,
"Failed to search orgs"
,
err
)
}
return
J
son
(
200
,
query
.
Result
)
return
J
SON
(
200
,
query
.
Result
)
}
pkg/api/org_invite.go
View file @
8d7fa644
...
...
@@ -16,30 +16,30 @@ func GetPendingOrgInvites(c *m.ReqContext) Response {
query
:=
m
.
GetTempUsersQuery
{
OrgId
:
c
.
OrgId
,
Status
:
m
.
TmpUserInvitePending
}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to get invites from db"
,
err
)
return
Error
(
500
,
"Failed to get invites from db"
,
err
)
}
for
_
,
invite
:=
range
query
.
Result
{
invite
.
Url
=
setting
.
ToAbsUrl
(
"invite/"
+
invite
.
Code
)
}
return
J
son
(
200
,
query
.
Result
)
return
J
SON
(
200
,
query
.
Result
)
}
func
AddOrgInvite
(
c
*
m
.
ReqContext
,
inviteDto
dtos
.
AddInviteForm
)
Response
{
if
!
inviteDto
.
Role
.
IsValid
()
{
return
Api
Error
(
400
,
"Invalid role specified"
,
nil
)
return
Error
(
400
,
"Invalid role specified"
,
nil
)
}
// first try get existing user
userQuery
:=
m
.
GetUserByLoginQuery
{
LoginOrEmail
:
inviteDto
.
LoginOrEmail
}
if
err
:=
bus
.
Dispatch
(
&
userQuery
);
err
!=
nil
{
if
err
!=
m
.
ErrUserNotFound
{
return
Api
Error
(
500
,
"Failed to query db for existing user check"
,
err
)
return
Error
(
500
,
"Failed to query db for existing user check"
,
err
)
}
if
setting
.
DisableLoginForm
{
return
Api
Error
(
401
,
"User could not be found"
,
nil
)
return
Error
(
401
,
"User could not be found"
,
nil
)
}
}
else
{
return
inviteExistingUserToOrg
(
c
,
userQuery
.
Result
,
&
inviteDto
)
...
...
@@ -56,7 +56,7 @@ func AddOrgInvite(c *m.ReqContext, inviteDto dtos.AddInviteForm) Response {
cmd
.
RemoteAddr
=
c
.
Req
.
RemoteAddr
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to save invite to database"
,
err
)
return
Error
(
500
,
"Failed to save invite to database"
,
err
)
}
// send invite email
...
...
@@ -74,18 +74,18 @@ func AddOrgInvite(c *m.ReqContext, inviteDto dtos.AddInviteForm) Response {
}
if
err
:=
bus
.
Dispatch
(
&
emailCmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to send email invite"
,
err
)
return
Error
(
500
,
"Failed to send email invite"
,
err
)
}
emailSentCmd
:=
m
.
UpdateTempUserWithEmailSentCommand
{
Code
:
cmd
.
Result
.
Code
}
if
err
:=
bus
.
Dispatch
(
&
emailSentCmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to update invite with email sent info"
,
err
)
return
Error
(
500
,
"Failed to update invite with email sent info"
,
err
)
}
return
Api
Success
(
fmt
.
Sprintf
(
"Sent invite to %s"
,
inviteDto
.
LoginOrEmail
))
return
Success
(
fmt
.
Sprintf
(
"Sent invite to %s"
,
inviteDto
.
LoginOrEmail
))
}
return
Api
Success
(
fmt
.
Sprintf
(
"Created invite for %s"
,
inviteDto
.
LoginOrEmail
))
return
Success
(
fmt
.
Sprintf
(
"Created invite for %s"
,
inviteDto
.
LoginOrEmail
))
}
func
inviteExistingUserToOrg
(
c
*
m
.
ReqContext
,
user
*
m
.
User
,
inviteDto
*
dtos
.
AddInviteForm
)
Response
{
...
...
@@ -93,9 +93,9 @@ func inviteExistingUserToOrg(c *m.ReqContext, user *m.User, inviteDto *dtos.AddI
createOrgUserCmd
:=
m
.
AddOrgUserCommand
{
OrgId
:
c
.
OrgId
,
UserId
:
user
.
Id
,
Role
:
inviteDto
.
Role
}
if
err
:=
bus
.
Dispatch
(
&
createOrgUserCmd
);
err
!=
nil
{
if
err
==
m
.
ErrOrgUserAlreadyAdded
{
return
Api
Error
(
412
,
fmt
.
Sprintf
(
"User %s is already added to organization"
,
inviteDto
.
LoginOrEmail
),
err
)
return
Error
(
412
,
fmt
.
Sprintf
(
"User %s is already added to organization"
,
inviteDto
.
LoginOrEmail
),
err
)
}
return
Api
Error
(
500
,
"Error while trying to create org user"
,
err
)
return
Error
(
500
,
"Error while trying to create org user"
,
err
)
}
if
inviteDto
.
SendEmail
&&
util
.
IsEmail
(
user
.
Email
)
{
...
...
@@ -110,11 +110,11 @@ func inviteExistingUserToOrg(c *m.ReqContext, user *m.User, inviteDto *dtos.AddI
}
if
err
:=
bus
.
Dispatch
(
&
emailCmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to send email invited_to_org"
,
err
)
return
Error
(
500
,
"Failed to send email invited_to_org"
,
err
)
}
}
return
Api
Success
(
fmt
.
Sprintf
(
"Existing Grafana user %s added to org %s"
,
user
.
NameOrFallback
(),
c
.
OrgName
))
return
Success
(
fmt
.
Sprintf
(
"Existing Grafana user %s added to org %s"
,
user
.
NameOrFallback
(),
c
.
OrgName
))
}
func
RevokeInvite
(
c
*
m
.
ReqContext
)
Response
{
...
...
@@ -122,7 +122,7 @@ func RevokeInvite(c *m.ReqContext) Response {
return
rsp
}
return
Api
Success
(
"Invite revoked"
)
return
Success
(
"Invite revoked"
)
}
func
GetInviteInfoByCode
(
c
*
m
.
ReqContext
)
Response
{
...
...
@@ -130,14 +130,14 @@ func GetInviteInfoByCode(c *m.ReqContext) Response {
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
if
err
==
m
.
ErrTempUserNotFound
{
return
Api
Error
(
404
,
"Invite not found"
,
nil
)
return
Error
(
404
,
"Invite not found"
,
nil
)
}
return
Api
Error
(
500
,
"Failed to get invite"
,
err
)
return
Error
(
500
,
"Failed to get invite"
,
err
)
}
invite
:=
query
.
Result
return
J
son
(
200
,
dtos
.
InviteInfo
{
return
J
SON
(
200
,
dtos
.
InviteInfo
{
Email
:
invite
.
Email
,
Name
:
invite
.
Name
,
Username
:
invite
.
Email
,
...
...
@@ -150,14 +150,14 @@ func CompleteInvite(c *m.ReqContext, completeInvite dtos.CompleteInviteForm) Res
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
if
err
==
m
.
ErrTempUserNotFound
{
return
Api
Error
(
404
,
"Invite not found"
,
nil
)
return
Error
(
404
,
"Invite not found"
,
nil
)
}
return
Api
Error
(
500
,
"Failed to get invite"
,
err
)
return
Error
(
500
,
"Failed to get invite"
,
err
)
}
invite
:=
query
.
Result
if
invite
.
Status
!=
m
.
TmpUserInvitePending
{
return
Api
Error
(
412
,
fmt
.
Sprintf
(
"Invite cannot be used in status %s"
,
invite
.
Status
),
nil
)
return
Error
(
412
,
fmt
.
Sprintf
(
"Invite cannot be used in status %s"
,
invite
.
Status
),
nil
)
}
cmd
:=
m
.
CreateUserCommand
{
...
...
@@ -169,7 +169,7 @@ func CompleteInvite(c *m.ReqContext, completeInvite dtos.CompleteInviteForm) Res
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"failed to create user"
,
err
)
return
Error
(
500
,
"failed to create user"
,
err
)
}
user
:=
&
cmd
.
Result
...
...
@@ -188,14 +188,14 @@ func CompleteInvite(c *m.ReqContext, completeInvite dtos.CompleteInviteForm) Res
metrics
.
M_Api_User_SignUpCompleted
.
Inc
()
metrics
.
M_Api_User_SignUpInvite
.
Inc
()
return
Api
Success
(
"User created and logged in"
)
return
Success
(
"User created and logged in"
)
}
func
updateTempUserStatus
(
code
string
,
status
m
.
TempUserStatus
)
(
bool
,
Response
)
{
// update temp user status
updateTmpUserCmd
:=
m
.
UpdateTempUserStatusCommand
{
Code
:
code
,
Status
:
status
}
if
err
:=
bus
.
Dispatch
(
&
updateTmpUserCmd
);
err
!=
nil
{
return
false
,
Api
Error
(
500
,
"Failed to update invite status"
,
err
)
return
false
,
Error
(
500
,
"Failed to update invite status"
,
err
)
}
return
true
,
nil
...
...
@@ -206,7 +206,7 @@ func applyUserInvite(user *m.User, invite *m.TempUserDTO, setActive bool) (bool,
addOrgUserCmd
:=
m
.
AddOrgUserCommand
{
OrgId
:
invite
.
OrgId
,
UserId
:
user
.
Id
,
Role
:
invite
.
Role
}
if
err
:=
bus
.
Dispatch
(
&
addOrgUserCmd
);
err
!=
nil
{
if
err
!=
m
.
ErrOrgUserAlreadyAdded
{
return
false
,
Api
Error
(
500
,
"Error while trying to create org user"
,
err
)
return
false
,
Error
(
500
,
"Error while trying to create org user"
,
err
)
}
}
...
...
@@ -218,7 +218,7 @@ func applyUserInvite(user *m.User, invite *m.TempUserDTO, setActive bool) (bool,
if
setActive
{
// set org to active
if
err
:=
bus
.
Dispatch
(
&
m
.
SetUsingOrgCommand
{
OrgId
:
invite
.
OrgId
,
UserId
:
user
.
Id
});
err
!=
nil
{
return
false
,
Api
Error
(
500
,
"Failed to set org as active"
,
err
)
return
false
,
Error
(
500
,
"Failed to set org as active"
,
err
)
}
}
...
...
pkg/api/org_users.go
View file @
8d7fa644
...
...
@@ -20,13 +20,13 @@ func AddOrgUser(c *m.ReqContext, cmd m.AddOrgUserCommand) Response {
func
addOrgUserHelper
(
cmd
m
.
AddOrgUserCommand
)
Response
{
if
!
cmd
.
Role
.
IsValid
()
{
return
Api
Error
(
400
,
"Invalid role specified"
,
nil
)
return
Error
(
400
,
"Invalid role specified"
,
nil
)
}
userQuery
:=
m
.
GetUserByLoginQuery
{
LoginOrEmail
:
cmd
.
LoginOrEmail
}
err
:=
bus
.
Dispatch
(
&
userQuery
)
if
err
!=
nil
{
return
Api
Error
(
404
,
"User not found"
,
nil
)
return
Error
(
404
,
"User not found"
,
nil
)
}
userToAdd
:=
userQuery
.
Result
...
...
@@ -35,12 +35,12 @@ func addOrgUserHelper(cmd m.AddOrgUserCommand) Response {
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
if
err
==
m
.
ErrOrgUserAlreadyAdded
{
return
Api
Error
(
409
,
"User is already member of this organization"
,
nil
)
return
Error
(
409
,
"User is already member of this organization"
,
nil
)
}
return
Api
Error
(
500
,
"Could not add user to organization"
,
err
)
return
Error
(
500
,
"Could not add user to organization"
,
err
)
}
return
Api
Success
(
"User added to organization"
)
return
Success
(
"User added to organization"
)
}
// GET /api/org/users
...
...
@@ -61,14 +61,14 @@ func getOrgUsersHelper(orgID int64, query string, limit int) Response {
}
if
err
:=
bus
.
Dispatch
(
&
q
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to get account user"
,
err
)
return
Error
(
500
,
"Failed to get account user"
,
err
)
}
for
_
,
user
:=
range
q
.
Result
{
user
.
AvatarUrl
=
dtos
.
GetGravatarUrl
(
user
.
Email
)
}
return
J
son
(
200
,
q
.
Result
)
return
J
SON
(
200
,
q
.
Result
)
}
// PATCH /api/org/users/:userId
...
...
@@ -87,17 +87,17 @@ func UpdateOrgUser(c *m.ReqContext, cmd m.UpdateOrgUserCommand) Response {
func
updateOrgUserHelper
(
cmd
m
.
UpdateOrgUserCommand
)
Response
{
if
!
cmd
.
Role
.
IsValid
()
{
return
Api
Error
(
400
,
"Invalid role specified"
,
nil
)
return
Error
(
400
,
"Invalid role specified"
,
nil
)
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
if
err
==
m
.
ErrLastOrgAdmin
{
return
Api
Error
(
400
,
"Cannot change role so that there is no organization admin left"
,
nil
)
return
Error
(
400
,
"Cannot change role so that there is no organization admin left"
,
nil
)
}
return
Api
Error
(
500
,
"Failed update org user"
,
err
)
return
Error
(
500
,
"Failed update org user"
,
err
)
}
return
Api
Success
(
"Organization user updated"
)
return
Success
(
"Organization user updated"
)
}
// DELETE /api/org/users/:userId
...
...
@@ -118,10 +118,10 @@ func removeOrgUserHelper(orgID int64, userID int64) Response {
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
if
err
==
m
.
ErrLastOrgAdmin
{
return
Api
Error
(
400
,
"Cannot remove last organization admin"
,
nil
)
return
Error
(
400
,
"Cannot remove last organization admin"
,
nil
)
}
return
Api
Error
(
500
,
"Failed to remove user from organization"
,
err
)
return
Error
(
500
,
"Failed to remove user from organization"
,
err
)
}
return
Api
Success
(
"User removed from organization"
)
return
Success
(
"User removed from organization"
)
}
pkg/api/password.go
View file @
8d7fa644
...
...
@@ -12,15 +12,15 @@ func SendResetPasswordEmail(c *m.ReqContext, form dtos.SendResetPasswordEmailFor
if
err
:=
bus
.
Dispatch
(
&
userQuery
);
err
!=
nil
{
c
.
Logger
.
Info
(
"Requested password reset for user that was not found"
,
"user"
,
userQuery
.
LoginOrEmail
)
return
Api
Error
(
200
,
"Email sent"
,
err
)
return
Error
(
200
,
"Email sent"
,
err
)
}
emailCmd
:=
m
.
SendResetPasswordEmailCommand
{
User
:
userQuery
.
Result
}
if
err
:=
bus
.
Dispatch
(
&
emailCmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to send email"
,
err
)
return
Error
(
500
,
"Failed to send email"
,
err
)
}
return
Api
Success
(
"Email sent"
)
return
Success
(
"Email sent"
)
}
func
ResetPassword
(
c
*
m
.
ReqContext
,
form
dtos
.
ResetUserPasswordForm
)
Response
{
...
...
@@ -28,13 +28,13 @@ func ResetPassword(c *m.ReqContext, form dtos.ResetUserPasswordForm) Response {
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
if
err
==
m
.
ErrInvalidEmailCode
{
return
Api
Error
(
400
,
"Invalid or expired reset password code"
,
nil
)
return
Error
(
400
,
"Invalid or expired reset password code"
,
nil
)
}
return
Api
Error
(
500
,
"Unknown error validating email code"
,
err
)
return
Error
(
500
,
"Unknown error validating email code"
,
err
)
}
if
form
.
NewPassword
!=
form
.
ConfirmPassword
{
return
Api
Error
(
400
,
"Passwords do not match"
,
nil
)
return
Error
(
400
,
"Passwords do not match"
,
nil
)
}
cmd
:=
m
.
ChangeUserPasswordCommand
{}
...
...
@@ -42,8 +42,8 @@ func ResetPassword(c *m.ReqContext, form dtos.ResetUserPasswordForm) Response {
cmd
.
NewPassword
=
util
.
EncodePassword
(
form
.
NewPassword
,
query
.
Result
.
Salt
)
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to change user password"
,
err
)
return
Error
(
500
,
"Failed to change user password"
,
err
)
}
return
Api
Success
(
"User password changed"
)
return
Success
(
"User password changed"
)
}
pkg/api/playlist.go
View file @
8d7fa644
...
...
@@ -55,10 +55,10 @@ func SearchPlaylists(c *m.ReqContext) Response {
err
:=
bus
.
Dispatch
(
&
searchQuery
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"Search failed"
,
err
)
return
Error
(
500
,
"Search failed"
,
err
)
}
return
J
son
(
200
,
searchQuery
.
Result
)
return
J
SON
(
200
,
searchQuery
.
Result
)
}
func
GetPlaylist
(
c
*
m
.
ReqContext
)
Response
{
...
...
@@ -66,7 +66,7 @@ func GetPlaylist(c *m.ReqContext) Response {
cmd
:=
m
.
GetPlaylistByIdQuery
{
Id
:
id
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Playlist not found"
,
err
)
return
Error
(
500
,
"Playlist not found"
,
err
)
}
playlistDTOs
,
_
:=
LoadPlaylistItemDTOs
(
id
)
...
...
@@ -79,7 +79,7 @@ func GetPlaylist(c *m.ReqContext) Response {
Items
:
playlistDTOs
,
}
return
J
son
(
200
,
dto
)
return
J
SON
(
200
,
dto
)
}
func
LoadPlaylistItemDTOs
(
id
int64
)
([]
m
.
PlaylistItemDTO
,
error
)
{
...
...
@@ -120,10 +120,10 @@ func GetPlaylistItems(c *m.ReqContext) Response {
playlistDTOs
,
err
:=
LoadPlaylistItemDTOs
(
id
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"Could not load playlist items"
,
err
)
return
Error
(
500
,
"Could not load playlist items"
,
err
)
}
return
J
son
(
200
,
playlistDTOs
)
return
J
SON
(
200
,
playlistDTOs
)
}
func
GetPlaylistDashboards
(
c
*
m
.
ReqContext
)
Response
{
...
...
@@ -131,10 +131,10 @@ func GetPlaylistDashboards(c *m.ReqContext) Response {
playlists
,
err
:=
LoadPlaylistDashboards
(
c
.
OrgId
,
c
.
SignedInUser
,
playlistID
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"Could not load dashboards"
,
err
)
return
Error
(
500
,
"Could not load dashboards"
,
err
)
}
return
J
son
(
200
,
playlists
)
return
J
SON
(
200
,
playlists
)
}
func
DeletePlaylist
(
c
*
m
.
ReqContext
)
Response
{
...
...
@@ -142,34 +142,34 @@ func DeletePlaylist(c *m.ReqContext) Response {
cmd
:=
m
.
DeletePlaylistCommand
{
Id
:
id
,
OrgId
:
c
.
OrgId
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to delete playlist"
,
err
)
return
Error
(
500
,
"Failed to delete playlist"
,
err
)
}
return
J
son
(
200
,
""
)
return
J
SON
(
200
,
""
)
}
func
CreatePlaylist
(
c
*
m
.
ReqContext
,
cmd
m
.
CreatePlaylistCommand
)
Response
{
cmd
.
OrgId
=
c
.
OrgId
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to create playlist"
,
err
)
return
Error
(
500
,
"Failed to create playlist"
,
err
)
}
return
J
son
(
200
,
cmd
.
Result
)
return
J
SON
(
200
,
cmd
.
Result
)
}
func
UpdatePlaylist
(
c
*
m
.
ReqContext
,
cmd
m
.
UpdatePlaylistCommand
)
Response
{
cmd
.
OrgId
=
c
.
OrgId
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to save playlist"
,
err
)
return
Error
(
500
,
"Failed to save playlist"
,
err
)
}
playlistDTOs
,
err
:=
LoadPlaylistItemDTOs
(
cmd
.
Id
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to save playlist"
,
err
)
return
Error
(
500
,
"Failed to save playlist"
,
err
)
}
cmd
.
Result
.
Items
=
playlistDTOs
return
J
son
(
200
,
cmd
.
Result
)
return
J
SON
(
200
,
cmd
.
Result
)
}
pkg/api/playlist_play.go
View file @
8d7fa644
...
...
@@ -11,11 +11,11 @@ import (
"github.com/grafana/grafana/pkg/services/search"
)
func
populateDashboardsByI
d
(
dashboardByIds
[]
int64
,
dashboardId
Order
map
[
int64
]
int
)
(
dtos
.
PlaylistDashboardsSlice
,
error
)
{
func
populateDashboardsByI
D
(
dashboardByIDs
[]
int64
,
dashboardID
Order
map
[
int64
]
int
)
(
dtos
.
PlaylistDashboardsSlice
,
error
)
{
result
:=
make
(
dtos
.
PlaylistDashboardsSlice
,
0
)
if
len
(
dashboardByI
d
s
)
>
0
{
dashboardQuery
:=
m
.
GetDashboardsQuery
{
DashboardIds
:
dashboardByI
d
s
}
if
len
(
dashboardByI
D
s
)
>
0
{
dashboardQuery
:=
m
.
GetDashboardsQuery
{
DashboardIds
:
dashboardByI
D
s
}
if
err
:=
bus
.
Dispatch
(
&
dashboardQuery
);
err
!=
nil
{
return
result
,
err
}
...
...
@@ -26,7 +26,7 @@ func populateDashboardsById(dashboardByIds []int64, dashboardIdOrder map[int64]i
Slug
:
item
.
Slug
,
Title
:
item
.
Title
,
Uri
:
"db/"
+
item
.
Slug
,
Order
:
dashboardI
d
Order
[
item
.
Id
],
Order
:
dashboardI
D
Order
[
item
.
Id
],
})
}
}
...
...
@@ -85,7 +85,7 @@ func LoadPlaylistDashboards(orgID int64, signedInUser *m.SignedInUser, playlistI
result
:=
make
(
dtos
.
PlaylistDashboardsSlice
,
0
)
var
k
,
_
=
populateDashboardsByI
d
(
dashboardByIDs
,
dashboardIDOrder
)
var
k
,
_
=
populateDashboardsByI
D
(
dashboardByIDs
,
dashboardIDOrder
)
result
=
append
(
result
,
k
...
)
result
=
append
(
result
,
populateDashboardsByTag
(
orgID
,
signedInUser
,
dashboardByTag
,
dashboardTagOrder
)
...
)
...
...
pkg/api/pluginproxy/ds_proxy.go
View file @
8d7fa644
...
...
@@ -25,8 +25,8 @@ import (
)
var
(
logger
log
.
Logger
=
log
.
New
(
"data-proxy-log"
)
client
*
http
.
Client
=
&
http
.
Client
{
logger
=
log
.
New
(
"data-proxy-log"
)
client
=
&
http
.
Client
{
Timeout
:
time
.
Second
*
30
,
Transport
:
&
http
.
Transport
{
Proxy
:
http
.
ProxyFromEnvironment
},
}
...
...
@@ -49,14 +49,14 @@ type DataSourceProxy struct {
}
func
NewDataSourceProxy
(
ds
*
m
.
DataSource
,
plugin
*
plugins
.
DataSourcePlugin
,
ctx
*
m
.
ReqContext
,
proxyPath
string
)
*
DataSourceProxy
{
targetU
rl
,
_
:=
url
.
Parse
(
ds
.
Url
)
targetU
RL
,
_
:=
url
.
Parse
(
ds
.
Url
)
return
&
DataSourceProxy
{
ds
:
ds
,
plugin
:
plugin
,
ctx
:
ctx
,
proxyPath
:
proxyPath
,
targetUrl
:
targetU
rl
,
targetUrl
:
targetU
RL
,
}
}
...
...
@@ -279,16 +279,16 @@ func (proxy *DataSourceProxy) applyRoute(req *http.Request) {
SecureJsonData
:
proxy
.
ds
.
SecureJsonData
.
Decrypt
(),
}
routeU
rl
,
err
:=
url
.
Parse
(
proxy
.
route
.
Url
)
routeU
RL
,
err
:=
url
.
Parse
(
proxy
.
route
.
Url
)
if
err
!=
nil
{
logger
.
Error
(
"Error parsing plugin route url"
)
return
}
req
.
URL
.
Scheme
=
routeU
rl
.
Scheme
req
.
URL
.
Host
=
routeU
rl
.
Host
req
.
Host
=
routeU
rl
.
Host
req
.
URL
.
Path
=
util
.
JoinUrlFragments
(
routeU
rl
.
Path
,
proxy
.
proxyPath
)
req
.
URL
.
Scheme
=
routeU
RL
.
Scheme
req
.
URL
.
Host
=
routeU
RL
.
Host
req
.
Host
=
routeU
RL
.
Host
req
.
URL
.
Path
=
util
.
JoinUrlFragments
(
routeU
RL
.
Path
,
proxy
.
proxyPath
)
if
err
:=
addHeaders
(
&
req
.
Header
,
proxy
.
route
,
data
);
err
!=
nil
{
logger
.
Error
(
"Failed to render plugin headers"
,
"error"
,
err
)
...
...
@@ -320,11 +320,11 @@ func (proxy *DataSourceProxy) getAccessToken(data templateData) (string, error)
params
:=
make
(
url
.
Values
)
for
key
,
value
:=
range
proxy
.
route
.
TokenAuth
.
Params
{
if
interpolatedParam
,
err
:=
interpolateString
(
value
,
data
);
err
!=
nil
{
interpolatedParam
,
err
:=
interpolateString
(
value
,
data
)
if
err
!=
nil
{
return
""
,
err
}
else
{
params
.
Add
(
key
,
interpolatedParam
)
}
params
.
Add
(
key
,
interpolatedParam
)
}
getTokenReq
,
_
:=
http
.
NewRequest
(
"POST"
,
urlInterpolated
,
bytes
.
NewBufferString
(
params
.
Encode
()))
...
...
@@ -354,13 +354,13 @@ func (proxy *DataSourceProxy) getAccessToken(data templateData) (string, error)
func
interpolateString
(
text
string
,
data
templateData
)
(
string
,
error
)
{
t
,
err
:=
template
.
New
(
"content"
)
.
Parse
(
text
)
if
err
!=
nil
{
return
""
,
errors
.
New
(
fmt
.
Sprintf
(
"Could not parse template %s."
,
text
)
)
return
""
,
fmt
.
Errorf
(
"could not parse template %s"
,
text
)
}
var
contentBuf
bytes
.
Buffer
err
=
t
.
Execute
(
&
contentBuf
,
data
)
if
err
!=
nil
{
return
""
,
errors
.
New
(
fmt
.
Sprintf
(
"Failed to execute template %s."
,
text
)
)
return
""
,
fmt
.
Errorf
(
"failed to execute template %s"
,
text
)
}
return
contentBuf
.
String
(),
nil
...
...
pkg/api/pluginproxy/ds_proxy_test.go
View file @
8d7fa644
...
...
@@ -107,8 +107,8 @@ func TestDSRouteRule(t *testing.T) {
proxy
:=
NewDataSourceProxy
(
ds
,
plugin
,
ctx
,
"/render"
)
requestU
rl
,
_
:=
url
.
Parse
(
"http://grafana.com/sub"
)
req
:=
http
.
Request
{
URL
:
requestU
rl
}
requestU
RL
,
_
:=
url
.
Parse
(
"http://grafana.com/sub"
)
req
:=
http
.
Request
{
URL
:
requestU
RL
}
proxy
.
getDirector
()(
&
req
)
...
...
@@ -132,8 +132,8 @@ func TestDSRouteRule(t *testing.T) {
ctx
:=
&
m
.
ReqContext
{}
proxy
:=
NewDataSourceProxy
(
ds
,
plugin
,
ctx
,
""
)
requestU
rl
,
_
:=
url
.
Parse
(
"http://grafana.com/sub"
)
req
:=
http
.
Request
{
URL
:
requestU
rl
}
requestU
RL
,
_
:=
url
.
Parse
(
"http://grafana.com/sub"
)
req
:=
http
.
Request
{
URL
:
requestU
RL
}
proxy
.
getDirector
()(
&
req
)
...
...
@@ -162,8 +162,8 @@ func TestDSRouteRule(t *testing.T) {
ctx
:=
&
m
.
ReqContext
{}
proxy
:=
NewDataSourceProxy
(
ds
,
plugin
,
ctx
,
""
)
requestU
rl
,
_
:=
url
.
Parse
(
"http://grafana.com/sub"
)
req
:=
http
.
Request
{
URL
:
requestU
rl
,
Header
:
make
(
http
.
Header
)}
requestU
RL
,
_
:=
url
.
Parse
(
"http://grafana.com/sub"
)
req
:=
http
.
Request
{
URL
:
requestU
RL
,
Header
:
make
(
http
.
Header
)}
cookies
:=
"grafana_user=admin; grafana_remember=99; grafana_sess=11; JSESSION_ID=test"
req
.
Header
.
Set
(
"Cookie"
,
cookies
)
...
...
@@ -188,8 +188,8 @@ func TestDSRouteRule(t *testing.T) {
ctx
:=
&
m
.
ReqContext
{}
proxy
:=
NewDataSourceProxy
(
ds
,
plugin
,
ctx
,
""
)
requestU
rl
,
_
:=
url
.
Parse
(
"http://grafana.com/sub"
)
req
:=
http
.
Request
{
URL
:
requestU
rl
,
Header
:
make
(
http
.
Header
)}
requestU
RL
,
_
:=
url
.
Parse
(
"http://grafana.com/sub"
)
req
:=
http
.
Request
{
URL
:
requestU
RL
,
Header
:
make
(
http
.
Header
)}
cookies
:=
"grafana_user=admin; grafana_remember=99; grafana_sess=11; JSESSION_ID=test"
req
.
Header
.
Set
(
"Cookie"
,
cookies
)
...
...
pkg/api/pluginproxy/pluginproxy.go
View file @
8d7fa644
...
...
@@ -19,10 +19,10 @@ type templateData struct {
SecureJsonData
map
[
string
]
string
}
func
getHeaders
(
route
*
plugins
.
AppPluginRoute
,
orgId
int64
,
appI
d
string
)
(
http
.
Header
,
error
)
{
func
getHeaders
(
route
*
plugins
.
AppPluginRoute
,
orgId
int64
,
appI
D
string
)
(
http
.
Header
,
error
)
{
result
:=
http
.
Header
{}
query
:=
m
.
GetPluginSettingByIdQuery
{
OrgId
:
orgId
,
PluginId
:
appI
d
}
query
:=
m
.
GetPluginSettingByIdQuery
{
OrgId
:
orgId
,
PluginId
:
appI
D
}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
nil
,
err
...
...
@@ -37,16 +37,16 @@ func getHeaders(route *plugins.AppPluginRoute, orgId int64, appId string) (http.
return
result
,
err
}
func
NewApiPluginProxy
(
ctx
*
m
.
ReqContext
,
proxyPath
string
,
route
*
plugins
.
AppPluginRoute
,
appI
d
string
)
*
httputil
.
ReverseProxy
{
targetU
rl
,
_
:=
url
.
Parse
(
route
.
Url
)
func
NewApiPluginProxy
(
ctx
*
m
.
ReqContext
,
proxyPath
string
,
route
*
plugins
.
AppPluginRoute
,
appI
D
string
)
*
httputil
.
ReverseProxy
{
targetU
RL
,
_
:=
url
.
Parse
(
route
.
Url
)
director
:=
func
(
req
*
http
.
Request
)
{
req
.
URL
.
Scheme
=
targetU
rl
.
Scheme
req
.
URL
.
Host
=
targetU
rl
.
Host
req
.
Host
=
targetU
rl
.
Host
req
.
URL
.
Scheme
=
targetU
RL
.
Scheme
req
.
URL
.
Host
=
targetU
RL
.
Host
req
.
Host
=
targetU
RL
.
Host
req
.
URL
.
Path
=
util
.
JoinUrlFragments
(
targetU
rl
.
Path
,
proxyPath
)
req
.
URL
.
Path
=
util
.
JoinUrlFragments
(
targetU
RL
.
Path
,
proxyPath
)
// clear cookie headers
req
.
Header
.
Del
(
"Cookie"
)
...
...
@@ -80,7 +80,7 @@ func NewApiPluginProxy(ctx *m.ReqContext, proxyPath string, route *plugins.AppPl
req
.
Header
.
Add
(
"X-Grafana-Context"
,
string
(
ctxJson
))
if
len
(
route
.
Headers
)
>
0
{
headers
,
err
:=
getHeaders
(
route
,
ctx
.
OrgId
,
appI
d
)
headers
,
err
:=
getHeaders
(
route
,
ctx
.
OrgId
,
appI
D
)
if
err
!=
nil
{
ctx
.
JsonApiErr
(
500
,
"Could not generate plugin route header"
,
err
)
return
...
...
pkg/api/plugins.go
View file @
8d7fa644
...
...
@@ -19,7 +19,7 @@ func GetPluginList(c *m.ReqContext) Response {
pluginSettingsMap
,
err
:=
plugins
.
GetPluginSettings
(
c
.
OrgId
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to get list of plugins"
,
err
)
return
Error
(
500
,
"Failed to get list of plugins"
,
err
)
}
result
:=
make
(
dtos
.
PluginList
,
0
)
...
...
@@ -75,7 +75,7 @@ func GetPluginList(c *m.ReqContext) Response {
}
sort
.
Sort
(
result
)
return
J
son
(
200
,
result
)
return
J
SON
(
200
,
result
)
}
func
GetPluginSettingByID
(
c
*
m
.
ReqContext
)
Response
{
...
...
@@ -83,7 +83,7 @@ func GetPluginSettingByID(c *m.ReqContext) Response {
def
,
exists
:=
plugins
.
Plugins
[
pluginID
]
if
!
exists
{
return
Api
Error
(
404
,
"Plugin not found, no installed plugin with that id"
,
nil
)
return
Error
(
404
,
"Plugin not found, no installed plugin with that id"
,
nil
)
}
dto
:=
&
dtos
.
PluginSetting
{
...
...
@@ -104,7 +104,7 @@ func GetPluginSettingByID(c *m.ReqContext) Response {
query
:=
m
.
GetPluginSettingByIdQuery
{
PluginId
:
pluginID
,
OrgId
:
c
.
OrgId
}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
if
err
!=
m
.
ErrPluginSettingNotFound
{
return
Api
Error
(
500
,
"Failed to get login settings"
,
nil
)
return
Error
(
500
,
"Failed to get login settings"
,
nil
)
}
}
else
{
dto
.
Enabled
=
query
.
Result
.
Enabled
...
...
@@ -112,7 +112,7 @@ func GetPluginSettingByID(c *m.ReqContext) Response {
dto
.
JsonData
=
query
.
Result
.
JsonData
}
return
J
son
(
200
,
dto
)
return
J
SON
(
200
,
dto
)
}
func
UpdatePluginSetting
(
c
*
m
.
ReqContext
,
cmd
m
.
UpdatePluginSettingCmd
)
Response
{
...
...
@@ -122,14 +122,14 @@ func UpdatePluginSetting(c *m.ReqContext, cmd m.UpdatePluginSettingCmd) Response
cmd
.
PluginId
=
pluginID
if
_
,
ok
:=
plugins
.
Apps
[
cmd
.
PluginId
];
!
ok
{
return
Api
Error
(
404
,
"Plugin not installed."
,
nil
)
return
Error
(
404
,
"Plugin not installed."
,
nil
)
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to update plugin setting"
,
err
)
return
Error
(
500
,
"Failed to update plugin setting"
,
err
)
}
return
Api
Success
(
"Plugin settings updated"
)
return
Success
(
"Plugin settings updated"
)
}
func
GetPluginDashboards
(
c
*
m
.
ReqContext
)
Response
{
...
...
@@ -138,13 +138,13 @@ func GetPluginDashboards(c *m.ReqContext) Response {
list
,
err
:=
plugins
.
GetPluginDashboards
(
c
.
OrgId
,
pluginID
)
if
err
!=
nil
{
if
notfound
,
ok
:=
err
.
(
plugins
.
PluginNotFoundError
);
ok
{
return
Api
Error
(
404
,
notfound
.
Error
(),
nil
)
return
Error
(
404
,
notfound
.
Error
(),
nil
)
}
return
Api
Error
(
500
,
"Failed to get plugin dashboards"
,
err
)
return
Error
(
500
,
"Failed to get plugin dashboards"
,
err
)
}
return
J
son
(
200
,
list
)
return
J
SON
(
200
,
list
)
}
func
GetPluginMarkdown
(
c
*
m
.
ReqContext
)
Response
{
...
...
@@ -154,10 +154,10 @@ func GetPluginMarkdown(c *m.ReqContext) Response {
content
,
err
:=
plugins
.
GetPluginMarkdown
(
pluginID
,
name
)
if
err
!=
nil
{
if
notfound
,
ok
:=
err
.
(
plugins
.
PluginNotFoundError
);
ok
{
return
Api
Error
(
404
,
notfound
.
Error
(),
nil
)
return
Error
(
404
,
notfound
.
Error
(),
nil
)
}
return
Api
Error
(
500
,
"Could not get markdown file"
,
err
)
return
Error
(
500
,
"Could not get markdown file"
,
err
)
}
resp
:=
Respond
(
200
,
content
)
...
...
@@ -178,8 +178,8 @@ func ImportDashboard(c *m.ReqContext, apiCmd dtos.ImportDashboardCommand) Respon
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to import dashboard"
,
err
)
return
Error
(
500
,
"Failed to import dashboard"
,
err
)
}
return
J
son
(
200
,
cmd
.
Result
)
return
J
SON
(
200
,
cmd
.
Result
)
}
pkg/api/preferences.go
View file @
8d7fa644
...
...
@@ -13,10 +13,10 @@ func SetHomeDashboard(c *m.ReqContext, cmd m.SavePreferencesCommand) Response {
cmd
.
OrgId
=
c
.
OrgId
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to set home dashboard"
,
err
)
return
Error
(
500
,
"Failed to set home dashboard"
,
err
)
}
return
Api
Success
(
"Home dashboard set"
)
return
Success
(
"Home dashboard set"
)
}
// GET /api/user/preferences
...
...
@@ -28,16 +28,16 @@ func getPreferencesFor(orgID int64, userID int64) Response {
prefsQuery
:=
m
.
GetPreferencesQuery
{
UserId
:
userID
,
OrgId
:
orgID
}
if
err
:=
bus
.
Dispatch
(
&
prefsQuery
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to get preferences"
,
err
)
return
Error
(
500
,
"Failed to get preferences"
,
err
)
}
dto
:=
dtos
.
Prefs
{
Theme
:
prefsQuery
.
Result
.
Theme
,
HomeDashboardI
d
:
prefsQuery
.
Result
.
HomeDashboardId
,
HomeDashboardI
D
:
prefsQuery
.
Result
.
HomeDashboardId
,
Timezone
:
prefsQuery
.
Result
.
Timezone
,
}
return
J
son
(
200
,
&
dto
)
return
J
SON
(
200
,
&
dto
)
}
// PUT /api/user/preferences
...
...
@@ -51,14 +51,14 @@ func updatePreferencesFor(orgID int64, userID int64, dtoCmd *dtos.UpdatePrefsCmd
OrgId
:
orgID
,
Theme
:
dtoCmd
.
Theme
,
Timezone
:
dtoCmd
.
Timezone
,
HomeDashboardId
:
dtoCmd
.
HomeDashboardI
d
,
HomeDashboardId
:
dtoCmd
.
HomeDashboardI
D
,
}
if
err
:=
bus
.
Dispatch
(
&
saveCmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to save preferences"
,
err
)
return
Error
(
500
,
"Failed to save preferences"
,
err
)
}
return
Api
Success
(
"Preferences updated"
)
return
Success
(
"Preferences updated"
)
}
// GET /api/org/preferences
...
...
pkg/api/quota.go
View file @
8d7fa644
...
...
@@ -8,60 +8,60 @@ import (
func
GetOrgQuotas
(
c
*
m
.
ReqContext
)
Response
{
if
!
setting
.
Quota
.
Enabled
{
return
Api
Error
(
404
,
"Quotas not enabled"
,
nil
)
return
Error
(
404
,
"Quotas not enabled"
,
nil
)
}
query
:=
m
.
GetOrgQuotasQuery
{
OrgId
:
c
.
ParamsInt64
(
":orgId"
)}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to get org quotas"
,
err
)
return
Error
(
500
,
"Failed to get org quotas"
,
err
)
}
return
J
son
(
200
,
query
.
Result
)
return
J
SON
(
200
,
query
.
Result
)
}
func
UpdateOrgQuota
(
c
*
m
.
ReqContext
,
cmd
m
.
UpdateOrgQuotaCmd
)
Response
{
if
!
setting
.
Quota
.
Enabled
{
return
Api
Error
(
404
,
"Quotas not enabled"
,
nil
)
return
Error
(
404
,
"Quotas not enabled"
,
nil
)
}
cmd
.
OrgId
=
c
.
ParamsInt64
(
":orgId"
)
cmd
.
Target
=
c
.
Params
(
":target"
)
if
_
,
ok
:=
setting
.
Quota
.
Org
.
ToMap
()[
cmd
.
Target
];
!
ok
{
return
Api
Error
(
404
,
"Invalid quota target"
,
nil
)
return
Error
(
404
,
"Invalid quota target"
,
nil
)
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to update org quotas"
,
err
)
return
Error
(
500
,
"Failed to update org quotas"
,
err
)
}
return
Api
Success
(
"Organization quota updated"
)
return
Success
(
"Organization quota updated"
)
}
func
GetUserQuotas
(
c
*
m
.
ReqContext
)
Response
{
if
!
setting
.
Quota
.
Enabled
{
return
Api
Error
(
404
,
"Quotas not enabled"
,
nil
)
return
Error
(
404
,
"Quotas not enabled"
,
nil
)
}
query
:=
m
.
GetUserQuotasQuery
{
UserId
:
c
.
ParamsInt64
(
":id"
)}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to get org quotas"
,
err
)
return
Error
(
500
,
"Failed to get org quotas"
,
err
)
}
return
J
son
(
200
,
query
.
Result
)
return
J
SON
(
200
,
query
.
Result
)
}
func
UpdateUserQuota
(
c
*
m
.
ReqContext
,
cmd
m
.
UpdateUserQuotaCmd
)
Response
{
if
!
setting
.
Quota
.
Enabled
{
return
Api
Error
(
404
,
"Quotas not enabled"
,
nil
)
return
Error
(
404
,
"Quotas not enabled"
,
nil
)
}
cmd
.
UserId
=
c
.
ParamsInt64
(
":id"
)
cmd
.
Target
=
c
.
Params
(
":target"
)
if
_
,
ok
:=
setting
.
Quota
.
User
.
ToMap
()[
cmd
.
Target
];
!
ok
{
return
Api
Error
(
404
,
"Invalid quota target"
,
nil
)
return
Error
(
404
,
"Invalid quota target"
,
nil
)
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to update org quotas"
,
err
)
return
Error
(
500
,
"Failed to update org quotas"
,
err
)
}
return
Api
Success
(
"Organization quota updated"
)
return
Success
(
"Organization quota updated"
)
}
pkg/api/signup.go
View file @
8d7fa644
...
...
@@ -12,7 +12,7 @@ import (
// GET /api/user/signup/options
func
GetSignUpOptions
(
c
*
m
.
ReqContext
)
Response
{
return
J
son
(
200
,
util
.
DynMap
{
return
J
SON
(
200
,
util
.
DynMap
{
"verifyEmailEnabled"
:
setting
.
VerifyEmailEnabled
,
"autoAssignOrg"
:
setting
.
AutoAssignOrg
,
})
...
...
@@ -21,12 +21,12 @@ func GetSignUpOptions(c *m.ReqContext) Response {
// POST /api/user/signup
func
SignUp
(
c
*
m
.
ReqContext
,
form
dtos
.
SignUpForm
)
Response
{
if
!
setting
.
AllowUserSignUp
{
return
Api
Error
(
401
,
"User signup is disabled"
,
nil
)
return
Error
(
401
,
"User signup is disabled"
,
nil
)
}
existing
:=
m
.
GetUserByLoginQuery
{
LoginOrEmail
:
form
.
Email
}
if
err
:=
bus
.
Dispatch
(
&
existing
);
err
==
nil
{
return
Api
Error
(
422
,
"User with same email address already exists"
,
nil
)
return
Error
(
422
,
"User with same email address already exists"
,
nil
)
}
cmd
:=
m
.
CreateTempUserCommand
{}
...
...
@@ -38,7 +38,7 @@ func SignUp(c *m.ReqContext, form dtos.SignUpForm) Response {
cmd
.
RemoteAddr
=
c
.
Req
.
RemoteAddr
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to create signup"
,
err
)
return
Error
(
500
,
"Failed to create signup"
,
err
)
}
bus
.
Publish
(
&
events
.
SignUpStarted
{
...
...
@@ -48,12 +48,12 @@ func SignUp(c *m.ReqContext, form dtos.SignUpForm) Response {
metrics
.
M_Api_User_SignUpStarted
.
Inc
()
return
J
son
(
200
,
util
.
DynMap
{
"status"
:
"SignUpCreated"
})
return
J
SON
(
200
,
util
.
DynMap
{
"status"
:
"SignUpCreated"
})
}
func
SignUpStep2
(
c
*
m
.
ReqContext
,
form
dtos
.
SignUpStep2Form
)
Response
{
if
!
setting
.
AllowUserSignUp
{
return
Api
Error
(
401
,
"User signup is disabled"
,
nil
)
return
Error
(
401
,
"User signup is disabled"
,
nil
)
}
createUserCmd
:=
m
.
CreateUserCommand
{
...
...
@@ -75,12 +75,12 @@ func SignUpStep2(c *m.ReqContext, form dtos.SignUpStep2Form) Response {
// check if user exists
existing
:=
m
.
GetUserByLoginQuery
{
LoginOrEmail
:
form
.
Email
}
if
err
:=
bus
.
Dispatch
(
&
existing
);
err
==
nil
{
return
Api
Error
(
401
,
"User with same email address already exists"
,
nil
)
return
Error
(
401
,
"User with same email address already exists"
,
nil
)
}
// dispatch create command
if
err
:=
bus
.
Dispatch
(
&
createUserCmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to create user"
,
err
)
return
Error
(
500
,
"Failed to create user"
,
err
)
}
// publish signup event
...
...
@@ -98,7 +98,7 @@ func SignUpStep2(c *m.ReqContext, form dtos.SignUpStep2Form) Response {
// check for pending invites
invitesQuery
:=
m
.
GetTempUsersQuery
{
Email
:
form
.
Email
,
Status
:
m
.
TmpUserInvitePending
}
if
err
:=
bus
.
Dispatch
(
&
invitesQuery
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to query database for invites"
,
err
)
return
Error
(
500
,
"Failed to query database for invites"
,
err
)
}
apiResponse
:=
util
.
DynMap
{
"message"
:
"User sign up completed successfully"
,
"code"
:
"redirect-to-landing-page"
}
...
...
@@ -112,7 +112,7 @@ func SignUpStep2(c *m.ReqContext, form dtos.SignUpStep2Form) Response {
loginUserWithUser
(
user
,
c
)
metrics
.
M_Api_User_SignUpCompleted
.
Inc
()
return
J
son
(
200
,
apiResponse
)
return
J
SON
(
200
,
apiResponse
)
}
func
verifyUserSignUpEmail
(
email
string
,
code
string
)
(
bool
,
Response
)
{
...
...
@@ -120,14 +120,14 @@ func verifyUserSignUpEmail(email string, code string) (bool, Response) {
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
if
err
==
m
.
ErrTempUserNotFound
{
return
false
,
Api
Error
(
404
,
"Invalid email verification code"
,
nil
)
return
false
,
Error
(
404
,
"Invalid email verification code"
,
nil
)
}
return
false
,
Api
Error
(
500
,
"Failed to read temp user"
,
err
)
return
false
,
Error
(
500
,
"Failed to read temp user"
,
err
)
}
tempUser
:=
query
.
Result
if
tempUser
.
Email
!=
email
{
return
false
,
Api
Error
(
404
,
"Email verification code does not match email"
,
nil
)
return
false
,
Error
(
404
,
"Email verification code does not match email"
,
nil
)
}
return
true
,
nil
...
...
pkg/api/stars.go
View file @
8d7fa644
...
...
@@ -7,20 +7,20 @@ import (
func
StarDashboard
(
c
*
m
.
ReqContext
)
Response
{
if
!
c
.
IsSignedIn
{
return
Api
Error
(
412
,
"You need to sign in to star dashboards"
,
nil
)
return
Error
(
412
,
"You need to sign in to star dashboards"
,
nil
)
}
cmd
:=
m
.
StarDashboardCommand
{
UserId
:
c
.
UserId
,
DashboardId
:
c
.
ParamsInt64
(
":id"
)}
if
cmd
.
DashboardId
<=
0
{
return
Api
Error
(
400
,
"Missing dashboard id"
,
nil
)
return
Error
(
400
,
"Missing dashboard id"
,
nil
)
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to star dashboard"
,
err
)
return
Error
(
500
,
"Failed to star dashboard"
,
err
)
}
return
Api
Success
(
"Dashboard starred!"
)
return
Success
(
"Dashboard starred!"
)
}
func
UnstarDashboard
(
c
*
m
.
ReqContext
)
Response
{
...
...
@@ -28,12 +28,12 @@ func UnstarDashboard(c *m.ReqContext) Response {
cmd
:=
m
.
UnstarDashboardCommand
{
UserId
:
c
.
UserId
,
DashboardId
:
c
.
ParamsInt64
(
":id"
)}
if
cmd
.
DashboardId
<=
0
{
return
Api
Error
(
400
,
"Missing dashboard id"
,
nil
)
return
Error
(
400
,
"Missing dashboard id"
,
nil
)
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to unstar dashboard"
,
err
)
return
Error
(
500
,
"Failed to unstar dashboard"
,
err
)
}
return
Api
Success
(
"Dashboard unstarred"
)
return
Success
(
"Dashboard unstarred"
)
}
pkg/api/team.go
View file @
8d7fa644
...
...
@@ -12,12 +12,12 @@ func CreateTeam(c *m.ReqContext, cmd m.CreateTeamCommand) Response {
cmd
.
OrgId
=
c
.
OrgId
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
if
err
==
m
.
ErrTeamNameTaken
{
return
Api
Error
(
409
,
"Team name taken"
,
err
)
return
Error
(
409
,
"Team name taken"
,
err
)
}
return
Api
Error
(
500
,
"Failed to create Team"
,
err
)
return
Error
(
500
,
"Failed to create Team"
,
err
)
}
return
J
son
(
200
,
&
util
.
DynMap
{
return
J
SON
(
200
,
&
util
.
DynMap
{
"teamId"
:
cmd
.
Result
.
Id
,
"message"
:
"Team created"
,
})
...
...
@@ -29,23 +29,23 @@ func UpdateTeam(c *m.ReqContext, cmd m.UpdateTeamCommand) Response {
cmd
.
Id
=
c
.
ParamsInt64
(
":teamId"
)
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
if
err
==
m
.
ErrTeamNameTaken
{
return
Api
Error
(
400
,
"Team name taken"
,
err
)
return
Error
(
400
,
"Team name taken"
,
err
)
}
return
Api
Error
(
500
,
"Failed to update Team"
,
err
)
return
Error
(
500
,
"Failed to update Team"
,
err
)
}
return
Api
Success
(
"Team updated"
)
return
Success
(
"Team updated"
)
}
// DELETE /api/teams/:teamId
func
DeleteTeamByID
(
c
*
m
.
ReqContext
)
Response
{
if
err
:=
bus
.
Dispatch
(
&
m
.
DeleteTeamCommand
{
OrgId
:
c
.
OrgId
,
Id
:
c
.
ParamsInt64
(
":teamId"
)});
err
!=
nil
{
if
err
==
m
.
ErrTeamNotFound
{
return
Api
Error
(
404
,
"Failed to delete Team. ID not found"
,
nil
)
return
Error
(
404
,
"Failed to delete Team. ID not found"
,
nil
)
}
return
Api
Error
(
500
,
"Failed to update Team"
,
err
)
return
Error
(
500
,
"Failed to update Team"
,
err
)
}
return
Api
Success
(
"Team deleted"
)
return
Success
(
"Team deleted"
)
}
// GET /api/teams/search
...
...
@@ -68,7 +68,7 @@ func SearchTeams(c *m.ReqContext) Response {
}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to search Teams"
,
err
)
return
Error
(
500
,
"Failed to search Teams"
,
err
)
}
for
_
,
team
:=
range
query
.
Result
.
Teams
{
...
...
@@ -78,7 +78,7 @@ func SearchTeams(c *m.ReqContext) Response {
query
.
Result
.
Page
=
page
query
.
Result
.
PerPage
=
perPage
return
J
son
(
200
,
query
.
Result
)
return
J
SON
(
200
,
query
.
Result
)
}
// GET /api/teams/:teamId
...
...
@@ -87,11 +87,11 @@ func GetTeamByID(c *m.ReqContext) Response {
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
if
err
==
m
.
ErrTeamNotFound
{
return
Api
Error
(
404
,
"Team not found"
,
err
)
return
Error
(
404
,
"Team not found"
,
err
)
}
return
Api
Error
(
500
,
"Failed to get Team"
,
err
)
return
Error
(
500
,
"Failed to get Team"
,
err
)
}
return
J
son
(
200
,
&
query
.
Result
)
return
J
SON
(
200
,
&
query
.
Result
)
}
pkg/api/team_members.go
View file @
8d7fa644
...
...
@@ -12,14 +12,14 @@ func GetTeamMembers(c *m.ReqContext) Response {
query
:=
m
.
GetTeamMembersQuery
{
OrgId
:
c
.
OrgId
,
TeamId
:
c
.
ParamsInt64
(
":teamId"
)}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to get Team Members"
,
err
)
return
Error
(
500
,
"Failed to get Team Members"
,
err
)
}
for
_
,
member
:=
range
query
.
Result
{
member
.
AvatarUrl
=
dtos
.
GetGravatarUrl
(
member
.
Email
)
}
return
J
son
(
200
,
query
.
Result
)
return
J
SON
(
200
,
query
.
Result
)
}
// POST /api/teams/:teamId/members
...
...
@@ -29,17 +29,17 @@ func AddTeamMember(c *m.ReqContext, cmd m.AddTeamMemberCommand) Response {
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
if
err
==
m
.
ErrTeamNotFound
{
return
Api
Error
(
404
,
"Team not found"
,
nil
)
return
Error
(
404
,
"Team not found"
,
nil
)
}
if
err
==
m
.
ErrTeamMemberAlreadyAdded
{
return
Api
Error
(
400
,
"User is already added to this team"
,
nil
)
return
Error
(
400
,
"User is already added to this team"
,
nil
)
}
return
Api
Error
(
500
,
"Failed to add Member to Team"
,
err
)
return
Error
(
500
,
"Failed to add Member to Team"
,
err
)
}
return
J
son
(
200
,
&
util
.
DynMap
{
return
J
SON
(
200
,
&
util
.
DynMap
{
"message"
:
"Member added to Team"
,
})
}
...
...
@@ -48,14 +48,14 @@ func AddTeamMember(c *m.ReqContext, cmd m.AddTeamMemberCommand) Response {
func
RemoveTeamMember
(
c
*
m
.
ReqContext
)
Response
{
if
err
:=
bus
.
Dispatch
(
&
m
.
RemoveTeamMemberCommand
{
OrgId
:
c
.
OrgId
,
TeamId
:
c
.
ParamsInt64
(
":teamId"
),
UserId
:
c
.
ParamsInt64
(
":userId"
)});
err
!=
nil
{
if
err
==
m
.
ErrTeamNotFound
{
return
Api
Error
(
404
,
"Team not found"
,
nil
)
return
Error
(
404
,
"Team not found"
,
nil
)
}
if
err
==
m
.
ErrTeamMemberNotFound
{
return
Api
Error
(
404
,
"Team member not found"
,
nil
)
return
Error
(
404
,
"Team member not found"
,
nil
)
}
return
Api
Error
(
500
,
"Failed to remove Member from Team"
,
err
)
return
Error
(
500
,
"Failed to remove Member from Team"
,
err
)
}
return
Api
Success
(
"Team Member removed"
)
return
Success
(
"Team Member removed"
)
}
pkg/api/user.go
View file @
8d7fa644
...
...
@@ -23,12 +23,12 @@ func getUserUserProfile(userID int64) Response {
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
if
err
==
m
.
ErrUserNotFound
{
return
Api
Error
(
404
,
m
.
ErrUserNotFound
.
Error
(),
nil
)
return
Error
(
404
,
m
.
ErrUserNotFound
.
Error
(),
nil
)
}
return
Api
Error
(
500
,
"Failed to get user"
,
err
)
return
Error
(
500
,
"Failed to get user"
,
err
)
}
return
J
son
(
200
,
query
.
Result
)
return
J
SON
(
200
,
query
.
Result
)
}
// GET /api/users/lookup
...
...
@@ -36,9 +36,9 @@ func GetUserByLoginOrEmail(c *m.ReqContext) Response {
query
:=
m
.
GetUserByLoginQuery
{
LoginOrEmail
:
c
.
Query
(
"loginOrEmail"
)}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
if
err
==
m
.
ErrUserNotFound
{
return
Api
Error
(
404
,
m
.
ErrUserNotFound
.
Error
(),
nil
)
return
Error
(
404
,
m
.
ErrUserNotFound
.
Error
(),
nil
)
}
return
Api
Error
(
500
,
"Failed to get user"
,
err
)
return
Error
(
500
,
"Failed to get user"
,
err
)
}
user
:=
query
.
Result
result
:=
m
.
UserProfileDTO
{
...
...
@@ -50,17 +50,17 @@ func GetUserByLoginOrEmail(c *m.ReqContext) Response {
IsGrafanaAdmin
:
user
.
IsAdmin
,
OrgId
:
user
.
OrgId
,
}
return
J
son
(
200
,
&
result
)
return
J
SON
(
200
,
&
result
)
}
// POST /api/user
func
UpdateSignedInUser
(
c
*
m
.
ReqContext
,
cmd
m
.
UpdateUserCommand
)
Response
{
if
setting
.
AuthProxyEnabled
{
if
setting
.
AuthProxyHeaderProperty
==
"email"
&&
cmd
.
Email
!=
c
.
Email
{
return
Api
Error
(
400
,
"Not allowed to change email when auth proxy is using email property"
,
nil
)
return
Error
(
400
,
"Not allowed to change email when auth proxy is using email property"
,
nil
)
}
if
setting
.
AuthProxyHeaderProperty
==
"username"
&&
cmd
.
Login
!=
c
.
Login
{
return
Api
Error
(
400
,
"Not allowed to change username when auth proxy is using username property"
,
nil
)
return
Error
(
400
,
"Not allowed to change username when auth proxy is using username property"
,
nil
)
}
}
cmd
.
UserId
=
c
.
UserId
...
...
@@ -79,31 +79,31 @@ func UpdateUserActiveOrg(c *m.ReqContext) Response {
orgID
:=
c
.
ParamsInt64
(
":orgId"
)
if
!
validateUsingOrg
(
userID
,
orgID
)
{
return
Api
Error
(
401
,
"Not a valid organization"
,
nil
)
return
Error
(
401
,
"Not a valid organization"
,
nil
)
}
cmd
:=
m
.
SetUsingOrgCommand
{
UserId
:
userID
,
OrgId
:
orgID
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to change active organization"
,
err
)
return
Error
(
500
,
"Failed to change active organization"
,
err
)
}
return
Api
Success
(
"Active organization changed"
)
return
Success
(
"Active organization changed"
)
}
func
handleUpdateUser
(
cmd
m
.
UpdateUserCommand
)
Response
{
if
len
(
cmd
.
Login
)
==
0
{
cmd
.
Login
=
cmd
.
Email
if
len
(
cmd
.
Login
)
==
0
{
return
Api
Error
(
400
,
"Validation error, need to specify either username or email"
,
nil
)
return
Error
(
400
,
"Validation error, need to specify either username or email"
,
nil
)
}
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to update user"
,
err
)
return
Error
(
500
,
"Failed to update user"
,
err
)
}
return
Api
Success
(
"User updated"
)
return
Success
(
"User updated"
)
}
// GET /api/user/orgs
...
...
@@ -120,10 +120,10 @@ func getUserOrgList(userID int64) Response {
query
:=
m
.
GetUserOrgListQuery
{
UserId
:
userID
}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to get user organizations"
,
err
)
return
Error
(
500
,
"Failed to get user organizations"
,
err
)
}
return
J
son
(
200
,
query
.
Result
)
return
J
SON
(
200
,
query
.
Result
)
}
func
validateUsingOrg
(
userID
int64
,
orgID
int64
)
bool
{
...
...
@@ -149,16 +149,16 @@ func UserSetUsingOrg(c *m.ReqContext) Response {
orgID
:=
c
.
ParamsInt64
(
":id"
)
if
!
validateUsingOrg
(
c
.
UserId
,
orgID
)
{
return
Api
Error
(
401
,
"Not a valid organization"
,
nil
)
return
Error
(
401
,
"Not a valid organization"
,
nil
)
}
cmd
:=
m
.
SetUsingOrgCommand
{
UserId
:
c
.
UserId
,
OrgId
:
orgID
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to change active organization"
,
err
)
return
Error
(
500
,
"Failed to change active organization"
,
err
)
}
return
Api
Success
(
"Active organization changed"
)
return
Success
(
"Active organization changed"
)
}
// GET /profile/switch-org/:id
...
...
@@ -180,53 +180,53 @@ func ChangeActiveOrgAndRedirectToHome(c *m.ReqContext) {
func
ChangeUserPassword
(
c
*
m
.
ReqContext
,
cmd
m
.
ChangeUserPasswordCommand
)
Response
{
if
setting
.
LdapEnabled
||
setting
.
AuthProxyEnabled
{
return
Api
Error
(
400
,
"Not allowed to change password when LDAP or Auth Proxy is enabled"
,
nil
)
return
Error
(
400
,
"Not allowed to change password when LDAP or Auth Proxy is enabled"
,
nil
)
}
userQuery
:=
m
.
GetUserByIdQuery
{
Id
:
c
.
UserId
}
if
err
:=
bus
.
Dispatch
(
&
userQuery
);
err
!=
nil
{
return
Api
Error
(
500
,
"Could not read user from database"
,
err
)
return
Error
(
500
,
"Could not read user from database"
,
err
)
}
passwordHashed
:=
util
.
EncodePassword
(
cmd
.
OldPassword
,
userQuery
.
Result
.
Salt
)
if
passwordHashed
!=
userQuery
.
Result
.
Password
{
return
Api
Error
(
401
,
"Invalid old password"
,
nil
)
return
Error
(
401
,
"Invalid old password"
,
nil
)
}
password
:=
m
.
Password
(
cmd
.
NewPassword
)
if
password
.
IsWeak
()
{
return
Api
Error
(
400
,
"New password is too short"
,
nil
)
return
Error
(
400
,
"New password is too short"
,
nil
)
}
cmd
.
UserId
=
c
.
UserId
cmd
.
NewPassword
=
util
.
EncodePassword
(
cmd
.
NewPassword
,
userQuery
.
Result
.
Salt
)
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to change user password"
,
err
)
return
Error
(
500
,
"Failed to change user password"
,
err
)
}
return
Api
Success
(
"User password changed"
)
return
Success
(
"User password changed"
)
}
// GET /api/users
func
SearchUsers
(
c
*
m
.
ReqContext
)
Response
{
query
,
err
:=
searchUser
(
c
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to fetch users"
,
err
)
return
Error
(
500
,
"Failed to fetch users"
,
err
)
}
return
J
son
(
200
,
query
.
Result
.
Users
)
return
J
SON
(
200
,
query
.
Result
.
Users
)
}
// GET /api/users/search
func
SearchUsersWithPaging
(
c
*
m
.
ReqContext
)
Response
{
query
,
err
:=
searchUser
(
c
)
if
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to fetch users"
,
err
)
return
Error
(
500
,
"Failed to fetch users"
,
err
)
}
return
J
son
(
200
,
query
.
Result
)
return
J
SON
(
200
,
query
.
Result
)
}
func
searchUser
(
c
*
m
.
ReqContext
)
(
*
m
.
SearchUsersQuery
,
error
)
{
...
...
@@ -269,10 +269,10 @@ func SetHelpFlag(c *m.ReqContext) Response {
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to update help flag"
,
err
)
return
Error
(
500
,
"Failed to update help flag"
,
err
)
}
return
J
son
(
200
,
&
util
.
DynMap
{
"message"
:
"Help flag set"
,
"helpFlags1"
:
cmd
.
HelpFlags1
})
return
J
SON
(
200
,
&
util
.
DynMap
{
"message"
:
"Help flag set"
,
"helpFlags1"
:
cmd
.
HelpFlags1
})
}
func
ClearHelpFlags
(
c
*
m
.
ReqContext
)
Response
{
...
...
@@ -282,8 +282,8 @@ func ClearHelpFlags(c *m.ReqContext) Response {
}
if
err
:=
bus
.
Dispatch
(
&
cmd
);
err
!=
nil
{
return
Api
Error
(
500
,
"Failed to update help flag"
,
err
)
return
Error
(
500
,
"Failed to update help flag"
,
err
)
}
return
J
son
(
200
,
&
util
.
DynMap
{
"message"
:
"Help flag set"
,
"helpFlags1"
:
cmd
.
HelpFlags1
})
return
J
SON
(
200
,
&
util
.
DynMap
{
"message"
:
"Help flag set"
,
"helpFlags1"
:
cmd
.
HelpFlags1
})
}
pkg/cmd/grafana-server/server.go
View file @
8d7fa644
...
...
@@ -49,7 +49,7 @@ type GrafanaServerImpl struct {
childRoutines
*
errgroup
.
Group
log
log
.
Logger
httpServer
*
api
.
H
ttp
Server
httpServer
*
api
.
H
TTP
Server
}
func
(
g
*
GrafanaServerImpl
)
Start
()
error
{
...
...
pkg/middleware/auth_proxy.go
View file @
8d7fa644
...
...
@@ -14,7 +14,7 @@ import (
"github.com/grafana/grafana/pkg/setting"
)
func
initContextWithAuthProxy
(
ctx
*
m
.
ReqContext
,
orgI
d
int64
)
bool
{
func
initContextWithAuthProxy
(
ctx
*
m
.
ReqContext
,
orgI
D
int64
)
bool
{
if
!
setting
.
AuthProxyEnabled
{
return
false
}
...
...
@@ -31,31 +31,31 @@ func initContextWithAuthProxy(ctx *m.ReqContext, orgId int64) bool {
}
query
:=
getSignedInUserQueryForProxyAuth
(
proxyHeaderValue
)
query
.
OrgId
=
orgI
d
query
.
OrgId
=
orgI
D
if
err
:=
bus
.
Dispatch
(
query
);
err
!=
nil
{
if
err
!=
m
.
ErrUserNotFound
{
ctx
.
Handle
(
500
,
"Failed to find user specified in auth proxy header"
,
err
)
return
true
}
if
setting
.
AuthProxyAutoSignUp
{
cmd
:=
getCreateUserCommandForProxyAuth
(
proxyHeaderValue
)
if
setting
.
LdapEnabled
{
cmd
.
SkipOrgSetup
=
true
}
if
err
:=
bus
.
Dispatch
(
cmd
);
err
!=
nil
{
ctx
.
Handle
(
500
,
"Failed to create user specified in auth proxy header"
,
err
)
return
true
}
query
=
&
m
.
GetSignedInUserQuery
{
UserId
:
cmd
.
Result
.
Id
,
OrgId
:
orgId
}
if
err
:=
bus
.
Dispatch
(
query
);
err
!=
nil
{
ctx
.
Handle
(
500
,
"Failed find user after creation"
,
err
)
return
true
}
}
else
{
if
!
setting
.
AuthProxyAutoSignUp
{
return
false
}
cmd
:=
getCreateUserCommandForProxyAuth
(
proxyHeaderValue
)
if
setting
.
LdapEnabled
{
cmd
.
SkipOrgSetup
=
true
}
if
err
:=
bus
.
Dispatch
(
cmd
);
err
!=
nil
{
ctx
.
Handle
(
500
,
"Failed to create user specified in auth proxy header"
,
err
)
return
true
}
query
=
&
m
.
GetSignedInUserQuery
{
UserId
:
cmd
.
Result
.
Id
,
OrgId
:
orgID
}
if
err
:=
bus
.
Dispatch
(
query
);
err
!=
nil
{
ctx
.
Handle
(
500
,
"Failed find user after creation"
,
err
)
return
true
}
}
// initialize session
...
...
@@ -96,50 +96,53 @@ func initContextWithAuthProxy(ctx *m.ReqContext, orgId int64) bool {
}
var
syncGrafanaUserWithLdapUser
=
func
(
ctx
*
m
.
ReqContext
,
query
*
m
.
GetSignedInUserQuery
)
error
{
if
setting
.
LdapEnabled
{
expireEpoch
:=
time
.
Now
()
.
Add
(
time
.
Duration
(
-
setting
.
AuthProxyLdapSyncTtl
)
*
time
.
Minute
)
.
Unix
()
if
!
setting
.
LdapEnabled
{
return
nil
}
var
lastLdapSync
int64
if
lastLdapSyncInSession
:=
ctx
.
Session
.
Get
(
session
.
SESS_KEY_LASTLDAPSYNC
);
lastLdapSyncInSession
!=
nil
{
lastLdapSync
=
lastLdapSyncInSession
.
(
int64
)
}
expireEpoch
:=
time
.
Now
()
.
Add
(
time
.
Duration
(
-
setting
.
AuthProxyLdapSyncTtl
)
*
time
.
Minute
)
.
Unix
()
if
lastLdapSync
<
expireEpoch
{
ldapCfg
:=
login
.
LdapCfg
var
lastLdapSync
int64
if
lastLdapSyncInSession
:=
ctx
.
Session
.
Get
(
session
.
SESS_KEY_LASTLDAPSYNC
);
lastLdapSyncInSession
!=
nil
{
lastLdapSync
=
lastLdapSyncInSession
.
(
int64
)
}
for
_
,
server
:=
range
ldapCfg
.
Servers
{
author
:=
login
.
NewLdapAuthenticator
(
server
)
if
err
:=
author
.
SyncSignedInUser
(
query
.
Result
);
err
!=
nil
{
return
err
}
}
if
lastLdapSync
<
expireEpoch
{
ldapCfg
:=
login
.
LdapCfg
ctx
.
Session
.
Set
(
session
.
SESS_KEY_LASTLDAPSYNC
,
time
.
Now
()
.
Unix
())
for
_
,
server
:=
range
ldapCfg
.
Servers
{
author
:=
login
.
NewLdapAuthenticator
(
server
)
if
err
:=
author
.
SyncSignedInUser
(
query
.
Result
);
err
!=
nil
{
return
err
}
}
ctx
.
Session
.
Set
(
session
.
SESS_KEY_LASTLDAPSYNC
,
time
.
Now
()
.
Unix
())
}
return
nil
}
func
checkAuthenticationProxy
(
ctx
*
m
.
ReqContext
,
proxyHeaderValue
string
)
error
{
if
len
(
strings
.
TrimSpace
(
setting
.
AuthProxyWhitelist
))
>
0
{
proxies
:=
strings
.
Split
(
setting
.
AuthProxyWhitelist
,
","
)
remoteAddrSplit
:=
strings
.
Split
(
ctx
.
Req
.
RemoteAddr
,
":"
)
sourceIP
:=
remoteAddrSplit
[
0
]
found
:=
false
for
_
,
proxyIP
:=
range
proxies
{
if
sourceIP
==
strings
.
TrimSpace
(
proxyIP
)
{
found
=
true
break
}
if
len
(
strings
.
TrimSpace
(
setting
.
AuthProxyWhitelist
))
==
0
{
return
nil
}
proxies
:=
strings
.
Split
(
setting
.
AuthProxyWhitelist
,
","
)
remoteAddrSplit
:=
strings
.
Split
(
ctx
.
Req
.
RemoteAddr
,
":"
)
sourceIP
:=
remoteAddrSplit
[
0
]
found
:=
false
for
_
,
proxyIP
:=
range
proxies
{
if
sourceIP
==
strings
.
TrimSpace
(
proxyIP
)
{
found
=
true
break
}
}
if
!
found
{
msg
:=
fmt
.
Sprintf
(
"Request for user (%s) is not from the authentication proxy"
,
proxyHeaderValue
)
err
:=
errors
.
New
(
msg
)
return
err
}
if
!
found
{
msg
:=
fmt
.
Sprintf
(
"Request for user (%s) is not from the authentication proxy"
,
proxyHeaderValue
)
err
:=
errors
.
New
(
msg
)
return
err
}
return
nil
...
...
pkg/middleware/dashboard_redirect.go
View file @
8d7fa644
...
...
@@ -10,8 +10,8 @@ import (
"gopkg.in/macaron.v1"
)
func
getDashboardU
rlBySlug
(
orgId
int64
,
slug
string
)
(
string
,
error
)
{
query
:=
m
.
GetDashboardQuery
{
Slug
:
slug
,
OrgId
:
orgI
d
}
func
getDashboardU
RLBySlug
(
orgID
int64
,
slug
string
)
(
string
,
error
)
{
query
:=
m
.
GetDashboardQuery
{
Slug
:
slug
,
OrgId
:
orgI
D
}
if
err
:=
bus
.
Dispatch
(
&
query
);
err
!=
nil
{
return
""
,
m
.
ErrDashboardNotFound
...
...
@@ -25,7 +25,7 @@ func RedirectFromLegacyDashboardURL() macaron.Handler {
slug
:=
c
.
Params
(
"slug"
)
if
slug
!=
""
{
if
url
,
err
:=
getDashboardU
rl
BySlug
(
c
.
OrgId
,
slug
);
err
==
nil
{
if
url
,
err
:=
getDashboardU
RL
BySlug
(
c
.
OrgId
,
slug
);
err
==
nil
{
url
=
fmt
.
Sprintf
(
"%s?%s"
,
url
,
c
.
Req
.
URL
.
RawQuery
)
c
.
Redirect
(
url
,
301
)
return
...
...
@@ -34,13 +34,13 @@ func RedirectFromLegacyDashboardURL() macaron.Handler {
}
}
func
RedirectFromLegacyDashboardSoloU
rl
()
macaron
.
Handler
{
func
RedirectFromLegacyDashboardSoloU
RL
()
macaron
.
Handler
{
return
func
(
c
*
m
.
ReqContext
)
{
slug
:=
c
.
Params
(
"slug"
)
renderRequest
:=
c
.
QueryBool
(
"render"
)
if
slug
!=
""
{
if
url
,
err
:=
getDashboardU
rl
BySlug
(
c
.
OrgId
,
slug
);
err
==
nil
{
if
url
,
err
:=
getDashboardU
RL
BySlug
(
c
.
OrgId
,
slug
);
err
==
nil
{
if
renderRequest
&&
strings
.
Contains
(
url
,
setting
.
AppSubUrl
)
{
url
=
strings
.
Replace
(
url
,
setting
.
AppSubUrl
,
""
,
1
)
}
...
...
pkg/middleware/dashboard_redirect_test.go
View file @
8d7fa644
...
...
@@ -14,7 +14,7 @@ func TestMiddlewareDashboardRedirect(t *testing.T) {
Convey
(
"Given the dashboard redirect middleware"
,
t
,
func
()
{
bus
.
ClearBusHandlers
()
redirectFromLegacyDashboardUrl
:=
RedirectFromLegacyDashboardURL
()
redirectFromLegacyDashboardSoloUrl
:=
RedirectFromLegacyDashboardSoloU
rl
()
redirectFromLegacyDashboardSoloUrl
:=
RedirectFromLegacyDashboardSoloU
RL
()
fakeDash
:=
m
.
NewDashboard
(
"Child dash"
)
fakeDash
.
Id
=
1
...
...
pkg/middleware/render_auth.go
View file @
8d7fa644
...
...
@@ -19,16 +19,16 @@ func initContextWithRenderAuth(ctx *m.ReqContext) bool {
renderKeysLock
.
Lock
()
defer
renderKeysLock
.
Unlock
()
if
renderUser
,
exists
:=
renderKeys
[
key
];
!
exists
{
renderUser
,
exists
:=
renderKeys
[
key
]
if
!
exists
{
ctx
.
JsonApiErr
(
401
,
"Invalid Render Key"
,
nil
)
return
true
}
else
{
ctx
.
IsSignedIn
=
true
ctx
.
SignedInUser
=
renderUser
ctx
.
IsRenderCall
=
true
return
true
}
ctx
.
IsSignedIn
=
true
ctx
.
SignedInUser
=
renderUser
ctx
.
IsRenderCall
=
true
return
true
}
type
renderContextFunc
func
(
key
string
)
(
string
,
error
)
...
...
pkg/services/dashboards/folder_service.go
View file @
8d7fa644
...
...
@@ -10,8 +10,8 @@ import (
// FolderService service for operating on folders
type
FolderService
interface
{
GetFolders
(
limit
int
)
([]
*
models
.
Folder
,
error
)
GetFolderByI
d
(
id
int64
)
(
*
models
.
Folder
,
error
)
GetFolderByU
id
(
uid
string
)
(
*
models
.
Folder
,
error
)
GetFolderByI
D
(
id
int64
)
(
*
models
.
Folder
,
error
)
GetFolderByU
ID
(
uid
string
)
(
*
models
.
Folder
,
error
)
CreateFolder
(
cmd
*
models
.
CreateFolderCommand
)
error
UpdateFolder
(
uid
string
,
cmd
*
models
.
UpdateFolderCommand
)
error
DeleteFolder
(
uid
string
)
(
*
models
.
Folder
,
error
)
...
...
@@ -57,7 +57,7 @@ func (dr *dashboardServiceImpl) GetFolders(limit int) ([]*models.Folder, error)
return
folders
,
nil
}
func
(
dr
*
dashboardServiceImpl
)
GetFolderByI
d
(
id
int64
)
(
*
models
.
Folder
,
error
)
{
func
(
dr
*
dashboardServiceImpl
)
GetFolderByI
D
(
id
int64
)
(
*
models
.
Folder
,
error
)
{
query
:=
models
.
GetDashboardQuery
{
OrgId
:
dr
.
orgId
,
Id
:
id
}
dashFolder
,
err
:=
getFolder
(
query
)
...
...
@@ -76,7 +76,7 @@ func (dr *dashboardServiceImpl) GetFolderById(id int64) (*models.Folder, error)
return
dashToFolder
(
dashFolder
),
nil
}
func
(
dr
*
dashboardServiceImpl
)
GetFolderByU
id
(
uid
string
)
(
*
models
.
Folder
,
error
)
{
func
(
dr
*
dashboardServiceImpl
)
GetFolderByU
ID
(
uid
string
)
(
*
models
.
Folder
,
error
)
{
query
:=
models
.
GetDashboardQuery
{
OrgId
:
dr
.
orgId
,
Uid
:
uid
}
dashFolder
,
err
:=
getFolder
(
query
)
...
...
pkg/services/dashboards/folder_service_test.go
View file @
8d7fa644
...
...
@@ -36,13 +36,13 @@ func TestFolderService(t *testing.T) {
})
Convey
(
"When get folder by id should return access denied error"
,
func
()
{
_
,
err
:=
service
.
GetFolderByI
d
(
1
)
_
,
err
:=
service
.
GetFolderByI
D
(
1
)
So
(
err
,
ShouldNotBeNil
)
So
(
err
,
ShouldEqual
,
models
.
ErrFolderAccessDenied
)
})
Convey
(
"When get folder by uid should return access denied error"
,
func
()
{
_
,
err
:=
service
.
GetFolderByU
id
(
"uid"
)
_
,
err
:=
service
.
GetFolderByU
ID
(
"uid"
)
So
(
err
,
ShouldNotBeNil
)
So
(
err
,
ShouldEqual
,
models
.
ErrFolderAccessDenied
)
})
...
...
@@ -147,14 +147,14 @@ func TestFolderService(t *testing.T) {
})
Convey
(
"When get folder by id should return folder"
,
func
()
{
f
,
_
:=
service
.
GetFolderByI
d
(
1
)
f
,
_
:=
service
.
GetFolderByI
D
(
1
)
So
(
f
.
Id
,
ShouldEqual
,
dashFolder
.
Id
)
So
(
f
.
Uid
,
ShouldEqual
,
dashFolder
.
Uid
)
So
(
f
.
Title
,
ShouldEqual
,
dashFolder
.
Title
)
})
Convey
(
"When get folder by uid should return folder"
,
func
()
{
f
,
_
:=
service
.
GetFolderByU
id
(
"uid"
)
f
,
_
:=
service
.
GetFolderByU
ID
(
"uid"
)
So
(
f
.
Id
,
ShouldEqual
,
dashFolder
.
Id
)
So
(
f
.
Uid
,
ShouldEqual
,
dashFolder
.
Uid
)
So
(
f
.
Title
,
ShouldEqual
,
dashFolder
.
Title
)
...
...
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