Procházet zdrojové kódy

working on account registration and more

Torkel Ödegaard před 11 roky
rodič
revize
31fe471da5

+ 2 - 2
pkg/api/api.go

@@ -51,8 +51,8 @@ func (self *HttpServer) ListenAndServe() {
 	}
 
 	// register default route
-	self.router.GET("/", self.authMiddleware(), self.index)
-	self.router.GET("/dashboard/*_", self.authMiddleware(), self.index)
+	self.router.GET("/", self.auth(), self.index)
+	self.router.GET("/dashboard/*_", self.auth(), self.index)
 
 	self.router.Run(":" + self.port)
 }

+ 5 - 4
pkg/api/api_dashboard.go

@@ -8,16 +8,17 @@ import (
 
 func init() {
 	addRoutes(func(self *HttpServer) {
-		self.router.GET("/api/dashboards/:id", self.getDashboard)
-		self.router.GET("/api/search/", self.search)
-		self.router.POST("/api/dashboard", self.postDashboard)
+		self.router.GET("/api/dashboards/:id", self.auth(), self.getDashboard)
+		self.router.GET("/api/search/", self.auth(), self.search)
+		self.router.POST("/api/dashboard", self.auth(), self.postDashboard)
 	})
 }
 
 func (self *HttpServer) getDashboard(c *gin.Context) {
 	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 {
 		c.JSON(404, newErrorResponse("Dashboard not found"))
 		return

+ 23 - 11
pkg/api/api_login.go

@@ -5,7 +5,6 @@ import "github.com/gin-gonic/gin"
 func init() {
 	addRoutes(func(self *HttpServer) {
 		self.router.GET("/login/*_", self.index)
-		self.router.GET("/register/*_", self.index)
 		self.router.POST("/login", self.loginPost)
 		self.router.POST("/logout", self.logoutPost)
 	})
@@ -20,18 +19,28 @@ type loginJsonModel struct {
 func (self *HttpServer) loginPost(c *gin.Context) {
 	var loginModel loginJsonModel
 
-	if c.EnsureBody(&loginModel) {
-		if loginModel.Email == "manu" && loginModel.Password == "123" {
+	if !c.EnsureBody(&loginModel) {
+		c.JSON(400, gin.H{"status": "bad request"})
+		return
+	}
 
-			session, _ := sessionStore.Get(c.Request, "grafana-session")
-			session.Values["login"] = true
-			session.Save(c.Request, c.Writer)
+	account, err := self.store.GetUserAccountLogin(loginModel.Email)
+	if err != nil {
+		c.JSON(400, gin.H{"status": "some error"})
+	}
 
-			c.JSON(200, gin.H{"status": "you are logged in"})
-		} else {
-			c.JSON(401, gin.H{"status": "unauthorized"})
-		}
+	if loginModel.Password != account.Password {
+		c.JSON(401, gin.H{"status": "unauthorized"})
+		return
 	}
+
+	session, _ := sessionStore.Get(c.Request, "grafana-session")
+	session.Values["login"] = true
+	session.Values["accountId"] = account.DatabaseId
+
+	session.Save(c.Request, c.Writer)
+
+	c.JSON(200, gin.H{"status": "you are logged in"})
 }
 
 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"})
 }
 
-func (self *HttpServer) authMiddleware() gin.HandlerFunc {
+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"])
+
 		session.Save(c.Request, c.Writer)
 	}
 }

+ 45 - 0
pkg/api/api_register.go

@@ -0,0 +1,45 @@
+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"})
+}

+ 20 - 0
pkg/models/dashboards.go

@@ -21,6 +21,26 @@ type Dashboard struct {
 	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 {
 	UserId    string
 	AccountId string

+ 5 - 0
pkg/stores/rethinkdb.go

@@ -39,10 +39,15 @@ func NewRethinkStore(config *RethinkCfg) *rethinkStore {
 	r.Db(config.DatabaseName).TableCreate("dashboards").Exec(session)
 	r.Db(config.DatabaseName).TableCreate("accounts").Exec(session)
 	r.Db(config.DatabaseName).TableCreate("master").Exec(session)
+
 	r.Db(config.DatabaseName).Table("dashboards").IndexCreateFunc("AccountIdSlug", func(row r.Term) interface{} {
 		return []interface{}{row.Field("AccountId"), row.Field("Slug")}
 	}).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)
 	if err != nil {
 		log.Error("Failed to insert master ids row", err)

+ 23 - 6
pkg/stores/rethinkdb_accounts.go

@@ -4,6 +4,7 @@ import (
 	"errors"
 
 	r "github.com/dancannon/gorethink"
+	"github.com/torkelo/grafana-pro/pkg/models"
 )
 
 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
 }
 
-func (self *rethinkStore) createAccount() (*Account, error) {
+func (self *rethinkStore) SaveUserAccount(account *models.UserAccount) error {
 	accountId, err := self.getNextAccountId()
 	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)
 	if err != nil {
-		return nil, err
+		return err
 	}
 
 	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) {

+ 10 - 5
pkg/stores/rethinkdb_test.go

@@ -35,15 +35,20 @@ func TestRethinkStore(t *testing.T) {
 	})
 
 	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(account, ShouldNotBeNil)
-		So(account.Id, ShouldNotEqual, 0)
+		So(account.DatabaseId, 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() {
-		account, err := store.createAccount()
-		dashId, err := store.getNextDashboardNumber(account.Id)
+		account := &models.UserAccount{UserName: "torkelo", Email: "mupp"}
+		err := store.SaveUserAccount(account)
+		dashId, err := store.getNextDashboardNumber(account.DatabaseId)
 		So(err, ShouldBeNil)
 		So(dashId, ShouldEqual, 1)
 	})

+ 2 - 0
pkg/stores/store.go

@@ -8,6 +8,8 @@ type Store interface {
 	GetDashboard(title string, accountId int) (*models.Dashboard, error)
 	SaveDashboard(dash *models.Dashboard) error
 	Query(query string) ([]*models.SearchResult, error)
+	SaveUserAccount(acccount *models.UserAccount) error
+	GetUserAccountLogin(emailOrName string) (*models.UserAccount, error)
 	Close()
 }