From 6088f83408cb4b77f5cfd6a8c2b101931b0a1de1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 18 Jul 2015 17:39:12 +0200 Subject: [PATCH] feat(invite): inital pass on sending new user invite email, #2353 --- pkg/api/api.go | 1 - pkg/api/dtos/invite.go | 7 +- pkg/api/org_invite.go | 23 + pkg/util/strings.go | 8 + public/emails/new_user_invite.html | 867 +++++++++++++++++++++++++++++ 5 files changed, 902 insertions(+), 4 deletions(-) create mode 100644 pkg/util/strings.go create mode 100644 public/emails/new_user_invite.html diff --git a/pkg/api/api.go b/pkg/api/api.go index e1cb22dcae3..b41100e80ed 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -39,7 +39,6 @@ func Register(r *macaron.Macaron) { r.Get("/dashboard/*", reqSignedIn, Index) // sign up - r.Get("/signup", Index) r.Post("/api/user/signup", bind(m.CreateUserCommand{}), wrap(SignUp)) // reset password diff --git a/pkg/api/dtos/invite.go b/pkg/api/dtos/invite.go index d2d4129fa5b..8a857e7fc8d 100644 --- a/pkg/api/dtos/invite.go +++ b/pkg/api/dtos/invite.go @@ -3,7 +3,8 @@ package dtos import m "github.com/grafana/grafana/pkg/models" type AddInviteForm struct { - Email string `json:"email" binding:"Required"` - Name string `json:"name"` - Role m.RoleType `json:"role" binding:"Required"` + Email string `json:"email" binding:"Required"` + Name string `json:"name"` + Role m.RoleType `json:"role" binding:"Required"` + SkipEmails bool `json:"skipEmails"` } diff --git a/pkg/api/org_invite.go b/pkg/api/org_invite.go index 96264382943..20f2221b4d5 100644 --- a/pkg/api/org_invite.go +++ b/pkg/api/org_invite.go @@ -5,6 +5,7 @@ import ( "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/middleware" m "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util" ) @@ -22,6 +23,9 @@ func AddOrgInvite(c *middleware.Context, inviteDto dtos.AddInviteForm) Response if !inviteDto.Role.IsValid() { return ApiError(400, "Invalid role specified", nil) } + if !util.IsEmail(inviteDto.Email) { + return ApiError(400, "Invalid email specified", nil) + } // first try get existing user userQuery := m.GetUserByLoginQuery{LoginOrEmail: inviteDto.Email} @@ -52,5 +56,24 @@ func AddOrgInvite(c *middleware.Context, inviteDto dtos.AddInviteForm) Response return ApiError(500, "Failed to save invite to database", err) } + // send invite email + if !inviteDto.SkipEmails { + emailCmd := m.SendEmailCommand{ + To: []string{inviteDto.Email}, + Template: "new_user_invite.html", + Data: map[string]interface{}{ + "NameOrEmail": util.StringsFallback2(cmd.Name, cmd.Email), + "OrgName": c.OrgName, + "Email": c.Email, + "LinkUrl": setting.ToAbsUrl("signup/invited/" + cmd.Code), + "InvitedBy": util.StringsFallback2(c.Name, c.Email), + }, + } + + if err := bus.Dispatch(&emailCmd); err != nil { + return ApiError(500, "Failed to send email invite", err) + } + } + return ApiSuccess("ok, done!") } diff --git a/pkg/util/strings.go b/pkg/util/strings.go new file mode 100644 index 00000000000..277e5e036c8 --- /dev/null +++ b/pkg/util/strings.go @@ -0,0 +1,8 @@ +package util + +func StringsFallback2(val1 string, val2 string) string { + if val1 != "" { + return val1 + } + return val2 +} diff --git a/public/emails/new_user_invite.html b/public/emails/new_user_invite.html new file mode 100644 index 00000000000..68a4a99b31a --- /dev/null +++ b/public/emails/new_user_invite.html @@ -0,0 +1,867 @@ +{{Subject .Subject "{{.InvitedBy}} has invited you to join Grafana"}} + + + + + + + + + + + + + + +
+
+ + + + + +
+
+ + + + + +
+ + + + + + +
+ +
+ +
+ +
+
+ + + + + +
+ + + + + +
+ + + + + + +
+

You're invited to sign up to Grafana and join {{.OrgName}}

+
+ +
+ + + + + +
+ + + + + +
+ + + + +
+ Complete Sign Up +
+
+ +
+ + +
+ +
+
+ +