forked from Alex13658/SchoolServer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
change-password.go
141 lines (137 loc) · 5.5 KB
/
change-password.go
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// change-password
package restapi
import (
"crypto/md5"
"encoding/hex"
"encoding/json"
"net/http"
"strings"
)
// changePasswordRequest используется в ChangePasswordHandler
type changePasswordRequest struct {
Old string `json:"old"`
New string `json:"new"`
}
// getMD5Hash получает md5 сумму.
func getMD5Hash(text string) string {
hash := md5.Sum([]byte(text))
return hex.EncodeToString(hash[:])
}
// ChangePasswordHandler обрабатывает запросы на удаление письма
func (rest *RestAPI) ChangePasswordHandler(respwr http.ResponseWriter, req *http.Request) {
rest.logger.Info("REST: ChangePasswordHandler called", "IP", req.RemoteAddr)
// Проверка метода запроса
if req.Method != "POST" {
rest.logger.Info("REST: Wrong method", "Method", req.Method, "IP", req.RemoteAddr)
respwr.WriteHeader(http.StatusMethodNotAllowed)
return
}
// Получить существующие имя и объект локальной сессии
sessionName, session := rest.getLocalSession(respwr, req)
if session == nil {
return
}
// Чтение запроса от клиента
var rReq changePasswordRequest
decoder := json.NewDecoder(req.Body)
err := decoder.Decode(&rReq)
if err != nil {
rest.logger.Info("REST: Malformed request data", "Error", err.Error(), "IP", req.RemoteAddr)
respwr.WriteHeader(http.StatusBadRequest)
status, err := respwr.Write(rest.Errors.MalformedData)
if err != nil {
rest.logger.Error("REST: Error occured when sending response", "Error", err, "Status", status, "IP", req.RemoteAddr)
} else {
rest.logger.Info("REST: Successfully sent response", "IP", req.RemoteAddr)
}
return
}
// Распечатаем запрос от клиента
rest.logger.Info("REST: Request data", "Data", rReq, "IP", req.RemoteAddr)
// Проверим валидность данных
if rReq.New == "" || rReq.Old == "" {
rest.logger.Info("REST: Invalid data: empty passwords", "IP", req.RemoteAddr)
respwr.WriteHeader(http.StatusBadRequest)
status, err := respwr.Write(rest.Errors.InvalidData)
if err != nil {
rest.logger.Error("REST: Error occured when sending response", "Error", err, "Status", status, "IP", req.RemoteAddr)
} else {
rest.logger.Info("REST: Successfully sent response", "IP", req.RemoteAddr)
}
return
}
// Получим удаленную сессию
remoteSession, ok := rest.sessionsMap[sessionName]
if !ok {
// Если нет удаленной сессии
rest.logger.Info("REST: No remote session", "IP", req.RemoteAddr)
// Создать новую
remoteSession = rest.remoteRelogin(respwr, req, session)
if remoteSession == nil {
return
}
}
// Применить md5 к паролям
oldPasskey := getMD5Hash(rReq.Old)
newPasskey := getMD5Hash(rReq.New)
// Сходить по удаленной сессии
err = remoteSession.ChangePassword(oldPasskey, newPasskey)
if err != nil {
if strings.Contains(err.Error(), "You was logged out from server") {
// Если удаленная сессия есть, но не активна
rest.logger.Info("REST: Remote connection timed out", "IP", req.RemoteAddr)
// Создать новую
remoteSession = rest.remoteRelogin(respwr, req, session)
if remoteSession == nil {
return
}
// Повторно получить с сайта школы
err = remoteSession.ChangePassword(oldPasskey, newPasskey)
if err != nil {
// Ошибка
rest.logger.Error("REST: Error occured when getting data from site", "Error", err, "IP", req.RemoteAddr)
respwr.WriteHeader(http.StatusBadGateway)
return
}
} else if strings.Contains(err.Error(), "Invalid old password") {
// Если старый пароль введен неверно
rest.logger.Info("REST: Invalid old password")
respwr.WriteHeader(http.StatusBadRequest)
status, err := respwr.Write(rest.Errors.WrongOldPassword)
if err != nil {
rest.logger.Error("REST: Error occured when sending response", "Error", err, "Status", status, "IP", req.RemoteAddr)
} else {
rest.logger.Info("REST: Successfully sent response", "IP", req.RemoteAddr)
}
return
} else if strings.Contains(err.Error(), "Equal new and old passwords") {
// Если пароли одинаковы
rest.logger.Info("REST: Equal new and old passwords")
respwr.WriteHeader(http.StatusBadRequest)
status, err := respwr.Write(rest.Errors.SamePassword)
if err != nil {
rest.logger.Error("REST: Error occured when sending response", "Error", err, "Status", status, "IP", req.RemoteAddr)
} else {
rest.logger.Info("REST: Successfully sent response", "IP", req.RemoteAddr)
}
return
} else {
// Другая ошибка
rest.logger.Error("REST: Error occured when getting data from site", "Error", err, "IP", req.RemoteAddr)
respwr.WriteHeader(http.StatusBadGateway)
return
}
}
userName := session.Values["userName"]
schoolID := session.Values["schoolID"]
// Обновить пароль в БД
err = rest.Db.UpdateUser(userName.(string), newPasskey, schoolID.(int), "", 0, nil, nil)
if err != nil {
rest.logger.Error("REST: Error occured when saving updated password to DB", "Error", err, "userName", userName, "schoolID", schoolID, "newPasskey", newPasskey, "IP", req.RemoteAddr)
respwr.WriteHeader(http.StatusInternalServerError)
return
}
// Отправить ответ клиенту
rest.logger.Info("REST: Successfully updated password", "IP", req.RemoteAddr)
respwr.WriteHeader(http.StatusOK)
}