MCPcopy Index your code
hub / github.com/bytebase/bytebase / sendInviteEmails

Method sendInviteEmails

backend/api/v1/workspace_service.go:471–568  ·  view source on GitHub ↗

sendInviteEmails sends invite emails to newly added members. Errors are logged, never returned.

(ctx context.Context, workspaceID string, oldPolicy *storepb.IamPolicy, deltas []*v1pb.BindingDelta)

Source from the content-addressed store, hash-verified

469
470// sendInviteEmails sends invite emails to newly added members. Errors are logged, never returned.
471func (s *WorkspaceService) sendInviteEmails(ctx context.Context, workspaceID string, oldPolicy *storepb.IamPolicy, deltas []*v1pb.BindingDelta) {
472 emailSetting, err := resolvePreLoginEmailSetting(ctx, s.store, workspaceID)
473 if err != nil || emailSetting == nil {
474 return
475 }
476
477 sender, err := mailer.NewSender(emailSetting)
478 if err != nil {
479 slog.Warn("failed to create mail sender for invite emails", log.BBError(err))
480 return
481 }
482
483 // Get workspace URL and title.
484 externalURL, err := utils.GetEffectiveExternalURL(ctx, s.store, s.profile, workspaceID)
485 if err != nil {
486 slog.Warn("failed to get external URL for invite emails", log.BBError(err))
487 return
488 }
489 if externalURL == "" {
490 slog.Warn("empty external URL, skip send invite emails")
491 return
492 }
493 workspaceTitle := workspaceID
494 if ws, err := s.store.GetWorkspaceByID(ctx, workspaceID); err == nil && ws != nil && ws.Payload.GetTitle() != "" {
495 workspaceTitle = ws.Payload.GetTitle()
496 }
497
498 // Build set of members who already existed in the old policy (any role).
499 existingMembers := make(map[string]bool)
500 for _, binding := range oldPolicy.GetBindings() {
501 for _, member := range binding.Members {
502 if email, ok := strings.CutPrefix(member, common.UserNamePrefix); ok {
503 existingMembers[email] = true
504 } else if groupName, ok := strings.CutPrefix(member, common.GroupPrefix); ok {
505 // Expand group to individual members.
506 group, err := s.store.GetGroupByName(ctx, workspaceID, common.GroupPrefix+groupName)
507 if err != nil || group == nil || group.Payload == nil {
508 continue
509 }
510 for _, m := range group.Payload.Members {
511 if email, ok := strings.CutPrefix(m.Member, common.UserNamePrefix); ok {
512 existingMembers[email] = true
513 }
514 }
515 }
516 }
517 }
518
519 // Collect truly new user emails and their roles. Map deduplicates by email.
520 invites := make(map[string]string) // email -> roleName
521 for _, delta := range deltas {
522 if delta.Action != v1pb.BindingDelta_ADD {
523 continue
524 }
525 roleName := delta.Role
526 if role, err := s.store.GetRole(ctx, &store.FindRoleMessage{Workspace: workspaceID, ResourceID: &delta.Role}); err == nil && role != nil {
527 roleName = role.Name
528 }

Callers 1

SetIamPolicyMethod · 0.95

Calls 11

SendMethod · 0.95
NewSenderFunction · 0.92
BBErrorFunction · 0.92
GetEffectiveExternalURLFunction · 0.92
GetWorkspaceByIDMethod · 0.80
GetGroupByNameMethod · 0.80
GetRoleMethod · 0.65
StringMethod · 0.65
GetTitleMethod · 0.45
GetBindingsMethod · 0.45

Tested by

no test coverage detected