Working on collaborators

This commit is contained in:
Torkel Ödegaard
2014-09-19 17:37:18 +02:00
parent 1705734435
commit a9a06ad51d
11 changed files with 174 additions and 98 deletions
+4 -12
View File
@@ -7,6 +7,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/gorilla/sessions"
"github.com/torkelo/grafana-pro/pkg/components"
"github.com/torkelo/grafana-pro/pkg/models"
"github.com/torkelo/grafana-pro/pkg/stores"
)
@@ -61,9 +62,9 @@ func (self *HttpServer) ListenAndServe() {
func (self *HttpServer) index(c *gin.Context) {
viewModel := &IndexDto{}
login, _ := c.Get("login")
if login != nil {
viewModel.User.Login = login.(string)
userAccount, _ := c.Get("userAccount")
if userAccount != nil {
viewModel.User.Login = userAccount.(*models.UserAccount).Login
}
c.HTML(200, "index.html", viewModel)
@@ -74,12 +75,3 @@ func CacheHeadersMiddleware() gin.HandlerFunc {
c.Writer.Header().Add("Cache-Control", "max-age=0, public, must-revalidate, proxy-revalidate")
}
}
// Api Handler Registration
var routeHandlers = make([]routeHandlerRegisterFn, 0)
type routeHandlerRegisterFn func(self *HttpServer)
func addRoutes(fn routeHandlerRegisterFn) {
routeHandlers = append(routeHandlers, fn)
}
+17 -11
View File
@@ -4,7 +4,7 @@ import "github.com/gin-gonic/gin"
func init() {
addRoutes(func(self *HttpServer) {
self.router.POST("/api/account/collaborators/add", self.auth(), self.addCollaborator)
self.addRoute("POST", "/api/account/collaborators/add", self.addCollaborator)
})
}
@@ -12,28 +12,34 @@ type addCollaboratorDto struct {
Email string `json:"email" binding:"required"`
}
func (self *HttpServer) addCollaborator(c *gin.Context) {
func (self *HttpServer) addCollaborator(c *gin.Context, auth *authContext) {
var model addCollaboratorDto
if !c.EnsureBody(&model) {
c.JSON(400, gin.H{"status": "bad request"})
c.JSON(400, gin.H{"status": "Collaborator not found"})
return
}
accountId, _ := c.Get("accountId")
account, err := self.store.GetAccount(accountId.(int))
if err != nil {
c.JSON(401, gin.H{"status": "Authentication error"})
}
collaborator, err := self.store.GetUserAccountLogin(model.Email)
if err != nil {
c.JSON(404, gin.H{"status": "Collaborator not found"})
return
}
account.AddCollaborator(collaborator.Id)
userAccount := auth.userAccount
self.store.SaveUserAccount(account)
if collaborator.Id == userAccount.Id {
c.JSON(400, gin.H{"status": "Cannot add yourself as collaborator"})
return
}
err = userAccount.AddCollaborator(collaborator.Id)
if err != nil {
c.JSON(400, gin.H{"status": err.Error()})
return
}
self.store.SaveUserAccount(userAccount)
c.JSON(200, gin.H{"status": "Collaborator added"})
}
+48
View File
@@ -0,0 +1,48 @@
package api
import (
"github.com/gin-gonic/gin"
"github.com/torkelo/grafana-pro/pkg/models"
)
type authContext struct {
account *models.UserAccount
userAccount *models.UserAccount
}
func (auth *authContext) getAccountId() int {
return auth.account.Id
}
func (self *HttpServer) authDenied(c *gin.Context) {
c.Writer.Header().Set("Location", "/login")
c.Abort(302)
}
func (self *HttpServer) auth() gin.HandlerFunc {
return func(c *gin.Context) {
session, _ := sessionStore.Get(c.Request, "grafana-session")
if c.Request.URL.Path != "/login" && session.Values["userAccountId"] == nil {
self.authDenied(c)
return
}
account, err := self.store.GetAccount(session.Values["userAccountId"].(int))
if err != nil {
self.authDenied(c)
return
}
usingAccount, err := self.store.GetAccount(session.Values["usingAccountId"].(int))
if err != nil {
self.authDenied(c)
return
}
c.Set("userAccount", account)
c.Set("usingAccount", usingAccount)
session.Save(c.Request, c.Writer)
}
}
+13 -17
View File
@@ -8,18 +8,17 @@ import (
func init() {
addRoutes(func(self *HttpServer) {
self.router.GET("/api/dashboards/:slug", self.auth(), self.getDashboard)
self.router.GET("/api/search/", self.auth(), self.search)
self.router.POST("/api/dashboard", self.auth(), self.postDashboard)
self.router.DELETE("/api/dashboard/:slug", self.auth(), self.deleteDashboard)
self.addRoute("GET", "/api/dashboards/:slug", self.getDashboard)
self.addRoute("GET", "/api/search/", self.search)
self.addRoute("POST", "/api/dashboard/", self.postDashboard)
self.addRoute("DELETE", "/api/dashboard/:slug", self.deleteDashboard)
})
}
func (self *HttpServer) getDashboard(c *gin.Context) {
func (self *HttpServer) getDashboard(c *gin.Context, auth *authContext) {
slug := c.Params.ByName("slug")
accountId, err := c.Get("accountId")
dash, err := self.store.GetDashboard(slug, accountId.(int))
dash, err := self.store.GetDashboard(slug, auth.getAccountId())
if err != nil {
c.JSON(404, newErrorResponse("Dashboard not found"))
return
@@ -30,17 +29,16 @@ func (self *HttpServer) getDashboard(c *gin.Context) {
c.JSON(200, dash.Data)
}
func (self *HttpServer) deleteDashboard(c *gin.Context) {
func (self *HttpServer) deleteDashboard(c *gin.Context, auth *authContext) {
slug := c.Params.ByName("slug")
accountId, err := c.Get("accountId")
dash, err := self.store.GetDashboard(slug, accountId.(int))
dash, err := self.store.GetDashboard(slug, auth.getAccountId())
if err != nil {
c.JSON(404, newErrorResponse("Dashboard not found"))
return
}
err = self.store.DeleteDashboard(slug, accountId.(int))
err = self.store.DeleteDashboard(slug, auth.getAccountId())
if err != nil {
c.JSON(500, newErrorResponse("Failed to delete dashboard: "+err.Error()))
return
@@ -51,11 +49,10 @@ func (self *HttpServer) deleteDashboard(c *gin.Context) {
c.JSON(200, resp)
}
func (self *HttpServer) search(c *gin.Context) {
func (self *HttpServer) search(c *gin.Context, auth *authContext) {
query := c.Params.ByName("q")
accountId, err := c.Get("accountId")
results, err := self.store.Query(query, accountId.(int))
results, err := self.store.Query(query, auth.getAccountId())
if err != nil {
log.Error("Store query error: %v", err)
c.JSON(500, newErrorResponse("Failed"))
@@ -65,15 +62,14 @@ func (self *HttpServer) search(c *gin.Context) {
c.JSON(200, results)
}
func (self *HttpServer) postDashboard(c *gin.Context) {
func (self *HttpServer) postDashboard(c *gin.Context, auth *authContext) {
var command saveDashboardCommand
accountId, _ := c.Get("accountId")
if c.EnsureBody(&command) {
dashboard := models.NewDashboard("test")
dashboard.Data = command.Dashboard
dashboard.Title = dashboard.Data["title"].(string)
dashboard.AccountId = accountId.(int)
dashboard.AccountId = auth.getAccountId()
dashboard.UpdateSlug()
if dashboard.Data["id"] != nil {
+3 -20
View File
@@ -35,8 +35,8 @@ func (self *HttpServer) loginPost(c *gin.Context) {
}
session, _ := sessionStore.Get(c.Request, "grafana-session")
session.Values["login"] = loginModel.Email
session.Values["accountId"] = account.Id
session.Values["userAccountId"] = account.Id
session.Values["usingAccountId"] = account.UsingAccountId
session.Save(c.Request, c.Writer)
var resp = &LoginResultDto{}
@@ -48,25 +48,8 @@ func (self *HttpServer) loginPost(c *gin.Context) {
func (self *HttpServer) logoutPost(c *gin.Context) {
session, _ := sessionStore.Get(c.Request, "grafana-session")
session.Values["login"] = nil
session.Values = nil
session.Save(c.Request, c.Writer)
c.JSON(200, gin.H{"status": "logged out"})
}
func (self *HttpServer) auth() gin.HandlerFunc {
return func(c *gin.Context) {
session, _ := sessionStore.Get(c.Request, "grafana-session")
if c.Request.URL.Path != "/login" && session.Values["login"] == nil {
c.Writer.Header().Set("Location", "/login")
c.Abort(302)
return
}
c.Set("accountId", session.Values["accountId"])
c.Set("login", session.Values["login"])
session.Save(c.Request, c.Writer)
}
}
+36
View File
@@ -0,0 +1,36 @@
package api
import (
"github.com/gin-gonic/gin"
"github.com/torkelo/grafana-pro/pkg/models"
)
type routeHandlerRegisterFn func(self *HttpServer)
type routeHandlerFn func(c *gin.Context, auth *authContext)
var routeHandlers = make([]routeHandlerRegisterFn, 0)
func getRouteHandlerWrapper(handler routeHandlerFn) gin.HandlerFunc {
return func(c *gin.Context) {
authContext := authContext{
account: c.MustGet("usingAccount").(*models.UserAccount),
userAccount: c.MustGet("userAccount").(*models.UserAccount),
}
handler(c, &authContext)
}
}
func (self *HttpServer) addRoute(method string, path string, handler routeHandlerFn) {
switch method {
case "GET":
self.router.GET(path, self.auth(), getRouteHandlerWrapper(handler))
case "POST":
self.router.POST(path, self.auth(), getRouteHandlerWrapper(handler))
case "DELETE":
self.router.DELETE(path, self.auth(), getRouteHandlerWrapper(handler))
}
}
func addRoutes(fn routeHandlerRegisterFn) {
routeHandlers = append(routeHandlers, fn)
}