mirror of
https://github.com/grafana/grafana.git
synced 2024-11-27 03:11:01 -06:00
c5f906f472
* Refactor redirect_to cookie with secure flag in middleware * Refactor redirect_to cookie with secure flag in api/login * Refactor redirect_to cookie with secure flag in api/login_oauth * Removed the deletion of 'Set-Cookie' header to prevent logout * Removed the deletion of 'Set-Cookie' at top of api/login.go * Add HttpOnly flag on redirect_to cookies where missing * Refactor duplicated code * Add tests * Refactor cookie options * Replace local function for deleting cookie * Delete redundant calls Co-authored-by: Sofia Papagiannaki <papagian@users.noreply.github.com>
119 lines
2.4 KiB
Go
119 lines
2.4 KiB
Go
package middleware
|
|
|
|
import (
|
|
"net/url"
|
|
"strings"
|
|
|
|
macaron "gopkg.in/macaron.v1"
|
|
|
|
m "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 *m.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 *m.ReqContext) {
|
|
if c.IsApiRequest() {
|
|
c.JsonApiErr(403, "Permission denied", nil)
|
|
return
|
|
}
|
|
|
|
c.Redirect(setting.AppSubUrl + "/")
|
|
}
|
|
|
|
func notAuthorized(c *m.ReqContext) {
|
|
if c.IsApiRequest() {
|
|
c.JsonApiErr(401, "Unauthorized", nil)
|
|
return
|
|
}
|
|
|
|
WriteCookie(c.Resp, "redirect_to", url.QueryEscape(setting.AppSubUrl+c.Req.RequestURI), 0, newCookieOptions)
|
|
|
|
c.Redirect(setting.AppSubUrl + "/login")
|
|
}
|
|
|
|
func EnsureEditorOrViewerCanEdit(c *m.ReqContext) {
|
|
if !c.SignedInUser.HasRole(m.ROLE_EDITOR) && !setting.ViewersCanEdit {
|
|
accessForbidden(c)
|
|
}
|
|
}
|
|
|
|
func RoleAuth(roles ...m.RoleType) macaron.Handler {
|
|
return func(c *m.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 *m.ReqContext) {
|
|
if !c.IsSignedIn && options.ReqSignedIn && !c.AllowAnonymous {
|
|
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 *m.ReqContext) {
|
|
if c.OrgRole == m.ROLE_ADMIN {
|
|
return
|
|
}
|
|
|
|
if !enabled {
|
|
accessForbidden(c)
|
|
}
|
|
}
|
|
}
|
|
|
|
func SnapshotPublicModeOrSignedIn() macaron.Handler {
|
|
return func(c *m.ReqContext) {
|
|
if setting.SnapshotPublicMode {
|
|
return
|
|
}
|
|
|
|
_, err := c.Invoke(ReqSignedIn)
|
|
if err != nil {
|
|
c.JsonApiErr(500, "Failed to invoke required signed in middleware", err)
|
|
}
|
|
}
|
|
}
|