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/models" | ||||
| 	"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) { | ||||
| 	Convey("Validate login attempts", t, func() { | ||||
| 		Convey("Given brute force login protection enabled", func() { | ||||
| 			cfg := setting.NewCfg() | ||||
| 			cfg.DisableBruteForceLoginProtection = false | ||||
| 			query := &models.LoginUserQuery{ | ||||
| 				Username: "user", | ||||
| 				Cfg:      cfg, | ||||
| func TestValidateLoginAttempts(t *testing.T) { | ||||
| 	testCases := []struct { | ||||
| 		name          string | ||||
| 		loginAttempts int64 | ||||
| 		cfg           *setting.Cfg | ||||
| 		expected      error | ||||
| 	}{ | ||||
| 		{ | ||||
| 			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() { | ||||
| 				withLoginAttempts(maxInvalidLoginAttempts - 1) | ||||
| 	for _, tc := range testCases { | ||||
| 		t.Run(tc.name, func(t *testing.T) { | ||||
| 			withLoginAttempts(t, tc.loginAttempts) | ||||
| 
 | ||||
| 			query := &models.LoginUserQuery{Username: "user", Cfg: tc.cfg} | ||||
| 			err := validateLoginAttempts(query) | ||||
| 
 | ||||
| 				Convey("it should not result in error", func() { | ||||
| 					So(err, ShouldBeNil) | ||||
| 				}) | ||||
| 			require.Equal(t, tc.expected, err) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 			Convey("When user login attempt count equals max ", func() { | ||||
| 				withLoginAttempts(maxInvalidLoginAttempts) | ||||
| 				err := validateLoginAttempts(query) | ||||
| func TestSaveInvalidLoginAttempt(t *testing.T) { | ||||
| 	t.Run("When brute force protection enabled", func(t *testing.T) { | ||||
| 		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{} | ||||
| 
 | ||||
| 		bus.AddHandler("test", func(cmd *models.CreateLoginAttemptCommand) error { | ||||
| 			createLoginAttemptCmd = cmd | ||||
| 			return nil | ||||
|  | @ -59,79 +81,52 @@ func TestLoginAttemptsValidation(t *testing.T) { | |||
| 			Username:  "user", | ||||
| 			Password:  "pwd", | ||||
| 			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() { | ||||
| 					So(createLoginAttemptCmd, ShouldNotBeNil) | ||||
| 					So(createLoginAttemptCmd.Username, ShouldEqual, "user") | ||||
| 					So(createLoginAttemptCmd.IpAddress, ShouldEqual, "192.168.1.1:56433") | ||||
| 				}) | ||||
| 			}) | ||||
| 		require.NotNil(t, createLoginAttemptCmd) | ||||
| 		assert.Equal(t, "user", createLoginAttemptCmd.Username) | ||||
| 		assert.Equal(t, "192.168.1.1:56433", createLoginAttemptCmd.IpAddress) | ||||
| 	}) | ||||
| 
 | ||||
| 		Convey("Given brute force login protection disabled", func() { | ||||
| 	t.Run("When brute force protection disabled", func(t *testing.T) { | ||||
| 		t.Cleanup(func() { bus.ClearBusHandlers() }) | ||||
| 
 | ||||
| 		var createLoginAttemptCmd *models.CreateLoginAttemptCommand | ||||
| 		bus.AddHandler("test", func(cmd *models.CreateLoginAttemptCommand) error { | ||||
| 			createLoginAttemptCmd = cmd | ||||
| 			return nil | ||||
| 		}) | ||||
| 
 | ||||
| 		err := saveInvalidLoginAttempt(&models.LoginUserQuery{ | ||||
| 			Username:  "user", | ||||
| 			Password:  "pwd", | ||||
| 			IpAddress: "192.168.1.1:56433", | ||||
| 			Cfg:       cfgWithBruteForceLoginProtectionDisabled(t), | ||||
| 		}) | ||||
| 		require.NoError(t, err) | ||||
| 
 | ||||
| 		require.Nil(t, createLoginAttemptCmd) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func cfgWithBruteForceLoginProtectionDisabled(t *testing.T) *setting.Cfg { | ||||
| 	t.Helper() | ||||
| 	cfg := setting.NewCfg() | ||||
| 	cfg.DisableBruteForceLoginProtection = true | ||||
| 			query := &models.LoginUserQuery{ | ||||
| 				Username: "user", | ||||
| 				Cfg:      cfg, | ||||
| 	return 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 | ||||
| 
 | ||||
| 				bus.AddHandler("test", func(cmd *models.CreateLoginAttemptCommand) error { | ||||
| 					createLoginAttemptCmd = cmd | ||||
| 					return nil | ||||
| 				}) | ||||
| 
 | ||||
| 				err := saveInvalidLoginAttempt(&models.LoginUserQuery{ | ||||
| 					Username:  "user", | ||||
| 					Password:  "pwd", | ||||
| 					IpAddress: "192.168.1.1:56433", | ||||
| 					Cfg:       cfg, | ||||
| 				}) | ||||
| 				So(err, ShouldBeNil) | ||||
| 
 | ||||
| 				Convey("it should not dispatch command", func() { | ||||
| 					So(createLoginAttemptCmd, ShouldBeNil) | ||||
| 				}) | ||||
| 			}) | ||||
| 		}) | ||||
| 	}) | ||||
| func cfgWithBruteForceLoginProtectionEnabled(t *testing.T) *setting.Cfg { | ||||
| 	t.Helper() | ||||
| 	cfg := setting.NewCfg() | ||||
| 	require.False(t, cfg.DisableBruteForceLoginProtection) | ||||
| 	return cfg | ||||
| } | ||||
| 
 | ||||
| func withLoginAttempts(loginAttempts int64) { | ||||
| func withLoginAttempts(t *testing.T, loginAttempts int64) { | ||||
| 	t.Helper() | ||||
| 	bus.AddHandler("test", func(query *models.GetUserLoginAttemptCountQuery) error { | ||||
| 		query.Result = loginAttempts | ||||
| 		return nil | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue