浏览代码

Worked on ease of use for non multi tenant scenarios, Closes #20

Torkel Ödegaard 11 年之前
父节点
当前提交
757b185398

+ 17 - 5
conf/grafana.ini

@@ -40,16 +40,28 @@ session_id_hashkey =
 admin_user = admin
 ; default admin password, can be changed before first start of grafana,  or in profile settings
 admin_password = admin
-; used for sig
-secret_key = !#@FDEWREWR&*(
+; used for signing
+secret_key = SW2YcwTIb9zpOOhoPsMm
 ; Auto-login remember days
 login_remember_days = 7
 cookie_username = grafana_user
 cookie_remember_name = grafana_remember
 
-[auth]
-anonymous = false
-anonymous_account_id =
+[account.single]
+; Enable this feature to auto assign new users to a single account, suitable for NON multi tenant setups
+enabled = true
+; Name of default account
+account_name = main
+; Default role new users will be automatically assigned
+default_role = Editor
+
+[auth.anonymous]
+; enable anonymous access
+enabled = false
+; specify account name that should be used for unauthenticated users
+account = main
+; specify role for unauthenticated users
+role = Viewer
 
 [auth.github]
 enabled = false

+ 1 - 5
pkg/api/signup.go

@@ -4,16 +4,12 @@ import (
 	"github.com/torkelo/grafana-pro/pkg/bus"
 	"github.com/torkelo/grafana-pro/pkg/middleware"
 	m "github.com/torkelo/grafana-pro/pkg/models"
-	"github.com/torkelo/grafana-pro/pkg/util"
 )
 
-// POST /api/account/signup
+// POST /api/user/signup
 func SignUp(c *middleware.Context, cmd m.CreateUserCommand) {
 
 	cmd.Login = cmd.Email
-	cmd.Salt = util.GetRandomString(10)
-	cmd.Rands = util.GetRandomString(10)
-	cmd.Password = util.EncodePassword(cmd.Password, cmd.Salt)
 
 	if err := bus.Dispatch(&cmd); err != nil {
 		c.JsonApiErr(500, "failed to create user", err)

+ 0 - 2
pkg/models/user.go

@@ -36,8 +36,6 @@ type CreateUserCommand struct {
 	Name     string `json:"name"`
 	Company  string `json:"compay"`
 	Password string `json:"password" binding:"Required"`
-	Salt     string `json:"-"`
-	Rands    string `json:"-"`
 	IsAdmin  bool   `json:"-"`
 
 	Result User `json:"-"`

+ 28 - 0
pkg/services/sqlstore/account_test.go

@@ -6,6 +6,7 @@ import (
 	. "github.com/smartystreets/goconvey/convey"
 
 	m "github.com/torkelo/grafana-pro/pkg/models"
+	"github.com/torkelo/grafana-pro/pkg/setting"
 )
 
 func TestAccountDataAccess(t *testing.T) {
@@ -13,7 +14,34 @@ func TestAccountDataAccess(t *testing.T) {
 	Convey("Testing Account DB Access", t, func() {
 		InitTestDB(t)
 
+		Convey("Given single account mode", func() {
+			setting.SingleAccountMode = true
+			setting.DefaultAccountName = "test"
+			setting.DefaultAccountRole = "Viewer"
+
+			Convey("Users should be added to default account", func() {
+				ac1cmd := m.CreateUserCommand{Login: "ac1", Email: "ac1@test.com", Name: "ac1 name"}
+				ac2cmd := m.CreateUserCommand{Login: "ac2", Email: "ac2@test.com", Name: "ac2 name"}
+
+				err := CreateUser(&ac1cmd)
+				So(err, ShouldBeNil)
+				err = CreateUser(&ac2cmd)
+				So(err, ShouldBeNil)
+
+				q1 := m.GetUserAccountsQuery{UserId: ac1cmd.Result.Id}
+				q2 := m.GetUserAccountsQuery{UserId: ac2cmd.Result.Id}
+				GetUserAccounts(&q1)
+				GetUserAccounts(&q2)
+
+				So(q1.Result[0].AccountId, ShouldEqual, q2.Result[0].AccountId)
+				So(q1.Result[0].Role, ShouldEqual, "Viewer")
+			})
+		})
+
 		Convey("Given two saved users", func() {
+			setting.SingleAccountMode = false
+
+			setting.DefaultAccountName = "test"
 			ac1cmd := m.CreateUserCommand{Login: "ac1", Email: "ac1@test.com", Name: "ac1 name"}
 			ac2cmd := m.CreateUserCommand{Login: "ac2", Email: "ac2@test.com", Name: "ac2 name", IsAdmin: true}
 

+ 1 - 0
pkg/services/sqlstore/datasource_test.go

@@ -13,6 +13,7 @@ import (
 
 func InitTestDB(t *testing.T) {
 
+	t.Log("InitTestDB")
 	x, err := xorm.NewEngine(sqlutil.TestDB_Sqlite3.DriverName, sqlutil.TestDB_Sqlite3.ConnStr)
 	//x, err := xorm.NewEngine(sqlutil.TestDB_Mysql.DriverName, sqlutil.TestDB_Mysql.ConnStr)
 	//x, err := xorm.NewEngine(sqlutil.TestDB_Postgres.DriverName, sqlutil.TestDB_Postgres.ConnStr)

+ 1 - 4
pkg/services/sqlstore/sqlstore.go

@@ -11,7 +11,6 @@ import (
 	m "github.com/torkelo/grafana-pro/pkg/models"
 	"github.com/torkelo/grafana-pro/pkg/services/sqlstore/migrator"
 	"github.com/torkelo/grafana-pro/pkg/setting"
-	"github.com/torkelo/grafana-pro/pkg/util"
 
 	_ "github.com/go-sql-driver/mysql"
 	"github.com/go-xorm/xorm"
@@ -40,9 +39,7 @@ func EnsureAdminUser() {
 		cmd := m.CreateUserCommand{}
 		cmd.Login = setting.AdminUser
 		cmd.Email = setting.AdminUser + "@localhost"
-		cmd.Salt = util.GetRandomString(10)
-		cmd.Rands = util.GetRandomString(10)
-		cmd.Password = util.EncodePassword(setting.AdminPassword, cmd.Salt)
+		cmd.Password = setting.AdminPassword
 		cmd.IsAdmin = true
 
 		if err = bus.Dispatch(&cmd); err != nil {

+ 45 - 15
pkg/services/sqlstore/user.go

@@ -8,6 +8,8 @@ import (
 
 	"github.com/torkelo/grafana-pro/pkg/bus"
 	m "github.com/torkelo/grafana-pro/pkg/models"
+	"github.com/torkelo/grafana-pro/pkg/setting"
+	"github.com/torkelo/grafana-pro/pkg/util"
 )
 
 func init() {
@@ -21,48 +23,76 @@ func init() {
 	bus.AddHandler("sql", GetUserAccounts)
 }
 
-func CreateUser(cmd *m.CreateUserCommand) error {
-	return inTransaction(func(sess *xorm.Session) error {
+func getAccountIdForNewUser(userEmail string, sess *xorm.Session) (int64, error) {
+	var account m.Account
 
-		// create account
-		account := m.Account{
-			Name:    cmd.Email,
-			Created: time.Now(),
-			Updated: time.Now(),
+	if setting.SingleAccountMode {
+		has, err := sess.Where("name=?", setting.DefaultAccountName).Get(&account)
+		if err != nil {
+			return 0, err
 		}
+		if has {
+			return account.Id, nil
+		} else {
+			account.Name = setting.DefaultAccountName
+		}
+	} else {
+		account.Name = userEmail
+	}
+
+	account.Created = time.Now()
+	account.Updated = time.Now()
 
-		if _, err := sess.Insert(&account); err != nil {
+	if _, err := sess.Insert(&account); err != nil {
+		return 0, err
+	}
+
+	return account.Id, nil
+}
+
+func CreateUser(cmd *m.CreateUserCommand) error {
+	return inTransaction(func(sess *xorm.Session) error {
+		accountId, err := getAccountIdForNewUser(cmd.Email, sess)
+		if err != nil {
 			return err
 		}
 
 		// create user
 		user := m.User{
 			Email:     cmd.Email,
-			Password:  cmd.Password,
 			Name:      cmd.Name,
 			Login:     cmd.Login,
 			Company:   cmd.Company,
-			Salt:      cmd.Salt,
-			Rands:     cmd.Rands,
 			IsAdmin:   cmd.IsAdmin,
-			AccountId: account.Id,
+			AccountId: accountId,
 			Created:   time.Now(),
 			Updated:   time.Now(),
 		}
 
+		user.Salt = util.GetRandomString(10)
+		user.Rands = util.GetRandomString(10)
+		user.Password = util.EncodePassword(cmd.Password, user.Salt)
+
 		sess.UseBool("is_admin")
+
 		if _, err := sess.Insert(&user); err != nil {
 			return err
 		}
 
 		// create account user link
-		_, err := sess.Insert(&m.AccountUser{
-			AccountId: account.Id,
+		accountUser := m.AccountUser{
+			AccountId: accountId,
 			UserId:    user.Id,
 			Role:      m.ROLE_ADMIN,
 			Created:   time.Now(),
 			Updated:   time.Now(),
-		})
+		}
+
+		if setting.SingleAccountMode {
+			accountUser.Role = m.RoleType(setting.DefaultAccountRole)
+		}
+
+		_, err = sess.Insert(&accountUser)
 
 		cmd.Result = user
 		return err

+ 11 - 1
pkg/setting/setting.go

@@ -64,6 +64,11 @@ var (
 	CookieUserName     string
 	CookieRememberName string
 
+	// single account
+	SingleAccountMode  bool
+	DefaultAccountName string
+	DefaultAccountRole string
+
 	// Http auth
 	AdminUser          string
 	AdminPassword      string
@@ -190,7 +195,12 @@ func NewConfigContext() {
 	CookieUserName = security.Key("cookie_username").String()
 	CookieRememberName = security.Key("cookie_remember_name").String()
 
-	// Http auth
+	// single account
+	SingleAccountMode = Cfg.Section("account.single").Key("enabled").MustBool(false)
+	DefaultAccountName = Cfg.Section("account.single").Key("account_name").MustString("main")
+	DefaultAccountRole = Cfg.Section("account.single").Key("default_role").In("Editor", []string{"Editor", "Admin", "Viewer"})
+
+	// admin
 	AdminUser = security.Key("admin_user").String()
 	AdminPassword = security.Key("admin_password").String()