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