Mercurial > gemma
annotate pkg/controllers/pwreset.go @ 3678:8f58851927c0
client: make layer factory only return new layer config for individual maps
instead of each time it is invoked. The purpose of the factory was to support multiple maps with individual layers.
But returning a new config each time it is invoked leads to bugs that rely on the layer's state. Now this factory
reuses the same objects it created before, per map.
author | Markus Kottlaender <markus@intevation.de> |
---|---|
date | Mon, 17 Jun 2019 17:31:35 +0200 |
parents | cabf4789e02b |
children | ed4820efb7e6 |
rev | line source |
---|---|
1017
a244b18cb916
Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1001
diff
changeset
|
1 // This is Free Software under GNU Affero General Public License v >= 3.0 |
a244b18cb916
Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1001
diff
changeset
|
2 // without warranty, see README.md and license for details. |
a244b18cb916
Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1001
diff
changeset
|
3 // |
a244b18cb916
Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1001
diff
changeset
|
4 // SPDX-License-Identifier: AGPL-3.0-or-later |
a244b18cb916
Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1001
diff
changeset
|
5 // License-Filename: LICENSES/AGPL-3.0.txt |
a244b18cb916
Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1001
diff
changeset
|
6 // |
a244b18cb916
Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1001
diff
changeset
|
7 // Copyright (C) 2018 by via donau |
a244b18cb916
Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1001
diff
changeset
|
8 // – Österreichische Wasserstraßen-Gesellschaft mbH |
a244b18cb916
Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1001
diff
changeset
|
9 // Software engineering by Intevation GmbH |
a244b18cb916
Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1001
diff
changeset
|
10 // |
a244b18cb916
Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1001
diff
changeset
|
11 // Author(s): |
a244b18cb916
Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1001
diff
changeset
|
12 // * Sascha L. Teichmann <sascha.teichmann@intevation.de> |
a244b18cb916
Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1001
diff
changeset
|
13 // * Bernhard E. Reiter <bernhard.reiter@intevation.de> |
1317
5443f5c9154c
Added missing authors names in Go files.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1017
diff
changeset
|
14 // * Tom Gottfried <tom.gottfried.intevation.de> |
1017
a244b18cb916
Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1001
diff
changeset
|
15 |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
16 package controllers |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
17 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
18 import ( |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
19 "bytes" |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
20 "context" |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
21 "database/sql" |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
22 "encoding/hex" |
535
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
23 "errors" |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
24 "log" |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
25 "net/http" |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
26 "os/exec" |
511
b96b1b258cfa
Use already declared password length in reset password.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
501
diff
changeset
|
27 "strconv" |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
28 "strings" |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
29 "text/template" |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
30 "time" |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
31 |
339
33b59c848771
Factored out some miscellaneous code into own package.
Sascha L. Teichmann <teichmann@intevation.de>
parents:
332
diff
changeset
|
32 "github.com/gorilla/mux" |
33b59c848771
Factored out some miscellaneous code into own package.
Sascha L. Teichmann <teichmann@intevation.de>
parents:
332
diff
changeset
|
33 |
414
c1047fd04a3a
Moved project specific Go packages to new pkg folder.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
408
diff
changeset
|
34 "gemma.intevation.de/gemma/pkg/auth" |
c1047fd04a3a
Moved project specific Go packages to new pkg folder.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
408
diff
changeset
|
35 "gemma.intevation.de/gemma/pkg/common" |
1001
e2860eff5d03
Wait in PW reset clean up code until config is loaded.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
562
diff
changeset
|
36 "gemma.intevation.de/gemma/pkg/config" |
414
c1047fd04a3a
Moved project specific Go packages to new pkg folder.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
408
diff
changeset
|
37 "gemma.intevation.de/gemma/pkg/misc" |
442
fc37e7072022
Moved some models used in controllers to to model package because they may be needed elsewhere (e.g. GeoServer config).
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
438
diff
changeset
|
38 "gemma.intevation.de/gemma/pkg/models" |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
39 ) |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
40 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
41 const ( |
478
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
42 insertRequestSQL = `INSERT INTO sys_admin.password_reset_requests |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
43 (hash, username) VALUES ($1, $2)` |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
44 |
478
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
45 countRequestsSQL = `SELECT count(*) FROM sys_admin.password_reset_requests` |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
46 |
478
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
47 countRequestsUserSQL = `SELECT count(*) FROM sys_admin.password_reset_requests |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
48 WHERE username = $1` |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
49 |
478
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
50 deleteRequestSQL = `DELETE FROM sys_admin.password_reset_requests |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
51 WHERE hash = $1` |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
52 |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
53 findRequestSQL = `SELECT lu.email_address, lu.username |
478
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
54 FROM sys_admin.password_reset_requests prr |
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
55 JOIN users.list_users lu on prr.username = lu.username |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
56 WHERE prr.hash = $1` |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
57 |
478
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
58 cleanupRequestsSQL = `DELETE FROM sys_admin.password_reset_requests |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
59 WHERE issued < $1` |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
60 |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
61 userExistsSQL = `SELECT email_address |
478
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
62 FROM users.list_users WHERE username = $1` |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
63 |
478
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
64 updatePasswordSQL = `UPDATE users.list_users |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
65 SET pw = $1 WHERE username = $2` |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
66 ) |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
67 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
68 const ( |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
69 hashLength = 16 |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
70 passwordLength = 20 |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
71 passwordResetValid = 12 * time.Hour |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
72 maxPasswordResets = 1000 |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
73 maxPasswordRequestsPerUser = 5 |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
74 cleanupPause = 15 * time.Minute |
304
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 |
478
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
77 const pwResetRole = "sys_admin" |
438
ffdb507d5b42
Removed db service user. Use an impersonated metamorph user instead.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
414
diff
changeset
|
78 |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
79 var ( |
535
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
80 errTooMuchPasswordResets = errors.New("Too many password resets") |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
81 errTooMuchPasswordResetsPerUser = errors.New("Too many password resets per user") |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
82 errNoSuchUser = errors.New("User does not exist") |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
83 errInvalidUser = errors.New("Invalid user") |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
84 ) |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
85 |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
86 var ( |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
87 passwordResetRequestMailTmpl = template.Must( |
516
9b3db1d7a7eb
proxy: improve texts for password reset mails.
Bernhard Reiter <bernhard@intevation.de>
parents:
511
diff
changeset
|
88 template.New("request").Parse(`You or someone else has requested a password change |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
89 for your account {{ .User }} on |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
90 {{ .HTTPS }}://{{ .Server }} |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
91 |
516
9b3db1d7a7eb
proxy: improve texts for password reset mails.
Bernhard Reiter <bernhard@intevation.de>
parents:
511
diff
changeset
|
92 Please follow this link to have a new password generated and mailed to you: |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
93 |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
94 {{ .HTTPS }}://{{ .Server }}/api/users/passwordreset/{{ .Hash }} |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
95 |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
96 The link is only valid for 12 hours. |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
97 |
516
9b3db1d7a7eb
proxy: improve texts for password reset mails.
Bernhard Reiter <bernhard@intevation.de>
parents:
511
diff
changeset
|
98 If you did not initiate this password reset or do not want to reset the |
9b3db1d7a7eb
proxy: improve texts for password reset mails.
Bernhard Reiter <bernhard@intevation.de>
parents:
511
diff
changeset
|
99 password, just ignore this email. |
9b3db1d7a7eb
proxy: improve texts for password reset mails.
Bernhard Reiter <bernhard@intevation.de>
parents:
511
diff
changeset
|
100 |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
101 Best regards |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
102 Your service team`)) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
103 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
104 passwordResetMailTmpl = template.Must( |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
105 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
|
106 {{ .HTTPS }}://{{ .Server }} |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
107 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
108 has been changed to |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
109 {{ .Password }} |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
110 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
111 Change it as soon as possible. |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
112 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
113 Best regards |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
114 Your service team`)) |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
115 ) |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
116 |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
117 func init() { |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
118 go removeOutdated() |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
119 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
120 |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
121 func removeOutdated() { |
1001
e2860eff5d03
Wait in PW reset clean up code until config is loaded.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
562
diff
changeset
|
122 config.WaitReady() |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
123 for { |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
124 time.Sleep(cleanupPause) |
1327
cabf4789e02b
To make golint happier made context.Context to be the first argument of auth.RunAs.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1317
diff
changeset
|
125 ctx := context.Background() |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
126 err := auth.RunAs( |
1327
cabf4789e02b
To make golint happier made context.Context to be the first argument of auth.RunAs.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1317
diff
changeset
|
127 ctx, pwResetRole, |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
128 func(conn *sql.Conn) error { |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
129 good := time.Now().Add(-passwordResetValid) |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
130 _, err := conn.ExecContext( |
1327
cabf4789e02b
To make golint happier made context.Context to be the first argument of auth.RunAs.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1317
diff
changeset
|
131 ctx, cleanupRequestsSQL, good) |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
132 return err |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
133 }) |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
134 if err != nil { |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
135 log.Printf("error: %v\n", err) |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
136 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
137 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
138 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
139 |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
140 func requestMessageBody(https, user, hash, server string) string { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
141 var content = struct { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
142 User string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
143 HTTPS string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
144 Server string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
145 Hash string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
146 }{ |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
147 User: user, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
148 HTTPS: https, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
149 Server: server, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
150 Hash: hash, |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
151 } |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
152 var buf bytes.Buffer |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
153 if err := passwordResetRequestMailTmpl.Execute(&buf, &content); err != nil { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
154 log.Printf("error: %v\n", err) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
155 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
156 return buf.String() |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
157 } |
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 func changedMessageBody(https, user, password, server string) string { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
160 var content = struct { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
161 User string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
162 HTTPS string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
163 Server string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
164 Password string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
165 }{ |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
166 User: user, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
167 HTTPS: https, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
168 Server: server, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
169 Password: password, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
170 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
171 var buf bytes.Buffer |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
172 if err := passwordResetMailTmpl.Execute(&buf, &content); err != nil { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
173 log.Printf("error: %v\n", err) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
174 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
175 return buf.String() |
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 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
178 func useHTTPS(req *http.Request) string { |
560
66073a476baf
If header "X-Use-Protocol" is set by proxy generate https URLS in password resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
558
diff
changeset
|
179 if req.Header.Get("X-Use-Protocol") == "https" || |
66073a476baf
If header "X-Use-Protocol" is set by proxy generate https URLS in password resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
558
diff
changeset
|
180 req.URL.Scheme == "https" { |
66073a476baf
If header "X-Use-Protocol" is set by proxy generate https URLS in password resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
558
diff
changeset
|
181 return "https" |
66073a476baf
If header "X-Use-Protocol" is set by proxy generate https URLS in password resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
558
diff
changeset
|
182 } |
66073a476baf
If header "X-Use-Protocol" is set by proxy generate https URLS in password resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
558
diff
changeset
|
183 return "http" |
310
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 |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
186 func generateHash() string { |
408
ac23905e64b1
Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
339
diff
changeset
|
187 return hex.EncodeToString(common.GenerateRandomKey(hashLength)) |
310
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 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
190 func generateNewPassword() string { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
191 // First try pwgen |
511
b96b1b258cfa
Use already declared password length in reset password.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
501
diff
changeset
|
192 out, err := exec.Command( |
b96b1b258cfa
Use already declared password length in reset password.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
501
diff
changeset
|
193 "pwgen", "-y", strconv.Itoa(passwordLength), "1").Output() |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
194 if err == nil { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
195 return strings.TrimSpace(string(out)) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
196 } |
317
5cb18bedb3a9
Simplified internal password generator.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
316
diff
changeset
|
197 // Use internal generator. |
511
b96b1b258cfa
Use already declared password length in reset password.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
501
diff
changeset
|
198 return common.RandomString(passwordLength) |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
199 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
200 |
535
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
201 func backgroundRequest(https, host string, user *models.PWResetUser) error { |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
202 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
203 if user.User == "" { |
535
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
204 return errInvalidUser |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
205 } |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
206 |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
207 var hash, email string |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
208 |
535
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
209 ctx := context.Background() |
521
139214cecc8f
backend: add FIXMEs to password reset.
Bernhard Reiter <bernhard@intevation.de>
parents:
516
diff
changeset
|
210 |
535
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
211 if err := auth.RunAs( |
1327
cabf4789e02b
To make golint happier made context.Context to be the first argument of auth.RunAs.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1317
diff
changeset
|
212 ctx, pwResetRole, |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
213 func(conn *sql.Conn) error { |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
214 |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
215 var count int64 |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
216 if err := conn.QueryRowContext( |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
217 ctx, countRequestsSQL).Scan(&count); err != nil { |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
218 return err |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
219 } |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
220 |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
221 // Limit total number of password requests. |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
222 if count >= maxPasswordResets { |
535
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
223 return errTooMuchPasswordResets |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
224 } |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
225 |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
226 err := conn.QueryRowContext(ctx, userExistsSQL, user.User).Scan(&email) |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
227 |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
228 switch { |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
229 case err == sql.ErrNoRows: |
535
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
230 return errNoSuchUser |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
231 case err != nil: |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
232 return err |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
233 } |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
234 |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
235 if err := conn.QueryRowContext( |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
236 ctx, countRequestsUserSQL, user.User).Scan(&count); err != nil { |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
237 return err |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
238 } |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
239 |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
240 // Limit requests per user |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
241 if count >= maxPasswordRequestsPerUser { |
535
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
242 return errTooMuchPasswordResetsPerUser |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
243 } |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
244 |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
245 hash = generateHash() |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
246 _, err = conn.ExecContext(ctx, insertRequestSQL, hash, user.User) |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
247 return err |
535
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
248 }, |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
249 ); err != nil { |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
250 return err |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
251 } |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
252 |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
253 body := requestMessageBody(https, user.User, hash, host) |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
254 |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
255 return misc.SendMail(email, "Password Reset Link", body) |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
256 } |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
257 |
557
009171c1485c
Password reset: Generate right URLs for the server if we are behind a proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
535
diff
changeset
|
258 // host checks if we are behind a proxy and returns the name |
009171c1485c
Password reset: Generate right URLs for the server if we are behind a proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
535
diff
changeset
|
259 // of the up-front server. |
009171c1485c
Password reset: Generate right URLs for the server if we are behind a proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
535
diff
changeset
|
260 func host(req *http.Request) string { |
009171c1485c
Password reset: Generate right URLs for the server if we are behind a proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
535
diff
changeset
|
261 if fwd := req.Header.Get("X-Forwarded-Host"); fwd != "" { |
009171c1485c
Password reset: Generate right URLs for the server if we are behind a proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
535
diff
changeset
|
262 return fwd |
009171c1485c
Password reset: Generate right URLs for the server if we are behind a proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
535
diff
changeset
|
263 } |
009171c1485c
Password reset: Generate right URLs for the server if we are behind a proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
535
diff
changeset
|
264 return req.Host |
009171c1485c
Password reset: Generate right URLs for the server if we are behind a proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
535
diff
changeset
|
265 } |
009171c1485c
Password reset: Generate right URLs for the server if we are behind a proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
535
diff
changeset
|
266 |
535
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
267 func passwordResetRequest( |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
268 input interface{}, |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
269 req *http.Request, |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
270 _ *sql.Conn, |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
271 ) (jr JSONResult, err error) { |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
272 |
535
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
273 // We do the checks and the emailing in background |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
274 // no reduce the risks of timing attacks. |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
275 go func(https, host string, user *models.PWResetUser) { |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
276 if err := backgroundRequest(https, host, user); err != nil { |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
277 log.Printf("error: %v\n", err) |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
278 } |
557
009171c1485c
Password reset: Generate right URLs for the server if we are behind a proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
535
diff
changeset
|
279 }(useHTTPS(req), host(req), input.(*models.PWResetUser)) |
535
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
280 |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
281 // Send a neutral message to avoid being an user oracle. |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
282 const neutralMessage = "If this account exists, a reset link will be mailed." |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
283 |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
284 jr.Result = &struct { |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
285 Message string `json:"message"` |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
286 }{neutralMessage} |
da5f47a0941c
Password reset: Reduce the risk of timing attacks and being a user oracle when requesting resets.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
521
diff
changeset
|
287 |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
288 return |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
289 } |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
290 |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
291 func passwordReset( |
316
423d0f1d8ee0
JSON input is not used when doing a password reset.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
315
diff
changeset
|
292 _ interface{}, |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
293 req *http.Request, |
486
b2dc9c2f69e0
First stab to use the metamorphic db to do all database stuff.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
478
diff
changeset
|
294 _ *sql.Conn, |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
295 ) (jr JSONResult, err error) { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
296 |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
297 hash := mux.Vars(req)["hash"] |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
298 if _, err = hex.DecodeString(hash); err != nil { |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
299 err = JSONError{http.StatusBadRequest, "Invalid hash"} |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
300 return |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
301 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
302 |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
303 var email, user, password string |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
304 |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
305 ctx := req.Context() |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
306 |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
307 if err = auth.RunAs( |
1327
cabf4789e02b
To make golint happier made context.Context to be the first argument of auth.RunAs.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1317
diff
changeset
|
308 ctx, pwResetRole, func(conn *sql.Conn) error { |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
309 err := conn.QueryRowContext(ctx, findRequestSQL, hash).Scan(&email, &user) |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
310 switch { |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
311 case err == sql.ErrNoRows: |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
312 return JSONError{http.StatusNotFound, "No such hash"} |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
313 case err != nil: |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
314 return err |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
315 } |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
316 password = generateNewPassword() |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
317 res, err := conn.ExecContext(ctx, updatePasswordSQL, password, user) |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
318 if err != nil { |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
319 return err |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
320 } |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
321 if n, err2 := res.RowsAffected(); err2 == nil && n == 0 { |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
322 return JSONError{http.StatusNotFound, "User not found"} |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
323 } |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
324 _, err = conn.ExecContext(ctx, deleteRequestSQL, hash) |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
325 return err |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
326 }); err == nil { |
557
009171c1485c
Password reset: Generate right URLs for the server if we are behind a proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
535
diff
changeset
|
327 body := changedMessageBody(useHTTPS(req), user, password, host(req)) |
339
33b59c848771
Factored out some miscellaneous code into own package.
Sascha L. Teichmann <teichmann@intevation.de>
parents:
332
diff
changeset
|
328 if err = misc.SendMail(email, "Password Reset Done", body); err == nil { |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
329 jr.Result = &struct { |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
330 SendTo string `json:"send-to"` |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
331 }{email} |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
332 } |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
333 } |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
334 return |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
335 } |