Sfoglia il codice sorgente

API token -> API key rename

Torkel Ödegaard 11 anni fa
parent
commit
951ce0a102

+ 1 - 1
grafana

@@ -1 +1 @@
-Subproject commit d2f21bc93e96d9ac36b1925c0b0b137a7edc94d2
+Subproject commit 11b74baf7920bcd4e39b5e77bfb49e6b08752dc2

+ 6 - 6
pkg/api/api.go

@@ -58,13 +58,13 @@ func Register(r *macaron.Macaron) {
 			r.Delete("/users/:id", RemoveAccountUser)
 		}, reqAccountAdmin)
 
-		// Token
-		r.Group("/tokens", func() {
+		// auth api keys
+		r.Group("/auth/keys", func() {
 			r.Combo("/").
-				Get(GetTokens).
-				Post(bind(m.AddTokenCommand{}), AddToken).
-				Put(bind(m.UpdateTokenCommand{}), UpdateToken)
-			r.Delete("/:id", DeleteToken)
+				Get(GetApiKeys).
+				Post(bind(m.AddApiKeyCommand{}), AddApiKey).
+				Put(bind(m.UpdateApiKeyCommand{}), UpdateApiKey)
+			r.Delete("/:id", DeleteApiKey)
 		}, reqAccountAdmin)
 
 		// Data sources

+ 83 - 0
pkg/api/apikey.go

@@ -0,0 +1,83 @@
+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"
+	"github.com/torkelo/grafana-pro/pkg/util"
+)
+
+func GetApiKeys(c *middleware.Context) {
+	query := m.GetApiKeysQuery{AccountId: c.AccountId}
+
+	if err := bus.Dispatch(&query); err != nil {
+		c.JsonApiErr(500, "Failed to list api keys", err)
+		return
+	}
+
+	result := make([]*m.ApiKeyDTO, len(query.Result))
+	for i, t := range query.Result {
+		result[i] = &m.ApiKeyDTO{
+			Id:   t.Id,
+			Name: t.Name,
+			Role: t.Role,
+			Key:  t.Key,
+		}
+	}
+	c.JSON(200, result)
+}
+
+func DeleteApiKey(c *middleware.Context) {
+	id := c.ParamsInt64(":id")
+
+	cmd := &m.DeleteApiKeyCommand{Id: id, AccountId: c.AccountId}
+
+	err := bus.Dispatch(cmd)
+	if err != nil {
+		c.JsonApiErr(500, "Failed to delete API key", err)
+		return
+	}
+
+	c.JsonOK("API key deleted")
+}
+
+func AddApiKey(c *middleware.Context, cmd m.AddApiKeyCommand) {
+	if !cmd.Role.IsValid() {
+		c.JsonApiErr(400, "Invalid role specified", nil)
+		return
+	}
+
+	cmd.AccountId = c.AccountId
+	cmd.Key = util.GetRandomString(64)
+
+	if err := bus.Dispatch(&cmd); err != nil {
+		c.JsonApiErr(500, "Failed to add API key", err)
+		return
+	}
+
+	result := &m.ApiKeyDTO{
+		Id:   cmd.Result.Id,
+		Name: cmd.Result.Name,
+		Role: cmd.Result.Role,
+		Key:  cmd.Result.Key,
+	}
+
+	c.JSON(200, result)
+}
+
+func UpdateApiKey(c *middleware.Context, cmd m.UpdateApiKeyCommand) {
+	if !cmd.Role.IsValid() {
+		c.JsonApiErr(400, "Invalid role specified", nil)
+		return
+	}
+
+	cmd.AccountId = c.AccountId
+
+	err := bus.Dispatch(&cmd)
+	if err != nil {
+		c.JsonApiErr(500, "Failed to update api key", err)
+		return
+	}
+
+	c.JsonOK("API key updated")
+}

+ 0 - 83
pkg/api/token.go

@@ -1,83 +0,0 @@
-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"
-	"github.com/torkelo/grafana-pro/pkg/util"
-)
-
-func GetTokens(c *middleware.Context) {
-	query := m.GetTokensQuery{AccountId: c.AccountId}
-
-	if err := bus.Dispatch(&query); err != nil {
-		c.JsonApiErr(500, "Failed to list tokens", err)
-		return
-	}
-
-	result := make([]*m.TokenDTO, len(query.Result))
-	for i, t := range query.Result {
-		result[i] = &m.TokenDTO{
-			Id:    t.Id,
-			Name:  t.Name,
-			Role:  t.Role,
-			Token: t.Token,
-		}
-	}
-	c.JSON(200, result)
-}
-
-func DeleteToken(c *middleware.Context) {
-	id := c.ParamsInt64(":id")
-
-	cmd := &m.DeleteTokenCommand{Id: id, AccountId: c.AccountId}
-
-	err := bus.Dispatch(cmd)
-	if err != nil {
-		c.JsonApiErr(500, "Failed to delete token", err)
-		return
-	}
-
-	c.JsonOK("Token deleted")
-}
-
-func AddToken(c *middleware.Context, cmd m.AddTokenCommand) {
-	if !cmd.Role.IsValid() {
-		c.JsonApiErr(400, "Invalid role specified", nil)
-		return
-	}
-
-	cmd.AccountId = c.AccountId
-	cmd.Token = util.GetRandomString(64)
-
-	if err := bus.Dispatch(&cmd); err != nil {
-		c.JsonApiErr(500, "Failed to add token", err)
-		return
-	}
-
-	result := &m.TokenDTO{
-		Id:    cmd.Result.Id,
-		Name:  cmd.Result.Name,
-		Role:  cmd.Result.Role,
-		Token: cmd.Result.Token,
-	}
-
-	c.JSON(200, result)
-}
-
-func UpdateToken(c *middleware.Context, cmd m.UpdateTokenCommand) {
-	if !cmd.Role.IsValid() {
-		c.JsonApiErr(400, "Invalid role specified", nil)
-		return
-	}
-
-	cmd.AccountId = c.AccountId
-
-	err := bus.Dispatch(&cmd)
-	if err != nil {
-		c.JsonApiErr(500, "Failed to update token", err)
-		return
-	}
-
-	c.JsonOK("Token updated")
-}

+ 3 - 3
pkg/middleware/auth.go

@@ -31,12 +31,12 @@ func getRequestUserId(c *Context) int64 {
 	return 0
 }
 
-func getApiToken(c *Context) string {
+func getApiKey(c *Context) string {
 	header := c.Req.Header.Get("Authorization")
 	parts := strings.SplitN(header, " ", 2)
 	if len(parts) == 2 || parts[0] == "Bearer" {
-		token := parts[1]
-		return token
+		key := parts[1]
+		return key
 	}
 
 	return ""

+ 8 - 8
pkg/middleware/middleware.go

@@ -39,22 +39,22 @@ func GetContextHandler() macaron.Handler {
 				ctx.IsSignedIn = true
 				ctx.SignedInUser = query.Result
 			}
-		} else if token := getApiToken(ctx); token != "" {
+		} else if key := getApiKey(ctx); key != "" {
 			// Try API Key auth
-			tokenQuery := m.GetTokenByTokenQuery{Token: token}
-			if err := bus.Dispatch(&tokenQuery); err != nil {
-				ctx.JsonApiErr(401, "Invalid token", err)
+			keyQuery := m.GetApiKeyByKeyQuery{Key: key}
+			if err := bus.Dispatch(&keyQuery); err != nil {
+				ctx.JsonApiErr(401, "Invalid API key", err)
 				return
 			} else {
-				tokenInfo := tokenQuery.Result
+				keyInfo := keyQuery.Result
 
 				ctx.IsSignedIn = true
 				ctx.SignedInUser = &m.SignedInUser{}
 
 				// TODO: fix this
-				ctx.AccountRole = tokenInfo.Role
-				ctx.ApiKeyId = tokenInfo.Id
-				ctx.AccountId = tokenInfo.AccountId
+				ctx.AccountRole = keyInfo.Role
+				ctx.ApiKeyId = keyInfo.Id
+				ctx.AccountId = keyInfo.AccountId
 			}
 		}
 

+ 65 - 0
pkg/models/apikey.go

@@ -0,0 +1,65 @@
+package models
+
+import (
+	"errors"
+	"time"
+)
+
+var ErrInvalidApiKey = errors.New("Invalid API Key")
+
+type ApiKey struct {
+	Id        int64
+	AccountId int64
+	Name      string
+	Key       string
+	Role      RoleType
+	Created   time.Time
+	Updated   time.Time
+}
+
+// ---------------------
+// COMMANDS
+type AddApiKeyCommand struct {
+	Name      string   `json:"name" binding:"required"`
+	Role      RoleType `json:"role" binding:"required"`
+	AccountId int64    `json:"-"`
+	Key       string   `json:"-"`
+
+	Result *ApiKey `json:"-"`
+}
+
+type UpdateApiKeyCommand struct {
+	Id   int64    `json:"id"`
+	Name string   `json:"name"`
+	Role RoleType `json:"role"`
+
+	AccountId int64 `json:"-"`
+}
+
+type DeleteApiKeyCommand struct {
+	Id        int64 `json:"id"`
+	AccountId int64 `json:"-"`
+}
+
+// ----------------------
+// QUERIES
+
+type GetApiKeysQuery struct {
+	AccountId int64
+	Result    []*ApiKey
+}
+
+type GetApiKeyByKeyQuery struct {
+	Key    string
+	Result *ApiKey
+}
+
+// ------------------------
+// DTO & Projections
+
+type ApiKeyDTO struct {
+	Id   int64    `json:"id"`
+	Name string   `json:"name"`
+	Key  string   `json:"key"`
+	Role RoleType `json:"role"`
+}

+ 0 - 66
pkg/models/token.go

@@ -1,66 +0,0 @@
-package models
-
-import (
-	"errors"
-	"time"
-)
-
-var ErrInvalidToken = errors.New("Invalid token")
-
-type Token struct {
-	Id        int64
-	AccountId int64    `xorm:"not null unique(uix_account_id_name)"`
-	Name      string   `xorm:"not null unique(uix_account_id_name)"`
-	Token     string   `xorm:"UNIQUE NOT NULL"`
-	Role      RoleType `xorm:"not null"`
-	Created   time.Time
-	Updated   time.Time
-}
-
-// ---------------------
-// COMMANDS
-type AddTokenCommand struct {
-	Name      string   `json:"name" binding:"required"`
-	Role      RoleType `json:"role" binding:"required"`
-	AccountId int64    `json:"-"`
-	Token     string   `json:"-"`
-	Result    *Token   `json:"-"`
-}
-
-type UpdateTokenCommand struct {
-	Id   int64    `json:"id"`
-	Name string   `json:"name"`
-	Role RoleType `json:"role"`
-
-	AccountId int64  `json:"-"`
-	Result    *Token `json:"-"`
-}
-
-type DeleteTokenCommand struct {
-	Id        int64  `json:"id"`
-	AccountId int64  `json:"-"`
-	Result    *Token `json:"-"`
-}
-
-// ----------------------
-// QUERIES
-
-type GetTokensQuery struct {
-	AccountId int64
-	Result    []*Token
-}
-
-type GetTokenByTokenQuery struct {
-	Token  string
-	Result *Token
-}
-
-// ------------------------
-// DTO & Projections
-
-type TokenDTO struct {
-	Id    int64    `json:"id"`
-	Name  string   `json:"name"`
-	Token string   `json:"token"`
-	Role  RoleType `json:"role"`
-}

+ 19 - 21
pkg/services/sqlstore/tokens.go → pkg/services/sqlstore/apikey.go

@@ -9,35 +9,35 @@ import (
 )
 
 func init() {
-	bus.AddHandler("sql", GetTokens)
-	bus.AddHandler("sql", GetTokenByToken)
-	bus.AddHandler("sql", UpdateToken)
-	bus.AddHandler("sql", DeleteToken)
-	bus.AddHandler("sql", AddToken)
+	bus.AddHandler("sql", GetApiKeys)
+	bus.AddHandler("sql", GetApiKeyByKey)
+	bus.AddHandler("sql", UpdateApiKey)
+	bus.AddHandler("sql", DeleteApiKey)
+	bus.AddHandler("sql", AddApiKey)
 }
 
-func GetTokens(query *m.GetTokensQuery) error {
+func GetApiKeys(query *m.GetApiKeysQuery) error {
 	sess := x.Limit(100, 0).Where("account_id=?", query.AccountId).Asc("name")
 
-	query.Result = make([]*m.Token, 0)
+	query.Result = make([]*m.ApiKey, 0)
 	return sess.Find(&query.Result)
 }
 
-func DeleteToken(cmd *m.DeleteTokenCommand) error {
+func DeleteApiKey(cmd *m.DeleteApiKeyCommand) error {
 	return inTransaction(func(sess *xorm.Session) error {
-		var rawSql = "DELETE FROM token WHERE id=? and account_id=?"
+		var rawSql = "DELETE FROM api_key WHERE id=? and account_id=?"
 		_, err := sess.Exec(rawSql, cmd.Id, cmd.AccountId)
 		return err
 	})
 }
 
-func AddToken(cmd *m.AddTokenCommand) error {
+func AddApiKey(cmd *m.AddApiKeyCommand) error {
 	return inTransaction(func(sess *xorm.Session) error {
-		t := m.Token{
+		t := m.ApiKey{
 			AccountId: cmd.AccountId,
 			Name:      cmd.Name,
 			Role:      cmd.Role,
-			Token:     cmd.Token,
+			Key:       cmd.Key,
 			Created:   time.Now(),
 			Updated:   time.Now(),
 		}
@@ -50,32 +50,30 @@ func AddToken(cmd *m.AddTokenCommand) error {
 	})
 }
 
-func UpdateToken(cmd *m.UpdateTokenCommand) error {
-
+func UpdateApiKey(cmd *m.UpdateApiKeyCommand) error {
 	return inTransaction(func(sess *xorm.Session) error {
-		t := m.Token{
+		t := m.ApiKey{
 			Id:        cmd.Id,
 			AccountId: cmd.AccountId,
 			Name:      cmd.Name,
 			Role:      cmd.Role,
 			Updated:   time.Now(),
 		}
-
 		_, err := sess.Where("id=? and account_id=?", t.Id, t.AccountId).Update(&t)
 		return err
 	})
 }
 
-func GetTokenByToken(query *m.GetTokenByTokenQuery) error {
-	var token m.Token
-	has, err := x.Where("token=?", query.Token).Get(&token)
+func GetApiKeyByKey(query *m.GetApiKeyByKeyQuery) error {
+	var apikey m.ApiKey
+	has, err := x.Where("key=?", query.Key).Get(&apikey)
 
 	if err != nil {
 		return err
 	} else if has == false {
-		return m.ErrInvalidToken
+		return m.ErrInvalidApiKey
 	}
 
-	query.Result = &token
+	query.Result = &apikey
 	return nil
 }

+ 16 - 7
pkg/services/sqlstore/migrations.go

@@ -2,13 +2,19 @@ package sqlstore
 
 import . "github.com/torkelo/grafana-pro/pkg/services/sqlstore/migrator"
 
+// --- Migration Guide line ---
+// 1. Never change a migration that is committed and pushed to master
+// 2. Always add new migrations (to change or undo previous migrations)
+// 3. Some migraitons are not yet written (rename column, table, drop table, index etc)
+// 4
+
 func addMigrations(mg *Migrator) {
 	addMigrationLogMigrations(mg)
 	addUserMigrations(mg)
 	addAccountMigrations(mg)
 	addDashboardMigration(mg)
 	addDataSourceMigration(mg)
-	addTokenMigrations(mg)
+	addApiKeyMigrations(mg)
 }
 
 func addMigrationLogMigrations(mg *Migrator) {
@@ -131,19 +137,22 @@ func addDataSourceMigration(mg *Migrator) {
 		Table("data_source").Columns("account_id", "name").Unique())
 }
 
-func addTokenMigrations(mg *Migrator) {
-	mg.AddMigration("create token table", new(AddTableMigration).
-		Name("token").WithColumns(
+func addApiKeyMigrations(mg *Migrator) {
+	mg.AddMigration("create api_key table", new(AddTableMigration).
+		Name("api_key").WithColumns(
 		&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
 		&Column{Name: "account_id", Type: DB_BigInt, Nullable: false},
 		&Column{Name: "name", Type: DB_NVarchar, Length: 255, Nullable: false},
-		&Column{Name: "token", Type: DB_NVarchar, Length: 255, Nullable: false},
+		&Column{Name: "key", Type: DB_Varchar, Length: 64, Nullable: false},
 		&Column{Name: "role", Type: DB_NVarchar, Length: 255, Nullable: false},
 		&Column{Name: "created", Type: DB_DateTime, Nullable: false},
 		&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
 	))
 
 	//-------  indexes ------------------
-	mg.AddMigration("add index token.account_id", new(AddIndexMigration).
-		Table("token").Columns("account_id"))
+	mg.AddMigration("add index api_key.account_id", new(AddIndexMigration).
+		Table("api_key").Columns("account_id"))
+
+	mg.AddMigration("add index api_key.key", new(AddIndexMigration).
+		Table("api_key").Columns("key").Unique())
 }