diff --git a/conf/grafana.ini b/conf/grafana.ini index bd9b39cf134..74a180a2022 100644 --- a/conf/grafana.ini +++ b/conf/grafana.ini @@ -59,7 +59,7 @@ default_role = Editor [auth.anonymous] ; enable anonymous access -enabled = true +enabled = false ; specify account name that should be used for unauthenticated users account_name = main ; specify role for unauthenticated users diff --git a/grafana b/grafana index 9d0982f2f75..3b5c813be71 160000 --- a/grafana +++ b/grafana @@ -1 +1 @@ -Subproject commit 9d0982f2f7552a08053b66d4b17ee0f583e8339e +Subproject commit 3b5c813be71c4816f3c2ef40e4c1439a8026236f diff --git a/pkg/api/api.go b/pkg/api/api.go index 1bd79f11581..ab0b76c39c0 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -6,7 +6,6 @@ import ( "github.com/torkelo/grafana-pro/pkg/api/dtos" "github.com/torkelo/grafana-pro/pkg/middleware" m "github.com/torkelo/grafana-pro/pkg/models" - "github.com/torkelo/grafana-pro/pkg/setting" ) // Register adds http routes @@ -46,6 +45,8 @@ func Register(r *macaron.Macaron) { r.Put("/", bind(m.UpdateUserCommand{}), UpdateUser) r.Post("/using/:id", SetUsingAccount) r.Get("/accounts", GetUserAccounts) + r.Post("/favorites/dashboard/:id", AddAsFavorite) + r.Delete("/favorites/dashboard/:id", RemoveAsFavorite) }) // account @@ -97,51 +98,3 @@ func Register(r *macaron.Macaron) { r.NotFound(NotFound) } - -func setIndexViewData(c *middleware.Context) error { - settings, err := getFrontendSettings(c) - if err != nil { - return err - } - - currentUser := &dtos.CurrentUser{ - IsSignedIn: c.IsSignedIn, - Login: c.Login, - Email: c.Email, - Name: c.Name, - AccountName: c.AccountName, - AccountRole: c.AccountRole, - GravatarUrl: dtos.GetGravatarUrl(c.Email), - IsGrafanaAdmin: c.IsGrafanaAdmin, - } - - c.Data["User"] = currentUser - c.Data["Settings"] = settings - c.Data["AppUrl"] = setting.AppUrl - c.Data["AppSubUrl"] = setting.AppSubUrl - - return nil -} - -func Index(c *middleware.Context) { - if err := setIndexViewData(c); err != nil { - c.Handle(500, "Failed to get settings", err) - return - } - - c.HTML(200, "index") -} - -func NotFound(c *middleware.Context) { - if c.IsApiRequest() { - c.JsonApiErr(200, "Not found", nil) - return - } - - if err := setIndexViewData(c); err != nil { - c.Handle(500, "Failed to get settings", err) - return - } - - c.HTML(404, "index") -} diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go index e505179f149..ec99c435dfa 100644 --- a/pkg/api/dashboard.go +++ b/pkg/api/dashboard.go @@ -1,6 +1,7 @@ package api import ( + "github.com/torkelo/grafana-pro/pkg/api/dtos" "github.com/torkelo/grafana-pro/pkg/bus" "github.com/torkelo/grafana-pro/pkg/middleware" m "github.com/torkelo/grafana-pro/pkg/models" @@ -17,9 +18,13 @@ func GetDashboard(c *middleware.Context) { return } - query.Result.Data["id"] = query.Result.Id + dash := query.Result + dto := dtos.Dashboard{ + IsFavorite: false, + Dashboard: dash.Data, + } - c.JSON(200, query.Result.Data) + c.JSON(200, dto) } func DeleteDashboard(c *middleware.Context) { diff --git a/pkg/api/dtos/models.go b/pkg/api/dtos/models.go index b4089862a72..d14365a41cc 100644 --- a/pkg/api/dtos/models.go +++ b/pkg/api/dtos/models.go @@ -25,6 +25,11 @@ type CurrentUser struct { GravatarUrl string `json:"gravatarUrl"` } +type Dashboard struct { + IsFavorite bool `json:"isFavorite"` + Dashboard map[string]interface{} `json:"dashboard"` +} + type DataSource struct { Id int64 `json:"id"` AccountId int64 `json:"accountId"` diff --git a/pkg/api/favorite.go b/pkg/api/favorite.go new file mode 100644 index 00000000000..180315567ab --- /dev/null +++ b/pkg/api/favorite.go @@ -0,0 +1,35 @@ +package api + +import ( + "github.com/torkelo/grafana-pro/pkg/bus" + "github.com/torkelo/grafana-pro/pkg/middleware" + m "github.com/torkelo/grafana-pro/pkg/models" +) + +func AddAsFavorite(c *middleware.Context) { + var cmd = m.AddAsFavoriteCommand{ + UserId: c.UserId, + DashboardId: c.ParamsInt64(":id"), + } + + if err := bus.Dispatch(&cmd); err != nil { + c.JsonApiErr(500, "Failed to add favorite", err) + return + } + + c.JsonOK("Dashboard marked as favorite") +} + +func RemoveAsFavorite(c *middleware.Context) { + var cmd = m.RemoveAsFavoriteCommand{ + UserId: c.UserId, + DashboardId: c.ParamsInt64(":id"), + } + + if err := bus.Dispatch(&cmd); err != nil { + c.JsonApiErr(500, "Failed to remove favorite", err) + return + } + + c.JsonOK("Favorite removed") +} diff --git a/pkg/api/index.go b/pkg/api/index.go new file mode 100644 index 00000000000..6ab2b77a9d5 --- /dev/null +++ b/pkg/api/index.go @@ -0,0 +1,55 @@ +package api + +import ( + "github.com/torkelo/grafana-pro/pkg/api/dtos" + "github.com/torkelo/grafana-pro/pkg/middleware" + "github.com/torkelo/grafana-pro/pkg/setting" +) + +func setIndexViewData(c *middleware.Context) error { + settings, err := getFrontendSettings(c) + if err != nil { + return err + } + + currentUser := &dtos.CurrentUser{ + IsSignedIn: c.IsSignedIn, + Login: c.Login, + Email: c.Email, + Name: c.Name, + AccountName: c.AccountName, + AccountRole: c.AccountRole, + GravatarUrl: dtos.GetGravatarUrl(c.Email), + IsGrafanaAdmin: c.IsGrafanaAdmin, + } + + c.Data["User"] = currentUser + c.Data["Settings"] = settings + c.Data["AppUrl"] = setting.AppUrl + c.Data["AppSubUrl"] = setting.AppSubUrl + + return nil +} + +func Index(c *middleware.Context) { + if err := setIndexViewData(c); err != nil { + c.Handle(500, "Failed to get settings", err) + return + } + + c.HTML(200, "index") +} + +func NotFound(c *middleware.Context) { + if c.IsApiRequest() { + c.JsonApiErr(200, "Not found", nil) + return + } + + if err := setIndexViewData(c); err != nil { + c.Handle(500, "Failed to get settings", err) + return + } + + c.HTML(404, "index") +} diff --git a/pkg/api/login.go b/pkg/api/login.go index d4bd3f2f99d..278ad86f779 100644 --- a/pkg/api/login.go +++ b/pkg/api/login.go @@ -119,7 +119,7 @@ func loginUserWithUser(user *m.User, c *middleware.Context) { log.Error(3, "User login with nil user") } - c.Session.Set("userId", user.Id) + c.Session.Set(middleware.SESS_KEY_USERID, user.Id) } func LogoutPost(c *middleware.Context) { diff --git a/pkg/api/render.go b/pkg/api/render.go index 9a5c32c7c2c..db4dbc4a1e3 100644 --- a/pkg/api/render.go +++ b/pkg/api/render.go @@ -1,8 +1,8 @@ package api import ( + "fmt" "net/http" - "strconv" "github.com/torkelo/grafana-pro/pkg/components/renderer" "github.com/torkelo/grafana-pro/pkg/middleware" @@ -11,7 +11,7 @@ import ( func RenderToPng(c *middleware.Context) { queryReader := util.NewUrlQueryReader(c.Req.URL) - queryParams := "?render=1&userId=" + strconv.FormatInt(c.UserId, 10) + "&" + c.Req.URL.RawQuery + queryParams := fmt.Sprintf("?render=1&%s=%d&%s", middleware.SESS_KEY_USERID, c.UserId, c.Req.URL.RawQuery) renderOpts := &renderer.RenderOpts{ Url: c.Params("*") + queryParams, diff --git a/pkg/middleware/auth.go b/pkg/middleware/auth.go index 848dc424285..a3ab8e780eb 100644 --- a/pkg/middleware/auth.go +++ b/pkg/middleware/auth.go @@ -16,7 +16,7 @@ type AuthOptions struct { } func getRequestUserId(c *Context) int64 { - userId := c.Session.Get("userId") + userId := c.Session.Get(SESS_KEY_USERID) if userId != nil { return userId.(int64) @@ -24,8 +24,8 @@ func getRequestUserId(c *Context) int64 { // TODO: figure out a way to secure this if c.Query("render") == "1" { - userId := c.QueryInt64("userId") - c.Session.Set("userId", userId) + userId := c.QueryInt64(SESS_KEY_USERID) + c.Session.Set(SESS_KEY_USERID, userId) return userId } diff --git a/pkg/middleware/session.go b/pkg/middleware/session.go new file mode 100644 index 00000000000..1eb1dd5acbf --- /dev/null +++ b/pkg/middleware/session.go @@ -0,0 +1,6 @@ +package middleware + +const ( + SESS_KEY_USERID = "uid" + SESS_KEY_FAVORITES = "favorites" +) diff --git a/pkg/models/favorite.go b/pkg/models/favorite.go index 9d91918c6f9..a38d256b8de 100644 --- a/pkg/models/favorite.go +++ b/pkg/models/favorite.go @@ -6,6 +6,9 @@ type Favorite struct { DashboardId int64 } +// ---------------------- +// COMMANDS + type AddAsFavoriteCommand struct { UserId int64 DashboardId int64 @@ -15,3 +18,12 @@ type RemoveAsFavoriteCommand struct { UserId int64 DashboardId int64 } + +// --------------------- +// QUERIES + +type GetUserFavoritesQuery struct { + UserId int64 + + Result []Favorite +} diff --git a/pkg/services/sqlstore/dashboard.go b/pkg/services/sqlstore/dashboard.go index 85391fdc936..0cef2f919e8 100644 --- a/pkg/services/sqlstore/dashboard.go +++ b/pkg/services/sqlstore/dashboard.go @@ -66,6 +66,7 @@ func GetDashboard(query *m.GetDashboardQuery) error { return m.ErrDashboardNotFound } + dashboard.Data["id"] = dashboard.Id query.Result = &dashboard return nil diff --git a/pkg/services/sqlstore/favorite.go b/pkg/services/sqlstore/favorite.go index f2241aa678c..4455559521f 100644 --- a/pkg/services/sqlstore/favorite.go +++ b/pkg/services/sqlstore/favorite.go @@ -10,6 +10,7 @@ import ( func init() { bus.AddHandler("sql", AddAsFavorite) bus.AddHandler("sql", RemoveAsFavorite) + bus.AddHandler("sql", GetUserFavorites) } func AddAsFavorite(cmd *m.AddAsFavoriteCommand) error { @@ -32,3 +33,9 @@ func RemoveAsFavorite(cmd *m.RemoveAsFavoriteCommand) error { return err }) } + +func GetUserFavorites(query *m.GetUserFavoritesQuery) error { + query.Result = make([]m.Favorite, 0) + err := x.Where("user_id=?", query.UserId).Find(&query.Result) + return err +}