mirror of https://github.com/grafana/grafana.git
				
				
				
			Chore: Rewrite brute force login protection test to standard library (#29986)
This commit is contained in:
		
							parent
							
								
									d236eabe8c
								
							
						
					
					
						commit
						1b53558173
					
				|  | @ -6,50 +6,72 @@ import ( | ||||||
| 	"github.com/grafana/grafana/pkg/bus" | 	"github.com/grafana/grafana/pkg/bus" | ||||||
| 	"github.com/grafana/grafana/pkg/models" | 	"github.com/grafana/grafana/pkg/models" | ||||||
| 	"github.com/grafana/grafana/pkg/setting" | 	"github.com/grafana/grafana/pkg/setting" | ||||||
| 	. "github.com/smartystreets/goconvey/convey" | 	"github.com/stretchr/testify/assert" | ||||||
|  | 	"github.com/stretchr/testify/require" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestLoginAttemptsValidation(t *testing.T) { | func TestValidateLoginAttempts(t *testing.T) { | ||||||
| 	Convey("Validate login attempts", t, func() { | 	testCases := []struct { | ||||||
| 		Convey("Given brute force login protection enabled", func() { | 		name          string | ||||||
| 			cfg := setting.NewCfg() | 		loginAttempts int64 | ||||||
| 			cfg.DisableBruteForceLoginProtection = false | 		cfg           *setting.Cfg | ||||||
| 			query := &models.LoginUserQuery{ | 		expected      error | ||||||
| 				Username: "user", | 	}{ | ||||||
| 				Cfg:      cfg, | 		{ | ||||||
|  | 			name:          "When brute force protection enabled and user login attempt count is less than max", | ||||||
|  | 			loginAttempts: maxInvalidLoginAttempts - 1, | ||||||
|  | 			cfg:           cfgWithBruteForceLoginProtectionEnabled(t), | ||||||
|  | 			expected:      nil, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:          "When brute force protection enabled and user login attempt count equals max", | ||||||
|  | 			loginAttempts: maxInvalidLoginAttempts, | ||||||
|  | 			cfg:           cfgWithBruteForceLoginProtectionEnabled(t), | ||||||
|  | 			expected:      ErrTooManyLoginAttempts, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:          "When brute force protection enabled and user login attempt count is greater than max", | ||||||
|  | 			loginAttempts: maxInvalidLoginAttempts + 1, | ||||||
|  | 			cfg:           cfgWithBruteForceLoginProtectionEnabled(t), | ||||||
|  | 			expected:      ErrTooManyLoginAttempts, | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		{ | ||||||
|  | 			name:          "When brute force protection disabled and user login attempt count is less than max", | ||||||
|  | 			loginAttempts: maxInvalidLoginAttempts - 1, | ||||||
|  | 			cfg:           cfgWithBruteForceLoginProtectionDisabled(t), | ||||||
|  | 			expected:      nil, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:          "When brute force protection disabled and user login attempt count equals max", | ||||||
|  | 			loginAttempts: maxInvalidLoginAttempts, | ||||||
|  | 			cfg:           cfgWithBruteForceLoginProtectionDisabled(t), | ||||||
|  | 			expected:      nil, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:          "When brute force protection disabled and user login attempt count is greater than max", | ||||||
|  | 			loginAttempts: maxInvalidLoginAttempts + 1, | ||||||
|  | 			cfg:           cfgWithBruteForceLoginProtectionDisabled(t), | ||||||
|  | 			expected:      nil, | ||||||
|  | 		}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 			Convey("When user login attempt count equals max-1 ", func() { | 	for _, tc := range testCases { | ||||||
| 				withLoginAttempts(maxInvalidLoginAttempts - 1) | 		t.Run(tc.name, func(t *testing.T) { | ||||||
|  | 			withLoginAttempts(t, tc.loginAttempts) | ||||||
|  | 
 | ||||||
|  | 			query := &models.LoginUserQuery{Username: "user", Cfg: tc.cfg} | ||||||
| 			err := validateLoginAttempts(query) | 			err := validateLoginAttempts(query) | ||||||
| 
 | 			require.Equal(t, tc.expected, err) | ||||||
| 				Convey("it should not result in error", func() { |  | ||||||
| 					So(err, ShouldBeNil) |  | ||||||
| 				}) |  | ||||||
| 		}) | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| 			Convey("When user login attempt count equals max ", func() { | func TestSaveInvalidLoginAttempt(t *testing.T) { | ||||||
| 				withLoginAttempts(maxInvalidLoginAttempts) | 	t.Run("When brute force protection enabled", func(t *testing.T) { | ||||||
| 				err := validateLoginAttempts(query) | 		t.Cleanup(func() { bus.ClearBusHandlers() }) | ||||||
| 
 | 
 | ||||||
| 				Convey("it should result in too many login attempts error", func() { |  | ||||||
| 					So(err, ShouldEqual, ErrTooManyLoginAttempts) |  | ||||||
| 				}) |  | ||||||
| 			}) |  | ||||||
| 
 |  | ||||||
| 			Convey("When user login attempt count is greater than max ", func() { |  | ||||||
| 				withLoginAttempts(maxInvalidLoginAttempts + 5) |  | ||||||
| 				err := validateLoginAttempts(query) |  | ||||||
| 
 |  | ||||||
| 				Convey("it should result in too many login attempts error", func() { |  | ||||||
| 					So(err, ShouldEqual, ErrTooManyLoginAttempts) |  | ||||||
| 				}) |  | ||||||
| 			}) |  | ||||||
| 
 |  | ||||||
| 			Convey("When saving invalid login attempt", func() { |  | ||||||
| 				defer bus.ClearBusHandlers() |  | ||||||
| 		createLoginAttemptCmd := &models.CreateLoginAttemptCommand{} | 		createLoginAttemptCmd := &models.CreateLoginAttemptCommand{} | ||||||
| 
 |  | ||||||
| 		bus.AddHandler("test", func(cmd *models.CreateLoginAttemptCommand) error { | 		bus.AddHandler("test", func(cmd *models.CreateLoginAttemptCommand) error { | ||||||
| 			createLoginAttemptCmd = cmd | 			createLoginAttemptCmd = cmd | ||||||
| 			return nil | 			return nil | ||||||
|  | @ -59,57 +81,19 @@ func TestLoginAttemptsValidation(t *testing.T) { | ||||||
| 			Username:  "user", | 			Username:  "user", | ||||||
| 			Password:  "pwd", | 			Password:  "pwd", | ||||||
| 			IpAddress: "192.168.1.1:56433", | 			IpAddress: "192.168.1.1:56433", | ||||||
| 					Cfg:       setting.NewCfg(), | 			Cfg:       cfgWithBruteForceLoginProtectionEnabled(t), | ||||||
| 		}) | 		}) | ||||||
| 				So(err, ShouldBeNil) | 		require.NoError(t, err) | ||||||
| 
 | 
 | ||||||
| 				Convey("it should dispatch command", func() { | 		require.NotNil(t, createLoginAttemptCmd) | ||||||
| 					So(createLoginAttemptCmd, ShouldNotBeNil) | 		assert.Equal(t, "user", createLoginAttemptCmd.Username) | ||||||
| 					So(createLoginAttemptCmd.Username, ShouldEqual, "user") | 		assert.Equal(t, "192.168.1.1:56433", createLoginAttemptCmd.IpAddress) | ||||||
| 					So(createLoginAttemptCmd.IpAddress, ShouldEqual, "192.168.1.1:56433") |  | ||||||
| 				}) |  | ||||||
| 			}) |  | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 		Convey("Given brute force login protection disabled", func() { | 	t.Run("When brute force protection disabled", func(t *testing.T) { | ||||||
| 			cfg := setting.NewCfg() | 		t.Cleanup(func() { bus.ClearBusHandlers() }) | ||||||
| 			cfg.DisableBruteForceLoginProtection = true |  | ||||||
| 			query := &models.LoginUserQuery{ |  | ||||||
| 				Username: "user", |  | ||||||
| 				Cfg:      cfg, |  | ||||||
| 			} |  | ||||||
| 
 | 
 | ||||||
| 			Convey("When user login attempt count equals max-1 ", func() { |  | ||||||
| 				withLoginAttempts(maxInvalidLoginAttempts - 1) |  | ||||||
| 				err := validateLoginAttempts(query) |  | ||||||
| 
 |  | ||||||
| 				Convey("it should not result in error", func() { |  | ||||||
| 					So(err, ShouldBeNil) |  | ||||||
| 				}) |  | ||||||
| 			}) |  | ||||||
| 
 |  | ||||||
| 			Convey("When user login attempt count equals max ", func() { |  | ||||||
| 				withLoginAttempts(maxInvalidLoginAttempts) |  | ||||||
| 				err := validateLoginAttempts(query) |  | ||||||
| 
 |  | ||||||
| 				Convey("it should not result in error", func() { |  | ||||||
| 					So(err, ShouldBeNil) |  | ||||||
| 				}) |  | ||||||
| 			}) |  | ||||||
| 
 |  | ||||||
| 			Convey("When user login attempt count is greater than max ", func() { |  | ||||||
| 				withLoginAttempts(maxInvalidLoginAttempts + 5) |  | ||||||
| 				err := validateLoginAttempts(query) |  | ||||||
| 
 |  | ||||||
| 				Convey("it should not result in error", func() { |  | ||||||
| 					So(err, ShouldBeNil) |  | ||||||
| 				}) |  | ||||||
| 			}) |  | ||||||
| 
 |  | ||||||
| 			Convey("When saving invalid login attempt", func() { |  | ||||||
| 				defer bus.ClearBusHandlers() |  | ||||||
| 		var createLoginAttemptCmd *models.CreateLoginAttemptCommand | 		var createLoginAttemptCmd *models.CreateLoginAttemptCommand | ||||||
| 
 |  | ||||||
| 		bus.AddHandler("test", func(cmd *models.CreateLoginAttemptCommand) error { | 		bus.AddHandler("test", func(cmd *models.CreateLoginAttemptCommand) error { | ||||||
| 			createLoginAttemptCmd = cmd | 			createLoginAttemptCmd = cmd | ||||||
| 			return nil | 			return nil | ||||||
|  | @ -119,19 +103,30 @@ func TestLoginAttemptsValidation(t *testing.T) { | ||||||
| 			Username:  "user", | 			Username:  "user", | ||||||
| 			Password:  "pwd", | 			Password:  "pwd", | ||||||
| 			IpAddress: "192.168.1.1:56433", | 			IpAddress: "192.168.1.1:56433", | ||||||
| 					Cfg:       cfg, | 			Cfg:       cfgWithBruteForceLoginProtectionDisabled(t), | ||||||
| 		}) | 		}) | ||||||
| 				So(err, ShouldBeNil) | 		require.NoError(t, err) | ||||||
| 
 | 
 | ||||||
| 				Convey("it should not dispatch command", func() { | 		require.Nil(t, createLoginAttemptCmd) | ||||||
| 					So(createLoginAttemptCmd, ShouldBeNil) |  | ||||||
| 				}) |  | ||||||
| 			}) |  | ||||||
| 		}) |  | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func withLoginAttempts(loginAttempts int64) { | func cfgWithBruteForceLoginProtectionDisabled(t *testing.T) *setting.Cfg { | ||||||
|  | 	t.Helper() | ||||||
|  | 	cfg := setting.NewCfg() | ||||||
|  | 	cfg.DisableBruteForceLoginProtection = true | ||||||
|  | 	return cfg | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func cfgWithBruteForceLoginProtectionEnabled(t *testing.T) *setting.Cfg { | ||||||
|  | 	t.Helper() | ||||||
|  | 	cfg := setting.NewCfg() | ||||||
|  | 	require.False(t, cfg.DisableBruteForceLoginProtection) | ||||||
|  | 	return cfg | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func withLoginAttempts(t *testing.T, loginAttempts int64) { | ||||||
|  | 	t.Helper() | ||||||
| 	bus.AddHandler("test", func(query *models.GetUserLoginAttemptCountQuery) error { | 	bus.AddHandler("test", func(query *models.GetUserLoginAttemptCountQuery) error { | ||||||
| 		query.Result = loginAttempts | 		query.Result = loginAttempts | ||||||
| 		return nil | 		return nil | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue