summaryrefslogtreecommitdiff
blob: 5cdb9e54c0485a398d5402cbc4a05690a95e6298 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Used to show the change password page

package account

import (
	"glsamaker/pkg/app/handler/authentication/utils"
	"glsamaker/pkg/database/connection"
	"glsamaker/pkg/logger"
	"glsamaker/pkg/models"
	"glsamaker/pkg/models/users"
	"html/template"
	"net/http"
)

// ChangePassword changes the password of a user in case of a valid POST request.
// In case of a GET request the dialog for the password change is displayed
func ChangePassword(w http.ResponseWriter, r *http.Request) {

	user := utils.GetAuthenticatedUser(r)

	if r.Method == "POST" {

		r.ParseForm()

		oldPassword := getStringParam("oldPassword", r)
		newPassword := getStringParam("newPassword", r)
		confirmedNewPassword := getStringParam("confirmedNewPassword", r)

		if newPassword != confirmedNewPassword {
			renderPasswordChangeTemplate(w, r, user, false, "The passwords you have entered do not match")
			return
		}

		if !user.CheckPassword(oldPassword) {
			renderPasswordChangeTemplate(w, r, user, false, "The old password you have entered is not correct")
			return
		}

		err := user.UpdatePassword(newPassword)
		if err != nil {
			renderPasswordChangeTemplate(w, r, user, false, "Internal error during hash calculation.")
			return
		}

		wasForcedToChange := user.ForcePasswordRotation
		user.ForcePasswordRotation = false

		_, err = connection.DB.Model(user).Column("password").WherePK().Update()
		_, err = connection.DB.Model(user).Column("force_password_rotation").WherePK().Update()

		if err != nil {
			logger.Info.Println("error during password update")
			logger.Info.Println(err)
			renderPasswordChangeTemplate(w, r, user, false, "Internal error during password update.")
			return
		}

		if wasForcedToChange {
			http.Redirect(w, r, "/", 301)
			return
		}

		updatedUser := utils.GetAuthenticatedUser(r)

		renderPasswordChangeTemplate(w, r, updatedUser, true, "Your password has been changed successfully.")
		return
	}

	renderPasswordChangeTemplate(w, r, user, false, "")
}

// renderPasswordChangeTemplate renders all templates used for the login page
func renderPasswordChangeTemplate(w http.ResponseWriter, r *http.Request, user *users.User, success bool, message string) {

	templates := template.Must(
		template.Must(
			template.New("Show").
				ParseGlob("web/templates/layout/*.tmpl")).
			ParseGlob("web/templates/account/password/*.tmpl"))

	templates.ExecuteTemplate(w, "password.tmpl", createPasswordChangeData("account", user, success, message))
}

// createPasswordChangeData creates the data used in the template of the password change page
func createPasswordChangeData(page string, user *users.User, success bool, message string) interface{} {

	return struct {
		Page        string
		Application *models.GlobalSettings
		User        *users.User
		Success     bool
		Message     string
	}{
		Page:        page,
		Application: models.GetDefaultGlobalSettings(),
		User:        user,
		Success:     success,
		Message:     message,
	}
}

// returns the value of a parameter with the given key of a POST request
func getStringParam(key string, r *http.Request) string {
	if len(r.Form[key]) > 0 {
		return r.Form[key][0]
	}

	return ""
}