package internal import ( "net/http" "reflect" "regexp" "strings" "testing" "github.com/element-hq/dendrite/setup/config" "github.com/matrix-org/gomatrixserverlib/spec" "github.com/matrix-org/util" ) func Test_validatePassword(t *testing.T) { tests := []struct { name string password string wantError error wantJSON *util.JSONResponse }{ { name: "password too short", password: "shortpw", wantError: ErrPasswordWeak, wantJSON: &util.JSONResponse{Code: http.StatusBadRequest, JSON: spec.WeakPassword(ErrPasswordWeak.Error())}, }, { name: "password too long", password: strings.Repeat("a", maxPasswordLength+1), wantError: ErrPasswordTooLong, wantJSON: &util.JSONResponse{Code: http.StatusBadRequest, JSON: spec.BadJSON(ErrPasswordTooLong.Error())}, }, { name: "password OK", password: util.RandomString(10), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { gotErr := ValidatePassword(tt.password) if !reflect.DeepEqual(gotErr, tt.wantError) { t.Errorf("validatePassword() = %v, wantError %v", gotErr, tt.wantError) } if got := PasswordResponse(gotErr); !reflect.DeepEqual(got, tt.wantJSON) { t.Errorf("validatePassword() = %v, wantJSON %v", got, tt.wantJSON) } }) } } func Test_validateUsername(t *testing.T) { tooLongUsername := strings.Repeat("a", maxUsernameLength) tests := []struct { name string localpart string domain spec.ServerName wantErr error wantJSON *util.JSONResponse }{ { name: "empty username", localpart: "", domain: "localhost", wantErr: ErrUsernameInvalid, wantJSON: &util.JSONResponse{ Code: http.StatusBadRequest, JSON: spec.InvalidUsername(ErrUsernameInvalid.Error()), }, }, { name: "invalid username", localpart: "INVALIDUSERNAME", domain: "localhost", wantErr: ErrUsernameInvalid, wantJSON: &util.JSONResponse{ Code: http.StatusBadRequest, JSON: spec.InvalidUsername(ErrUsernameInvalid.Error()), }, }, { name: "username too long", localpart: tooLongUsername, domain: "localhost", wantErr: ErrUsernameTooLong, wantJSON: &util.JSONResponse{ Code: http.StatusBadRequest, JSON: spec.BadJSON(ErrUsernameTooLong.Error()), }, }, { name: "localpart starting with an underscore", localpart: "_notvalid", domain: "localhost", wantErr: ErrUsernameUnderscore, wantJSON: &util.JSONResponse{ Code: http.StatusBadRequest, JSON: spec.InvalidUsername(ErrUsernameUnderscore.Error()), }, }, { name: "valid username", localpart: "valid", domain: "localhost", }, { name: "complex username", localpart: "f00_bar-baz.=40/", domain: "localhost", }, { name: "rejects emoji username 💥", localpart: "💥", domain: "localhost", wantErr: ErrUsernameInvalid, wantJSON: &util.JSONResponse{ Code: http.StatusBadRequest, JSON: spec.InvalidUsername(ErrUsernameInvalid.Error()), }, }, { name: "special characters are allowed", localpart: "/dev/null", domain: "localhost", }, { name: "special characters are allowed 2", localpart: "i_am_allowed=1", domain: "localhost", }, { name: "special characters are allowed 3", localpart: "+55555555555", domain: "localhost", }, { name: "not all special characters are allowed", localpart: "notallowed#", // contains # domain: "localhost", wantErr: ErrUsernameInvalid, wantJSON: &util.JSONResponse{ Code: http.StatusBadRequest, JSON: spec.InvalidUsername(ErrUsernameInvalid.Error()), }, }, { name: "not all special characters are allowed 2", localpart: "