mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			140 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
	
| package middleware
 | |
| 
 | |
| import (
 | |
| 	"net/url"
 | |
| 	"strconv"
 | |
| 	"strings"
 | |
| 
 | |
| 	macaron "gopkg.in/macaron.v1"
 | |
| 
 | |
| 	"github.com/grafana/grafana/pkg/models"
 | |
| 	"github.com/grafana/grafana/pkg/setting"
 | |
| 	"github.com/grafana/grafana/pkg/util"
 | |
| )
 | |
| 
 | |
| type AuthOptions struct {
 | |
| 	ReqGrafanaAdmin bool
 | |
| 	ReqSignedIn     bool
 | |
| }
 | |
| 
 | |
| func getApiKey(c *models.ReqContext) string {
 | |
| 	header := c.Req.Header.Get("Authorization")
 | |
| 	parts := strings.SplitN(header, " ", 2)
 | |
| 	if len(parts) == 2 && parts[0] == "Bearer" {
 | |
| 		key := parts[1]
 | |
| 		return key
 | |
| 	}
 | |
| 
 | |
| 	username, password, err := util.DecodeBasicAuthHeader(header)
 | |
| 	if err == nil && username == "api_key" {
 | |
| 		return password
 | |
| 	}
 | |
| 
 | |
| 	return ""
 | |
| }
 | |
| 
 | |
| func accessForbidden(c *models.ReqContext) {
 | |
| 	if c.IsApiRequest() {
 | |
| 		c.JsonApiErr(403, "Permission denied", nil)
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	c.Redirect(setting.AppSubUrl + "/")
 | |
| }
 | |
| 
 | |
| func notAuthorized(c *models.ReqContext) {
 | |
| 	if c.IsApiRequest() {
 | |
| 		c.JsonApiErr(401, "Unauthorized", nil)
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	redirectTo := c.Req.RequestURI
 | |
| 	if setting.AppSubUrl != "" && !strings.HasPrefix(redirectTo, setting.AppSubUrl) {
 | |
| 		redirectTo = setting.AppSubUrl + c.Req.RequestURI
 | |
| 	}
 | |
| 
 | |
| 	// remove forceLogin query param if it exists
 | |
| 	if parsed, err := url.ParseRequestURI(redirectTo); err == nil {
 | |
| 		params := parsed.Query()
 | |
| 		params.Del("forceLogin")
 | |
| 		parsed.RawQuery = params.Encode()
 | |
| 		WriteCookie(c.Resp, "redirect_to", url.QueryEscape(parsed.String()), 0, newCookieOptions)
 | |
| 	} else {
 | |
| 		c.Logger.Debug("Failed parsing request URI; redirect cookie will not be set", "redirectTo", redirectTo, "error", err)
 | |
| 	}
 | |
| 	c.Redirect(setting.AppSubUrl + "/login")
 | |
| }
 | |
| 
 | |
| func EnsureEditorOrViewerCanEdit(c *models.ReqContext) {
 | |
| 	if !c.SignedInUser.HasRole(models.ROLE_EDITOR) && !setting.ViewersCanEdit {
 | |
| 		accessForbidden(c)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func RoleAuth(roles ...models.RoleType) macaron.Handler {
 | |
| 	return func(c *models.ReqContext) {
 | |
| 		ok := false
 | |
| 		for _, role := range roles {
 | |
| 			if role == c.OrgRole {
 | |
| 				ok = true
 | |
| 				break
 | |
| 			}
 | |
| 		}
 | |
| 		if !ok {
 | |
| 			accessForbidden(c)
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func Auth(options *AuthOptions) macaron.Handler {
 | |
| 	return func(c *models.ReqContext) {
 | |
| 		forceLogin := false
 | |
| 		if c.AllowAnonymous {
 | |
| 			forceLoginParam, err := strconv.ParseBool(c.Req.URL.Query().Get("forceLogin"))
 | |
| 			if err == nil {
 | |
| 				forceLogin = forceLoginParam
 | |
| 			}
 | |
| 		}
 | |
| 		requireLogin := !c.AllowAnonymous || forceLogin
 | |
| 		if !c.IsSignedIn && options.ReqSignedIn && requireLogin {
 | |
| 			notAuthorized(c)
 | |
| 			return
 | |
| 		}
 | |
| 
 | |
| 		if !c.IsGrafanaAdmin && options.ReqGrafanaAdmin {
 | |
| 			accessForbidden(c)
 | |
| 			return
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // AdminOrFeatureEnabled creates a middleware that allows access
 | |
| // if the signed in user is either an Org Admin or if the
 | |
| // feature flag is enabled.
 | |
| // Intended for when feature flags open up access to APIs that
 | |
| // are otherwise only available to admins.
 | |
| func AdminOrFeatureEnabled(enabled bool) macaron.Handler {
 | |
| 	return func(c *models.ReqContext) {
 | |
| 		if c.OrgRole == models.ROLE_ADMIN {
 | |
| 			return
 | |
| 		}
 | |
| 
 | |
| 		if !enabled {
 | |
| 			accessForbidden(c)
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func SnapshotPublicModeOrSignedIn() macaron.Handler {
 | |
| 	return func(c *models.ReqContext) {
 | |
| 		if setting.SnapshotPublicMode {
 | |
| 			return
 | |
| 		}
 | |
| 
 | |
| 		_, err := c.Invoke(ReqSignedIn)
 | |
| 		if err != nil {
 | |
| 			c.JsonApiErr(500, "Failed to invoke required signed in middleware", err)
 | |
| 		}
 | |
| 	}
 | |
| }
 |