Worked on reset password views, refactored out password strength to a reusable directive
This commit is contained in:
@@ -41,6 +41,13 @@ func Register(r *macaron.Macaron) {
|
||||
r.Get("/signup", Index)
|
||||
r.Post("/api/user/signup", bind(m.CreateUserCommand{}), SignUp)
|
||||
|
||||
// reset password
|
||||
r.Get("/user/password/send-reset-email", Index)
|
||||
r.Get("/user/password/reset", Index)
|
||||
|
||||
r.Post("/api/user/password/send-reset-email", bind(dtos.SendResetPasswordEmailForm{}), wrap(SendResetPasswordEmail))
|
||||
r.Post("/api/user/password/reset", wrap(ViewResetPasswordForm))
|
||||
|
||||
// dashboard snapshots
|
||||
r.Post("/api/snapshots/", bind(m.CreateDashboardSnapshotCommand{}), CreateDashboardSnapshot)
|
||||
r.Get("/dashboard/snapshot/*", Index)
|
||||
|
||||
@@ -27,3 +27,7 @@ type AdminUserListItem struct {
|
||||
Login string `json:"login"`
|
||||
IsGrafanaAdmin bool `json:"isGrafanaAdmin"`
|
||||
}
|
||||
|
||||
type SendResetPasswordEmailForm struct {
|
||||
UserOrEmail string `json:"userOrEmail" binding:"Required"`
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/middleware"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
func SendResetPasswordEmail(c *middleware.Context, form dtos.SendResetPasswordEmailForm) Response {
|
||||
userQuery := m.GetUserByLoginQuery{LoginOrEmail: form.UserOrEmail}
|
||||
|
||||
if err := bus.Dispatch(&userQuery); err != nil {
|
||||
return ApiError(404, "User does not exist", err)
|
||||
}
|
||||
|
||||
emailCmd := m.SendResetPasswordEmailCommand{User: userQuery.Result}
|
||||
if err := bus.Dispatch(&emailCmd); err != nil {
|
||||
return ApiError(500, "Failed to send email", err)
|
||||
}
|
||||
|
||||
return ApiSuccess("Email sent")
|
||||
}
|
||||
|
||||
func ViewResetPasswordForm(c *middleware.Context) Response {
|
||||
return ApiSuccess("Email sent")
|
||||
}
|
||||
@@ -5,7 +5,6 @@ type SendEmailCommand struct {
|
||||
From string
|
||||
Subject string
|
||||
Body string
|
||||
Type string
|
||||
Massive bool
|
||||
Info string
|
||||
}
|
||||
@@ -16,13 +15,7 @@ type SendResetPasswordEmailCommand struct {
|
||||
|
||||
// create mail content
|
||||
func (m *SendEmailCommand) Content() string {
|
||||
// set mail type
|
||||
contentType := "text/plain; charset=UTF-8"
|
||||
if m.Type == "html" {
|
||||
contentType = "text/html; charset=UTF-8"
|
||||
}
|
||||
|
||||
// create mail content
|
||||
contentType := "text/html; charset=UTF-8"
|
||||
content := "From: " + m.From + "\r\nSubject: " + m.Subject + "\r\nContent-Type: " + contentType + "\r\n\r\n" + m.Body
|
||||
return content
|
||||
}
|
||||
@@ -34,6 +27,5 @@ func NewSendEmailCommand(To []string, From, Subject, Body string) SendEmailComma
|
||||
From: From,
|
||||
Subject: Subject,
|
||||
Body: Body,
|
||||
Type: "html",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,16 @@ type User struct {
|
||||
Updated time.Time
|
||||
}
|
||||
|
||||
func (u *User) NameOrFallback() string {
|
||||
if u.Name != "" {
|
||||
return u.Name
|
||||
} else if u.Login != "" {
|
||||
return u.Login
|
||||
} else {
|
||||
return u.Email
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------
|
||||
// COMMANDS
|
||||
|
||||
|
||||
@@ -55,12 +55,6 @@ func processMailQueue() {
|
||||
}
|
||||
}
|
||||
|
||||
func encodeRFC2047(text string) string {
|
||||
// use mail's rfc2047 to encode any string
|
||||
addr := mail.Address{Address: text}
|
||||
return strings.Trim(addr.String(), " <>")
|
||||
}
|
||||
|
||||
func handleEmailCommand(cmd *m.SendEmailCommand) error {
|
||||
log.Info("Sending on queue")
|
||||
mailQueue <- cmd
|
||||
@@ -166,47 +160,6 @@ func sendToSmtpServer(recipients []string, msgContent []byte) error {
|
||||
}
|
||||
|
||||
return client.Quit()
|
||||
// smtpServer := "smtp.gmail.com"
|
||||
// auth := smtp.PlainAuth(
|
||||
// "",
|
||||
// "torkel.odegaard@gmail.com",
|
||||
// "peslpwstnnloiksq",
|
||||
// smtpServer,
|
||||
// )
|
||||
//
|
||||
// from := mail.Address{Name: "test", Address: "torkel@test.com"}
|
||||
// to := mail.Address{Name: "Torkel Ödegaard", Address: "torkel@raintank.io"}
|
||||
// title := "Message from Grafana"
|
||||
//
|
||||
// body := "Testing email sending"
|
||||
//
|
||||
// header := make(map[string]string)
|
||||
// header["From"] = from.String()
|
||||
// header["To"] = to.String()
|
||||
// header["Subject"] = encodeRFC2047(title)
|
||||
// header["MIME-Version"] = "1.0"
|
||||
// header["Content-Type"] = "text/plain; charset=\"utf-8\""
|
||||
// header["Content-Transfer-Encoding"] = "base64"
|
||||
//
|
||||
// message := ""
|
||||
// for k, v := range header {
|
||||
// message += fmt.Sprintf("%s: %s\r\n", k, v)
|
||||
// }
|
||||
// message += "\r\n" + base64.StdEncoding.EncodeToString([]byte(body))
|
||||
//
|
||||
// // Connect to the server, authenticate, set the sender and recipient,
|
||||
// // and send the email all in one step.
|
||||
// err := smtp.SendMail(
|
||||
// smtpServer+":587",
|
||||
// auth,
|
||||
// from.Address,
|
||||
// []string{to.Address},
|
||||
// []byte(message),
|
||||
// )
|
||||
// if err != nil {
|
||||
// log.Info("Failed to send email: %v", err)
|
||||
// }
|
||||
// kkkk
|
||||
}
|
||||
|
||||
func buildAndSend(msg *m.SendEmailCommand) (int, error) {
|
||||
|
||||
@@ -20,10 +20,10 @@ func getMailTmplData(u *m.User) map[interface{}]interface{} {
|
||||
data["AppUrl"] = setting.AppUrl
|
||||
data["BuildVersion"] = setting.BuildVersion
|
||||
data["BuildStamp"] = setting.BuildStamp
|
||||
data["BuildCommit"] = setting.BuildCommit
|
||||
data["EmailCodeValidHours"] = setting.EmailCodeValidMinutes / 60
|
||||
data["Subject"] = map[string]interface{}{}
|
||||
if u != nil {
|
||||
data["User"] = u
|
||||
data["Name"] = u.NameOrFallback()
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
@@ -35,6 +35,10 @@ func Init() error {
|
||||
return errors.New("Invalid email address for smpt from_adress config")
|
||||
}
|
||||
|
||||
if setting.EmailCodeValidMinutes == 0 {
|
||||
setting.EmailCodeValidMinutes = 120
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -50,7 +54,7 @@ func subjectTemplateFunc(obj map[string]interface{}, value string) string {
|
||||
func sendResetPasswordEmail(cmd *m.SendResetPasswordEmailCommand) error {
|
||||
var buffer bytes.Buffer
|
||||
|
||||
var data = getMailTmplData(nil)
|
||||
var data = getMailTmplData(cmd.User)
|
||||
code := CreateUserActiveCode(cmd.User, nil)
|
||||
data["Code"] = code
|
||||
|
||||
@@ -75,3 +79,35 @@ func CreateUserActiveCode(u *m.User, startInf interface{}) string {
|
||||
code += hex.EncodeToString([]byte(u.Login))
|
||||
return code
|
||||
}
|
||||
|
||||
// // verify active code when active account
|
||||
// func VerifyUserActiveCode(code string) (user *User) {
|
||||
// minutes := setting.Service.ActiveCodeLives
|
||||
//
|
||||
// if user = getVerifyUser(code); user != nil {
|
||||
// // time limit code
|
||||
// prefix := code[:base.TimeLimitCodeLength]
|
||||
// data := com.ToStr(user.Id) + user.Email + user.LowerName + user.Passwd + user.Rands
|
||||
//
|
||||
// if base.VerifyTimeLimitCode(data, minutes, prefix) {
|
||||
// return user
|
||||
// }
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
//
|
||||
// // verify active code when active account
|
||||
// func VerifyUserActiveCode(code string) (user *User) {
|
||||
// minutes := setting.Service.ActiveCodeLives
|
||||
//
|
||||
// if user = getVerifyUser(code); user != nil {
|
||||
// // time limit code
|
||||
// prefix := code[:base.TimeLimitCodeLength]
|
||||
// data := com.ToStr(user.Id) + user.Email + user.LowerName + user.Passwd + user.Rands
|
||||
//
|
||||
// if base.VerifyTimeLimitCode(data, minutes, prefix) {
|
||||
// return user
|
||||
// }
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
|
||||
@@ -28,8 +28,8 @@ func TestNotifications(t *testing.T) {
|
||||
|
||||
Convey("When sending reset email password", func() {
|
||||
sendResetPasswordEmail(&m.SendResetPasswordEmailCommand{User: &m.User{Email: "asd@asd.com"}})
|
||||
So(sentMail.Body, ShouldContainSubstring, "h2")
|
||||
So(sentMail.Subject, ShouldEqual, "Welcome to Grafana")
|
||||
So(sentMail.Body, ShouldContainSubstring, "body")
|
||||
So(sentMail.Subject, ShouldEqual, "Reset your Grafana password")
|
||||
So(sentMail.Body, ShouldNotContainSubstring, "Subject")
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user