mirror of
				https://github.com/grafana/grafana.git
				synced 2025-02-25 18:55:37 -06:00 
			
		
		
		
	Refactoring of auth middleware, and starting work on account admin
This commit is contained in:
		@@ -12,27 +12,44 @@ import (
 | 
			
		||||
	"github.com/torkelo/grafana-pro/pkg/setting"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func authGetRequestAccountId(c *Context) (int64, error) {
 | 
			
		||||
type AuthOptions struct {
 | 
			
		||||
	ReqAdmin    bool
 | 
			
		||||
	ReqSignedIn bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getRequestAccountId(c *Context) (int64, error) {
 | 
			
		||||
	accountId := c.Session.Get("accountId")
 | 
			
		||||
 | 
			
		||||
	urlQuery := c.Req.URL.Query()
 | 
			
		||||
	if accountId != nil {
 | 
			
		||||
		return accountId.(int64), nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// TODO: check that this is a localhost request
 | 
			
		||||
	// localhost render query
 | 
			
		||||
	urlQuery := c.Req.URL.Query()
 | 
			
		||||
	if len(urlQuery["render"]) > 0 {
 | 
			
		||||
		accId, _ := strconv.ParseInt(urlQuery["accountId"][0], 10, 64)
 | 
			
		||||
		c.Session.Set("accountId", accId)
 | 
			
		||||
		accountId = accId
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if accountId == nil {
 | 
			
		||||
		if setting.Anonymous {
 | 
			
		||||
			return setting.AnonymousAccountId, nil
 | 
			
		||||
	// check api token
 | 
			
		||||
	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 -1, errors.New("Auth: session account id not found")
 | 
			
		||||
		return userQuery.Result.Id, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return accountId.(int64), nil
 | 
			
		||||
	// anonymous gues user
 | 
			
		||||
	if setting.Anonymous {
 | 
			
		||||
		return setting.AnonymousAccountId, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return -1, errors.New("Auth: session account id not found")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func authDenied(c *Context) {
 | 
			
		||||
@@ -43,57 +60,17 @@ func authDenied(c *Context) {
 | 
			
		||||
	c.Redirect(setting.AppSubUrl + "/login")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func authByToken(c *Context) {
 | 
			
		||||
	header := c.Req.Header.Get("Authorization")
 | 
			
		||||
	parts := strings.SplitN(header, " ", 2)
 | 
			
		||||
	if len(parts) != 2 || parts[0] != "Bearer" {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	token := parts[1]
 | 
			
		||||
	userQuery := m.GetAccountByTokenQuery{Token: token}
 | 
			
		||||
 | 
			
		||||
	if err := bus.Dispatch(&userQuery); err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	usingQuery := m.GetAccountByIdQuery{Id: userQuery.Result.UsingAccountId}
 | 
			
		||||
	if err := bus.Dispatch(&usingQuery); err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.UserAccount = userQuery.Result
 | 
			
		||||
	c.Account = usingQuery.Result
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func authBySession(c *Context) {
 | 
			
		||||
	accountId, err := authGetRequestAccountId(c)
 | 
			
		||||
 | 
			
		||||
	if err != nil && c.Req.URL.Path != "/login" {
 | 
			
		||||
		authDenied(c)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	userQuery := m.GetAccountByIdQuery{Id: accountId}
 | 
			
		||||
	if err := bus.Dispatch(&userQuery); err != nil {
 | 
			
		||||
		authDenied(c)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	usingQuery := m.GetAccountByIdQuery{Id: userQuery.Result.UsingAccountId}
 | 
			
		||||
	if err := bus.Dispatch(&usingQuery); err != nil {
 | 
			
		||||
		authDenied(c)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.UserAccount = userQuery.Result
 | 
			
		||||
	c.Account = usingQuery.Result
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Auth() macaron.Handler {
 | 
			
		||||
func Auth(options *AuthOptions) macaron.Handler {
 | 
			
		||||
	return func(c *Context) {
 | 
			
		||||
		authByToken(c)
 | 
			
		||||
		if c.UserAccount == nil {
 | 
			
		||||
			authBySession(c)
 | 
			
		||||
 | 
			
		||||
		if !c.IsSignedIn && options.ReqSignedIn {
 | 
			
		||||
			authDenied(c)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if !c.IsAdmin && options.ReqAdmin {
 | 
			
		||||
			authDenied(c)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,8 +8,9 @@ import (
 | 
			
		||||
	"github.com/Unknwon/macaron"
 | 
			
		||||
	"github.com/macaron-contrib/session"
 | 
			
		||||
 | 
			
		||||
	"github.com/torkelo/grafana-pro/pkg/bus"
 | 
			
		||||
	"github.com/torkelo/grafana-pro/pkg/log"
 | 
			
		||||
	"github.com/torkelo/grafana-pro/pkg/models"
 | 
			
		||||
	m "github.com/torkelo/grafana-pro/pkg/models"
 | 
			
		||||
	"github.com/torkelo/grafana-pro/pkg/setting"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -17,8 +18,11 @@ type Context struct {
 | 
			
		||||
	*macaron.Context
 | 
			
		||||
	Session session.Store
 | 
			
		||||
 | 
			
		||||
	Account     *models.Account
 | 
			
		||||
	UserAccount *models.Account
 | 
			
		||||
	IsSignedIn bool
 | 
			
		||||
	IsAdmin    bool
 | 
			
		||||
 | 
			
		||||
	Account     *m.Account
 | 
			
		||||
	UserAccount *m.Account
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Context) GetAccountId() int64 {
 | 
			
		||||
@@ -32,6 +36,29 @@ func GetContextHandler() macaron.Handler {
 | 
			
		||||
			Session: sess,
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// try get account id from request
 | 
			
		||||
		if accountId, err := getRequestAccountId(ctx); err == nil {
 | 
			
		||||
			// fetch user
 | 
			
		||||
			userQuery := m.GetAccountByIdQuery{Id: accountId}
 | 
			
		||||
			if err := bus.Dispatch(&userQuery); err != nil {
 | 
			
		||||
				log.Error(3, "Failed to get user by id, %v, %v", accountId, err)
 | 
			
		||||
			} else {
 | 
			
		||||
				// fetch using account
 | 
			
		||||
				ctx.UserAccount = userQuery.Result
 | 
			
		||||
				usingQuery := m.GetAccountByIdQuery{Id: ctx.UserAccount.UsingAccountId}
 | 
			
		||||
				if err := bus.Dispatch(&usingQuery); err != nil {
 | 
			
		||||
					log.Error(3, "Faild to get account's using account, account: %v, usingAccountId: %v, err:%v", accountId, ctx.UserAccount.Id, err)
 | 
			
		||||
				} else {
 | 
			
		||||
					ctx.Account = usingQuery.Result
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ctx.Account != nil {
 | 
			
		||||
			ctx.IsSignedIn = true
 | 
			
		||||
			ctx.IsAdmin = ctx.Account.IsAdmin
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		c.Map(ctx)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user