Răsfoiți Sursa

Add password generator package

Andrea Fazzi 6 ani în urmă
părinte
comite
44817d5aa6

+ 5 - 0
Godeps/Godeps.json

@@ -64,6 +64,11 @@
 			"ImportPath": "github.com/jinzhu/inflection",
 			"Rev": "1c35d901db3da928c72a72d8458480cc9ade058f"
 		},
+		{
+			"ImportPath": "github.com/sethvargo/go-password/password",
+			"Comment": "v0.1.1-2-g669be2f",
+			"Rev": "669be2fd9899edfa540cb081008de6d098461541"
+		},
 		{
 			"ImportPath": "gopkg.in/yaml.v2",
 			"Rev": "287cf08546ab5e7e37d55a84f7ed3fd1db036de5"

+ 16 - 4
orm/credential.go

@@ -5,19 +5,22 @@ import (
 	"encoding/base64"
 	"fmt"
 	"strings"
+
+	"github.com/sethvargo/go-password/password"
 )
 
+type Checkbox bool
+
 type Credential struct {
 	Name            string
 	Surname         string
-	Username        string
 	Password        string
 	PlainPassword   string
 	Email           string
 	AltEmail        string
 	TelephoneNumber string
 
-	MailSent bool
+	MailSent bool `schema:"MailSent" sql:"default: false"`
 }
 
 func (c *Credential) sanitize(s string) string {
@@ -26,16 +29,25 @@ func (c *Credential) sanitize(s string) string {
 	return r.Replace(lower)
 }
 
-func (c *Credential) GenerateUsername() string {
+func (c *Credential) Username() string {
 	return strings.Join([]string{c.sanitize(c.Name), c.sanitize(c.Surname)}, ".")
 }
 
-func (c *Credential) GenerateSaltedPassword(password string) string {
+func (c *Credential) SaltPassword(password string) string {
 	bs := sha1.Sum([]byte(password + "salt"))
 	str := base64.StdEncoding.EncodeToString(append(bs[:], []byte("salt")...))
 	return fmt.Sprintf("%s", str)
 }
 
+func (c *Credential) GeneratePassword() (string, error) {
+	password, err := password.Generate(8, 2, 0, false, true)
+	if err != nil {
+		return "", err
+	}
+	return password, nil
+
+}
+
 func (c *Credential) CompleteName() string {
 	return fmt.Sprintf("%s, %s", c.Name, c.Surname)
 }

+ 1 - 1
templates/teachers_add_update.html.tpl

@@ -47,7 +47,7 @@
     </div>
 
     <div class="form-check has-feedback">
-      <input type="checkbox" name="MailSent" class="form-check-input" id="teacher_mailsent" {{if .Options.Get "update"}}value="{{.Data.MailSent}}"{{else}}value="false"{{end}} {{if .Options.Get "update"}}{{if .Data.MailSent}}checked{{end}}{{end}}>
+      <input type="checkbox" name="MailSent" class="form-check-input" id="teacher_mailsent" {{if .Options.Get "update"}}{{if .Data.MailSent}}checked{{end}}{{end}}>
       <label class="form-check-label has-feedback" for="teacher_mailsent">Credenziali inviate</label>
     </div>
     

+ 20 - 0
vendor/github.com/sethvargo/go-password/LICENSE

@@ -0,0 +1,20 @@
+Copyright 2017 Seth Vargo <seth@sethvargo.com>
+
+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.

+ 242 - 0
vendor/github.com/sethvargo/go-password/password/generate.go

@@ -0,0 +1,242 @@
+// Package password provides a library for generating high-entropy random
+// password strings via the crypto/rand package.
+//
+//    res, err := Generate(64, 10, 10, false, false)
+//    if err != nil  {
+//      log.Fatal(err)
+//    }
+//    log.Printf(res)
+//
+// Most functions are safe for concurrent use.
+package password
+
+import (
+	"crypto/rand"
+	"errors"
+	"math/big"
+	"strings"
+)
+
+const (
+	// LowerLetters is the list of lowercase letters.
+	LowerLetters = "abcdefghijklmnopqrstuvwxyz"
+
+	// UpperLetters is the list of uppercase letters.
+	UpperLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+
+	// Digits is the list of permitted digits.
+	Digits = "0123456789"
+
+	// Symbols is the list of symbols.
+	Symbols = "~!@#$%^&*()_+`-={}|[]\\:\"<>?,./"
+)
+
+var (
+	// ErrExceedsTotalLength is the error returned with the number of digits and
+	// symbols is greater than the total length.
+	ErrExceedsTotalLength = errors.New("number of digits and symbols must be less than total length")
+
+	// ErrLettersExceedsAvailable is the error returned with the number of letters
+	// exceeds the number of available letters and repeats are not allowed.
+	ErrLettersExceedsAvailable = errors.New("number of letters exceeds available letters and repeats are not allowed")
+
+	// ErrDigitsExceedsAvailable is the error returned with the number of digits
+	// exceeds the number of available digits and repeats are not allowed.
+	ErrDigitsExceedsAvailable = errors.New("number of digits exceeds available digits and repeats are not allowed")
+
+	// ErrSymbolsExceedsAvailable is the error returned with the number of symbols
+	// exceeds the number of available symbols and repeats are not allowed.
+	ErrSymbolsExceedsAvailable = errors.New("number of symbols exceeds available symbols and repeats are not allowed")
+)
+
+// Generator is the stateful generator which can be used to customize the list
+// of letters, digits, and/or symbols.
+type Generator struct {
+	lowerLetters string
+	upperLetters string
+	digits       string
+	symbols      string
+}
+
+// GeneratorInput is used as input to the NewGenerator function.
+type GeneratorInput struct {
+	LowerLetters string
+	UpperLetters string
+	Digits       string
+	Symbols      string
+}
+
+// NewGenerator creates a new Generator from the specified configuration. If no
+// input is given, all the default values are used. This function is safe for
+// concurrent use.
+func NewGenerator(i *GeneratorInput) (*Generator, error) {
+	if i == nil {
+		i = new(GeneratorInput)
+	}
+
+	g := &Generator{
+		lowerLetters: i.LowerLetters,
+		upperLetters: i.UpperLetters,
+		digits:       i.Digits,
+		symbols:      i.Symbols,
+	}
+
+	if g.lowerLetters == "" {
+		g.lowerLetters = LowerLetters
+	}
+
+	if g.upperLetters == "" {
+		g.upperLetters = UpperLetters
+	}
+
+	if g.digits == "" {
+		g.digits = Digits
+	}
+
+	if g.symbols == "" {
+		g.symbols = Symbols
+	}
+
+	return g, nil
+}
+
+// Generate generates a password with the given requirements. length is the
+// total number of characters in the password. numDigits is the number of digits
+// to include in the result. numSymbols is the number of symbols to include in
+// the result. noUpper excludes uppercase letters from the results. allowRepeat
+// allows characters to repeat.
+//
+// The algorithm is fast, but it's not designed to be performant; it favors
+// entropy over speed. This function is safe for concurrent use.
+func (g *Generator) Generate(length, numDigits, numSymbols int, noUpper, allowRepeat bool) (string, error) {
+	letters := g.lowerLetters
+	if !noUpper {
+		letters += g.upperLetters
+	}
+
+	chars := length - numDigits - numSymbols
+	if chars < 0 {
+		return "", ErrExceedsTotalLength
+	}
+
+	if !allowRepeat && chars > len(letters) {
+		return "", ErrLettersExceedsAvailable
+	}
+
+	if !allowRepeat && numDigits > len(g.digits) {
+		return "", ErrDigitsExceedsAvailable
+	}
+
+	if !allowRepeat && numSymbols > len(g.symbols) {
+		return "", ErrSymbolsExceedsAvailable
+	}
+
+	var result string
+
+	// Characters
+	for i := 0; i < chars; i++ {
+		ch, err := randomElement(letters)
+		if err != nil {
+			return "", err
+		}
+
+		if !allowRepeat && strings.Contains(result, ch) {
+			i--
+			continue
+		}
+
+		result, err = randomInsert(result, ch)
+		if err != nil {
+			return "", err
+		}
+	}
+
+	// Digits
+	for i := 0; i < numDigits; i++ {
+		d, err := randomElement(g.digits)
+		if err != nil {
+			return "", err
+		}
+
+		if !allowRepeat && strings.Contains(result, d) {
+			i--
+			continue
+		}
+
+		result, err = randomInsert(result, d)
+		if err != nil {
+			return "", err
+		}
+	}
+
+	// Symbols
+	for i := 0; i < numSymbols; i++ {
+		sym, err := randomElement(g.symbols)
+		if err != nil {
+			return "", err
+		}
+
+		if !allowRepeat && strings.Contains(result, sym) {
+			i--
+			continue
+		}
+
+		result, err = randomInsert(result, sym)
+		if err != nil {
+			return "", err
+		}
+	}
+
+	return result, nil
+}
+
+// MustGenerate is the same as Generate, but panics on error.
+func (g *Generator) MustGenerate(length, numDigits, numSymbols int, noUpper, allowRepeat bool) string {
+	res, err := g.Generate(length, numDigits, numSymbols, noUpper, allowRepeat)
+	if err != nil {
+		panic(err)
+	}
+	return res
+}
+
+// See Generator.Generate for usage.
+func Generate(length, numDigits, numSymbols int, noUpper, allowRepeat bool) (string, error) {
+	gen, err := NewGenerator(nil)
+	if err != nil {
+		return "", err
+	}
+
+	return gen.Generate(length, numDigits, numSymbols, noUpper, allowRepeat)
+}
+
+// See Generator.MustGenerate for usage.
+func MustGenerate(length, numDigits, numSymbols int, noUpper, allowRepeat bool) string {
+	res, err := Generate(length, numDigits, numSymbols, noUpper, allowRepeat)
+	if err != nil {
+		panic(err)
+	}
+	return res
+}
+
+// randomInsert randomly inserts the given value into the given string.
+func randomInsert(s, val string) (string, error) {
+	if s == "" {
+		return val, nil
+	}
+
+	n, err := rand.Int(rand.Reader, big.NewInt(int64(len(s))))
+	if err != nil {
+		return "", err
+	}
+	i := n.Int64()
+	return s[0:i] + val + s[i:len(s)], nil
+}
+
+// randomElement extracts a random element from the given string.
+func randomElement(s string) (string, error) {
+	n, err := rand.Int(rand.Reader, big.NewInt(int64(len(s))))
+	if err != nil {
+		return "", err
+	}
+	return string(s[n.Int64()]), nil
+}