mirror of
https://github.com/kevin-DL/services.git
synced 2026-01-11 19:04:35 +00:00
81 lines
1.6 KiB
Go
81 lines
1.6 KiB
Go
package handler
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"strings"
|
|
|
|
pb "github.com/micro/services/password/proto"
|
|
)
|
|
|
|
const (
|
|
minLength = 8
|
|
|
|
special = "!@#$%&*"
|
|
numbers = "0123456789"
|
|
lowercase = "abcdefghijklmnopqrstuvwxyz"
|
|
uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
allChars = special + numbers + lowercase + uppercase
|
|
)
|
|
|
|
func random(chars string, i int) string {
|
|
bytes := make([]byte, i)
|
|
|
|
rand.Read(bytes)
|
|
for i, b := range bytes {
|
|
bytes[i] = chars[b%byte(len(chars))]
|
|
}
|
|
|
|
return string(bytes)
|
|
}
|
|
|
|
type Password struct{}
|
|
|
|
func (p *Password) Generate(ctx context.Context, req *pb.GenerateRequest, rsp *pb.GenerateResponse) error {
|
|
if req.Length <= 0 {
|
|
req.Length = int32(minLength)
|
|
}
|
|
|
|
charSpace := ""
|
|
if req.Numbers {
|
|
charSpace += numbers
|
|
}
|
|
if req.Lowercase {
|
|
charSpace += lowercase
|
|
}
|
|
if req.Uppercase {
|
|
charSpace += uppercase
|
|
}
|
|
if req.Special {
|
|
charSpace += special
|
|
}
|
|
if len(charSpace) == 0 {
|
|
charSpace = allChars
|
|
}
|
|
|
|
for {
|
|
// generate and return password
|
|
rsp.Password = random(charSpace, int(req.Length))
|
|
// validate we have minimums needed
|
|
reqsSatisfied := true
|
|
if req.Numbers {
|
|
reqsSatisfied = reqsSatisfied && strings.ContainsAny(rsp.Password, numbers)
|
|
}
|
|
if req.Lowercase {
|
|
reqsSatisfied = reqsSatisfied && strings.ContainsAny(rsp.Password, lowercase)
|
|
}
|
|
if req.Uppercase {
|
|
reqsSatisfied = reqsSatisfied && strings.ContainsAny(rsp.Password, uppercase)
|
|
}
|
|
if req.Special {
|
|
reqsSatisfied = reqsSatisfied && strings.ContainsAny(rsp.Password, special)
|
|
}
|
|
if reqsSatisfied {
|
|
break
|
|
}
|
|
// failed to satisfy all reqs, try again
|
|
}
|
|
|
|
return nil
|
|
}
|