annotate pkg/controllers/pwreset.go @ 5490:5f47eeea988d logging

Use own logging package.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 20 Sep 2021 17:45:39 +0200
parents 4394daeea96a
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 "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"
304
69e291f26bbd Password reset: Part II.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 302
diff changeset
29 "time"
302
0777aa6de45b Password reset. Part I
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
30
3956
4f9a1ff2c2ee Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3721
diff changeset
31 htmlTemplate "html/template"
4f9a1ff2c2ee Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3721
diff changeset
32 textTemplate "text/template"
4f9a1ff2c2ee Reworked password reset to be single mailed.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 3721
diff changeset
33
339
33b59c848771 Factored out some miscellaneous code into own package.
Sascha L. Teichmann <teichmann@intevation.de>
parents: 332
diff changeset
34 "github.com/gorilla/mux"
33b59c848771 Factored out some miscellaneous code into own package.
Sascha L. Teichmann <teichmann@intevation.de>
parents: 332
diff changeset
35
414
c1047fd04a3a Moved project specific Go packages to new pkg folder.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 408
diff changeset
36 "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
37 "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
38 "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
39 "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
40 "gemma.intevation.de/gemma/pkg/models"
4244
4394daeea96a Moved JSONHandler into middleware package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 4243
diff changeset
41
5490
5f47eeea988d Use own logging package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 4244
diff changeset
42 "gemma.intevation.de/gemma/pkg/log"
4244
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 {
5490
5f47eeea988d Use own logging package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 4244
diff changeset
145 log.Errorf("%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 {
5490
5f47eeea988d Use own logging package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 4244
diff changeset
162 log.Errorf("%v\n", err)
310
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 {
5490
5f47eeea988d Use own logging package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 4244
diff changeset
248 log.Errorf("%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 {
5490
5f47eeea988d Use own logging package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 4244
diff changeset
315 log.Errorf("%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 {
5490
5f47eeea988d Use own logging package.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 4244
diff changeset
329 log.Errorf("%v\n", err)
3956
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 }