Commit 951ce0a1 by Torkel Ödegaard

API token -> API key rename

parent db371d2a
Subproject commit d2f21bc93e96d9ac36b1925c0b0b137a7edc94d2
Subproject commit 11b74baf7920bcd4e39b5e77bfb49e6b08752dc2
......@@ -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
......
......@@ -7,65 +7,65 @@ import (
"github.com/torkelo/grafana-pro/pkg/util"
)
func GetTokens(c *middleware.Context) {
query := m.GetTokensQuery{AccountId: c.AccountId}
func GetApiKeys(c *middleware.Context) {
query := m.GetApiKeysQuery{AccountId: c.AccountId}
if err := bus.Dispatch(&query); err != nil {
c.JsonApiErr(500, "Failed to list tokens", err)
c.JsonApiErr(500, "Failed to list api keys", err)
return
}
result := make([]*m.TokenDTO, len(query.Result))
result := make([]*m.ApiKeyDTO, len(query.Result))
for i, t := range query.Result {
result[i] = &m.TokenDTO{
result[i] = &m.ApiKeyDTO{
Id: t.Id,
Name: t.Name,
Role: t.Role,
Token: t.Token,
Key: t.Key,
}
}
c.JSON(200, result)
}
func DeleteToken(c *middleware.Context) {
func DeleteApiKey(c *middleware.Context) {
id := c.ParamsInt64(":id")
cmd := &m.DeleteTokenCommand{Id: id, AccountId: c.AccountId}
cmd := &m.DeleteApiKeyCommand{Id: id, AccountId: c.AccountId}
err := bus.Dispatch(cmd)
if err != nil {
c.JsonApiErr(500, "Failed to delete token", err)
c.JsonApiErr(500, "Failed to delete API key", err)
return
}
c.JsonOK("Token deleted")
c.JsonOK("API key deleted")
}
func AddToken(c *middleware.Context, cmd m.AddTokenCommand) {
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.Token = util.GetRandomString(64)
cmd.Key = util.GetRandomString(64)
if err := bus.Dispatch(&cmd); err != nil {
c.JsonApiErr(500, "Failed to add token", err)
c.JsonApiErr(500, "Failed to add API key", err)
return
}
result := &m.TokenDTO{
result := &m.ApiKeyDTO{
Id: cmd.Result.Id,
Name: cmd.Result.Name,
Role: cmd.Result.Role,
Token: cmd.Result.Token,
Key: cmd.Result.Key,
}
c.JSON(200, result)
}
func UpdateToken(c *middleware.Context, cmd m.UpdateTokenCommand) {
func UpdateApiKey(c *middleware.Context, cmd m.UpdateApiKeyCommand) {
if !cmd.Role.IsValid() {
c.JsonApiErr(400, "Invalid role specified", nil)
return
......@@ -75,9 +75,9 @@ func UpdateToken(c *middleware.Context, cmd m.UpdateTokenCommand) {
err := bus.Dispatch(&cmd)
if err != nil {
c.JsonApiErr(500, "Failed to update token", err)
c.JsonApiErr(500, "Failed to update api key", err)
return
}
c.JsonOK("Token updated")
c.JsonOK("API key updated")
}
......@@ -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 ""
......
......@@ -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
}
}
......
......@@ -5,62 +5,61 @@ import (
"time"
)
var ErrInvalidToken = errors.New("Invalid token")
var ErrInvalidApiKey = errors.New("Invalid API Key")
type Token struct {
type ApiKey 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"`
AccountId int64
Name string
Key string
Role RoleType
Created time.Time
Updated time.Time
}
// ---------------------
// COMMANDS
type AddTokenCommand struct {
type AddApiKeyCommand struct {
Name string `json:"name" binding:"required"`
Role RoleType `json:"role" binding:"required"`
AccountId int64 `json:"-"`
Token string `json:"-"`
Result *Token `json:"-"`
Key string `json:"-"`
Result *ApiKey `json:"-"`
}
type UpdateTokenCommand struct {
type UpdateApiKeyCommand struct {
Id int64 `json:"id"`
Name string `json:"name"`
Role RoleType `json:"role"`
AccountId int64 `json:"-"`
Result *Token `json:"-"`
}
type DeleteTokenCommand struct {
type DeleteApiKeyCommand struct {
Id int64 `json:"id"`
AccountId int64 `json:"-"`
Result *Token `json:"-"`
}
// ----------------------
// QUERIES
type GetTokensQuery struct {
type GetApiKeysQuery struct {
AccountId int64
Result []*Token
Result []*ApiKey
}
type GetTokenByTokenQuery struct {
Token string
Result *Token
type GetApiKeyByKeyQuery struct {
Key string
Result *ApiKey
}
// ------------------------
// DTO & Projections
type TokenDTO struct {
type ApiKeyDTO struct {
Id int64 `json:"id"`
Name string `json:"name"`
Token string `json:"token"`
Key string `json:"key"`
Role RoleType `json:"role"`
}
......@@ -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
}
......@@ -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())
}
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