Merge branch 'master' into react-panels-step1

This commit is contained in:
Torkel Ödegaard
2018-10-12 13:31:20 +02:00
232 changed files with 15596 additions and 2187 deletions
+4 -4
View File
@@ -10,10 +10,10 @@ import (
)
func (hs *HTTPServer) registerRoutes() {
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)
reqSignedIn := middleware.ReqSignedIn
reqGrafanaAdmin := middleware.ReqGrafanaAdmin
reqEditorRole := middleware.ReqEditorRole
reqOrgAdmin := middleware.ReqOrgAdmin
redirectFromLegacyDashboardURL := middleware.RedirectFromLegacyDashboardURL()
redirectFromLegacyDashboardSoloURL := middleware.RedirectFromLegacyDashboardSoloURL()
quota := middleware.Quota
+15 -1
View File
@@ -51,7 +51,21 @@ func (hs *HTTPServer) ProxyDataSourceRequest(c *m.ReqContext) {
return
}
proxyPath := c.Params("*")
// macaron does not include trailing slashes when resolving a wildcard path
proxyPath := ensureProxyPathTrailingSlash(c.Req.URL.Path, c.Params("*"))
proxy := pluginproxy.NewDataSourceProxy(ds, plugin, c, proxyPath)
proxy.HandleRequest()
}
// ensureProxyPathTrailingSlash Check for a trailing slash in original path and makes
// sure that a trailing slash is added to proxy path, if not already exists.
func ensureProxyPathTrailingSlash(originalPath, proxyPath string) string {
if len(proxyPath) > 1 {
if originalPath[len(originalPath)-1] == '/' && proxyPath[len(proxyPath)-1] != '/' {
return proxyPath + "/"
}
}
return proxyPath
}
+19
View File
@@ -0,0 +1,19 @@
package api
import (
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestDataProxy(t *testing.T) {
Convey("Data proxy test", t, func() {
Convey("Should append trailing slash to proxy path if original path has a trailing slash", func() {
So(ensureProxyPathTrailingSlash("/api/datasources/proxy/6/api/v1/query_range/", "api/v1/query_range/"), ShouldEqual, "api/v1/query_range/")
})
Convey("Should not append trailing slash to proxy path if original path doesn't have a trailing slash", func() {
So(ensureProxyPathTrailingSlash("/api/datasources/proxy/6/api/v1/query_range", "api/v1/query_range"), ShouldEqual, "api/v1/query_range")
})
})
}
+14 -7
View File
@@ -316,6 +316,19 @@ func (hs *HTTPServer) setIndexViewData(c *m.ReqContext) (*dtos.IndexViewData, er
}
if c.IsGrafanaAdmin {
children := []*dtos.NavLink{
{Text: "Users", Id: "global-users", Url: setting.AppSubUrl + "/admin/users", Icon: "gicon gicon-user"},
{Text: "Orgs", Id: "global-orgs", Url: setting.AppSubUrl + "/admin/orgs", Icon: "gicon gicon-org"},
{Text: "Settings", Id: "server-settings", Url: setting.AppSubUrl + "/admin/settings", Icon: "gicon gicon-preferences"},
{Text: "Stats", Id: "server-stats", Url: setting.AppSubUrl + "/admin/stats", Icon: "fa fa-fw fa-bar-chart"},
}
if setting.IsEnterprise {
children = append(children, &dtos.NavLink{Text: "Licensing", Id: "licensing", Url: setting.AppSubUrl + "/admin/licensing", Icon: "fa fa-fw fa-unlock-alt"})
}
children = append(children, &dtos.NavLink{Text: "Style Guide", Id: "styleguide", Url: setting.AppSubUrl + "/styleguide", Icon: "fa fa-fw fa-eyedropper"})
cfgNode.Children = append(cfgNode.Children, &dtos.NavLink{
Text: "Server Admin",
HideFromTabs: true,
@@ -323,13 +336,7 @@ func (hs *HTTPServer) setIndexViewData(c *m.ReqContext) (*dtos.IndexViewData, er
Id: "admin",
Icon: "gicon gicon-shield",
Url: setting.AppSubUrl + "/admin/users",
Children: []*dtos.NavLink{
{Text: "Users", Id: "global-users", Url: setting.AppSubUrl + "/admin/users", Icon: "gicon gicon-user"},
{Text: "Orgs", Id: "global-orgs", Url: setting.AppSubUrl + "/admin/orgs", Icon: "gicon gicon-org"},
{Text: "Settings", Id: "server-settings", Url: setting.AppSubUrl + "/admin/settings", Icon: "gicon gicon-preferences"},
{Text: "Stats", Id: "server-stats", Url: setting.AppSubUrl + "/admin/stats", Icon: "fa fa-fw fa-bar-chart"},
{Text: "Style Guide", Id: "styleguide", Url: setting.AppSubUrl + "/styleguide", Icon: "fa fa-fw fa-eyedropper"},
},
Children: children,
})
}
+16 -10
View File
@@ -45,7 +45,7 @@ func addOrgUserHelper(cmd m.AddOrgUserCommand) Response {
// GET /api/org/users
func GetOrgUsersForCurrentOrg(c *m.ReqContext) Response {
return getOrgUsersHelper(c.OrgId, c.Params("query"), c.ParamsInt("limit"))
return getOrgUsersHelper(c.OrgId, c.Query("query"), c.QueryInt("limit"))
}
// GET /api/orgs/:orgId/users
@@ -102,26 +102,32 @@ func updateOrgUserHelper(cmd m.UpdateOrgUserCommand) Response {
// DELETE /api/org/users/:userId
func RemoveOrgUserForCurrentOrg(c *m.ReqContext) Response {
userID := c.ParamsInt64(":userId")
return removeOrgUserHelper(c.OrgId, userID)
return removeOrgUserHelper(&m.RemoveOrgUserCommand{
UserId: c.ParamsInt64(":userId"),
OrgId: c.OrgId,
ShouldDeleteOrphanedUser: true,
})
}
// DELETE /api/orgs/:orgId/users/:userId
func RemoveOrgUser(c *m.ReqContext) Response {
userID := c.ParamsInt64(":userId")
orgID := c.ParamsInt64(":orgId")
return removeOrgUserHelper(orgID, userID)
return removeOrgUserHelper(&m.RemoveOrgUserCommand{
UserId: c.ParamsInt64(":userId"),
OrgId: c.ParamsInt64(":orgId"),
})
}
func removeOrgUserHelper(orgID int64, userID int64) Response {
cmd := m.RemoveOrgUserCommand{OrgId: orgID, UserId: userID}
if err := bus.Dispatch(&cmd); err != nil {
func removeOrgUserHelper(cmd *m.RemoveOrgUserCommand) Response {
if err := bus.Dispatch(cmd); err != nil {
if err == m.ErrLastOrgAdmin {
return Error(400, "Cannot remove last organization admin", nil)
}
return Error(500, "Failed to remove user from organization", err)
}
if cmd.UserWasDeleted {
return Success("User deleted")
}
return Success("User removed from organization")
}
+17
View File
@@ -362,6 +362,23 @@ func TestDSRouteRule(t *testing.T) {
})
})
Convey("When proxying a custom datasource", func() {
plugin := &plugins.DataSourcePlugin{}
ds := &m.DataSource{
Type: "custom-datasource",
Url: "http://host/root/",
}
ctx := &m.ReqContext{}
proxy := NewDataSourceProxy(ds, plugin, ctx, "/path/to/folder/")
req, err := http.NewRequest(http.MethodGet, "http://grafana.com/sub", nil)
So(err, ShouldBeNil)
proxy.getDirector()(req)
Convey("Shoudl keep user request (including trailing slash)", func() {
So(req.URL.String(), ShouldEqual, "http://host/root/path/to/folder/")
})
})
})
}