-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
OCM-1294 | feat: Added password validator and tests
- Loading branch information
den-rgb
committed
Aug 29, 2023
1 parent
183b855
commit 0cdafa6
Showing
5 changed files
with
153 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package validations | ||
|
||
import ( | ||
"fmt" | ||
"regexp" | ||
"strings" | ||
) | ||
|
||
func PasswordValidator(val interface{}) error { | ||
if password, ok := val.(string); ok { | ||
re := regexp.MustCompile(`[^\x20-\x7E]`) | ||
invalidChars := re.FindAllString(password, -1) | ||
notAsciiOnly := len(invalidChars) > 0 | ||
containsSpace := strings.Contains(password, " ") | ||
tooShort := len(password) < 14 | ||
pwdErrors := []string{} | ||
if notAsciiOnly { | ||
pwdErrors = append(pwdErrors, fmt.Sprintf("must not contain special characters [%s]", | ||
strings.Join(invalidChars, ", "))) | ||
} | ||
if containsSpace { | ||
pwdErrors = append(pwdErrors, "must not contain whitespace") | ||
} | ||
if tooShort { | ||
pwdErrors = append(pwdErrors, fmt.Sprintf("must be at least 14 characters (got %d)", len(password))) | ||
} | ||
if notAsciiOnly || containsSpace || tooShort { | ||
if len(pwdErrors) > 1 { | ||
pwdErrors[len(pwdErrors)-1] = "and " + pwdErrors[len(pwdErrors)-1] | ||
} | ||
|
||
return fmt.Errorf("Password " + strings.Join(pwdErrors, ", ")) | ||
} | ||
hasUppercase, _ := regexp.MatchString(`[A-Z]`, password) | ||
hasLowercase, _ := regexp.MatchString(`[a-z]`, password) | ||
hasNumberOrSymbol, _ := regexp.MatchString(`[^a-zA-Z]`, password) | ||
if !hasUppercase || !hasLowercase || !hasNumberOrSymbol { | ||
return fmt.Errorf( | ||
"Password must include uppercase letters, lowercase letters, and numbers " + | ||
"or symbols (ASCII-standard characters only)") | ||
} | ||
return nil | ||
} | ||
return fmt.Errorf("can only validate strings, got '%v'", val) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package validations | ||
|
||
import ( | ||
"fmt" | ||
"regexp" | ||
"strings" | ||
|
||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
var _ = Describe("Password Validator", func() { | ||
Context("Valid password", func() { | ||
It("should not return an error", func() { | ||
err := PasswordValidator("Abcdefg123456@") | ||
Expect(err).NotTo(HaveOccurred()) | ||
}) | ||
}) | ||
|
||
Context("Password contains special characters", func() { | ||
It("should return an error", func() { | ||
password := "AbcdefAbcdef@日本語" | ||
err := PasswordValidator(password) | ||
re := regexp.MustCompile(`[^\x20-\x7E]`) | ||
invalidChars := re.FindAllString(password, -1) | ||
expectedErrMsg := fmt.Sprintf("Password must not contain special characters [%s]", strings.Join(invalidChars, ", ")) | ||
Expect(err.Error()).To(Equal(expectedErrMsg)) | ||
}) | ||
}) | ||
|
||
|
||
Context("Password contains whitespace", func() { | ||
It("should return an error", func() { | ||
expectedErrMsg := "Password must not contain whitespace" | ||
err := PasswordValidator("Abc defg123456@") | ||
Expect(err.Error()).To(Equal(expectedErrMsg)) | ||
}) | ||
}) | ||
|
||
Context("Password is too short", func() { | ||
It("should return an error", func() { | ||
password := "Abcd12@" | ||
expectedErrMsg := fmt.Sprintf("Password must be at least 14 characters (got %d)", len(password)) | ||
err := PasswordValidator(password) | ||
Expect(err.Error()).To(Equal(expectedErrMsg)) | ||
}) | ||
}) | ||
|
||
Context("Password does not contain uppercase letters", func() { | ||
It("should return an error", func() { | ||
expectedErrMsg := "Password must include uppercase letters, lowercase letters, and numbers or symbols (ASCII-standard characters only)" | ||
err := PasswordValidator("abcdefg123456@") | ||
Expect(err.Error()).To(Equal(expectedErrMsg)) | ||
}) | ||
}) | ||
|
||
Context("Password does not contain lowercase letters", func() { | ||
It("should return an error", func() { | ||
expectedErrMsg := "Password must include uppercase letters, lowercase letters, and numbers or symbols (ASCII-standard characters only)" | ||
err := PasswordValidator("ABCDEFG123456@") | ||
Expect(err.Error()).To(Equal(expectedErrMsg)) | ||
}) | ||
}) | ||
|
||
Context("Password does not contain numbers or symbols", func() { | ||
It("should return an error", func() { | ||
expectedErrMsg := "Password must include uppercase letters, lowercase letters, and numbers or symbols (ASCII-standard characters only)" | ||
err := PasswordValidator("Abcdefgabcdefg") | ||
Expect(err.Error()).To(Equal(expectedErrMsg)) | ||
}) | ||
}) | ||
|
||
Context("White space and too short password errors", func() { | ||
It("should return an error", func() { | ||
password := "Abc def" | ||
err := PasswordValidator(password) | ||
|
||
expectedErrMsg := "Password must not contain whitespace, and must be at least 14 characters (got 7)" | ||
Expect(err.Error()).To(Equal(expectedErrMsg)) | ||
}) | ||
}) | ||
|
||
Context("Multiple password errors", func() { | ||
It("should return an error", func() { | ||
password := "Abc 語def" | ||
err := PasswordValidator(password) | ||
re := regexp.MustCompile(`[^\x20-\x7E]`) | ||
invalidChars := re.FindAllString(password, -1) | ||
|
||
expectedErrMsg := fmt.Sprintf("Password must not contain special characters [%s], must not contain whitespace, and must be at least 14 characters (got %d)", strings.Join(invalidChars, ", "), len(password)) | ||
Expect(err.Error()).To(Equal(expectedErrMsg)) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package validations | ||
|
||
import ( | ||
"testing" | ||
|
||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
func TestValidations(t *testing.T) { | ||
RegisterFailHandler(Fail) | ||
RunSpecs(t, "Validations Suite") | ||
} |