authelia/internal/suites/scenario_reset_password_test.go
Amir Zarrinkafsh d82b46a3ec
[FEATURE] Autofocus on authentication and OTP pages (#806)
* [FEATURE] Autofocus on authentication and OTP pages
This change sets the input focus on the first factor authentication and OTP pages.

The behaviour for the first factor authentication page has also been amended slightly, if an incorrect username or password is provided the password field will be cleared and set as the focus.

One thing to note is that the OTP page does not focus on any re-rendering and this is because the component doesn't handle focusing. This means that the OTP input only is auto-focused when you first visit it, if you enter an incorrect OTP there will be no focus.

Ideally we should be looking for a different library or writing a component for this ourselves in future.

Closes #511.

* Add TODO markers for potential refactor
2020-04-01 10:27:54 +11:00

102 lines
2.5 KiB
Go

package suites
import (
"context"
"log"
"testing"
"time"
"github.com/stretchr/testify/suite"
)
type ResetPasswordScenario struct {
*SeleniumSuite
}
func NewResetPasswordScenario() *ResetPasswordScenario {
return &ResetPasswordScenario{SeleniumSuite: new(SeleniumSuite)}
}
func (s *ResetPasswordScenario) SetupSuite() {
wds, err := StartWebDriver()
if err != nil {
log.Fatal(err)
}
s.WebDriverSession = wds
}
func (s *ResetPasswordScenario) TearDownSuite() {
err := s.WebDriverSession.Stop()
if err != nil {
log.Fatal(err)
}
}
func (s *ResetPasswordScenario) SetupTest() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
s.doLogout(ctx, s.T())
s.doVisit(s.T(), HomeBaseURL)
s.verifyIsHome(ctx, s.T())
}
func (s *ResetPasswordScenario) TestShouldResetPassword() {
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
s.doVisit(s.T(), LoginBaseURL)
s.verifyIsFirstFactorPage(ctx, s.T())
// Reset the password to abc
s.doResetPassword(ctx, s.T(), "john", "abc", "abc")
// Try to login with the old password
s.doLoginOneFactor(ctx, s.T(), "john", "password", false, "")
s.verifyNotificationDisplayed(ctx, s.T(), "Incorrect username or password.")
// Try to login with the new password
s.doLoginOneFactor(ctx, s.T(), "john", "abc", false, "")
// Logout
s.doLogout(ctx, s.T())
// Reset the original password
s.doResetPassword(ctx, s.T(), "john", "password", "password")
}
func (s *ResetPasswordScenario) TestShouldMakeAttackerThinkPasswordResetIsInitiated() {
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
s.doVisit(s.T(), LoginBaseURL)
s.verifyIsFirstFactorPage(ctx, s.T())
// Try to initiate a password reset of an nonexistent user.
s.doInitiatePasswordReset(ctx, s.T(), "i_dont_exist")
// Check that the notification make the attacker thinks the process is initiated
s.verifyMailNotificationDisplayed(ctx, s.T())
}
func (s *ResetPasswordScenario) TestShouldLetUserNoticeThereIsAPasswordMismatch() {
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
s.doVisit(s.T(), LoginBaseURL)
s.verifyIsFirstFactorPage(ctx, s.T())
s.doInitiatePasswordReset(ctx, s.T(), "john")
s.verifyMailNotificationDisplayed(ctx, s.T())
s.doCompletePasswordReset(ctx, s.T(), "password", "another_password")
s.verifyNotificationDisplayed(ctx, s.T(), "Passwords do not match.")
}
func TestRunResetPasswordScenario(t *testing.T) {
suite.Run(t, NewResetPasswordScenario())
}