diff options
author | Carlos Tadeu Panato Junior <ctadeu@gmail.com> | 2018-05-28 16:20:08 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-28 16:20:08 +0200 |
commit | c3e9c414408a8c9c2806af12e659e395c605496f (patch) | |
tree | 26510a3576d891c01e1bd4a7595f24f50332ee21 | |
parent | b6d5cc4f696b7438317948710efb860e11c0a1a9 (diff) | |
download | chat-c3e9c414408a8c9c2806af12e659e395c605496f.tar.gz chat-c3e9c414408a8c9c2806af12e659e395c605496f.tar.bz2 chat-c3e9c414408a8c9c2806af12e659e395c605496f.zip |
[MM-1915] Add Deactivate Account - server side (#8699)
-rw-r--r-- | api4/user.go | 13 | ||||
-rw-r--r-- | api4/user_test.go | 15 | ||||
-rw-r--r-- | app/email.go | 22 | ||||
-rw-r--r-- | config/default.json | 1 | ||||
-rw-r--r-- | i18n/en.json | 20 | ||||
-rw-r--r-- | model/config.go | 5 | ||||
-rw-r--r-- | templates/deactivate_body.html | 41 | ||||
-rw-r--r-- | utils/config.go | 2 |
8 files changed, 118 insertions, 1 deletions
diff --git a/api4/user.go b/api4/user.go index 2a539a551..ea90d2127 100644 --- a/api4/user.go +++ b/api4/user.go @@ -713,6 +713,12 @@ func updateUserActive(c *Context, w http.ResponseWriter, r *http.Request) { return } + // if EnableUserDeactivation flag is disabled the user cannot deactivate himself. + if isSelfDeactive && !*c.App.GetConfig().TeamSettings.EnableUserDeactivation { + c.Err = model.NewAppError("updateUserActive", "api.user.update_active.not_enable.app_error", nil, "userId="+c.Params.UserId, http.StatusUnauthorized) + return + } + var user *model.User var err *model.AppError @@ -725,6 +731,13 @@ func updateUserActive(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err } else { c.LogAuditWithUserId(user.Id, fmt.Sprintf("active=%v", active)) + if isSelfDeactive { + c.App.Go(func() { + if err = c.App.SendDeactivateAccountEmail(user.Email, user.Locale, c.App.GetSiteURL()); err != nil { + mlog.Error(err.Error()) + } + }) + } ReturnStatusOK(w) } } diff --git a/api4/user_test.go b/api4/user_test.go index 4851f139e..593208c92 100644 --- a/api4/user_test.go +++ b/api4/user_test.go @@ -1198,6 +1198,12 @@ func TestUpdateUserActive(t *testing.T) { SystemAdminClient := th.SystemAdminClient user := th.BasicUser + EnableUserDeactivation := th.App.Config().TeamSettings.EnableUserDeactivation + defer func() { + th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.EnableUserDeactivation = EnableUserDeactivation }) + }() + + th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableUserDeactivation = true }) pass, resp := Client.UpdateUserActive(user.Id, false) CheckNoError(t, resp) @@ -1205,6 +1211,15 @@ func TestUpdateUserActive(t *testing.T) { t.Fatal("should have returned true") } + th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableUserDeactivation = false }) + pass, resp = Client.UpdateUserActive(user.Id, false) + CheckUnauthorizedStatus(t, resp) + + if pass { + t.Fatal("should have returned false") + } + + th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableUserDeactivation = true }) pass, resp = Client.UpdateUserActive(user.Id, false) CheckUnauthorizedStatus(t, resp) diff --git a/app/email.go b/app/email.go index aa05cefdb..206c48aaa 100644 --- a/app/email.go +++ b/app/email.go @@ -322,6 +322,28 @@ func (a *App) NewEmailTemplate(name, locale string) *utils.HTMLTemplate { return t } +func (a *App) SendDeactivateAccountEmail(email string, locale, siteURL string) *model.AppError { + T := utils.GetUserTranslations(locale) + + rawUrl, _ := url.Parse(siteURL) + + subject := T("api.templates.deactivate_subject", + map[string]interface{}{"SiteName": a.ClientConfig()["SiteName"], + "ServerURL": rawUrl.Host}) + + bodyPage := a.NewEmailTemplate("deactivate_body", locale) + bodyPage.Props["SiteURL"] = siteURL + bodyPage.Props["Title"] = T("api.templates.deactivate_body.title", map[string]interface{}{"ServerURL": rawUrl.Host}) + bodyPage.Html["Info"] = utils.TranslateAsHtml(T, "api.templates.deactivate_body.info", + map[string]interface{}{"SiteURL": siteURL}) + + if err := a.SendMail(email, subject, bodyPage.Render()); err != nil { + return model.NewAppError("SendDeactivateEmail", "api.user.send_deactivate_email_and_forget.failed.error", nil, err.Error(), http.StatusInternalServerError) + } + + return nil +} + func (a *App) SendMail(to, subject, htmlBody string) *model.AppError { license := a.License() return utils.SendMailUsingConfig(to, subject, htmlBody, a.Config(), license != nil && *license.Features.Compliance) diff --git a/config/default.json b/config/default.json index 2d6265dcc..3548339d0 100644 --- a/config/default.json +++ b/config/default.json @@ -71,6 +71,7 @@ "EnableTeamCreation": true, "EnableUserCreation": true, "EnableOpenServer": false, + "EnableUserDeactivation": false, "RestrictCreationToDomains": "", "EnableCustomBrand": false, "CustomBrandText": "", diff --git a/i18n/en.json b/i18n/en.json index 9b59e59f2..1f4d55476 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -2751,6 +2751,22 @@ "translation": "[{{ .SiteName }}] You joined {{ .ServerURL }}" }, { + "id": "api.templates.deactivate_subject", + "translation": "[{{ .SiteName }}] Your account at {{ .ServerURL }} has been deactivated" + }, + { + "id": "api.templates.deactivate_body.title", + "translation": "Your account has been deactivated at {{ .ServerURL }}" + }, + { + "id": "api.templates.deactivate_body.info", + "translation": "You deactivated your account on {{ .SiteURL }}.<br>If this change wasn't initiated by you or you want to reactivate your account, contact your system administrator." + }, + { + "id": "api.user.send_deactivate_email_and_forget.failed.error", + "translation": "Failed to send the deactivate account email successfully" + }, + { "id": "api.user.activate_mfa.email_and_ldap_only.app_error", "translation": "MFA is not available for this account type" }, @@ -3075,6 +3091,10 @@ "translation": "You do not have the appropriate permissions" }, { + "id": "api.user.update_active.not_enable.app_error", + "translation": "You cannot deactivate yourself because this feature is not enabled. Please contact your System Administrator." + }, + { "id": "api.user.update_mfa.not_available.app_error", "translation": "MFA not configured or available on this server" }, diff --git a/model/config.go b/model/config.go index deaae6db8..ba3a02d33 100644 --- a/model/config.go +++ b/model/config.go @@ -1002,6 +1002,7 @@ type TeamSettings struct { EnableTeamCreation *bool EnableUserCreation *bool EnableOpenServer *bool + EnableUserDeactivation *bool RestrictCreationToDomains string EnableCustomBrand *bool CustomBrandText *string @@ -1036,6 +1037,10 @@ func (s *TeamSettings) SetDefaults() { s.EnableCustomBrand = NewBool(false) } + if s.EnableUserDeactivation == nil { + s.EnableUserDeactivation = NewBool(false) + } + if s.CustomBrandText == nil { s.CustomBrandText = NewString(TEAM_SETTINGS_DEFAULT_CUSTOM_BRAND_TEXT) } diff --git a/templates/deactivate_body.html b/templates/deactivate_body.html new file mode 100644 index 000000000..45a2f42af --- /dev/null +++ b/templates/deactivate_body.html @@ -0,0 +1,41 @@ +{{define "deactivate_body"}} + +<table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="margin-top: 20px; line-height: 1.7; color: #555;"> + <tr> + <td> + <table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 660px; font-family: Helvetica, Arial, sans-serif; font-size: 14px; background: #FFF;"> + <tr> + <td style="border: 1px solid #ddd;"> + <table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;"> + <tr> + <td style="padding: 20px 20px 10px; text-align:left;"> + <img src="{{.Props.SiteURL}}/static/images/logo-email.png" width="130px" style="opacity: 0.5" alt=""> + </td> + </tr> + <tr> + <td> + <table border="0" cellpadding="0" cellspacing="0" style="padding: 20px 50px 0; text-align: center; margin: 0 auto"> + <tr> + <td style="border-bottom: 1px solid #ddd; padding: 0 0 20px;"> + <h2 style="font-weight: normal; margin-top: 10px;">{{.Props.Title}}</h2> + <p>{{.Html.Info}}</p> + </td> + </tr> + <tr> + {{template "email_info" . }} + </tr> + </table> + </td> + </tr> + <tr> + {{template "email_footer" . }} + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> +</table> + +{{end}} diff --git a/utils/config.go b/utils/config.go index c51ace554..d3fd733b7 100644 --- a/utils/config.go +++ b/utils/config.go @@ -448,7 +448,7 @@ func GenerateClientConfig(c *model.Config, diagnosticId string, license *model.L props["WebsocketURL"] = strings.TrimRight(*c.ServiceSettings.WebsocketURL, "/") props["SiteName"] = c.TeamSettings.SiteName props["EnableTeamCreation"] = strconv.FormatBool(*c.TeamSettings.EnableTeamCreation) - props["EnableUserCreation"] = strconv.FormatBool(*c.TeamSettings.EnableUserCreation) + props["EnableUserDeactivation"] = strconv.FormatBool(*c.TeamSettings.EnableUserDeactivation) props["EnableOpenServer"] = strconv.FormatBool(*c.TeamSettings.EnableOpenServer) props["RestrictDirectMessage"] = *c.TeamSettings.RestrictDirectMessage props["RestrictTeamInvite"] = *c.TeamSettings.RestrictTeamInvite |