Mercurial > gemma
annotate pkg/controllers/pwreset.go @ 4855:01b593ea2311
Added missing doc strings for the STR tree in the mesh package.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Tue, 19 Nov 2019 17:48:02 +0100 |
parents | 4394daeea96a |
children | 5f47eeea988d |
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" |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
24 "io" |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
25 "log" |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
26 "net/http" |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
27 "os/exec" |
511
b96b1b258cfa
Use already declared password length in reset password.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
501
diff
changeset
|
28 "strconv" |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
29 "strings" |
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 |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
32 htmlTemplate "html/template" |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
33 textTemplate "text/template" |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
34 |
339
33b59c848771
Factored out some miscellaneous code into own package.
Sascha L. Teichmann <teichmann@intevation.de>
parents:
332
diff
changeset
|
35 "github.com/gorilla/mux" |
33b59c848771
Factored out some miscellaneous code into own package.
Sascha L. Teichmann <teichmann@intevation.de>
parents:
332
diff
changeset
|
36 |
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/auth" |
c1047fd04a3a
Moved project specific Go packages to new pkg folder.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
408
diff
changeset
|
38 "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
|
39 "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
|
40 "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
|
41 "gemma.intevation.de/gemma/pkg/models" |
4244
4394daeea96a
Moved JSONHandler into middleware package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
4243
diff
changeset
|
42 |
4394daeea96a
Moved JSONHandler into middleware package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
4243
diff
changeset
|
43 mw "gemma.intevation.de/gemma/pkg/middleware" |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
44 ) |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
45 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
46 const ( |
478
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
47 insertRequestSQL = `INSERT INTO sys_admin.password_reset_requests |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
48 (hash, username) VALUES ($1, $2) |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
49 ON CONFLICT (username) DO UPDATE SET hash = $1` |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
50 |
478
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
51 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
|
52 |
478
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
53 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
|
54 WHERE hash = $1` |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
55 |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
56 findRequestSQL = `SELECT lu.username |
478
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
57 FROM sys_admin.password_reset_requests prr |
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
58 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
|
59 WHERE prr.hash = $1` |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
60 |
478
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
61 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
|
62 WHERE issued < $1` |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
63 |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
64 userExistsSQL = `SELECT email_address |
478
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
65 FROM users.list_users WHERE username = $1` |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
66 |
478
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
67 updatePasswordSQL = `UPDATE users.list_users |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
68 SET pw = $1 WHERE username = $2` |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
69 |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
70 deletePasswordResetRequestSQL = ` |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
71 DELETE FROM sys_admin.password_reset_requests |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
72 WHERE username = $1` |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
73 ) |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
74 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
75 const ( |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
76 hashLength = 16 |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
77 passwordLength = 20 |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
78 passwordResetValid = 12 * time.Hour |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
79 maxPasswordResets = 1000 |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
80 maxPasswordRequestsPerUser = 5 |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
81 cleanupPause = 15 * time.Minute |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
82 ) |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
83 |
478
3af7ca761f6a
Purge password reset role
Tom Gottfried <tom@intevation.de>
parents:
442
diff
changeset
|
84 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
|
85 |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
86 var ( |
3976
c412dff6e1da
Fixed cases for error strings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3973
diff
changeset
|
87 errTooMuchPasswordResets = errors.New("too many password resets") |
c412dff6e1da
Fixed cases for error strings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3973
diff
changeset
|
88 errNoSuchUser = errors.New("user does not exist") |
c412dff6e1da
Fixed cases for error strings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3973
diff
changeset
|
89 errInvalidUser = errors.New("invalid 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
|
90 ) |
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
|
91 |
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
|
92 var ( |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
93 passwordResetRequestMailTmpl = textTemplate.Must( |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
94 textTemplate.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
|
95 for your account {{ .User }} on |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
96 {{ .Server }} |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
97 |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
98 Please follow this link to have a new password generated: |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
99 |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
100 {{ .Server }}/api/users/passwordreset/{{ .Hash }} |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
101 |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
102 The link is only valid for 12 hours. |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
103 |
516
9b3db1d7a7eb
proxy: improve texts for password reset mails.
Bernhard Reiter <bernhard@intevation.de>
parents:
511
diff
changeset
|
104 If you did not initiate this password reset or do not want to reset the |
3961
9d395217bd1f
PW reset: Mention in mail that the request will be canceled if you log in before following the link.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3958
diff
changeset
|
105 password, just ignore this email. Logging in with your old password |
9d395217bd1f
PW reset: Mention in mail that the request will be canceled if you log in before following the link.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3958
diff
changeset
|
106 before following the link will cancel this password reset request, too. |
516
9b3db1d7a7eb
proxy: improve texts for password reset mails.
Bernhard Reiter <bernhard@intevation.de>
parents:
511
diff
changeset
|
107 |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
108 Best regards |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
109 Your service team`)) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
110 |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
111 passwordResetPage = htmlTemplate.Must( |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
112 htmlTemplate.New("page").Parse(`<!DOCTYPE html> |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
113 <html lang="en"> |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
114 <head> |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
115 <meta charset="utf-8" /> |
3973
5f3f571c105c
Cleaned up whitespace in HTML template for password reset.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3961
diff
changeset
|
116 <title>Password reset done</title> |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
117 </head> |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
118 <body> |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
119 <p>The password reset for user <strong><tt>{{ .User }}</tt></strong> successfully done.</p> |
3973
5f3f571c105c
Cleaned up whitespace in HTML template for password reset.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3961
diff
changeset
|
120 <p>New password: <strong><tt>{{ .Password }}</tt></strong></p> |
5f3f571c105c
Cleaned up whitespace in HTML template for password reset.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3961
diff
changeset
|
121 <p><a href="/">Go to login page.</a></p> |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
122 </body> |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
123 </html> |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
124 `)) |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
125 ) |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
126 |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
127 func init() { |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
128 go removeOutdated() |
304
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 |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
131 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
|
132 config.WaitReady() |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
133 for { |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
134 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
|
135 ctx := context.Background() |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
136 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
|
137 ctx, pwResetRole, |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
138 func(conn *sql.Conn) error { |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
139 good := time.Now().Add(-passwordResetValid) |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
140 _, 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
|
141 ctx, cleanupRequestsSQL, good) |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
142 return err |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
143 }) |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
144 if err != nil { |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
145 log.Printf("error: %v\n", err) |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
146 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
147 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
148 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
149 |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
150 func requestMessageBody(user, hash, server string) string { |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
151 var content = struct { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
152 User string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
153 Server string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
154 Hash string |
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 User: user, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
157 Server: server, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
158 Hash: hash, |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
159 } |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
160 var buf bytes.Buffer |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
161 if err := passwordResetRequestMailTmpl.Execute(&buf, &content); err != nil { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
162 log.Printf("error: %v\n", err) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
163 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
164 return buf.String() |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
165 } |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
166 |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
167 func changedMessageBody(w io.Writer, user, password string) error { |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
168 var content = struct { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
169 User string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
170 Password string |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
171 }{ |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
172 User: user, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
173 Password: password, |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
174 } |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
175 return passwordResetPage.Execute(w, &content) |
310
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 |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
178 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
|
179 return hex.EncodeToString(common.GenerateRandomKey(hashLength)) |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
180 } |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
181 |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
182 func generateNewPassword() string { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
183 // First try pwgen |
511
b96b1b258cfa
Use already declared password length in reset password.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
501
diff
changeset
|
184 out, err := exec.Command( |
b96b1b258cfa
Use already declared password length in reset password.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
501
diff
changeset
|
185 "pwgen", "-y", strconv.Itoa(passwordLength), "1").Output() |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
186 if err == nil { |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
187 return strings.TrimSpace(string(out)) |
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
188 } |
317
5cb18bedb3a9
Simplified internal password generator.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
316
diff
changeset
|
189 // Use internal generator. |
511
b96b1b258cfa
Use already declared password length in reset password.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
501
diff
changeset
|
190 return common.RandomString(passwordLength) |
310
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 |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
193 func backgroundRequest(host string, user *models.PWResetUser) error { |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
194 |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
195 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
|
196 return errInvalidUser |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
197 } |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
198 |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
199 var hash, email string |
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
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 ctx := context.Background() |
521
139214cecc8f
backend: add FIXMEs to password reset.
Bernhard Reiter <bernhard@intevation.de>
parents:
516
diff
changeset
|
202 |
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
|
203 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
|
204 ctx, pwResetRole, |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
205 func(conn *sql.Conn) error { |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
206 |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
207 var count int64 |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
208 if err := conn.QueryRowContext( |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
209 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
|
210 return err |
321
974a5e4c0055
Persist password reset requests in database.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
319
diff
changeset
|
211 } |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
212 |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
213 // 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
|
214 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
|
215 return errTooMuchPasswordResets |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
216 } |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
217 |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
218 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
|
219 |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
220 switch { |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
221 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
|
222 return errNoSuchUser |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
223 case err != nil: |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
224 return err |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
225 } |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
226 |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
227 hash = generateHash() |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
228 _, 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
|
229 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
|
230 }, |
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
|
231 ); 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
|
232 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
|
233 } |
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
|
234 |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
235 body := requestMessageBody(user.User, hash, host) |
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
|
236 |
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
|
237 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
|
238 } |
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
|
239 |
4244
4394daeea96a
Moved JSONHandler into middleware package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
4243
diff
changeset
|
240 func passwordResetRequest(req *http.Request) (jr mw.JSONResult, err error) { |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
241 |
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 // 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
|
243 // no reduce the risks of timing attacks. |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
244 go func(user *models.PWResetUser) { |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
245 config.WaitReady() |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
246 host := config.ExternalURL() |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
247 if err := backgroundRequest(host, user); err != nil { |
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 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
|
249 } |
4244
4394daeea96a
Moved JSONHandler into middleware package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
4243
diff
changeset
|
250 }(mw.JSONInput(req).(*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
|
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 // 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
|
253 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
|
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 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
|
256 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
|
257 }{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
|
258 |
302
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
259 return |
0777aa6de45b
Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
260 } |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
261 |
3721
ed4820efb7e6
Password reset: Send redirect to server starting page when reset succeeded.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1327
diff
changeset
|
262 func passwordReset(rw http.ResponseWriter, req *http.Request) { |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
263 |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
264 hash := mux.Vars(req)["hash"] |
3721
ed4820efb7e6
Password reset: Send redirect to server starting page when reset succeeded.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1327
diff
changeset
|
265 if _, err := hex.DecodeString(hash); err != nil { |
ed4820efb7e6
Password reset: Send redirect to server starting page when reset succeeded.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
1327
diff
changeset
|
266 http.Error(rw, "invalid hash", http.StatusBadRequest) |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
267 return |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
268 } |
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
269 |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
270 var user, password string |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
271 |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
272 ctx := req.Context() |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
273 |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
274 err := auth.RunAs( |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
275 ctx, pwResetRole, |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
276 func(conn *sql.Conn) error { |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
277 tx, err := conn.BeginTx(ctx, nil) |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
278 if err != nil { |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
279 return err |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
280 } |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
281 defer tx.Rollback() |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
282 |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
283 err = tx.QueryRowContext(ctx, findRequestSQL, hash).Scan(&user) |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
284 switch { |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
285 case err == sql.ErrNoRows: |
3976
c412dff6e1da
Fixed cases for error strings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3973
diff
changeset
|
286 return errors.New("this URL is no longer valid") |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
287 case err != nil: |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
288 return err |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
289 } |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
290 password = generateNewPassword() |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
291 res, err := tx.ExecContext(ctx, updatePasswordSQL, password, user) |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
292 if err != nil { |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
293 return err |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
294 } |
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
295 if n, err2 := res.RowsAffected(); err2 == nil && n == 0 { |
3976
c412dff6e1da
Fixed cases for error strings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3973
diff
changeset
|
296 return errors.New("user not found") |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
297 } |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
298 if _, err = tx.ExecContext(ctx, deleteRequestSQL, hash); err != nil { |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
299 return err |
501
c10c76c92797
Use metamorphic database connections for auth.RunAs().
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
486
diff
changeset
|
300 } |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
301 return tx.Commit() |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
302 }, |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
303 ) |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
304 |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
305 switch { |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
306 case err == sql.ErrNoRows: |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
307 http.Error(rw, "No such request", http.StatusNotFound) |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
308 return |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
309 case err != nil: |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
310 http.Error(rw, "Error: "+err.Error(), http.StatusInternalServerError) |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
311 return |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
312 } |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
313 |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
314 if err := changedMessageBody(rw, user, password); err != nil { |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
315 log.Printf("error: %v\n", err) |
310
4bee4ba6dc58
Password reset: Part III
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
304
diff
changeset
|
316 } |
304
69e291f26bbd
Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
302
diff
changeset
|
317 } |
3956
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
318 |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
319 func deletePasswordResetRequest(user string) { |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
320 ctx := context.Background() |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
321 if err := auth.RunAs( |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
322 ctx, |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
323 pwResetRole, |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
324 func(conn *sql.Conn) error { |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
325 _, err := conn.ExecContext(ctx, deletePasswordResetRequestSQL, user) |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
326 return err |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
327 }, |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
328 ); err != nil { |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
329 log.Printf("error: %v\n", err) |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
330 } |
4f9a1ff2c2ee
Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
3721
diff
changeset
|
331 } |