Mercurial > gemma
annotate controllers/pwreset.go @ 315:3ef0521609f5
Limit is not needed when fetching an email for a user.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Thu, 02 Aug 2018 10:03:54 +0200 |
parents | adceb47920fb |
children | 423d0f1d8ee0 |
rev | line source |
---|---|
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
1 package controllers |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
2 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
3 import ( |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
4 "bytes" |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
5 "database/sql" |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
6 "encoding/hex" |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
7 "log" |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
8 "math/big" |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
9 "net/http" |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
10 "os/exec" |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
11 "strings" |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
12 "sync" |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
13 "text/template" |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
14 "time" |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
15 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
16 "gemma.intevation.de/gemma/auth" |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
17 "gemma.intevation.de/gemma/config" |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
18 "github.com/gorilla/mux" |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
19 |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
20 gomail "gopkg.in/gomail.v2" |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
21 ) |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
22 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
23 const ( |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
24 userExistsSQL = `SELECT email_address |
315
3ef0521609f5
Limit is not needed when fetching an email for a user.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
314
diff
changeset
|
25 FROM users.list_users WHERE username = $1` |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
26 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
27 updatePasswordSQL = `UPDATE users.list_users |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
28 SET pw = $1 WHERE username = $2` |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
29 ) |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
30 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
31 const ( |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
32 passwordResetValid = time.Hour |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
33 maxPasswordResets = 1000 |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
34 maxPasswordRequestsPerUser = 5 |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
35 ) |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
36 |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
37 var ( |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
38 passwordResetRequestMailTmpl = template.Must( |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
39 template.New("request").Parse(`You have requested a password change |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
40 for your account {{ .User }} on |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
41 {{ .HTTPS }}://{{ .Server }} |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
42 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
43 Please follow this link to get to the page where you can change your password. |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
44 |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
45 {{ .HTTPS }}://{{ .Server }}/api/users/passwordreset/{{ .Hash }} |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
46 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
47 The link is only valid for one hour. |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
48 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
49 Best regards |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
50 Your service team`)) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
51 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
52 passwordResetMailTmpl = template.Must( |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
53 template.New("reset").Parse(`Your password for your account {{ .User }} on |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
54 {{ .HTTPS }}://{{ .Server }} |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
55 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
56 has been changed to |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
57 {{ .Password }} |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
58 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
59 Change it as soon as possible. |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
60 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
61 Best regards |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
62 Your service team`)) |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
63 ) |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
64 |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
65 type timedUser struct { |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
66 user string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
67 email string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
68 time time.Time |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
69 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
70 |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
71 type resetRequests struct { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
72 sync.Mutex |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
73 reqs map[string]*timedUser |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
74 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
75 |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
76 var passwordResetRequests = func() *resetRequests { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
77 rr := &resetRequests{reqs: map[string]*timedUser{}} |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
78 go func() { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
79 for { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
80 time.Sleep(2 * time.Minute) |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
81 rr.removeOutdated() |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
82 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
83 }() |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
84 return rr |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
85 }() |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
86 |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
87 func (rr *resetRequests) len() int { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
88 rr.Lock() |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
89 l := len(rr.reqs) |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
90 rr.Unlock() |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
91 return l |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
92 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
93 |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
94 func (rr *resetRequests) userAllowed(user string) bool { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
95 rr.Lock() |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
96 defer rr.Unlock() |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
97 var count int |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
98 for _, v := range rr.reqs { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
99 if v.user == user { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
100 if count++; count >= maxPasswordRequestsPerUser { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
101 return false |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
102 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
103 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
104 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
105 return true |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
106 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
107 |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
108 func (rr *resetRequests) store(hash, user, email string) { |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
109 now := time.Now() |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
110 rr.Lock() |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
111 rr.reqs[hash] = &timedUser{user, email, now} |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
112 rr.Unlock() |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
113 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
114 |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
115 func (rr *resetRequests) fetch(hash string) *timedUser { |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
116 rr.Lock() |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
117 defer rr.Unlock() |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
118 tu := rr.reqs[hash] |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
119 if tu == nil { |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
120 return nil |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
121 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
122 if tu.time.Before(time.Now().Add(-passwordResetValid)) { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
123 delete(rr.reqs, hash) |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
124 return nil |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
125 } |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
126 return tu |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
127 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
128 |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
129 func (rr *resetRequests) delete(hash string) { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
130 rr.Lock() |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
131 delete(rr.reqs, hash) |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
132 rr.Unlock() |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
133 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
134 |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
135 func (rr *resetRequests) removeOutdated() { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
136 good := time.Now().Add(-passwordResetValid) |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
137 rr.Lock() |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
138 defer rr.Unlock() |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
139 for k, v := range rr.reqs { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
140 if v.time.Before(good) { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
141 delete(rr.reqs, k) |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
142 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
143 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
144 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
145 |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
146 func requestMessageBody(https, user, hash, server string) string { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
147 var content = struct { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
148 User string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
149 HTTPS string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
150 Server string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
151 Hash string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
152 }{ |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
153 User: user, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
154 HTTPS: https, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
155 Server: server, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
156 Hash: hash, |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
157 } |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
158 var buf bytes.Buffer |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
159 if err := passwordResetRequestMailTmpl.Execute(&buf, &content); err != nil { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
160 log.Printf("error: %v\n", err) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
161 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
162 return buf.String() |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
163 } |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
164 |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
165 func changedMessageBody(https, user, password, server string) string { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
166 var content = struct { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
167 User string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
168 HTTPS string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
169 Server string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
170 Password string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
171 }{ |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
172 User: user, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
173 HTTPS: https, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
174 Server: server, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
175 Password: password, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
176 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
177 var buf bytes.Buffer |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
178 if err := passwordResetMailTmpl.Execute(&buf, &content); err != nil { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
179 log.Printf("error: %v\n", err) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
180 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
181 return buf.String() |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
182 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
183 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
184 func useHTTPS(req *http.Request) string { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
185 if strings.ToLower(req.URL.Scheme) == "https" { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
186 return "https" |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
187 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
188 return "http" |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
189 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
190 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
191 const ( |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
192 hashLength = 32 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
193 passwordLength = 20 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
194 ) |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
195 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
196 func generateHash() string { |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
197 return hex.EncodeToString(auth.GenerateRandomKey(hashLength)) |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
198 } |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
199 |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
200 const ( |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
201 base62alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
202 special = ",.!;" |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
203 ) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
204 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
205 var ( |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
206 zero = big.NewInt(0) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
207 div62 = big.NewInt(62) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
208 ) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
209 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
210 func encodeToString(src []byte, max int) string { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
211 v := new(big.Int) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
212 v.SetBytes(src[1:]) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
213 m := new(big.Int) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
214 z := new(big.Int) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
215 out := make([]byte, 0, max) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
216 for { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
217 z.DivMod(v, div62, m) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
218 // reverse order but it doesnt matter. |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
219 out = append(out, base62alphabet[m.Int64()]) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
220 if len(out) == max-1 || z.Cmp(zero) == 0 { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
221 break |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
222 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
223 v, z = z, v |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
224 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
225 out = append(out, special[int(src[0])%len(special)]) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
226 return string(out) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
227 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
228 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
229 func generateNewPassword() string { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
230 // First try pwgen |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
231 out, err := exec.Command("pwgen", "-y", "20", "1").Output() |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
232 if err == nil { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
233 return strings.TrimSpace(string(out)) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
234 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
235 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
236 // Use internal base62 encoder. |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
237 return encodeToString(auth.GenerateRandomKey(20), 20) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
238 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
239 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
240 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
241 func sendMail(email, subject, body string) error { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
242 cfg := &config.Config |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
243 m := gomail.NewMessage() |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
244 m.SetHeader("From", cfg.MailFrom) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
245 m.SetHeader("To", email) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
246 m.SetHeader("Subject", subject) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
247 m.SetBody("text/plain", body) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
248 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
249 d := gomail.Dialer{ |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
250 Host: cfg.MailHost, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
251 Port: int(cfg.MailPort), |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
252 Username: cfg.MailUser, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
253 Password: cfg.MailPassword, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
254 LocalName: cfg.MailHelo, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
255 SSL: cfg.MailPort == 465, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
256 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
257 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
258 return d.DialAndSend(m) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
259 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
260 |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
261 func passwordResetRequest( |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
262 input interface{}, |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
263 req *http.Request, |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
264 db *sql.DB, |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
265 ) (jr JSONResult, err error) { |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
266 |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
267 // Limit total number of password requests. |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
268 if passwordResetRequests.len() >= maxPasswordResets { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
269 err = JSONError{ |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
270 Code: http.StatusServiceUnavailable, |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
271 Message: "Too much password reset request", |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
272 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
273 return |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
274 } |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
275 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
276 user := input.(*PWResetUser) |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
277 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
278 if user.User == "" { |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
279 err = JSONError{http.StatusBadRequest, "Invalid user name"} |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
280 return |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
281 } |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
282 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
283 cfg := &config.Config |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
284 if db, err = auth.OpenDB(cfg.ServiceUser, cfg.ServicePassword); err != nil { |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
285 return |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
286 } |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
287 defer db.Close() |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
288 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
289 var email string |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
290 err = db.QueryRow(userExistsSQL, user.User).Scan(&email) |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
291 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
292 switch { |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
293 case err == sql.ErrNoRows: |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
294 err = JSONError{http.StatusNotFound, "User does not exist."} |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
295 return |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
296 case err != nil: |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
297 return |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
298 } |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
299 |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
300 // Limit requests per user |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
301 if !passwordResetRequests.userAllowed(user.User) { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
302 err = JSONError{ |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
303 Code: http.StatusServiceUnavailable, |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
304 Message: "Too much password reset requests for user", |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
305 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
306 return |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
307 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
308 |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
309 hash := generateHash() |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
310 |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
311 passwordResetRequests.store(hash, user.User, email) |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
312 |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
313 body := requestMessageBody(useHTTPS(req), user.User, hash, req.Host) |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
314 |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
315 if err = sendMail(email, "Password Reset Link", body); err != nil { |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
316 return |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
317 } |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
318 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
319 jr.Result = &struct { |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
320 SendTo string `json:"send-to"` |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
321 }{email} |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
322 |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
323 return |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
324 } |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
325 |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
326 func passwordReset( |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
327 input interface{}, |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
328 req *http.Request, |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
329 db *sql.DB, |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
330 ) (jr JSONResult, err error) { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
331 |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
332 hash := mux.Vars(req)["hash"] |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
333 if _, err = hex.DecodeString(hash); err != nil { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
334 err = JSONError{http.StatusBadRequest, "Invalid hash"} |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
335 return |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
336 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
337 |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
338 tu := passwordResetRequests.fetch(hash) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
339 if tu == nil { |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
340 err = JSONError{http.StatusNotFound, "No such hash"} |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
341 return |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
342 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
343 |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
344 password := generateNewPassword() |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
345 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
346 cfg := &config.Config |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
347 if db, err = auth.OpenDB(cfg.ServiceUser, cfg.ServicePassword); err != nil { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
348 return |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
349 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
350 defer db.Close() |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
351 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
352 var res sql.Result |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
353 if res, err = db.Exec( |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
354 updatePasswordSQL, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
355 password, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
356 tu.user, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
357 ); err != nil { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
358 return |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
359 } |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
360 |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
361 passwordResetRequests.delete(hash) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
362 |
311
74559e12a59f
sql.Result.RowsAffected is a driver specific feature. Check
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
310
diff
changeset
|
363 if n, err2 := res.RowsAffected(); err2 == nil && n == 0 { |
314
adceb47920fb
Cosmetics. Little less structure bloat.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
311
diff
changeset
|
364 err = JSONError{http.StatusNotFound, "User not found"} |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
365 return |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
366 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
367 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
368 body := changedMessageBody(useHTTPS(req), tu.user, password, req.Host) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
369 if err = sendMail(tu.email, "Password Reset Done", body); err != nil { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
370 return |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
371 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
372 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
373 jr.Result = &struct { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
374 Message string `json:"message"` |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
375 }{"User password changed"} |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
376 |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
377 return |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
378 } |