mirror of
https://github.com/grafana/grafana.git
synced 2025-07-29 22:12:08 +08:00
API token -> API key rename
This commit is contained in:
2
grafana
2
grafana
Submodule grafana updated: d2f21bc93e...11b74baf79
@ -58,13 +58,13 @@ func Register(r *macaron.Macaron) {
|
|||||||
r.Delete("/users/:id", RemoveAccountUser)
|
r.Delete("/users/:id", RemoveAccountUser)
|
||||||
}, reqAccountAdmin)
|
}, reqAccountAdmin)
|
||||||
|
|
||||||
// Token
|
// auth api keys
|
||||||
r.Group("/tokens", func() {
|
r.Group("/auth/keys", func() {
|
||||||
r.Combo("/").
|
r.Combo("/").
|
||||||
Get(GetTokens).
|
Get(GetApiKeys).
|
||||||
Post(bind(m.AddTokenCommand{}), AddToken).
|
Post(bind(m.AddApiKeyCommand{}), AddApiKey).
|
||||||
Put(bind(m.UpdateTokenCommand{}), UpdateToken)
|
Put(bind(m.UpdateApiKeyCommand{}), UpdateApiKey)
|
||||||
r.Delete("/:id", DeleteToken)
|
r.Delete("/:id", DeleteApiKey)
|
||||||
}, reqAccountAdmin)
|
}, reqAccountAdmin)
|
||||||
|
|
||||||
// Data sources
|
// Data sources
|
||||||
|
83
pkg/api/apikey.go
Normal file
83
pkg/api/apikey.go
Normal file
@ -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")
|
||||||
|
}
|
@ -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")
|
|
||||||
}
|
|
@ -31,12 +31,12 @@ func getRequestUserId(c *Context) int64 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func getApiToken(c *Context) string {
|
func getApiKey(c *Context) string {
|
||||||
header := c.Req.Header.Get("Authorization")
|
header := c.Req.Header.Get("Authorization")
|
||||||
parts := strings.SplitN(header, " ", 2)
|
parts := strings.SplitN(header, " ", 2)
|
||||||
if len(parts) == 2 || parts[0] == "Bearer" {
|
if len(parts) == 2 || parts[0] == "Bearer" {
|
||||||
token := parts[1]
|
key := parts[1]
|
||||||
return token
|
return key
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
|
@ -39,22 +39,22 @@ func GetContextHandler() macaron.Handler {
|
|||||||
ctx.IsSignedIn = true
|
ctx.IsSignedIn = true
|
||||||
ctx.SignedInUser = query.Result
|
ctx.SignedInUser = query.Result
|
||||||
}
|
}
|
||||||
} else if token := getApiToken(ctx); token != "" {
|
} else if key := getApiKey(ctx); key != "" {
|
||||||
// Try API Key auth
|
// Try API Key auth
|
||||||
tokenQuery := m.GetTokenByTokenQuery{Token: token}
|
keyQuery := m.GetApiKeyByKeyQuery{Key: key}
|
||||||
if err := bus.Dispatch(&tokenQuery); err != nil {
|
if err := bus.Dispatch(&keyQuery); err != nil {
|
||||||
ctx.JsonApiErr(401, "Invalid token", err)
|
ctx.JsonApiErr(401, "Invalid API key", err)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
tokenInfo := tokenQuery.Result
|
keyInfo := keyQuery.Result
|
||||||
|
|
||||||
ctx.IsSignedIn = true
|
ctx.IsSignedIn = true
|
||||||
ctx.SignedInUser = &m.SignedInUser{}
|
ctx.SignedInUser = &m.SignedInUser{}
|
||||||
|
|
||||||
// TODO: fix this
|
// TODO: fix this
|
||||||
ctx.AccountRole = tokenInfo.Role
|
ctx.AccountRole = keyInfo.Role
|
||||||
ctx.ApiKeyId = tokenInfo.Id
|
ctx.ApiKeyId = keyInfo.Id
|
||||||
ctx.AccountId = tokenInfo.AccountId
|
ctx.AccountId = keyInfo.AccountId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
65
pkg/models/apikey.go
Normal file
65
pkg/models/apikey.go
Normal file
@ -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"`
|
||||||
|
}
|
@ -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"`
|
|
||||||
}
|
|
@ -9,35 +9,35 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
bus.AddHandler("sql", GetTokens)
|
bus.AddHandler("sql", GetApiKeys)
|
||||||
bus.AddHandler("sql", GetTokenByToken)
|
bus.AddHandler("sql", GetApiKeyByKey)
|
||||||
bus.AddHandler("sql", UpdateToken)
|
bus.AddHandler("sql", UpdateApiKey)
|
||||||
bus.AddHandler("sql", DeleteToken)
|
bus.AddHandler("sql", DeleteApiKey)
|
||||||
bus.AddHandler("sql", AddToken)
|
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")
|
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)
|
return sess.Find(&query.Result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteToken(cmd *m.DeleteTokenCommand) error {
|
func DeleteApiKey(cmd *m.DeleteApiKeyCommand) error {
|
||||||
return inTransaction(func(sess *xorm.Session) 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)
|
_, err := sess.Exec(rawSql, cmd.Id, cmd.AccountId)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddToken(cmd *m.AddTokenCommand) error {
|
func AddApiKey(cmd *m.AddApiKeyCommand) error {
|
||||||
return inTransaction(func(sess *xorm.Session) error {
|
return inTransaction(func(sess *xorm.Session) error {
|
||||||
t := m.Token{
|
t := m.ApiKey{
|
||||||
AccountId: cmd.AccountId,
|
AccountId: cmd.AccountId,
|
||||||
Name: cmd.Name,
|
Name: cmd.Name,
|
||||||
Role: cmd.Role,
|
Role: cmd.Role,
|
||||||
Token: cmd.Token,
|
Key: cmd.Key,
|
||||||
Created: time.Now(),
|
Created: time.Now(),
|
||||||
Updated: 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 {
|
return inTransaction(func(sess *xorm.Session) error {
|
||||||
t := m.Token{
|
t := m.ApiKey{
|
||||||
Id: cmd.Id,
|
Id: cmd.Id,
|
||||||
AccountId: cmd.AccountId,
|
AccountId: cmd.AccountId,
|
||||||
Name: cmd.Name,
|
Name: cmd.Name,
|
||||||
Role: cmd.Role,
|
Role: cmd.Role,
|
||||||
Updated: time.Now(),
|
Updated: time.Now(),
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := sess.Where("id=? and account_id=?", t.Id, t.AccountId).Update(&t)
|
_, err := sess.Where("id=? and account_id=?", t.Id, t.AccountId).Update(&t)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetTokenByToken(query *m.GetTokenByTokenQuery) error {
|
func GetApiKeyByKey(query *m.GetApiKeyByKeyQuery) error {
|
||||||
var token m.Token
|
var apikey m.ApiKey
|
||||||
has, err := x.Where("token=?", query.Token).Get(&token)
|
has, err := x.Where("key=?", query.Key).Get(&apikey)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else if has == false {
|
} else if has == false {
|
||||||
return m.ErrInvalidToken
|
return m.ErrInvalidApiKey
|
||||||
}
|
}
|
||||||
|
|
||||||
query.Result = &token
|
query.Result = &apikey
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
@ -2,13 +2,19 @@ package sqlstore
|
|||||||
|
|
||||||
import . "github.com/torkelo/grafana-pro/pkg/services/sqlstore/migrator"
|
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) {
|
func addMigrations(mg *Migrator) {
|
||||||
addMigrationLogMigrations(mg)
|
addMigrationLogMigrations(mg)
|
||||||
addUserMigrations(mg)
|
addUserMigrations(mg)
|
||||||
addAccountMigrations(mg)
|
addAccountMigrations(mg)
|
||||||
addDashboardMigration(mg)
|
addDashboardMigration(mg)
|
||||||
addDataSourceMigration(mg)
|
addDataSourceMigration(mg)
|
||||||
addTokenMigrations(mg)
|
addApiKeyMigrations(mg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func addMigrationLogMigrations(mg *Migrator) {
|
func addMigrationLogMigrations(mg *Migrator) {
|
||||||
@ -131,19 +137,22 @@ func addDataSourceMigration(mg *Migrator) {
|
|||||||
Table("data_source").Columns("account_id", "name").Unique())
|
Table("data_source").Columns("account_id", "name").Unique())
|
||||||
}
|
}
|
||||||
|
|
||||||
func addTokenMigrations(mg *Migrator) {
|
func addApiKeyMigrations(mg *Migrator) {
|
||||||
mg.AddMigration("create token table", new(AddTableMigration).
|
mg.AddMigration("create api_key table", new(AddTableMigration).
|
||||||
Name("token").WithColumns(
|
Name("api_key").WithColumns(
|
||||||
&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
|
&Column{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
|
||||||
&Column{Name: "account_id", Type: DB_BigInt, Nullable: false},
|
&Column{Name: "account_id", Type: DB_BigInt, Nullable: false},
|
||||||
&Column{Name: "name", Type: DB_NVarchar, Length: 255, 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: "role", Type: DB_NVarchar, Length: 255, Nullable: false},
|
||||||
&Column{Name: "created", Type: DB_DateTime, Nullable: false},
|
&Column{Name: "created", Type: DB_DateTime, Nullable: false},
|
||||||
&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
|
&Column{Name: "updated", Type: DB_DateTime, Nullable: false},
|
||||||
))
|
))
|
||||||
|
|
||||||
//------- indexes ------------------
|
//------- indexes ------------------
|
||||||
mg.AddMigration("add index token.account_id", new(AddIndexMigration).
|
mg.AddMigration("add index api_key.account_id", new(AddIndexMigration).
|
||||||
Table("token").Columns("account_id"))
|
Table("api_key").Columns("account_id"))
|
||||||
|
|
||||||
|
mg.AddMigration("add index api_key.key", new(AddIndexMigration).
|
||||||
|
Table("api_key").Columns("key").Unique())
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user