2014-10-06 03:13:01 +08:00
|
|
|
package middleware
|
|
|
|
|
|
|
|
import (
|
2015-01-27 19:05:23 +08:00
|
|
|
"net/url"
|
2020-11-21 02:30:37 +08:00
|
|
|
"regexp"
|
2020-07-06 20:59:00 +08:00
|
|
|
"strconv"
|
2015-01-14 16:33:34 +08:00
|
|
|
"strings"
|
2014-11-20 22:19:44 +08:00
|
|
|
|
2019-03-05 19:41:01 +08:00
|
|
|
macaron "gopkg.in/macaron.v1"
|
2015-01-14 21:25:12 +08:00
|
|
|
|
2020-12-11 18:44:44 +08:00
|
|
|
"github.com/grafana/grafana/pkg/middleware/cookies"
|
2020-02-28 19:50:58 +08:00
|
|
|
"github.com/grafana/grafana/pkg/models"
|
2015-02-05 17:37:13 +08:00
|
|
|
"github.com/grafana/grafana/pkg/setting"
|
2014-10-06 03:13:01 +08:00
|
|
|
)
|
|
|
|
|
2015-01-15 19:16:54 +08:00
|
|
|
type AuthOptions struct {
|
2015-01-16 21:32:18 +08:00
|
|
|
ReqGrafanaAdmin bool
|
|
|
|
ReqSignedIn bool
|
2021-02-28 01:04:28 +08:00
|
|
|
ReqNoAnonynmous bool
|
2015-01-15 19:16:54 +08:00
|
|
|
}
|
|
|
|
|
2020-02-28 19:50:58 +08:00
|
|
|
func accessForbidden(c *models.ReqContext) {
|
2015-01-14 21:25:12 +08:00
|
|
|
if c.IsApiRequest() {
|
2015-09-08 16:46:31 +08:00
|
|
|
c.JsonApiErr(403, "Permission denied", nil)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-02-06 01:17:47 +08:00
|
|
|
c.Redirect(setting.AppSubUrl + "/")
|
2015-09-08 16:46:31 +08:00
|
|
|
}
|
|
|
|
|
2020-02-28 19:50:58 +08:00
|
|
|
func notAuthorized(c *models.ReqContext) {
|
2015-09-08 16:46:31 +08:00
|
|
|
if c.IsApiRequest() {
|
|
|
|
c.JsonApiErr(401, "Unauthorized", nil)
|
2015-01-27 19:05:23 +08:00
|
|
|
return
|
2015-01-14 21:25:12 +08:00
|
|
|
}
|
|
|
|
|
2020-03-11 17:04:48 +08:00
|
|
|
redirectTo := c.Req.RequestURI
|
|
|
|
if setting.AppSubUrl != "" && !strings.HasPrefix(redirectTo, setting.AppSubUrl) {
|
|
|
|
redirectTo = setting.AppSubUrl + c.Req.RequestURI
|
|
|
|
}
|
2018-02-15 17:56:29 +08:00
|
|
|
|
2020-11-21 02:30:37 +08:00
|
|
|
// remove any forceLogin=true params
|
|
|
|
redirectTo = removeForceLoginParams(redirectTo)
|
|
|
|
|
2020-12-11 18:44:44 +08:00
|
|
|
cookies.WriteCookie(c.Resp, "redirect_to", url.QueryEscape(redirectTo), 0, nil)
|
2015-01-05 04:03:40 +08:00
|
|
|
c.Redirect(setting.AppSubUrl + "/login")
|
2014-10-06 03:13:01 +08:00
|
|
|
}
|
|
|
|
|
2020-11-21 02:30:37 +08:00
|
|
|
var forceLoginParamsRegexp = regexp.MustCompile(`&?forceLogin=true`)
|
|
|
|
|
|
|
|
func removeForceLoginParams(str string) string {
|
|
|
|
return forceLoginParamsRegexp.ReplaceAllString(str, "")
|
|
|
|
}
|
|
|
|
|
2020-02-28 19:50:58 +08:00
|
|
|
func EnsureEditorOrViewerCanEdit(c *models.ReqContext) {
|
|
|
|
if !c.SignedInUser.HasRole(models.ROLE_EDITOR) && !setting.ViewersCanEdit {
|
2019-03-05 19:41:01 +08:00
|
|
|
accessForbidden(c)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-28 19:50:58 +08:00
|
|
|
func RoleAuth(roles ...models.RoleType) macaron.Handler {
|
|
|
|
return func(c *models.ReqContext) {
|
2015-01-16 22:28:44 +08:00
|
|
|
ok := false
|
|
|
|
for _, role := range roles {
|
2015-02-24 03:07:49 +08:00
|
|
|
if role == c.OrgRole {
|
2015-01-16 22:28:44 +08:00
|
|
|
ok = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !ok {
|
2015-09-08 16:46:31 +08:00
|
|
|
accessForbidden(c)
|
2015-01-16 22:28:44 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-15 19:16:54 +08:00
|
|
|
func Auth(options *AuthOptions) macaron.Handler {
|
2020-02-28 19:50:58 +08:00
|
|
|
return func(c *models.ReqContext) {
|
2020-07-06 20:59:00 +08:00
|
|
|
forceLogin := false
|
2021-02-28 01:04:28 +08:00
|
|
|
|
2020-07-06 20:59:00 +08:00
|
|
|
if c.AllowAnonymous {
|
|
|
|
forceLoginParam, err := strconv.ParseBool(c.Req.URL.Query().Get("forceLogin"))
|
|
|
|
if err == nil {
|
|
|
|
forceLogin = forceLoginParam
|
|
|
|
}
|
2020-10-23 22:34:35 +08:00
|
|
|
|
|
|
|
if !forceLogin {
|
|
|
|
orgIDValue := c.Req.URL.Query().Get("orgId")
|
|
|
|
orgID, err := strconv.ParseInt(orgIDValue, 10, 64)
|
|
|
|
if err == nil && orgID > 0 && orgID != c.OrgId {
|
|
|
|
forceLogin = true
|
|
|
|
}
|
|
|
|
}
|
2020-07-06 20:59:00 +08:00
|
|
|
}
|
2021-02-28 01:04:28 +08:00
|
|
|
|
|
|
|
requireLogin := !c.AllowAnonymous || forceLogin || options.ReqNoAnonynmous
|
|
|
|
|
2020-06-16 21:33:44 +08:00
|
|
|
if !c.IsSignedIn && options.ReqSignedIn && requireLogin {
|
2015-09-08 16:46:31 +08:00
|
|
|
notAuthorized(c)
|
2015-01-15 19:16:54 +08:00
|
|
|
return
|
|
|
|
}
|
2015-01-14 16:33:34 +08:00
|
|
|
|
2015-09-08 16:46:31 +08:00
|
|
|
if !c.IsGrafanaAdmin && options.ReqGrafanaAdmin {
|
|
|
|
accessForbidden(c)
|
2015-01-15 19:16:54 +08:00
|
|
|
return
|
2015-01-14 16:33:34 +08:00
|
|
|
}
|
2014-10-06 03:13:01 +08:00
|
|
|
}
|
|
|
|
}
|
2019-03-06 17:27:38 +08:00
|
|
|
|
2019-03-14 17:02:46 +08:00
|
|
|
// 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 {
|
2020-02-28 19:50:58 +08:00
|
|
|
return func(c *models.ReqContext) {
|
|
|
|
if c.OrgRole == models.ROLE_ADMIN {
|
2019-03-13 17:38:09 +08:00
|
|
|
return
|
2019-03-06 17:27:38 +08:00
|
|
|
}
|
|
|
|
|
2019-03-13 17:38:09 +08:00
|
|
|
if !enabled {
|
2019-03-06 17:27:38 +08:00
|
|
|
accessForbidden(c)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-09-02 21:15:46 +08:00
|
|
|
|
2021-02-17 16:51:50 +08:00
|
|
|
// SnapshotPublicModeOrSignedIn creates a middleware that allows access
|
|
|
|
// if snapshot public mode is enabled or if user is signed in.
|
2020-12-11 18:44:44 +08:00
|
|
|
func SnapshotPublicModeOrSignedIn(cfg *setting.Cfg) macaron.Handler {
|
2020-02-28 19:50:58 +08:00
|
|
|
return func(c *models.ReqContext) {
|
2020-12-11 18:44:44 +08:00
|
|
|
if cfg.SnapshotPublicMode {
|
2019-09-02 21:15:46 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-02-17 16:51:50 +08:00
|
|
|
if !c.IsSignedIn {
|
|
|
|
notAuthorized(c)
|
|
|
|
return
|
2019-09-02 21:15:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|