RBAC: Redirect to /login when forceLogin is set (#56469)

This commit is contained in:
Emil Tullstedt
2022-10-07 08:18:56 +02:00
committed by GitHub
parent b622a87aee
commit bb479e030a
2 changed files with 115 additions and 1 deletions

View File

@@ -3,12 +3,18 @@ package accesscontrol
import (
"bytes"
"context"
"errors"
"fmt"
"net/http"
"net/url"
"regexp"
"strconv"
"strings"
"text/template"
"time"
"github.com/grafana/grafana/pkg/middleware/cookies"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
@@ -23,6 +29,24 @@ func Middleware(ac AccessControl) func(web.Handler, Evaluator) web.Handler {
}
return func(c *models.ReqContext) {
if c.AllowAnonymous {
forceLogin, _ := strconv.ParseBool(c.Req.URL.Query().Get("forceLogin")) // ignoring error, assuming false for non-true values is ok.
orgID, err := strconv.ParseInt(c.Req.URL.Query().Get("orgId"), 10, 64)
if err == nil && orgID > 0 && orgID != c.OrgID {
forceLogin = true
}
if !c.IsSignedIn && forceLogin {
unauthorized(c, nil)
}
}
var revokedErr *models.TokenRevokedError
if errors.As(c.LookupTokenErr, &revokedErr) {
unauthorized(c, revokedErr)
return
}
authorize(c, ac, c.SignedInUser, evaluator)
}
}
@@ -80,6 +104,47 @@ func deny(c *models.ReqContext, evaluator Evaluator, err error) {
})
}
func unauthorized(c *models.ReqContext, err error) {
if c.IsApiRequest() {
response := map[string]interface{}{
"message": "Unauthorized",
}
var revokedErr *models.TokenRevokedError
if errors.As(err, &revokedErr) {
response["message"] = "Token revoked"
response["error"] = map[string]interface{}{
"id": "ERR_TOKEN_REVOKED",
"maxConcurrentSessions": revokedErr.MaxConcurrentSessions,
}
}
c.JSON(http.StatusUnauthorized, response)
return
}
writeRedirectCookie(c)
c.Redirect(setting.AppSubUrl + "/login")
}
func writeRedirectCookie(c *models.ReqContext) {
redirectTo := c.Req.RequestURI
if setting.AppSubUrl != "" && !strings.HasPrefix(redirectTo, setting.AppSubUrl) {
redirectTo = setting.AppSubUrl + c.Req.RequestURI
}
// remove any forceLogin=true params
redirectTo = removeForceLoginParams(redirectTo)
cookies.WriteCookie(c.Resp, "redirect_to", url.QueryEscape(redirectTo), 0, nil)
}
var forceLoginParamsRegexp = regexp.MustCompile(`&?forceLogin=true`)
func removeForceLoginParams(str string) string {
return forceLoginParamsRegexp.ReplaceAllString(str, "")
}
func newID() string {
// Less ambiguity than alphanumerical.
numerical := []byte("0123456789")