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