github.com/topsteplocal/gophish@v0.6.0/auth/auth.go (about) 1 package auth 2 3 import ( 4 "encoding/gob" 5 "errors" 6 "fmt" 7 "io" 8 "net/http" 9 10 "crypto/rand" 11 12 ctx "github.com/gophish/gophish/context" 13 log "github.com/gophish/gophish/logger" 14 "github.com/gophish/gophish/models" 15 "github.com/gorilla/securecookie" 16 "github.com/gorilla/sessions" 17 "github.com/jinzhu/gorm" 18 "golang.org/x/crypto/bcrypt" 19 ) 20 21 //init registers the necessary models to be saved in the session later 22 func init() { 23 gob.Register(&models.User{}) 24 gob.Register(&models.Flash{}) 25 Store.Options.HttpOnly = true 26 // This sets the maxAge to 5 days for all cookies 27 Store.MaxAge(86400 * 5) 28 } 29 30 // Store contains the session information for the request 31 var Store = sessions.NewCookieStore( 32 []byte(securecookie.GenerateRandomKey(64)), //Signing key 33 []byte(securecookie.GenerateRandomKey(32))) 34 35 // ErrInvalidPassword is thrown when a user provides an incorrect password. 36 var ErrInvalidPassword = errors.New("Invalid Password") 37 38 // ErrEmptyPassword is thrown when a user provides a blank password to the register 39 // or change password functions 40 var ErrEmptyPassword = errors.New("Password cannot be blank") 41 42 // ErrPasswordMismatch is thrown when a user provides passwords that do not match 43 var ErrPasswordMismatch = errors.New("Passwords must match") 44 45 // ErrUsernameTaken is thrown when a user attempts to register a username that is taken. 46 var ErrUsernameTaken = errors.New("Username already taken") 47 48 // Login attempts to login the user given a request. 49 func Login(r *http.Request) (bool, models.User, error) { 50 username, password := r.FormValue("username"), r.FormValue("password") 51 u, err := models.GetUserByUsername(username) 52 if err != nil { 53 return false, models.User{}, err 54 } 55 //If we've made it here, we should have a valid user stored in u 56 //Let's check the password 57 err = bcrypt.CompareHashAndPassword([]byte(u.Hash), []byte(password)) 58 if err != nil { 59 return false, models.User{}, ErrInvalidPassword 60 } 61 return true, u, nil 62 } 63 64 // Register attempts to register the user given a request. 65 func Register(r *http.Request) (bool, error) { 66 username := r.FormValue("username") 67 newPassword := r.FormValue("password") 68 confirmPassword := r.FormValue("confirm_password") 69 u, err := models.GetUserByUsername(username) 70 // If the given username already exists, throw an error and return false 71 if err == nil { 72 return false, ErrUsernameTaken 73 } 74 75 // If we have an error which is not simply indicating that no user was found, report it 76 if err != nil && err != gorm.ErrRecordNotFound { 77 log.Warn(err) 78 return false, err 79 } 80 81 u = models.User{} 82 // If we've made it here, we should have a valid username given 83 // Check that the passsword isn't blank 84 if newPassword == "" { 85 return false, ErrEmptyPassword 86 } 87 // Make sure passwords match 88 if newPassword != confirmPassword { 89 return false, ErrPasswordMismatch 90 } 91 // Let's create the password hash 92 h, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost) 93 if err != nil { 94 return false, err 95 } 96 u.Username = username 97 u.Hash = string(h) 98 u.ApiKey = GenerateSecureKey() 99 err = models.PutUser(&u) 100 return true, nil 101 } 102 103 // GenerateSecureKey creates a secure key to use 104 // as an API key 105 func GenerateSecureKey() string { 106 // Inspired from gorilla/securecookie 107 k := make([]byte, 32) 108 io.ReadFull(rand.Reader, k) 109 return fmt.Sprintf("%x", k) 110 } 111 112 func ChangePassword(r *http.Request) error { 113 u := ctx.Get(r, "user").(models.User) 114 currentPw := r.FormValue("current_password") 115 newPassword := r.FormValue("new_password") 116 confirmPassword := r.FormValue("confirm_new_password") 117 // Check the current password 118 err := bcrypt.CompareHashAndPassword([]byte(u.Hash), []byte(currentPw)) 119 if err != nil { 120 return ErrInvalidPassword 121 } 122 // Check that the new password isn't blank 123 if newPassword == "" { 124 return ErrEmptyPassword 125 } 126 // Check that new passwords match 127 if newPassword != confirmPassword { 128 return ErrPasswordMismatch 129 } 130 // Generate the new hash 131 h, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost) 132 if err != nil { 133 return err 134 } 135 u.Hash = string(h) 136 if err = models.PutUser(&u); err != nil { 137 return err 138 } 139 return nil 140 }