chore: password validation
This commit is contained in:
parent
3a0f0ced51
commit
7b5df08e45
26 changed files with 528 additions and 2 deletions
1
go.mod
1
go.mod
|
|
@ -4,6 +4,7 @@ go 1.24.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/gin-gonic/gin v1.10.0
|
github.com/gin-gonic/gin v1.10.0
|
||||||
|
github.com/go-passwd/validator v0.0.0-20180902184246-0b4c967e436b
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/rs/zerolog v1.33.0
|
github.com/rs/zerolog v1.33.0
|
||||||
github.com/stretchr/testify v1.9.0
|
github.com/stretchr/testify v1.9.0
|
||||||
|
|
|
||||||
2
go.sum
2
go.sum
|
|
@ -22,6 +22,8 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
|
||||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
||||||
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||||
|
github.com/go-passwd/validator v0.0.0-20180902184246-0b4c967e436b h1:XOkaXKVHqiFDTLzzHFkZ+VJkarlqnsSxIsuzcE75tk8=
|
||||||
|
github.com/go-passwd/validator v0.0.0-20180902184246-0b4c967e436b/go.mod h1:BOKCezpxxDZ5PLMqt+9MxZTCBeGcpUmDHDuYlkdPcI4=
|
||||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,5 @@ import "errors"
|
||||||
var (
|
var (
|
||||||
ErrUserHasInvalideChars = errors.New("username has invalide chars")
|
ErrUserHasInvalideChars = errors.New("username has invalide chars")
|
||||||
ErrUsernameIsTaken = errors.New("username already takebn")
|
ErrUsernameIsTaken = errors.New("username already takebn")
|
||||||
|
ErrPasswordNotComplexEnough = errors.New("password not complex enough")
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"git.keks.cloud/kekskurse/miniauth/pkg/userstore"
|
"git.keks.cloud/kekskurse/miniauth/pkg/userstore"
|
||||||
"git.keks.cloud/kekskurse/miniauth/pkg/utils"
|
"git.keks.cloud/kekskurse/miniauth/pkg/utils"
|
||||||
|
"github.com/go-passwd/validator"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -26,9 +27,24 @@ func (m Miniauth) RegisterUser(username string, mail string, password string) er
|
||||||
return utils.WrapError(ErrUserHasInvalideChars, err, log)
|
return utils.WrapError(ErrUserHasInvalideChars, err, log)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = m.checkPasswordForRegistration(password)
|
||||||
|
if err != nil {
|
||||||
|
return utils.WrapError(ErrPasswordNotComplexEnough, err, log)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m Miniauth) checkPasswordForRegistration(password string) error {
|
||||||
|
passwordValidator := validator.New(
|
||||||
|
validator.MinLength(15, nil),
|
||||||
|
validator.ContainsAtLeast("abcdefghijklmnopqrstuvwxyz", 5, nil),
|
||||||
|
validator.ContainsAtLeast("0123456789", 3, nil),
|
||||||
|
validator.ContainsAtLeast(",;.:-_#+*?=}])[({/&%$§!<>|", 3, nil))
|
||||||
|
err := passwordValidator.Validate(password)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func (m Miniauth) checkUsernameForRegistration(username string) error {
|
func (m Miniauth) checkUsernameForRegistration(username string) error {
|
||||||
reg := regexp.MustCompile("^[a-z0-9]{4,25}$")
|
reg := regexp.MustCompile("^[a-z0-9]{4,25}$")
|
||||||
if !reg.MatchString(username) {
|
if !reg.MatchString(username) {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,47 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestPasswordCheck(t *testing.T) {
|
||||||
|
tts := []struct {
|
||||||
|
name string
|
||||||
|
password string
|
||||||
|
exptErrorString string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "to short",
|
||||||
|
password: "abc",
|
||||||
|
exptErrorString: "Password length must be not lower that 15 chars",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no number",
|
||||||
|
password: "abcdefghijklmnop",
|
||||||
|
exptErrorString: "Password must contains at least 3 chars from 0123456789",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no special characters",
|
||||||
|
password: "abcd0e3fg5hijklmnop",
|
||||||
|
exptErrorString: "Password must contains at least 3 chars from ,;.:-_#+*?=}])[({/&%$§!<>|",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no special characters",
|
||||||
|
password: "abcd0e,3.f-g5hijklmnop",
|
||||||
|
exptErrorString: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
ma := getMiniAuth(t)
|
||||||
|
for _, tt := range tts {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
err := ma.checkPasswordForRegistration(tt.password)
|
||||||
|
if tt.exptErrorString != "" {
|
||||||
|
assert.Equal(t, tt.exptErrorString, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert.Nil(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestInvalideUsernames(t *testing.T) {
|
func TestInvalideUsernames(t *testing.T) {
|
||||||
tts := []struct {
|
tts := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
|
||||||
15
vendor/github.com/go-passwd/validator/.editorconfig
generated
vendored
Normal file
15
vendor/github.com/go-passwd/validator/.editorconfig
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = false
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
charset = utf-8
|
||||||
|
|
||||||
|
[*.go]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[Makefile]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
14
vendor/github.com/go-passwd/validator/.gitignore
generated
vendored
Normal file
14
vendor/github.com/go-passwd/validator/.gitignore
generated
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Binaries for programs and plugins
|
||||||
|
*.exe
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Test binary, build with `go test -c`
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
|
||||||
|
.glide/
|
||||||
20
vendor/github.com/go-passwd/validator/.travis.yml
generated
vendored
Normal file
20
vendor/github.com/go-passwd/validator/.travis.yml
generated
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
language: go
|
||||||
|
|
||||||
|
go: 1.10.x
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- go: 1.9.x
|
||||||
|
|
||||||
|
install:
|
||||||
|
- go get -t ./...
|
||||||
|
- go get golang.org/x/tools/cmd/cover
|
||||||
|
- go get github.com/mattn/goveralls
|
||||||
|
|
||||||
|
script:
|
||||||
|
- go test -v -covermode=count -coverprofile=coverage.out ./...
|
||||||
|
- goveralls -coverprofile=coverage.out -service=travis-ci -repotoken $COVERALLS_TOKEN
|
||||||
|
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- secure: "Wmo0t7rIF6eFYXmD8qACjJGqSmfxMlxvX7gDW0ILqxbo6Ud9UuVGnaPyQbzEv0AZCcKHVfgUauURsb4xrdE3tEzjNMCaC0CbeuorGwKKU5oAJ1NXFVuCMfWssJkeSNgIaOHKBGbqA/v1dfYOiCiQznlZBjslKjQ9WE97JtIZjJtlmu4s4recO8+G6/JlvZwMslVgjfnTZunqMLUY0hob0459l7H6Cct9IClihMSMmLQLJCm0gfKGvKMCf/thvGVBD7V3xrYK2DwaYD3VOLjO+ouOHVwR0aAtXoJ9EufwHBAPyPVzW+/EwJ6i6aZ8ghqZQLF35Zm6ECzcwzLnZiNZB6wX56ZI4WQME0uKcX0XnSMcRQOAx5kJ7l3X8nZDqyth9DQ62uhiA6pDXU9Cdufvz3rMQjc/xdpIhiW9TpqNjFRbT3WoAAF2jPLO7jO8hfZ+geAn3gXanpN67x22JU2Y5PSQxgUX09YdmppxpcOP/ZqdvI3Z1wEjMEONZEWN3D7BqjUbdRHYSAss19LhvumUy6PBi7M5wM/NVCXQ+qZ9HSVSYNrQMag1RcLDADGHIRHZ9p0JBFZo/Lk5Vy8ZS/QjGvrFq/jMsyXFJ5gRrADk2cwqvta0+f4V/hlrILFVRg5wHTGTmhMlXk+Vbg4gOpSj6CG1//m94ijWppZ3zB0nJgM="
|
||||||
21
vendor/github.com/go-passwd/validator/LICENSE
generated
vendored
Normal file
21
vendor/github.com/go-passwd/validator/LICENSE
generated
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Tomasz Jakub Rup
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
3
vendor/github.com/go-passwd/validator/Makefile
generated
vendored
Normal file
3
vendor/github.com/go-passwd/validator/Makefile
generated
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
test:
|
||||||
|
go vet ./...
|
||||||
|
go test -cover ./...
|
||||||
122
vendor/github.com/go-passwd/validator/README.md
generated
vendored
Normal file
122
vendor/github.com/go-passwd/validator/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
# Password validator library for Go
|
||||||
|
|
||||||
|
[](https://travis-ci.org/go-passwd/validator)
|
||||||
|
[](https://coveralls.io/github/go-passwd/validator?branch=master)
|
||||||
|
[](https://goreportcard.com/report/github.com/go-passwd/validator)
|
||||||
|
[](https://godoc.org/github.com/go-passwd/validator)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
~~~sh
|
||||||
|
go get -u github.com/go-passwd/validator
|
||||||
|
~~~
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
~~~go
|
||||||
|
import "github.com/go-passwd/validator"
|
||||||
|
|
||||||
|
passwordValidator := validator.New(validator.MinLength(5, nil), validator.MaxLength(10, nil))
|
||||||
|
err := passwordValidator.Validate(form.Password)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
|
You can pass to every validator functions ``customError`` parameter witch will be returned on error instead of default error.
|
||||||
|
|
||||||
|
~~~go
|
||||||
|
import "github.com/go-passwd/validator"
|
||||||
|
|
||||||
|
passwordValidator := validator.New(validator.MinLength(5, errors.New("too short")), validator.MaxLength(10, errors.New("too long")))
|
||||||
|
err := passwordValidator.Validate(form.Password)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
|
## Validators
|
||||||
|
|
||||||
|
### CommonPassword
|
||||||
|
|
||||||
|
Check if password is a common password.
|
||||||
|
|
||||||
|
Common password list is based on list created by Mark Burnett: https://xato.net/passwords/more-top-worst-passwords/
|
||||||
|
|
||||||
|
~~~go
|
||||||
|
passwordValidator := validator.New(validator.CommonPassword(nil))
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### ContainsAtLeast
|
||||||
|
|
||||||
|
Count occurrences of a chars and compares it with required value.
|
||||||
|
|
||||||
|
~~~go
|
||||||
|
passwordValidator := validator.New(validator.ContainsAtLeast(5, "abcdefghijklmnopqrstuvwxyz", nil))
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### ContainsOnly
|
||||||
|
|
||||||
|
Check if password contains only selected chars.
|
||||||
|
|
||||||
|
~~~go
|
||||||
|
passwordValidator := validator.New(validator.ContainsOnly("abcdefghijklmnopqrstuvwxyz", nil))
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### MaxLength
|
||||||
|
|
||||||
|
Check if password length is not greater that defined length.
|
||||||
|
|
||||||
|
~~~go
|
||||||
|
passwordValidator := validator.New(validator.MaxLength(10, nil))
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### MinLength
|
||||||
|
|
||||||
|
Check if password length is not lower that defined length.
|
||||||
|
|
||||||
|
~~~go
|
||||||
|
passwordValidator := validator.New(validator.MinLength(5, nil))
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### Noop
|
||||||
|
|
||||||
|
Always return custom error.
|
||||||
|
|
||||||
|
~~~go
|
||||||
|
passwordValidator := validator.New(validator.Noop(nil))
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### Regex
|
||||||
|
|
||||||
|
Check if password match regexp pattern.
|
||||||
|
|
||||||
|
~~~go
|
||||||
|
passwordValidator := validator.New(validator.Regex("^\\w+$", nil))
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### Similarity
|
||||||
|
|
||||||
|
Check if password is sufficiently different from the attributes.
|
||||||
|
|
||||||
|
Attributes can be: user login, email, first name, last name, …
|
||||||
|
|
||||||
|
~~~go
|
||||||
|
passwordValidator := validator.New(validator.Similarity([]string{"username", "username@example.com"}, nil, nil))
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### StartsWith
|
||||||
|
|
||||||
|
Check if password starts with one of letter.
|
||||||
|
|
||||||
|
~~~go
|
||||||
|
passwordValidator := validator.New(validator.StartsWith("abcdefghijklmnopqrstuvwxyz", nil))
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### Unique
|
||||||
|
|
||||||
|
Check if password contains only unique chars.
|
||||||
|
|
||||||
|
~~~go
|
||||||
|
passwordValidator := validator.New(validator.Unique(nil))
|
||||||
|
~~~
|
||||||
1
vendor/github.com/go-passwd/validator/TODO.md
generated
vendored
Normal file
1
vendor/github.com/go-passwd/validator/TODO.md
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
* NotSequential
|
||||||
27
vendor/github.com/go-passwd/validator/common_password.go
generated
vendored
Normal file
27
vendor/github.com/go-passwd/validator/common_password.go
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
23
vendor/github.com/go-passwd/validator/contains_at_least.go
generated
vendored
Normal file
23
vendor/github.com/go-passwd/validator/contains_at_least.go
generated
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
package validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ContainsAtLeast returns a ValidateFunc that count occurrences of a chars and compares it with required value
|
||||||
|
func ContainsAtLeast(chars string, occurrences int, customError error) ValidateFunc {
|
||||||
|
return ValidateFunc(func(password string) error {
|
||||||
|
cnt := 0
|
||||||
|
for _, char := range strings.Split(chars, "") {
|
||||||
|
cnt += strings.Count(password, char)
|
||||||
|
}
|
||||||
|
if cnt < occurrences {
|
||||||
|
if customError != nil {
|
||||||
|
return customError
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Password must contains at least %d chars from %s", occurrences, chars)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
24
vendor/github.com/go-passwd/validator/contains_only.go
generated
vendored
Normal file
24
vendor/github.com/go-passwd/validator/contains_only.go
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
package validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ContainsOnly returns a ValidateFunc that check if password contains only selected chars
|
||||||
|
func ContainsOnly(chars string, customError error) ValidateFunc {
|
||||||
|
return ValidateFunc(func(password string) error {
|
||||||
|
for _, char := range []rune(password) {
|
||||||
|
idx := strings.IndexFunc(chars, func(r rune) bool {
|
||||||
|
return r == char
|
||||||
|
})
|
||||||
|
if idx == -1 {
|
||||||
|
if customError != nil {
|
||||||
|
return customError
|
||||||
|
}
|
||||||
|
return fmt.Errorf("the password must contains only %s", chars)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
2
vendor/github.com/go-passwd/validator/doc.go
generated
vendored
Normal file
2
vendor/github.com/go-passwd/validator/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
// Package validator is a set of functions to validate passwords
|
||||||
|
package validator
|
||||||
16
vendor/github.com/go-passwd/validator/max_length.go
generated
vendored
Normal file
16
vendor/github.com/go-passwd/validator/max_length.go
generated
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
package validator
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// MaxLength returns a ValidateFunc that check if password length is not greater that "length"
|
||||||
|
func MaxLength(length int, customError error) ValidateFunc {
|
||||||
|
return ValidateFunc(func(password string) error {
|
||||||
|
if len(password) > length {
|
||||||
|
if customError != nil {
|
||||||
|
return customError
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Password length must be not greater that %d chars", length)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
16
vendor/github.com/go-passwd/validator/min_length.go
generated
vendored
Normal file
16
vendor/github.com/go-passwd/validator/min_length.go
generated
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
package validator
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// MinLength returns a ValidateFunc that check if password length is not lower that "length"
|
||||||
|
func MinLength(length int, customError error) ValidateFunc {
|
||||||
|
return ValidateFunc(func(password string) error {
|
||||||
|
if len(password) < length {
|
||||||
|
if customError != nil {
|
||||||
|
return customError
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Password length must be not lower that %d chars", length)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
8
vendor/github.com/go-passwd/validator/noop.go
generated
vendored
Normal file
8
vendor/github.com/go-passwd/validator/noop.go
generated
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
package validator
|
||||||
|
|
||||||
|
// Noop returns a ValidateFunc that always return custom error
|
||||||
|
func Noop(customError error) ValidateFunc {
|
||||||
|
return ValidateFunc(func(password string) error {
|
||||||
|
return customError
|
||||||
|
})
|
||||||
|
}
|
||||||
23
vendor/github.com/go-passwd/validator/regex.go
generated
vendored
Normal file
23
vendor/github.com/go-passwd/validator/regex.go
generated
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
package validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Regex returns ValidateFunc that check if password match regexp pattern
|
||||||
|
func Regex(pattern string, customError error) ValidateFunc {
|
||||||
|
return ValidateFunc(func(password string) error {
|
||||||
|
matched, err := regexp.MatchString(pattern, password)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if matched {
|
||||||
|
if customError != nil {
|
||||||
|
return customError
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Password shouldn't match \"%s\" pattern", pattern)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
47
vendor/github.com/go-passwd/validator/similarity.go
generated
vendored
Normal file
47
vendor/github.com/go-passwd/validator/similarity.go
generated
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
package validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Similarity returns ValidateFunc that validate whether the password is sufficiently different from the attributes
|
||||||
|
//
|
||||||
|
// Attributes can be: user login, email, first name, last name, …
|
||||||
|
func Similarity(attributes []string, maxSimilarity *float64, customError error) ValidateFunc {
|
||||||
|
if maxSimilarity == nil {
|
||||||
|
maxSimilarity = new(float64)
|
||||||
|
*maxSimilarity = 0.7
|
||||||
|
}
|
||||||
|
return ValidateFunc(func(password string) error {
|
||||||
|
for idx := range attributes {
|
||||||
|
if ratio(password, attributes[idx]) > *maxSimilarity {
|
||||||
|
if customError != nil {
|
||||||
|
return customError
|
||||||
|
}
|
||||||
|
return fmt.Errorf("The password is too similar to the %s", attributes[idx])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a measure of the sequences' similarity (float in [0,1]).
|
||||||
|
//
|
||||||
|
// Where T is the total number of elements in both sequences, and M is the number of matches, this is 2.0*M / T.
|
||||||
|
// Note that this is 1 if the sequences are identical, and 0 if they have nothing in common.
|
||||||
|
func ratio(a, b string) float64 {
|
||||||
|
t := float64(len(a) + len(b))
|
||||||
|
m := 0.0
|
||||||
|
sa := strings.Split(a, "")
|
||||||
|
sb := strings.Split(b, "")
|
||||||
|
for idx := range sb {
|
||||||
|
aidx := strings.Index(a, sb[idx])
|
||||||
|
if aidx > -1 {
|
||||||
|
sa = append(sa[:aidx], sa[aidx+1:]...)
|
||||||
|
a = strings.Join(sa, "")
|
||||||
|
m = m + 1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 2.0 * m / t
|
||||||
|
}
|
||||||
23
vendor/github.com/go-passwd/validator/starts_with.go
generated
vendored
Normal file
23
vendor/github.com/go-passwd/validator/starts_with.go
generated
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
package validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// StartsWith returns ValidateFunc that validate whether the password is starts with one of letter
|
||||||
|
func StartsWith(letters string, customError error) ValidateFunc {
|
||||||
|
return ValidateFunc(func(password string) error {
|
||||||
|
firstLetter := []rune(password)[0]
|
||||||
|
idx := strings.IndexFunc(letters, func(r rune) bool {
|
||||||
|
return r == firstLetter
|
||||||
|
})
|
||||||
|
if idx == -1 {
|
||||||
|
if customError != nil {
|
||||||
|
return customError
|
||||||
|
}
|
||||||
|
return fmt.Errorf("the password must starts with one of: %s", letters)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
24
vendor/github.com/go-passwd/validator/unique.go
generated
vendored
Normal file
24
vendor/github.com/go-passwd/validator/unique.go
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
package validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Unique returns ValidateFunc that validate whether the password has only unique chars
|
||||||
|
func Unique(customError error) ValidateFunc {
|
||||||
|
return ValidateFunc(func(password string) error {
|
||||||
|
runes := []rune(password)
|
||||||
|
for idx := range runes {
|
||||||
|
if strings.LastIndexFunc(password, func(r rune) bool {
|
||||||
|
return r == runes[idx]
|
||||||
|
}) != idx {
|
||||||
|
if customError != nil {
|
||||||
|
return customError
|
||||||
|
}
|
||||||
|
return errors.New("the password must contains unique chars")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
4
vendor/github.com/go-passwd/validator/validate_func.go
generated
vendored
Normal file
4
vendor/github.com/go-passwd/validator/validate_func.go
generated
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
package validator
|
||||||
|
|
||||||
|
// ValidateFunc defines a function to validate
|
||||||
|
type ValidateFunc func(password string) error
|
||||||
29
vendor/github.com/go-passwd/validator/validator.go
generated
vendored
Normal file
29
vendor/github.com/go-passwd/validator/validator.go
generated
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
package validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Validator represents set of password validators
|
||||||
|
type Validator []ValidateFunc
|
||||||
|
|
||||||
|
// New return new instance of Validator
|
||||||
|
func New(vfunc ...ValidateFunc) *Validator {
|
||||||
|
v := Validator{}
|
||||||
|
v = append(v, vfunc...)
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the password
|
||||||
|
func (v *Validator) Validate(password string) error {
|
||||||
|
if len(*v) == 0 {
|
||||||
|
return errors.New("Validator must contains at least 1 validator function")
|
||||||
|
}
|
||||||
|
for _, passwordValidator := range *v {
|
||||||
|
err := passwordValidator(password)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
3
vendor/modules.txt
vendored
3
vendor/modules.txt
vendored
|
|
@ -66,6 +66,9 @@ github.com/gin-gonic/gin/binding
|
||||||
github.com/gin-gonic/gin/internal/bytesconv
|
github.com/gin-gonic/gin/internal/bytesconv
|
||||||
github.com/gin-gonic/gin/internal/json
|
github.com/gin-gonic/gin/internal/json
|
||||||
github.com/gin-gonic/gin/render
|
github.com/gin-gonic/gin/render
|
||||||
|
# github.com/go-passwd/validator v0.0.0-20180902184246-0b4c967e436b
|
||||||
|
## explicit
|
||||||
|
github.com/go-passwd/validator
|
||||||
# github.com/go-playground/locales v0.14.1
|
# github.com/go-playground/locales v0.14.1
|
||||||
## explicit; go 1.17
|
## explicit; go 1.17
|
||||||
github.com/go-playground/locales
|
github.com/go-playground/locales
|
||||||
|
|
|
||||||
Reference in a new issue