Commit 31fe471d by Torkel Ödegaard

working on account registration and more

parent c684b1dd
...@@ -51,8 +51,8 @@ func (self *HttpServer) ListenAndServe() { ...@@ -51,8 +51,8 @@ func (self *HttpServer) ListenAndServe() {
} }
// register default route // register default route
self.router.GET("/", self.authMiddleware(), self.index) self.router.GET("/", self.auth(), self.index)
self.router.GET("/dashboard/*_", self.authMiddleware(), self.index) self.router.GET("/dashboard/*_", self.auth(), self.index)
self.router.Run(":" + self.port) self.router.Run(":" + self.port)
} }
......
...@@ -8,16 +8,17 @@ import ( ...@@ -8,16 +8,17 @@ import (
func init() { func init() {
addRoutes(func(self *HttpServer) { addRoutes(func(self *HttpServer) {
self.router.GET("/api/dashboards/:id", self.getDashboard) self.router.GET("/api/dashboards/:id", self.auth(), self.getDashboard)
self.router.GET("/api/search/", self.search) self.router.GET("/api/search/", self.auth(), self.search)
self.router.POST("/api/dashboard", self.postDashboard) self.router.POST("/api/dashboard", self.auth(), self.postDashboard)
}) })
} }
func (self *HttpServer) getDashboard(c *gin.Context) { func (self *HttpServer) getDashboard(c *gin.Context) {
id := c.Params.ByName("id") id := c.Params.ByName("id")
accountId, err := c.Get("accountId")
dash, err := self.store.GetDashboard(id, 1) dash, err := self.store.GetDashboard(id, accountId.(int))
if err != nil { if err != nil {
c.JSON(404, newErrorResponse("Dashboard not found")) c.JSON(404, newErrorResponse("Dashboard not found"))
return return
......
...@@ -5,7 +5,6 @@ import "github.com/gin-gonic/gin" ...@@ -5,7 +5,6 @@ import "github.com/gin-gonic/gin"
func init() { func init() {
addRoutes(func(self *HttpServer) { addRoutes(func(self *HttpServer) {
self.router.GET("/login/*_", self.index) self.router.GET("/login/*_", self.index)
self.router.GET("/register/*_", self.index)
self.router.POST("/login", self.loginPost) self.router.POST("/login", self.loginPost)
self.router.POST("/logout", self.logoutPost) self.router.POST("/logout", self.logoutPost)
}) })
...@@ -20,18 +19,28 @@ type loginJsonModel struct { ...@@ -20,18 +19,28 @@ type loginJsonModel struct {
func (self *HttpServer) loginPost(c *gin.Context) { func (self *HttpServer) loginPost(c *gin.Context) {
var loginModel loginJsonModel var loginModel loginJsonModel
if c.EnsureBody(&loginModel) { if !c.EnsureBody(&loginModel) {
if loginModel.Email == "manu" && loginModel.Password == "123" { c.JSON(400, gin.H{"status": "bad request"})
return
}
account, err := self.store.GetUserAccountLogin(loginModel.Email)
if err != nil {
c.JSON(400, gin.H{"status": "some error"})
}
if loginModel.Password != account.Password {
c.JSON(401, gin.H{"status": "unauthorized"})
return
}
session, _ := sessionStore.Get(c.Request, "grafana-session") session, _ := sessionStore.Get(c.Request, "grafana-session")
session.Values["login"] = true session.Values["login"] = true
session.Values["accountId"] = account.DatabaseId
session.Save(c.Request, c.Writer) session.Save(c.Request, c.Writer)
c.JSON(200, gin.H{"status": "you are logged in"}) c.JSON(200, gin.H{"status": "you are logged in"})
} else {
c.JSON(401, gin.H{"status": "unauthorized"})
}
}
} }
func (self *HttpServer) logoutPost(c *gin.Context) { func (self *HttpServer) logoutPost(c *gin.Context) {
...@@ -42,15 +51,18 @@ func (self *HttpServer) logoutPost(c *gin.Context) { ...@@ -42,15 +51,18 @@ func (self *HttpServer) logoutPost(c *gin.Context) {
c.JSON(200, gin.H{"status": "logged out"}) c.JSON(200, gin.H{"status": "logged out"})
} }
func (self *HttpServer) authMiddleware() gin.HandlerFunc { func (self *HttpServer) auth() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
session, _ := sessionStore.Get(c.Request, "grafana-session") session, _ := sessionStore.Get(c.Request, "grafana-session")
if c.Request.URL.Path != "/login" && session.Values["login"] == nil { if c.Request.URL.Path != "/login" && session.Values["login"] == nil {
c.Writer.Header().Set("Location", "/login") c.Writer.Header().Set("Location", "/login")
c.Abort(302) c.Abort(302)
return
} }
c.Set("accountId", session.Values["accountId"])
session.Save(c.Request, c.Writer) session.Save(c.Request, c.Writer)
} }
} }
package api
import (
log "github.com/alecthomas/log4go"
"github.com/gin-gonic/gin"
"github.com/torkelo/grafana-pro/pkg/models"
)
func init() {
addRoutes(func(self *HttpServer) {
self.router.GET("/register/*_", self.index)
self.router.POST("/api/register/user", self.registerUserPost)
})
}
type registerAccountJsonModel struct {
Email string `json:"email" binding:"required"`
Password string `json:"password" binding:"required"`
Password2 bool `json:"remember2"`
}
func (self *HttpServer) registerUserPost(c *gin.Context) {
var registerModel registerAccountJsonModel
if !c.EnsureBody(&registerModel) {
c.JSON(400, gin.H{"status": "bad request"})
return
}
account := models.UserAccount{
UserName: registerModel.Email,
Login: registerModel.Email,
Email: registerModel.Email,
Password: registerModel.Password,
}
err := self.store.SaveUserAccount(&account)
if err != nil {
log.Error("Failed to create user account, email: %v, error: %v", registerModel.Email, err)
c.JSON(500, gin.H{"status": "failed to create account"})
return
}
c.JSON(200, gin.H{"status": "ok"})
}
...@@ -21,6 +21,26 @@ type Dashboard struct { ...@@ -21,6 +21,26 @@ type Dashboard struct {
Data map[string]interface{} Data map[string]interface{}
} }
type UserAccountLink struct {
UserId int
Role string
ModifiedOn time.Time
CreatedOn time.Time
}
type UserAccount struct {
DatabaseId int `gorethink:"id"`
UserName string
Login string
Email string
Password string
NextDashboardId int
UsingAccountId int
GrantedAccess []UserAccountLink
CreatedOn time.Time
ModifiedOn time.Time
}
type UserContext struct { type UserContext struct {
UserId string UserId string
AccountId string AccountId string
......
...@@ -39,10 +39,15 @@ func NewRethinkStore(config *RethinkCfg) *rethinkStore { ...@@ -39,10 +39,15 @@ func NewRethinkStore(config *RethinkCfg) *rethinkStore {
r.Db(config.DatabaseName).TableCreate("dashboards").Exec(session) r.Db(config.DatabaseName).TableCreate("dashboards").Exec(session)
r.Db(config.DatabaseName).TableCreate("accounts").Exec(session) r.Db(config.DatabaseName).TableCreate("accounts").Exec(session)
r.Db(config.DatabaseName).TableCreate("master").Exec(session) r.Db(config.DatabaseName).TableCreate("master").Exec(session)
r.Db(config.DatabaseName).Table("dashboards").IndexCreateFunc("AccountIdSlug", func(row r.Term) interface{} { r.Db(config.DatabaseName).Table("dashboards").IndexCreateFunc("AccountIdSlug", func(row r.Term) interface{} {
return []interface{}{row.Field("AccountId"), row.Field("Slug")} return []interface{}{row.Field("AccountId"), row.Field("Slug")}
}).Exec(session) }).Exec(session)
r.Db(config.DatabaseName).Table("accounts").IndexCreateFunc("AccountLogin", func(row r.Term) interface{} {
return []interface{}{row.Field("Login")}
}).Exec(session)
_, err = r.Table("master").Insert(map[string]interface{}{"id": "ids", "NextAccountId": 0}).RunWrite(session) _, err = r.Table("master").Insert(map[string]interface{}{"id": "ids", "NextAccountId": 0}).RunWrite(session)
if err != nil { if err != nil {
log.Error("Failed to insert master ids row", err) log.Error("Failed to insert master ids row", err)
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"errors" "errors"
r "github.com/dancannon/gorethink" r "github.com/dancannon/gorethink"
"github.com/torkelo/grafana-pro/pkg/models"
) )
func (self *rethinkStore) getNextAccountId() (int, error) { func (self *rethinkStore) getNextAccountId() (int, error) {
...@@ -22,24 +23,40 @@ func (self *rethinkStore) getNextAccountId() (int, error) { ...@@ -22,24 +23,40 @@ func (self *rethinkStore) getNextAccountId() (int, error) {
return int(resp.NewValue.(map[string]interface{})["NextAccountId"].(float64)), nil return int(resp.NewValue.(map[string]interface{})["NextAccountId"].(float64)), nil
} }
func (self *rethinkStore) createAccount() (*Account, error) { func (self *rethinkStore) SaveUserAccount(account *models.UserAccount) error {
accountId, err := self.getNextAccountId() accountId, err := self.getNextAccountId()
if err != nil { if err != nil {
return nil, err return err
} }
account := &Account{Id: accountId, NextDashboardId: 0} account.DatabaseId = accountId
resp, err := r.Table("accounts").Insert(account).RunWrite(self.session) resp, err := r.Table("accounts").Insert(account).RunWrite(self.session)
if err != nil { if err != nil {
return nil, err return err
} }
if resp.Inserted == 0 { if resp.Inserted == 0 {
return nil, errors.New("Failed to insert acccount") return errors.New("Failed to insert acccount")
}
return nil
}
func (self *rethinkStore) GetUserAccountLogin(emailOrName string) (*models.UserAccount, error) {
resp, err := r.Table("accounts").GetAllByIndex("AccountLogin", []interface{}{emailOrName}).Run(self.session)
if err != nil {
return nil, err
}
var account models.UserAccount
err = resp.One(&account)
if err != nil {
return nil, errors.New("Not found")
} }
return account, nil return &account, nil
} }
func (self *rethinkStore) getNextDashboardNumber(accountId int) (int, error) { func (self *rethinkStore) getNextDashboardNumber(accountId int) (int, error) {
......
...@@ -35,15 +35,20 @@ func TestRethinkStore(t *testing.T) { ...@@ -35,15 +35,20 @@ func TestRethinkStore(t *testing.T) {
}) })
Convey("can create account", t, func() { Convey("can create account", t, func() {
account, err := store.createAccount() account := &models.UserAccount{UserName: "torkelo", Email: "mupp", Login: "test@test.com"}
err := store.SaveUserAccount(account)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(account, ShouldNotBeNil) So(account.DatabaseId, ShouldNotEqual, 0)
So(account.Id, ShouldNotEqual, 0)
read, err := store.GetUserAccountLogin("test@test.com")
So(err, ShouldBeNil)
So(read.DatabaseId, ShouldEqual, account.DatabaseId)
}) })
Convey("can get next dashboard id", t, func() { Convey("can get next dashboard id", t, func() {
account, err := store.createAccount() account := &models.UserAccount{UserName: "torkelo", Email: "mupp"}
dashId, err := store.getNextDashboardNumber(account.Id) err := store.SaveUserAccount(account)
dashId, err := store.getNextDashboardNumber(account.DatabaseId)
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(dashId, ShouldEqual, 1) So(dashId, ShouldEqual, 1)
}) })
......
...@@ -8,6 +8,8 @@ type Store interface { ...@@ -8,6 +8,8 @@ type Store interface {
GetDashboard(title string, accountId int) (*models.Dashboard, error) GetDashboard(title string, accountId int) (*models.Dashboard, error)
SaveDashboard(dash *models.Dashboard) error SaveDashboard(dash *models.Dashboard) error
Query(query string) ([]*models.SearchResult, error) Query(query string) ([]*models.SearchResult, error)
SaveUserAccount(acccount *models.UserAccount) error
GetUserAccountLogin(emailOrName string) (*models.UserAccount, error)
Close() Close()
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment