MM-39058 - invite people to join team and channels (#19849)
* MM-39058-invite-to-team-from-add-channel * fix tests by validating the memberInvite is not nil * fix i18n texts * fix lint problem * fix translation lines * fix the data structure * modify api4-team_local file to match with the expected structure * fix unit tests, fix translation tests * remove go routine cause not necesary * add unit test for invite to team and channel * remove unnecessary validation * allow both data structures, simple string array and object with memberInvite struct * fix texts * fix linter * fix problems with graceful invites workflow * handle error while parsing body * fix unit tests * take the address just once * rename channels to channelIds * fix unit tests * add tests and fix local channels invite support Co-authored-by: Pablo Velez Vidal <pablo.velez@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
0e4b0b6939
Коммит
4b354685e9
58
app/team.go
58
app/team.go
@@ -1207,7 +1207,7 @@ func (a *App) postRemoveFromTeamMessage(c *request.Context, user *model.User, ch
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) prepareInviteNewUsersToTeam(teamID, senderId string) (*model.User, *model.Team, *model.AppError) {
|
||||
func (a *App) prepareInviteNewUsersToTeam(teamID, senderId string, channelIds []string) (*model.User, *model.Team, []*model.Channel, *model.AppError) {
|
||||
tchan := make(chan store.StoreResult, 1)
|
||||
go func() {
|
||||
team, err := a.Srv().Store.Team().Get(teamID)
|
||||
@@ -1222,14 +1222,22 @@ func (a *App) prepareInviteNewUsersToTeam(teamID, senderId string) (*model.User,
|
||||
close(uchan)
|
||||
}()
|
||||
|
||||
var channels []*model.Channel
|
||||
var err error
|
||||
if len(channelIds) > 0 {
|
||||
channels, err = a.Srv().Store.Channel().GetChannelsByIds(channelIds, false)
|
||||
if err != nil {
|
||||
return nil, nil, nil, model.NewAppError("prepareInviteNewUsersToTeam", "app.channel.get_channels_by_ids.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
result := <-tchan
|
||||
if result.NErr != nil {
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
case errors.As(result.NErr, &nfErr):
|
||||
return nil, nil, model.NewAppError("prepareInviteNewUsersToTeam", "app.team.get_by_invite_id.finding.app_error", nil, nfErr.Error(), http.StatusNotFound)
|
||||
return nil, nil, nil, model.NewAppError("prepareInviteNewUsersToTeam", "app.team.get_by_invite_id.finding.app_error", nil, nfErr.Error(), http.StatusNotFound)
|
||||
default:
|
||||
return nil, nil, model.NewAppError("prepareInviteNewUsersToTeam", "app.team.get_by_invite_id.finding.app_error", nil, result.NErr.Error(), http.StatusInternalServerError)
|
||||
return nil, nil, nil, model.NewAppError("prepareInviteNewUsersToTeam", "app.team.get_by_invite_id.finding.app_error", nil, result.NErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
team := result.Data.(*model.Team)
|
||||
@@ -1239,25 +1247,34 @@ func (a *App) prepareInviteNewUsersToTeam(teamID, senderId string) (*model.User,
|
||||
var nfErr *store.ErrNotFound
|
||||
switch {
|
||||
case errors.As(result.NErr, &nfErr):
|
||||
return nil, nil, model.NewAppError("prepareInviteNewUsersToTeam", MissingAccountError, nil, nfErr.Error(), http.StatusNotFound)
|
||||
return nil, nil, nil, model.NewAppError("prepareInviteNewUsersToTeam", MissingAccountError, nil, nfErr.Error(), http.StatusNotFound)
|
||||
default:
|
||||
return nil, nil, model.NewAppError("prepareInviteNewUsersToTeam", "app.user.get.app_error", nil, result.NErr.Error(), http.StatusInternalServerError)
|
||||
return nil, nil, nil, model.NewAppError("prepareInviteNewUsersToTeam", "app.user.get.app_error", nil, result.NErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
user := result.Data.(*model.User)
|
||||
return user, team, nil
|
||||
|
||||
for _, channel := range channels {
|
||||
if channel.TeamId != teamID {
|
||||
return nil, nil, nil, model.NewAppError("prepareInviteGuestsToChannels", "api.team.invite_guests.channel_in_invalid_team.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
|
||||
return user, team, channels, nil
|
||||
}
|
||||
|
||||
func (a *App) InviteNewUsersToTeamGracefully(emailList []string, teamID, senderId string, reminderInterval string) ([]*model.EmailInviteWithError, *model.AppError) {
|
||||
func (a *App) InviteNewUsersToTeamGracefully(memberInvite *model.MemberInvite, teamID, senderId string, reminderInterval string) ([]*model.EmailInviteWithError, *model.AppError) {
|
||||
if !*a.Config().ServiceSettings.EnableEmailInvitations {
|
||||
return nil, model.NewAppError("InviteNewUsersToTeam", "api.team.invite_members.disabled.app_error", nil, "", http.StatusNotImplemented)
|
||||
}
|
||||
|
||||
emailList := memberInvite.Emails
|
||||
|
||||
if len(emailList) == 0 {
|
||||
err := model.NewAppError("InviteNewUsersToTeam", "api.team.invite_members.no_one.app_error", nil, "", http.StatusBadRequest)
|
||||
return nil, err
|
||||
}
|
||||
user, team, err := a.prepareInviteNewUsersToTeam(teamID, senderId)
|
||||
user, team, channels, err := a.prepareInviteNewUsersToTeam(teamID, senderId, memberInvite.ChannelIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1284,25 +1301,36 @@ func (a *App) InviteNewUsersToTeamGracefully(emailList []string, teamID, senderI
|
||||
|
||||
if len(goodEmails) > 0 {
|
||||
nameFormat := *a.Config().TeamSettings.TeammateNameDisplay
|
||||
eErr := a.Srv().EmailService.SendInviteEmails(team, user.GetDisplayName(nameFormat), user.Id, goodEmails, a.GetSiteURL(), reminderData, true)
|
||||
senderProfileImage, _, err := a.GetProfileImage(user)
|
||||
if err != nil {
|
||||
a.Log().Warn("Unable to get the sender user profile image.", mlog.String("user_id", user.Id), mlog.String("team_id", team.Id), mlog.Err(err))
|
||||
}
|
||||
var eErr error
|
||||
var invitesWithErrors2 []*model.EmailInviteWithError
|
||||
if len(channels) > 0 {
|
||||
invitesWithErrors2, eErr = a.Srv().EmailService.SendInviteEmailsToTeamAndChannels(team, channels, user.GetDisplayName(nameFormat), user.Id, senderProfileImage, goodEmails, a.GetSiteURL(), reminderData, memberInvite.Message, true)
|
||||
inviteListWithErrors = append(inviteListWithErrors, invitesWithErrors2...)
|
||||
} else {
|
||||
eErr = a.Srv().EmailService.SendInviteEmails(team, user.GetDisplayName(nameFormat), user.Id, goodEmails, a.GetSiteURL(), reminderData, true)
|
||||
}
|
||||
if eErr != nil {
|
||||
switch {
|
||||
case errors.Is(eErr, email.SendMailError):
|
||||
for i := range inviteListWithErrors {
|
||||
if inviteListWithErrors[i].Error == nil {
|
||||
if *a.Config().EmailSettings.SMTPServer == model.EmailSMTPDefaultServer && *a.Config().EmailSettings.SMTPPort == model.EmailSMTPDefaultPort {
|
||||
inviteListWithErrors[i].Error = model.NewAppError("InviteGuestsToChannelsGracefully", "api.team.invite_members.unable_to_send_email_with_defaults.app_error", nil, "", http.StatusInternalServerError)
|
||||
inviteListWithErrors[i].Error = model.NewAppError("InviteNewUsersToTeamGracefully", "api.team.invite_members.unable_to_send_email_with_defaults.app_error", nil, "", http.StatusInternalServerError)
|
||||
} else {
|
||||
inviteListWithErrors[i].Error = model.NewAppError("SendInviteEmails", "api.team.invite_members.unable_to_send_email.app_error", nil, "", http.StatusInternalServerError)
|
||||
inviteListWithErrors[i].Error = model.NewAppError("InviteNewUsersToTeamGracefully", "api.team.invite_members.unable_to_send_email.app_error", nil, "", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
}
|
||||
case errors.Is(eErr, email.NoRateLimiterError):
|
||||
return nil, model.NewAppError("SendInviteEmails", "app.email.no_rate_limiter.app_error", nil, fmt.Sprintf("user_id=%s, team_id=%s", user.Id, team.Id), http.StatusInternalServerError)
|
||||
return nil, model.NewAppError("InviteNewUsersToTeamGracefully", "app.email.no_rate_limiter.app_error", nil, fmt.Sprintf("user_id=%s, team_id=%s", user.Id, team.Id), http.StatusInternalServerError)
|
||||
case errors.Is(eErr, email.SetupRateLimiterError):
|
||||
return nil, model.NewAppError("SendInviteEmails", "app.email.setup_rate_limiter.app_error", nil, fmt.Sprintf("user_id=%s, team_id=%s, error=%v", user.Id, team.Id, eErr), http.StatusInternalServerError)
|
||||
return nil, model.NewAppError("InviteNewUsersToTeamGracefully", "app.email.setup_rate_limiter.app_error", nil, fmt.Sprintf("user_id=%s, team_id=%s, error=%v", user.Id, team.Id, eErr), http.StatusInternalServerError)
|
||||
default:
|
||||
return nil, model.NewAppError("SendInviteEmails", "app.email.rate_limit_exceeded.app_error", nil, fmt.Sprintf("user_id=%s, team_id=%s, error=%v", user.Id, team.Id, eErr), http.StatusRequestEntityTooLarge)
|
||||
return nil, model.NewAppError("InviteNewUsersToTeamGracefully", "app.email.rate_limit_exceeded.app_error", nil, fmt.Sprintf("user_id=%s, team_id=%s, error=%v", user.Id, team.Id, eErr), http.StatusRequestEntityTooLarge)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1440,7 +1468,7 @@ func (a *App) InviteNewUsersToTeam(emailList []string, teamID, senderId string)
|
||||
return err
|
||||
}
|
||||
|
||||
user, team, err := a.prepareInviteNewUsersToTeam(teamID, senderId)
|
||||
user, team, _, err := a.prepareInviteNewUsersToTeam(teamID, senderId, []string{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user