mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
parent
e17ef5e504
commit
aee5c6dea0
@ -90,7 +90,6 @@ Alpha features might be changed or removed without prior notice.
|
|||||||
| `showDashboardValidationWarnings` | Show warnings when dashboards do not validate against the schema |
|
| `showDashboardValidationWarnings` | Show warnings when dashboards do not validate against the schema |
|
||||||
| `mysqlAnsiQuotes` | Use double quotes to escape keyword in a MySQL query |
|
| `mysqlAnsiQuotes` | Use double quotes to escape keyword in a MySQL query |
|
||||||
| `showTraceId` | Show trace ids for requests |
|
| `showTraceId` | Show trace ids for requests |
|
||||||
| `authnService` | Use new auth service to perform authentication |
|
|
||||||
| `alertingBacktesting` | Rule backtesting API for alerting |
|
| `alertingBacktesting` | Rule backtesting API for alerting |
|
||||||
| `editPanelCSVDragAndDrop` | Enables drag and drop for CSV and Excel files |
|
| `editPanelCSVDragAndDrop` | Enables drag and drop for CSV and Excel files |
|
||||||
| `lokiQuerySplitting` | Split large interval queries into subqueries with smaller time intervals |
|
| `lokiQuerySplitting` | Split large interval queries into subqueries with smaller time intervals |
|
||||||
|
@ -59,7 +59,6 @@ export interface FeatureToggles {
|
|||||||
accessTokenExpirationCheck?: boolean;
|
accessTokenExpirationCheck?: boolean;
|
||||||
showTraceId?: boolean;
|
showTraceId?: boolean;
|
||||||
emptyDashboardPage?: boolean;
|
emptyDashboardPage?: boolean;
|
||||||
authnService?: boolean;
|
|
||||||
disablePrometheusExemplarSampling?: boolean;
|
disablePrometheusExemplarSampling?: boolean;
|
||||||
alertingBacktesting?: boolean;
|
alertingBacktesting?: boolean;
|
||||||
editPanelCSVDragAndDrop?: boolean;
|
editPanelCSVDragAndDrop?: boolean;
|
||||||
|
@ -617,7 +617,7 @@ func (hs *HTTPServer) addMiddlewaresAndStaticRoutes() {
|
|||||||
m.UseMiddleware(hs.ContextHandler.Middleware)
|
m.UseMiddleware(hs.ContextHandler.Middleware)
|
||||||
m.Use(middleware.OrgRedirect(hs.Cfg, hs.userService))
|
m.Use(middleware.OrgRedirect(hs.Cfg, hs.userService))
|
||||||
|
|
||||||
if !hs.Features.IsEnabled(featuremgmt.FlagAuthnService) {
|
if !hs.Cfg.AuthBrokerEnabled {
|
||||||
m.Use(accesscontrol.LoadPermissionsMiddleware(hs.accesscontrolService))
|
m.Use(accesscontrol.LoadPermissionsMiddleware(hs.accesscontrolService))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ func (hs *HTTPServer) LoginAPIPing(c *contextmodel.ReqContext) response.Response
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (hs *HTTPServer) LoginPost(c *contextmodel.ReqContext) response.Response {
|
func (hs *HTTPServer) LoginPost(c *contextmodel.ReqContext) response.Response {
|
||||||
if hs.Features.IsEnabled(featuremgmt.FlagAuthnService) {
|
if hs.Cfg.AuthBrokerEnabled {
|
||||||
identity, err := hs.authnService.Login(c.Req.Context(), authn.ClientForm, &authn.Request{HTTPRequest: c.Req, Resp: c.Resp})
|
identity, err := hs.authnService.Login(c.Req.Context(), authn.ClientForm, &authn.Request{HTTPRequest: c.Req, Resp: c.Resp})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tokenErr := &auth.CreateTokenErr{}
|
tokenErr := &auth.CreateTokenErr{}
|
||||||
|
@ -19,7 +19,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/middleware/cookies"
|
"github.com/grafana/grafana/pkg/middleware/cookies"
|
||||||
"github.com/grafana/grafana/pkg/services/authn"
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
||||||
loginservice "github.com/grafana/grafana/pkg/services/login"
|
loginservice "github.com/grafana/grafana/pkg/services/login"
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
"github.com/grafana/grafana/pkg/services/user"
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
@ -84,7 +83,7 @@ func (hs *HTTPServer) OAuthLogin(ctx *contextmodel.ReqContext) {
|
|||||||
|
|
||||||
code := ctx.Query("code")
|
code := ctx.Query("code")
|
||||||
|
|
||||||
if hs.Features.IsEnabled(featuremgmt.FlagAuthnService) {
|
if hs.Cfg.AuthBrokerEnabled {
|
||||||
req := &authn.Request{HTTPRequest: ctx.Req, Resp: ctx.Resp}
|
req := &authn.Request{HTTPRequest: ctx.Req, Resp: ctx.Resp}
|
||||||
if code == "" {
|
if code == "" {
|
||||||
redirect, err := hs.authnService.RedirectURL(ctx.Req.Context(), authn.ClientWithPrefix(name), req)
|
redirect, err := hs.authnService.RedirectURL(ctx.Req.Context(), authn.ClientWithPrefix(name), req)
|
||||||
@ -381,7 +380,7 @@ func (hs *HTTPServer) handleOAuthLoginError(ctx *contextmodel.ReqContext, info l
|
|||||||
ctx.Handle(hs.Cfg, err.HttpStatus, err.PublicMessage, err.Err)
|
ctx.Handle(hs.Cfg, err.HttpStatus, err.PublicMessage, err.Err)
|
||||||
|
|
||||||
// login hooks is handled by authn.Service
|
// login hooks is handled by authn.Service
|
||||||
if !hs.Features.IsEnabled(featuremgmt.FlagAuthnService) {
|
if !hs.Cfg.AuthBrokerEnabled {
|
||||||
info.Error = err.Err
|
info.Error = err.Err
|
||||||
if info.Error == nil {
|
if info.Error == nil {
|
||||||
info.Error = errors.New(err.PublicMessage)
|
info.Error = errors.New(err.PublicMessage)
|
||||||
@ -396,7 +395,7 @@ func (hs *HTTPServer) handleOAuthLoginErrorWithRedirect(ctx *contextmodel.ReqCon
|
|||||||
hs.redirectWithError(ctx, err, v...)
|
hs.redirectWithError(ctx, err, v...)
|
||||||
|
|
||||||
// login hooks is handled by authn.Service
|
// login hooks is handled by authn.Service
|
||||||
if !hs.Features.IsEnabled(featuremgmt.FlagAuthnService) {
|
if !hs.Cfg.AuthBrokerEnabled {
|
||||||
info.Error = err
|
info.Error = err
|
||||||
hs.HooksService.RunLoginHook(&info, ctx)
|
hs.HooksService.RunLoginHook(&info, ctx)
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ func (h *ContextHandler) Middleware(next http.Handler) http.Handler {
|
|||||||
reqContext.Logger = reqContext.Logger.New("traceID", traceID)
|
reqContext.Logger = reqContext.Logger.New("traceID", traceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.features.IsEnabled(featuremgmt.FlagAuthnService) {
|
if h.Cfg.AuthBrokerEnabled {
|
||||||
identity, err := h.authnService.Authenticate(ctx, &authn.Request{HTTPRequest: reqContext.Req, Resp: reqContext.Resp})
|
identity, err := h.authnService.Authenticate(ctx, &authn.Request{HTTPRequest: reqContext.Req, Resp: reqContext.Resp})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, auth.ErrInvalidSessionToken) {
|
if errors.Is(err, auth.ErrInvalidSessionToken) {
|
||||||
@ -207,7 +207,7 @@ func (h *ContextHandler) Middleware(next http.Handler) http.Handler {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// when using authn service this is implemented as a post auth hook
|
// when using authn service this is implemented as a post auth hook
|
||||||
if !h.features.IsEnabled(featuremgmt.FlagAuthnService) {
|
if !h.Cfg.AuthBrokerEnabled {
|
||||||
// update last seen every 5min
|
// update last seen every 5min
|
||||||
if reqContext.ShouldUpdateLastSeenAt() {
|
if reqContext.ShouldUpdateLastSeenAt() {
|
||||||
reqContext.Logger.Debug("Updating last user_seen_at", "user_id", reqContext.UserID)
|
reqContext.Logger.Debug("Updating last user_seen_at", "user_id", reqContext.UserID)
|
||||||
|
@ -279,12 +279,6 @@ var (
|
|||||||
Expression: "true", // enabled by default
|
Expression: "true", // enabled by default
|
||||||
Owner: grafanaDashboardsSquad,
|
Owner: grafanaDashboardsSquad,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Name: "authnService",
|
|
||||||
Description: "Use new auth service to perform authentication",
|
|
||||||
State: FeatureStateAlpha,
|
|
||||||
Owner: grafanaAuthnzSquad,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Name: "disablePrometheusExemplarSampling",
|
Name: "disablePrometheusExemplarSampling",
|
||||||
Description: "Disable Prometheus exemplar sampling",
|
Description: "Disable Prometheus exemplar sampling",
|
||||||
|
@ -40,7 +40,6 @@ nestedFolders,beta,@grafana/backend-platform,false,false,false,false
|
|||||||
accessTokenExpirationCheck,stable,@grafana/grafana-authnz-team,false,false,false,false
|
accessTokenExpirationCheck,stable,@grafana/grafana-authnz-team,false,false,false,false
|
||||||
showTraceId,alpha,@grafana/observability-logs,false,false,false,false
|
showTraceId,alpha,@grafana/observability-logs,false,false,false,false
|
||||||
emptyDashboardPage,stable,@grafana/dashboards-squad,false,false,false,true
|
emptyDashboardPage,stable,@grafana/dashboards-squad,false,false,false,true
|
||||||
authnService,alpha,@grafana/grafana-authnz-team,false,false,false,false
|
|
||||||
disablePrometheusExemplarSampling,stable,@grafana/observability-metrics,false,false,false,false
|
disablePrometheusExemplarSampling,stable,@grafana/observability-metrics,false,false,false,false
|
||||||
alertingBacktesting,alpha,@grafana/alerting-squad,false,false,false,false
|
alertingBacktesting,alpha,@grafana/alerting-squad,false,false,false,false
|
||||||
editPanelCSVDragAndDrop,alpha,@grafana/grafana-bi-squad,false,false,false,true
|
editPanelCSVDragAndDrop,alpha,@grafana/grafana-bi-squad,false,false,false,true
|
||||||
|
|
@ -171,10 +171,6 @@ const (
|
|||||||
// Enable the redesigned user interface of a dashboard page that includes no panels
|
// Enable the redesigned user interface of a dashboard page that includes no panels
|
||||||
FlagEmptyDashboardPage = "emptyDashboardPage"
|
FlagEmptyDashboardPage = "emptyDashboardPage"
|
||||||
|
|
||||||
// FlagAuthnService
|
|
||||||
// Use new auth service to perform authentication
|
|
||||||
FlagAuthnService = "authnService"
|
|
||||||
|
|
||||||
// FlagDisablePrometheusExemplarSampling
|
// FlagDisablePrometheusExemplarSampling
|
||||||
// Disable Prometheus exemplar sampling
|
// Disable Prometheus exemplar sampling
|
||||||
FlagDisablePrometheusExemplarSampling = "disablePrometheusExemplarSampling"
|
FlagDisablePrometheusExemplarSampling = "disablePrometheusExemplarSampling"
|
||||||
|
@ -277,6 +277,8 @@ type Cfg struct {
|
|||||||
// Not documented & not supported
|
// Not documented & not supported
|
||||||
// stand in until a more complete solution is implemented
|
// stand in until a more complete solution is implemented
|
||||||
AuthConfigUIAdminAccess bool
|
AuthConfigUIAdminAccess bool
|
||||||
|
// TO REMOVE: Not documented & not supported. Remove with legacy handlers in 10.2
|
||||||
|
AuthBrokerEnabled bool
|
||||||
|
|
||||||
// AWS Plugin Auth
|
// AWS Plugin Auth
|
||||||
AWSAllowedAuthProviders []string
|
AWSAllowedAuthProviders []string
|
||||||
@ -553,7 +555,7 @@ type CommandLineArgs struct {
|
|||||||
Args []string
|
Args []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg Cfg) parseAppUrlAndSubUrl(section *ini.Section) (string, string, error) {
|
func (cfg *Cfg) parseAppUrlAndSubUrl(section *ini.Section) (string, string, error) {
|
||||||
appUrl := valueAsString(section, "root_url", "http://localhost:3000/")
|
appUrl := valueAsString(section, "root_url", "http://localhost:3000/")
|
||||||
|
|
||||||
if appUrl[len(appUrl)-1] != '/' {
|
if appUrl[len(appUrl)-1] != '/' {
|
||||||
@ -776,7 +778,7 @@ func applyCommandLineProperties(props map[string]string, file *ini.File) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg Cfg) getCommandLineProperties(args []string) map[string]string {
|
func (cfg *Cfg) getCommandLineProperties(args []string) map[string]string {
|
||||||
props := make(map[string]string)
|
props := make(map[string]string)
|
||||||
|
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
@ -1492,8 +1494,11 @@ func readAuthSettings(iniFile *ini.File, cfg *Cfg) (err error) {
|
|||||||
|
|
||||||
// Debug setting unlocking frontend auth sync lock. Users will still be reset on their next login.
|
// Debug setting unlocking frontend auth sync lock. Users will still be reset on their next login.
|
||||||
cfg.DisableSyncLock = auth.Key("disable_sync_lock").MustBool(false)
|
cfg.DisableSyncLock = auth.Key("disable_sync_lock").MustBool(false)
|
||||||
|
|
||||||
// Do not use
|
// Do not use
|
||||||
cfg.AuthConfigUIAdminAccess = auth.Key("config_ui_admin_access").MustBool(false)
|
cfg.AuthConfigUIAdminAccess = auth.Key("config_ui_admin_access").MustBool(false)
|
||||||
|
cfg.AuthBrokerEnabled = auth.Key("broker").MustBool(true)
|
||||||
|
|
||||||
cfg.DisableLoginForm = auth.Key("disable_login_form").MustBool(false)
|
cfg.DisableLoginForm = auth.Key("disable_login_form").MustBool(false)
|
||||||
DisableSignoutMenu = auth.Key("disable_signout_menu").MustBool(false)
|
DisableSignoutMenu = auth.Key("disable_signout_menu").MustBool(false)
|
||||||
|
|
||||||
|
@ -199,6 +199,15 @@ func CreateGrafDir(t *testing.T, opts ...GrafanaOpts) (string, string) {
|
|||||||
_, err = serverSect.NewKey("static_root_path", publicDir)
|
_, err = serverSect.NewKey("static_root_path", publicDir)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
authSect, err := cfg.NewSection("auth")
|
||||||
|
require.NoError(t, err)
|
||||||
|
authBrokerState := "false"
|
||||||
|
if len(opts) > 0 && opts[0].AuthBrokerEnabled {
|
||||||
|
authBrokerState = "true"
|
||||||
|
}
|
||||||
|
_, err = authSect.NewKey("broker", authBrokerState)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
anonSect, err := cfg.NewSection("auth.anonymous")
|
anonSect, err := cfg.NewSection("auth.anonymous")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, err = anonSect.NewKey("enabled", "true")
|
_, err = anonSect.NewKey("enabled", "true")
|
||||||
@ -384,6 +393,7 @@ type GrafanaOpts struct {
|
|||||||
EnableLog bool
|
EnableLog bool
|
||||||
GRPCServerAddress string
|
GRPCServerAddress string
|
||||||
QueryRetries int64
|
QueryRetries int64
|
||||||
|
AuthBrokerEnabled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateUser(t *testing.T, store *sqlstore.SQLStore, cmd user.CreateUserCommand) *user.User {
|
func CreateUser(t *testing.T, store *sqlstore.SQLStore, cmd user.CreateUserCommand) *user.User {
|
||||||
|
@ -13,7 +13,6 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
||||||
"github.com/grafana/grafana/pkg/services/login"
|
"github.com/grafana/grafana/pkg/services/login"
|
||||||
databaseAuthInfo "github.com/grafana/grafana/pkg/services/login/authinfoservice/database"
|
databaseAuthInfo "github.com/grafana/grafana/pkg/services/login/authinfoservice/database"
|
||||||
"github.com/grafana/grafana/pkg/services/secrets/database"
|
"github.com/grafana/grafana/pkg/services/secrets/database"
|
||||||
@ -119,14 +118,12 @@ func TestIntegrationIndexViewAnalytics(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// can be removed once ff is removed
|
// can be removed once ff is removed
|
||||||
testCaseFeatures := map[string][]string{"none": {}, "authnService": {featuremgmt.FlagAuthnService}}
|
authBrokerStates := map[string]bool{"none": false, "authnService": true}
|
||||||
|
|
||||||
for k, tcFeatures := range testCaseFeatures {
|
for k, enabled := range authBrokerStates {
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name+"-"+k, func(t *testing.T) {
|
t.Run(tc.name+"-"+k, func(t *testing.T) {
|
||||||
grafDir, cfgPath := testinfra.CreateGrafDir(t, testinfra.GrafanaOpts{
|
grafDir, cfgPath := testinfra.CreateGrafDir(t, testinfra.GrafanaOpts{AuthBrokerEnabled: enabled})
|
||||||
EnableFeatureToggles: tcFeatures,
|
|
||||||
})
|
|
||||||
addr, store := testinfra.StartGrafana(t, grafDir, cfgPath)
|
addr, store := testinfra.StartGrafana(t, grafDir, cfgPath)
|
||||||
createdUser := testinfra.CreateUser(t, store, user.CreateUserCommand{
|
createdUser := testinfra.CreateUser(t, store, user.CreateUserCommand{
|
||||||
Login: "admin",
|
Login: "admin",
|
||||||
|
Loading…
Reference in New Issue
Block a user