diff --git a/pkg/api/token.go b/pkg/api/token.go index d0b381a1867..6f47aa69827 100644 --- a/pkg/api/token.go +++ b/pkg/api/token.go @@ -9,12 +9,12 @@ import ( func GetTokens(c *middleware.Context) { query := m.GetTokensQuery{AccountId: c.AccountId} - err := bus.Dispatch(&query) - if err != nil { + 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{ diff --git a/pkg/middleware/auth.go b/pkg/middleware/auth.go index 7e037b8d9c1..f1571668162 100644 --- a/pkg/middleware/auth.go +++ b/pkg/middleware/auth.go @@ -1,13 +1,11 @@ package middleware import ( - "errors" "strconv" "strings" "github.com/Unknwon/macaron" - "github.com/torkelo/grafana-pro/pkg/bus" m "github.com/torkelo/grafana-pro/pkg/models" "github.com/torkelo/grafana-pro/pkg/setting" ) @@ -17,11 +15,11 @@ type AuthOptions struct { ReqSignedIn bool } -func getRequestAccountId(c *Context) (int64, error) { +func getRequestAccountId(c *Context) int64 { accountId := c.Session.Get("accountId") if accountId != nil { - return accountId.(int64), nil + return accountId.(int64) } // localhost render query @@ -32,24 +30,18 @@ func getRequestAccountId(c *Context) (int64, error) { accountId = accId } - // check api token + return 0 +} + +func getApiToken(c *Context) string { header := c.Req.Header.Get("Authorization") parts := strings.SplitN(header, " ", 2) if len(parts) == 2 || parts[0] == "Bearer" { token := parts[1] - userQuery := m.GetAccountByTokenQuery{Token: token} - if err := bus.Dispatch(&userQuery); err != nil { - return -1, err - } - return userQuery.Result.Id, nil + return token } - // anonymous gues user - if setting.Anonymous { - return setting.AnonymousAccountId, nil - } - - return -1, errors.New("Auth: session account id not found") + return "" } func authDenied(c *Context) { diff --git a/pkg/middleware/middleware.go b/pkg/middleware/middleware.go index 0c7dc4b6eda..77ade01f75c 100644 --- a/pkg/middleware/middleware.go +++ b/pkg/middleware/middleware.go @@ -31,7 +31,7 @@ func GetContextHandler() macaron.Handler { } // try get account id from request - if accountId, err := getRequestAccountId(ctx); err == nil { + if accountId := getRequestAccountId(ctx); accountId != 0 { query := m.GetSignedInUserQuery{AccountId: accountId} if err := bus.Dispatch(&query); err != nil { log.Error(3, "Failed to get user by id, %v, %v", accountId, err) @@ -39,6 +39,28 @@ func GetContextHandler() macaron.Handler { ctx.IsSignedIn = true ctx.SignInUser = query.Result } + } else if token := getApiToken(ctx); token != "" { + // Try API Key auth + tokenQuery := m.GetTokenByTokenQuery{Token: token} + if err := bus.Dispatch(&tokenQuery); err != nil { + ctx.JsonApiErr(401, "Invalid token", err) + return + } else { + tokenInfo := tokenQuery.Result + query := m.GetSignedInUserQuery{AccountId: tokenInfo.AccountId} + if err := bus.Dispatch(&query); err != nil { + ctx.JsonApiErr(401, "Invalid token", err) + return + } + + ctx.IsSignedIn = true + ctx.SignInUser = query.Result + + // api key role + ctx.SignInUser.UserRole = tokenInfo.Role + ctx.SignInUser.UsingAccountId = ctx.SignInUser.AccountId + ctx.SignInUser.UsingAccountName = ctx.SignInUser.UserName + } } c.Map(ctx) diff --git a/pkg/models/token.go b/pkg/models/token.go index 02be6a90dd8..752c324f08c 100644 --- a/pkg/models/token.go +++ b/pkg/models/token.go @@ -1,9 +1,12 @@ 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)"` @@ -47,9 +50,9 @@ type GetTokensQuery struct { Result []*Token } -type GetAccountByTokenQuery struct { +type GetTokenByTokenQuery struct { Token string - Result *Account + Result *Token } // ------------------------ diff --git a/pkg/services/sqlstore/accounts.go b/pkg/services/sqlstore/accounts.go index e84d37aa25d..ca478a7e161 100644 --- a/pkg/services/sqlstore/accounts.go +++ b/pkg/services/sqlstore/accounts.go @@ -17,7 +17,6 @@ func init() { bus.AddHandler("sql", SetUsingAccount) bus.AddHandler("sql", GetAccountById) bus.AddHandler("sql", GetAccountByLogin) - bus.AddHandler("sql", GetAccountByToken) bus.AddHandler("sql", SearchAccounts) bus.AddHandler("sql", UpdateAccount) bus.AddHandler("sql", GetSignedInUser) @@ -111,30 +110,6 @@ func GetAccountById(query *m.GetAccountByIdQuery) error { return nil } -func GetAccountByToken(query *m.GetAccountByTokenQuery) error { - var err error - - var account m.Account - sess := x.Join("INNER", "token", "token.account_id = account.id") - sess.Omit("token.id", "token.account_id", "token.name", "token.token", - "token.role", "token.updated", "token.created") - has, err := sess.Where("token.token=?", query.Token).Get(&account) - - if err != nil { - return err - } else if has == false { - return m.ErrAccountNotFound - } - - if account.UsingAccountId == 0 { - account.UsingAccountId = account.Id - } - - query.Result = &account - - return nil -} - func GetAccountByLogin(query *m.GetAccountByLoginQuery) error { if query.LoginOrEmail == "" { return m.ErrAccountNotFound diff --git a/pkg/services/sqlstore/tokens.go b/pkg/services/sqlstore/tokens.go index 8603f43f08a..41bde590737 100644 --- a/pkg/services/sqlstore/tokens.go +++ b/pkg/services/sqlstore/tokens.go @@ -10,9 +10,10 @@ import ( func init() { bus.AddHandler("sql", GetTokens) - bus.AddHandler("sql", AddToken) + bus.AddHandler("sql", GetTokenByToken) bus.AddHandler("sql", UpdateToken) bus.AddHandler("sql", DeleteToken) + bus.AddHandler("sql", DeleteToken) } func GetTokens(query *m.GetTokensQuery) error { @@ -64,3 +65,17 @@ func UpdateToken(cmd *m.UpdateTokenCommand) error { return err }) } + +func GetTokenByToken(query *m.GetTokenByTokenQuery) error { + var token m.Token + has, err := x.Where("token=?", query.Token).Get(&token) + + if err != nil { + return err + } else if has == false { + return m.ErrInvalidToken + } + + query.Result = &token + return nil +}