mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Send registration email on user autoregistration (#16523)
When users login and are autoregistered send email notification. Fix #16178 * Protect public functions within the mailer by testing if the mailer is configured Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: 6543 <6543@obermui.de>
This commit is contained in:
		@@ -13,6 +13,7 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/web/middleware"
 | 
						"code.gitea.io/gitea/modules/web/middleware"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/services/mailer"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gouuid "github.com/google/uuid"
 | 
						gouuid "github.com/google/uuid"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -112,5 +113,7 @@ func (r *ReverseProxy) newUser(req *http.Request) *models.User {
 | 
				
			|||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mailer.SendRegisterNotifyMail(user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return user
 | 
						return user
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,7 @@ import (
 | 
				
			|||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models"
 | 
						"code.gitea.io/gitea/models"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/services/mailer"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Authenticate queries if login/password is valid against the LDAP directory pool,
 | 
					// Authenticate queries if login/password is valid against the LDAP directory pool,
 | 
				
			||||||
@@ -84,8 +85,13 @@ func (source *Source) Authenticate(user *models.User, login, password string) (*
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err := models.CreateUser(user)
 | 
						err := models.CreateUser(user)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return user, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err == nil && isAttributeSSHPublicKeySet && models.AddPublicKeysBySource(user, source.loginSource, sr.SSHPublicKey) {
 | 
						mailer.SendRegisterNotifyMail(user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if isAttributeSSHPublicKeySet && models.AddPublicKeysBySource(user, source.loginSource, sr.SSHPublicKey) {
 | 
				
			||||||
		err = models.RewriteAllPublicKeys()
 | 
							err = models.RewriteAllPublicKeys()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,7 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/models"
 | 
						"code.gitea.io/gitea/models"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/auth/pam"
 | 
						"code.gitea.io/gitea/modules/auth/pam"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/services/mailer"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/google/uuid"
 | 
						"github.com/google/uuid"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -58,5 +59,12 @@ func (source *Source) Authenticate(user *models.User, login, password string) (*
 | 
				
			|||||||
		LoginName:   login, // This is what the user typed in
 | 
							LoginName:   login, // This is what the user typed in
 | 
				
			||||||
		IsActive:    true,
 | 
							IsActive:    true,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return user, models.CreateUser(user)
 | 
					
 | 
				
			||||||
 | 
						if err := models.CreateUser(user); err != nil {
 | 
				
			||||||
 | 
							return user, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mailer.SendRegisterNotifyMail(user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return user, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models"
 | 
						"code.gitea.io/gitea/models"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/services/mailer"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Authenticate queries if the provided login/password is authenticates against the SMTP server
 | 
					// Authenticate queries if the provided login/password is authenticates against the SMTP server
 | 
				
			||||||
@@ -74,5 +75,12 @@ func (source *Source) Authenticate(user *models.User, login, password string) (*
 | 
				
			|||||||
		LoginName:   login,
 | 
							LoginName:   login,
 | 
				
			||||||
		IsActive:    true,
 | 
							IsActive:    true,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return user, models.CreateUser(user)
 | 
					
 | 
				
			||||||
 | 
						if err := models.CreateUser(user); err != nil {
 | 
				
			||||||
 | 
							return user, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mailer.SendRegisterNotifyMail(user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return user, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,7 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/templates"
 | 
						"code.gitea.io/gitea/modules/templates"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/web/middleware"
 | 
						"code.gitea.io/gitea/modules/web/middleware"
 | 
				
			||||||
	"code.gitea.io/gitea/services/auth/source/sspi"
 | 
						"code.gitea.io/gitea/services/auth/source/sspi"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/services/mailer"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gouuid "github.com/google/uuid"
 | 
						gouuid "github.com/google/uuid"
 | 
				
			||||||
	"github.com/quasoft/websspi"
 | 
						"github.com/quasoft/websspi"
 | 
				
			||||||
@@ -197,6 +198,9 @@ func (s *SSPI) newUser(username string, cfg *sspi.Source) (*models.User, error)
 | 
				
			|||||||
	if err := models.CreateUser(user); err != nil {
 | 
						if err := models.CreateUser(user); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mailer.SendRegisterNotifyMail(user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return user, nil
 | 
						return user, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,6 +57,10 @@ func InitMailRender(subjectTpl *texttmpl.Template, bodyTpl *template.Template) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// SendTestMail sends a test mail
 | 
					// SendTestMail sends a test mail
 | 
				
			||||||
func SendTestMail(email string) error {
 | 
					func SendTestMail(email string) error {
 | 
				
			||||||
 | 
						if setting.MailService == nil {
 | 
				
			||||||
 | 
							// No mail service configured
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return gomail.Send(Sender, NewMessage([]string{email}, "Gitea Test Email!", "Gitea Test Email!").ToMessage())
 | 
						return gomail.Send(Sender, NewMessage([]string{email}, "Gitea Test Email!", "Gitea Test Email!").ToMessage())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -90,17 +94,29 @@ func sendUserMail(language string, u *models.User, tpl base.TplName, code, subje
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// SendActivateAccountMail sends an activation mail to the user (new user registration)
 | 
					// SendActivateAccountMail sends an activation mail to the user (new user registration)
 | 
				
			||||||
func SendActivateAccountMail(locale translation.Locale, u *models.User) {
 | 
					func SendActivateAccountMail(locale translation.Locale, u *models.User) {
 | 
				
			||||||
 | 
						if setting.MailService == nil {
 | 
				
			||||||
 | 
							// No mail service configured
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	sendUserMail(locale.Language(), u, mailAuthActivate, u.GenerateEmailActivateCode(u.Email), locale.Tr("mail.activate_account"), "activate account")
 | 
						sendUserMail(locale.Language(), u, mailAuthActivate, u.GenerateEmailActivateCode(u.Email), locale.Tr("mail.activate_account"), "activate account")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SendResetPasswordMail sends a password reset mail to the user
 | 
					// SendResetPasswordMail sends a password reset mail to the user
 | 
				
			||||||
func SendResetPasswordMail(u *models.User) {
 | 
					func SendResetPasswordMail(u *models.User) {
 | 
				
			||||||
 | 
						if setting.MailService == nil {
 | 
				
			||||||
 | 
							// No mail service configured
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	locale := translation.NewLocale(u.Language)
 | 
						locale := translation.NewLocale(u.Language)
 | 
				
			||||||
	sendUserMail(u.Language, u, mailAuthResetPassword, u.GenerateEmailActivateCode(u.Email), locale.Tr("mail.reset_password"), "recover account")
 | 
						sendUserMail(u.Language, u, mailAuthResetPassword, u.GenerateEmailActivateCode(u.Email), locale.Tr("mail.reset_password"), "recover account")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SendActivateEmailMail sends confirmation email to confirm new email address
 | 
					// SendActivateEmailMail sends confirmation email to confirm new email address
 | 
				
			||||||
func SendActivateEmailMail(u *models.User, email *models.EmailAddress) {
 | 
					func SendActivateEmailMail(u *models.User, email *models.EmailAddress) {
 | 
				
			||||||
 | 
						if setting.MailService == nil {
 | 
				
			||||||
 | 
							// No mail service configured
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	locale := translation.NewLocale(u.Language)
 | 
						locale := translation.NewLocale(u.Language)
 | 
				
			||||||
	data := map[string]interface{}{
 | 
						data := map[string]interface{}{
 | 
				
			||||||
		"DisplayName":     u.DisplayName(),
 | 
							"DisplayName":     u.DisplayName(),
 | 
				
			||||||
@@ -129,6 +145,10 @@ func SendActivateEmailMail(u *models.User, email *models.EmailAddress) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// SendRegisterNotifyMail triggers a notify e-mail by admin created a account.
 | 
					// SendRegisterNotifyMail triggers a notify e-mail by admin created a account.
 | 
				
			||||||
func SendRegisterNotifyMail(u *models.User) {
 | 
					func SendRegisterNotifyMail(u *models.User) {
 | 
				
			||||||
 | 
						if setting.MailService == nil {
 | 
				
			||||||
 | 
							// No mail service configured
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	locale := translation.NewLocale(u.Language)
 | 
						locale := translation.NewLocale(u.Language)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data := map[string]interface{}{
 | 
						data := map[string]interface{}{
 | 
				
			||||||
@@ -156,6 +176,10 @@ func SendRegisterNotifyMail(u *models.User) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// SendCollaboratorMail sends mail notification to new collaborator.
 | 
					// SendCollaboratorMail sends mail notification to new collaborator.
 | 
				
			||||||
func SendCollaboratorMail(u, doer *models.User, repo *models.Repository) {
 | 
					func SendCollaboratorMail(u, doer *models.User, repo *models.Repository) {
 | 
				
			||||||
 | 
						if setting.MailService == nil {
 | 
				
			||||||
 | 
							// No mail service configured
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	locale := translation.NewLocale(u.Language)
 | 
						locale := translation.NewLocale(u.Language)
 | 
				
			||||||
	repoName := repo.FullName()
 | 
						repoName := repo.FullName()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -344,6 +368,10 @@ func sanitizeSubject(subject string) string {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// SendIssueAssignedMail composes and sends issue assigned email
 | 
					// SendIssueAssignedMail composes and sends issue assigned email
 | 
				
			||||||
func SendIssueAssignedMail(issue *models.Issue, doer *models.User, content string, comment *models.Comment, recipients []*models.User) error {
 | 
					func SendIssueAssignedMail(issue *models.Issue, doer *models.User, content string, comment *models.Comment, recipients []*models.User) error {
 | 
				
			||||||
 | 
						if setting.MailService == nil {
 | 
				
			||||||
 | 
							// No mail service configured
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	langMap := make(map[string][]*models.User)
 | 
						langMap := make(map[string][]*models.User)
 | 
				
			||||||
	for _, user := range recipients {
 | 
						for _, user := range recipients {
 | 
				
			||||||
		langMap[user.Language] = append(langMap[user.Language], user)
 | 
							langMap[user.Language] = append(langMap[user.Language], user)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,10 +7,16 @@ package mailer
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"code.gitea.io/gitea/models"
 | 
						"code.gitea.io/gitea/models"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MailParticipantsComment sends new comment emails to repository watchers and mentioned people.
 | 
					// MailParticipantsComment sends new comment emails to repository watchers and mentioned people.
 | 
				
			||||||
func MailParticipantsComment(c *models.Comment, opType models.ActionType, issue *models.Issue, mentions []*models.User) error {
 | 
					func MailParticipantsComment(c *models.Comment, opType models.ActionType, issue *models.Issue, mentions []*models.User) error {
 | 
				
			||||||
 | 
						if setting.MailService == nil {
 | 
				
			||||||
 | 
							// No mail service configured
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	content := c.Content
 | 
						content := c.Content
 | 
				
			||||||
	if c.Type == models.CommentTypePullPush {
 | 
						if c.Type == models.CommentTypePullPush {
 | 
				
			||||||
		content = ""
 | 
							content = ""
 | 
				
			||||||
@@ -30,6 +36,11 @@ func MailParticipantsComment(c *models.Comment, opType models.ActionType, issue
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// MailMentionsComment sends email to users mentioned in a code comment
 | 
					// MailMentionsComment sends email to users mentioned in a code comment
 | 
				
			||||||
func MailMentionsComment(pr *models.PullRequest, c *models.Comment, mentions []*models.User) (err error) {
 | 
					func MailMentionsComment(pr *models.PullRequest, c *models.Comment, mentions []*models.User) (err error) {
 | 
				
			||||||
 | 
						if setting.MailService == nil {
 | 
				
			||||||
 | 
							// No mail service configured
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	visited := make(map[int64]bool, len(mentions)+1)
 | 
						visited := make(map[int64]bool, len(mentions)+1)
 | 
				
			||||||
	visited[c.Poster.ID] = true
 | 
						visited[c.Poster.ID] = true
 | 
				
			||||||
	if err = mailIssueCommentBatch(
 | 
						if err = mailIssueCommentBatch(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models"
 | 
						"code.gitea.io/gitea/models"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func fallbackMailSubject(issue *models.Issue) string {
 | 
					func fallbackMailSubject(issue *models.Issue) string {
 | 
				
			||||||
@@ -163,6 +164,11 @@ func mailIssueCommentBatch(ctx *mailCommentContext, users []*models.User, visite
 | 
				
			|||||||
// MailParticipants sends new issue thread created emails to repository watchers
 | 
					// MailParticipants sends new issue thread created emails to repository watchers
 | 
				
			||||||
// and mentioned people.
 | 
					// and mentioned people.
 | 
				
			||||||
func MailParticipants(issue *models.Issue, doer *models.User, opType models.ActionType, mentions []*models.User) error {
 | 
					func MailParticipants(issue *models.Issue, doer *models.User, opType models.ActionType, mentions []*models.User) error {
 | 
				
			||||||
 | 
						if setting.MailService == nil {
 | 
				
			||||||
 | 
							// No mail service configured
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	content := issue.Content
 | 
						content := issue.Content
 | 
				
			||||||
	if opType == models.ActionCloseIssue || opType == models.ActionClosePullRequest ||
 | 
						if opType == models.ActionCloseIssue || opType == models.ActionClosePullRequest ||
 | 
				
			||||||
		opType == models.ActionReopenIssue || opType == models.ActionReopenPullRequest ||
 | 
							opType == models.ActionReopenIssue || opType == models.ActionReopenPullRequest ||
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,6 +23,11 @@ const (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// MailNewRelease send new release notify to all all repo watchers.
 | 
					// MailNewRelease send new release notify to all all repo watchers.
 | 
				
			||||||
func MailNewRelease(rel *models.Release) {
 | 
					func MailNewRelease(rel *models.Release) {
 | 
				
			||||||
 | 
						if setting.MailService == nil {
 | 
				
			||||||
 | 
							// No mail service configured
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	watcherIDList, err := models.GetRepoWatchersIDs(rel.RepoID)
 | 
						watcherIDList, err := models.GetRepoWatchersIDs(rel.RepoID)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Error("GetRepoWatchersIDs(%d): %v", rel.RepoID, err)
 | 
							log.Error("GetRepoWatchersIDs(%d): %v", rel.RepoID, err)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,12 +9,18 @@ import (
 | 
				
			|||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models"
 | 
						"code.gitea.io/gitea/models"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/templates"
 | 
						"code.gitea.io/gitea/modules/templates"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/translation"
 | 
						"code.gitea.io/gitea/modules/translation"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SendRepoTransferNotifyMail triggers a notification e-mail when a pending repository transfer was created
 | 
					// SendRepoTransferNotifyMail triggers a notification e-mail when a pending repository transfer was created
 | 
				
			||||||
func SendRepoTransferNotifyMail(doer, newOwner *models.User, repo *models.Repository) error {
 | 
					func SendRepoTransferNotifyMail(doer, newOwner *models.User, repo *models.Repository) error {
 | 
				
			||||||
 | 
						if setting.MailService == nil {
 | 
				
			||||||
 | 
							// No mail service configured
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if newOwner.IsOrganization() {
 | 
						if newOwner.IsOrganization() {
 | 
				
			||||||
		users, err := models.GetUsersWhoCanCreateOrgRepo(newOwner.ID)
 | 
							users, err := models.GetUsersWhoCanCreateOrgRepo(newOwner.ID)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user