Skip to content

Commit

Permalink
Merge pull request #4495 from nickmango/bug/email-cla-mgr
Browse files Browse the repository at this point in the history
[#3498] Bug/Email Template
  • Loading branch information
nickmango authored Dec 3, 2024
2 parents 8f1989d + 5fa2e02 commit f7fa410
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 86 deletions.
115 changes: 56 additions & 59 deletions cla-backend-go/cla_manager/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type IService interface {
PendingRequest(companyID, claGroupID, requestID string) (*models.ClaManagerRequest, error)
DeleteRequest(requestID string) error

AddClaManager(ctx context.Context, authUser *auth.User, companyID string, claGroupID string, LFID string, projectSFName string) (*models.Signature, error)
AddClaManager(ctx context.Context, authUser *auth.User, companyID string, claGroupID string, LFID string, projectSFID string) (*models.Signature, error)
RemoveClaManager(ctx context.Context, authUser *auth.User, companyID string, claGroupID string, LFID string, projectSFName string) (*models.Signature, error)
}

Expand Down Expand Up @@ -193,17 +193,17 @@ func (s service) DeleteRequest(requestID string) error {
}

// AddClaManager Adds LFID to Signature Access Control list
func (s service) AddClaManager(ctx context.Context, authUser *auth.User, companyID string, claGroupID string, LFID string, projectSFName string) (*models.Signature, error) {
func (s service) AddClaManager(ctx context.Context, authUser *auth.User, companyID string, claGroupID string, LFID string, projectSFID string) (*models.Signature, error) {

f := logrus.Fields{
"functionName": "v1.cla_manager.AddClaManager",
utils.XREQUESTID: ctx.Value(utils.XREQUESTID),
"companyID": companyID,
"claGroupID": claGroupID,
"LFID": LFID,
"projectName": projectSFName,
"projectSFID": projectSFID,
}

var projectSFName string
userModel, userErr := s.usersService.GetUserByLFUserName(LFID)
if userErr != nil || userModel == nil {
return nil, userErr
Expand All @@ -218,11 +218,6 @@ func (s service) AddClaManager(ctx context.Context, authUser *auth.User, company
return nil, projectErr
}

// if projectSFName is empty, we can set clagroup project name.
if projectSFName == "" {
projectSFName = claGroupModel.ProjectName
}

// Look up signature ACL to ensure the user can add cla manager

signed := true
Expand Down Expand Up @@ -258,16 +253,17 @@ func (s service) AddClaManager(ctx context.Context, authUser *auth.User, company
RecipientAddress: manager.LfEmail.String(),
CompanyName: companyModel.CompanyName,
},
Name: userModel.Username,
Email: userModel.LfEmail.String(),
Name: userModel.Username,
Email: userModel.LfEmail.String(),
ProjectSFID: projectSFID,
}, claGroupModel)
}
// Notify the added user
s.sendClaManagerAddedEmailToUser(s.emailTemplateService, emails.CommonEmailParams{
RecipientName: userModel.Username,
RecipientAddress: userModel.LfEmail.String(),
CompanyName: companyModel.CompanyName,
}, claGroupModel)
}, claGroupModel, projectSFID)

// Send an event
s.eventsService.LogEventWithContext(ctx, &events.LogEventArgs{
Expand Down Expand Up @@ -317,7 +313,7 @@ func (s service) getCompanySignature(ctx context.Context, companyID string, claG
}

// RemoveClaManager removes lfid from signature acl with given company and project
func (s service) RemoveClaManager(ctx context.Context, authUser *auth.User, companyID string, claGroupID string, LFID string, projectSFName string) (*models.Signature, error) {
func (s service) RemoveClaManager(ctx context.Context, authUser *auth.User, companyID string, claGroupID string, LFID string, projectSFID string) (*models.Signature, error) {

f := logrus.Fields{
"functionName": "v1.cla_manager.RemoveClaManager",
Expand All @@ -327,6 +323,7 @@ func (s service) RemoveClaManager(ctx context.Context, authUser *auth.User, comp
"companyID": companyID,
}

var projectSFName string
userModel, userErr := s.usersService.GetUserByLFUserName(LFID)
if userErr != nil || userModel == nil {
return nil, userErr
Expand All @@ -341,11 +338,6 @@ func (s service) RemoveClaManager(ctx context.Context, authUser *auth.User, comp
return nil, projectErr
}

// if projectSFName is empty, we can set clagroup project name.
if projectSFName == "" {
projectSFName = claGroupModel.ProjectName
}

signed := true
approved := true
sigModel, sigErr := s.sigService.GetProjectCompanySignature(ctx, companyID, claGroupID, &signed, &approved, nil, aws.Int64(5))
Expand Down Expand Up @@ -420,50 +412,56 @@ func (s service) RemoveClaManager(ctx context.Context, authUser *auth.User, comp

type ProjectDetails struct {
ProjectName string
ProjectSFID string
ProjectSFID []string
}

func (s service) getProjectDetails(ctx context.Context, claGroupModel *models.ClaGroup) ProjectDetails {
f := logrus.Fields{
"functionName": "v1.cla_manager.getProjectDetails",
utils.XREQUESTID: ctx.Value(utils.XREQUESTID),
"claGroupID": claGroupModel.ProjectID,
}
// func (s service) getProjectDetails(ctx context.Context, claGroupModel *models.ClaGroup) ProjectDetails {
// f := logrus.Fields{
// "functionName": "v1.cla_manager.getProjectDetails",
// utils.XREQUESTID: ctx.Value(utils.XREQUESTID),
// "claGroupID": claGroupModel.ProjectID,
// }
// projectSFIDs := make([]string, 0)

projectDetails := ProjectDetails{
ProjectName: claGroupModel.ProjectName,
ProjectSFID: claGroupModel.ProjectExternalID,
}
signedAtFoundation := false
// projectDetails := ProjectDetails{
// ProjectName: claGroupModel.ProjectName,
// }
// signedAtFoundation := false
// var err error

pcg, err := s.projectClaRepository.GetCLAGroup(ctx, claGroupModel.ProjectID)
if err != nil {
log.WithFields(f).Warnf("unable to fetch project cla group by project id: %s, error: %+v", claGroupModel.ProjectID, err)
}
// pcg, pcgErr := s.projectClaRepository.GetCLAGroup(ctx, claGroupModel.ProjectID)
// if pcgErr != nil {
// log.WithFields(f).WithError(err).Debug("unable too get pcg record")
// }

// check if cla group is signed at foundation level
if pcg != nil && pcg.FoundationSFID != "" {
signedAtFoundation, err = s.projectClaRepository.IsExistingFoundationLevelCLAGroup(ctx, pcg.FoundationSFID)
if err != nil {
log.WithFields(f).Warnf("unable to fetch foundation level cla group by foundation id: %s, error: %+v", pcg.FoundationSFID, err)
}
// signedAtFoundation, err = s.projectClaRepository.SignedAtFoundation(ctx, claGroupModel.ProjectID)
// if err != nil {
// log.WithFields(f).WithError(err).Debug("unable to get status of cla signed at foundation")
// }

if signedAtFoundation {
log.WithFields(f).Debugf("cla group is signed at foundation level...")
projectDetails.ProjectName = pcg.FoundationName
projectDetails.ProjectSFID = pcg.FoundationSFID
}
}
// if signedAtFoundation && pcg != nil && err != nil {
// log.WithFields(f).Debug("cla group is signed at foundation level...")
// projectDetails.ProjectName = pcg.FoundationName
// projectSFIDs = append(projectSFIDs, pcg.FoundationSFID)

return projectDetails
}
// } else {
// log.WithFields(f).Debug("cla group is signed at project level ...")

// }

func (s service) sendClaManagerAddedEmailToUser(emailSvc emails.EmailTemplateService, emailParams emails.CommonEmailParams, claGroupModel *models.ClaGroup) {
projectDetails := s.getProjectDetails(context.Background(), claGroupModel)
projectName := projectDetails.ProjectName
projectSFID := projectDetails.ProjectSFID
// projectDetails.ProjectSFID = projectSFIDs

// return projectDetails
// }

func (s service) sendClaManagerAddedEmailToUser(emailSvc emails.EmailTemplateService, emailParams emails.CommonEmailParams, claGroupModel *models.ClaGroup, projectSFID string) {
f := logrus.Fields{
"functionName": "sendClaManagerAddedEmailToUser",
"projectSFID": projectSFID,
}
log.WithFields(f).Info("Sending email to user")
// subject string, body string, recipients []string
subject := fmt.Sprintf("EasyCLA: Added as CLA Manager for Project :%s", projectName)
subject := fmt.Sprintf("EasyCLA: Added as CLA Manager for Project :%s", claGroupModel.ProjectName)
recipients := []string{emailParams.RecipientAddress}
body, err := emails.RenderClaManagerAddedEToUserTemplate(emailSvc, claGroupModel.Version, projectSFID, emails.ClaManagerAddedEToUserTemplateParams{
CommonEmailParams: emailParams,
Expand Down Expand Up @@ -553,10 +551,12 @@ func sendRemovedClaManagerEmailToRecipient(emailSvc emails.EmailTemplateService,
body, err := emails.RenderRemovedCLAManagerTemplate(
emailSvc,
claGroupModel.Version,
claGroupModel.ProjectExternalID,
emails.RemovedCLAManagerTemplateParams{
CommonEmailParams: emailParams,
CLAManagers: emailCLAManagerParams,
CLAGroupTemplateParams: emails.CLAGroupTemplateParams{
CLAGroupName: projectName,
},
})

if err != nil {
Expand All @@ -573,14 +573,11 @@ func sendRemovedClaManagerEmailToRecipient(emailSvc emails.EmailTemplateService,
}

func (s service) sendClaManagerDeleteEmailToCLAManagers(emailSvc emails.EmailTemplateService, emailParams emails.ClaManagerDeletedToCLAManagersTemplateParams, claGroupModel *models.ClaGroup) {
projectDetails := s.getProjectDetails(context.Background(), claGroupModel)
projectName := projectDetails.ProjectName
projectSFID := projectDetails.ProjectSFID

// subject string, body string, recipients []string
subject := fmt.Sprintf("EasyCLA: CLA Manager Removed Notice for %s", projectName)
subject := fmt.Sprintf("EasyCLA: CLA Manager Removed Notice for %s", claGroupModel.ProjectName)
recipients := []string{emailParams.RecipientAddress}
body, err := emails.RenderClaManagerDeletedToCLAManagersTemplate(emailSvc, claGroupModel.Version, projectSFID, emailParams)
body, err := emails.RenderClaManagerDeletedToCLAManagersTemplate(emailSvc, claGroupModel.Version, claGroupModel.ProjectName)

if err != nil {
log.Warnf("email template render : %s failed : %v", emails.ClaManagerDeletedToCLAManagersTemplateName, err)
Expand Down
26 changes: 10 additions & 16 deletions cla-backend-go/emails/cla_manager_templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ const (
// RemovedCLAManagerTemplate includes the email template for email when user is removed as CLA Manager
RemovedCLAManagerTemplate = `
<p>Hello {{.RecipientName}},</p>
<p>This is a notification email from EasyCLA regarding the project {{.GetProjectNameOrFoundation}} and CLA Group {{.CLAGroupName}}.</p>
<p>You have been removed as a CLA Manager from {{.CompanyName}} for the project {{.Project.ExternalProjectName}}.</p>
<p>This is a notification email from EasyCLA regarding the CLA Group {{.CLAGroupName}}.</p>
<p>You have been removed as a CLA Manager from {{.CompanyName}} for the CLA Group {{.CLAGroupName}}.</p>
<p>If you have further questions about this, please contact one of the existing managers from
{{.CompanyName}}:</p>
<ul>
Expand All @@ -29,13 +29,7 @@ const (
)

// RenderRemovedCLAManagerTemplate renders the RemovedCLAManagerTemplate
func RenderRemovedCLAManagerTemplate(svc EmailTemplateService, claGroupModelVersion, projectSFID string, params RemovedCLAManagerTemplateParams) (string, error) {
claGroupParams, err := svc.GetCLAGroupTemplateParamsFromProjectSFID(claGroupModelVersion, projectSFID)
if err != nil {
return "", err
}
params.CLAGroupTemplateParams = claGroupParams

func RenderRemovedCLAManagerTemplate(svc EmailTemplateService, claGroupModelVersion string, params RemovedCLAManagerTemplateParams) (string, error) {
return RenderTemplate(claGroupModelVersion, RemovedCLAManagerTemplateName, RemovedCLAManagerTemplate, params)
}

Expand Down Expand Up @@ -242,8 +236,9 @@ func RenderClaManagerAddedEToUserTemplate(svc EmailTemplateService, claGroupMode
type ClaManagerAddedToCLAManagersTemplateParams struct {
CommonEmailParams
CLAGroupTemplateParams
Name string
Email string
Name string
Email string
ProjectSFID string
}

const (
Expand Down Expand Up @@ -293,12 +288,11 @@ const (
)

// RenderClaManagerDeletedToCLAManagersTemplate renders the RemovedCLAManagerTemplate
func RenderClaManagerDeletedToCLAManagersTemplate(svc EmailTemplateService, claGroupModelVersion, projectSFID string, params ClaManagerDeletedToCLAManagersTemplateParams) (string, error) {
claGroupParams, err := svc.GetCLAGroupTemplateParamsFromProjectSFID(claGroupModelVersion, projectSFID)
if err != nil {
return "", err
func RenderClaManagerDeletedToCLAManagersTemplate(svc EmailTemplateService, claGroupModelVersion, claGroupName string) (string, error) {

params := CLAGroupTemplateParams{
CLAGroupName: claGroupName,
}
params.CLAGroupTemplateParams = claGroupParams

return RenderTemplate(claGroupModelVersion, ClaManagerDeletedToCLAManagersTemplateName, ClaManagerDeletedToCLAManagersTemplate, params)
}
13 changes: 3 additions & 10 deletions cla-backend-go/emails/cla_manager_templates_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ func TestRemovedCLAManagerTemplate(t *testing.T) {
params)
assert.NoError(t, err)
assert.Contains(t, result, "Hello JohnsClaManager")
assert.Contains(t, result, "regarding the project JohnsProject")
assert.Contains(t, result, "CLA Manager from JohnsCompany for the project JohnsProject")
assert.Contains(t, result, "regarding the CLA Group JohnsProject")
assert.Contains(t, result, "CLA Manager from JohnsCompany for the CLA Group JohnsProject")
assert.Contains(t, result, "<li>LFUserName LFEmail</li>")

// even if the foundation is set we should show the project name
Expand All @@ -41,15 +41,8 @@ func TestRemovedCLAManagerTemplate(t *testing.T) {
params)
assert.NoError(t, err)
assert.Contains(t, result, "Hello JohnsClaManager")
assert.Contains(t, result, "for the project JohnsProject")
assert.Contains(t, result, "for the CLA Group JohnsProject")

// then we increase the child project count so we should get the FoundationName instead of project name
params.ChildProjectCount = 2
result, err = RenderTemplate(utils.V1, RemovedCLAManagerTemplateName, RemovedCLAManagerTemplate,
params)
assert.NoError(t, err)
assert.Contains(t, result, "Hello JohnsClaManager")
assert.Contains(t, result, "regarding the project CNCF")
}

func TestRequestAccessToCLAManagersTemplate(t *testing.T) {
Expand Down
2 changes: 2 additions & 0 deletions cla-backend-go/emails/prefill.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ func (s *emailTemplateServiceProvider) PrefillV2CLAProjectParams(projectSFIDs []
claProjectParams = append(claProjectParams, params)
}

log.Debugf("claProjectParams: %+v", claProjectParams)

return claProjectParams, nil
}

Expand Down
15 changes: 15 additions & 0 deletions cla-backend-go/projects_cla_groups/mocks/mock_repository.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions cla-backend-go/projects_cla_groups/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ type Repository interface {
IsAssociated(ctx context.Context, projectSFID string, claGroupID string) (bool, error)
UpdateRepositoriesCount(ctx context.Context, projectSFID string, diff int64, reset bool) error
UpdateClaGroupName(ctx context.Context, projectSFID string, claGroupName string) error
SignedAtFoundation(ctx context.Context, claGroupID string) (bool, error)
}

type repo struct {
Expand Down Expand Up @@ -124,6 +125,26 @@ func (repo *repo) queryClaGroupsProjects(ctx context.Context, keyCondition expre
return projectClaGroups, nil
}

func (repo *repo) SignedAtFoundation(ctx context.Context, claGroupID string) (bool, error) {
f := logrus.Fields{
"functionName": "SignedAtFoundation",
"claGroupID": claGroupID,
}
pcgs, err := repo.GetProjectsIdsForClaGroup(ctx, claGroupID)
if err != nil {
return false, err
}

log.WithFields(f).Info("checking if claGroup is signed at foundation level..")
for _, pcg := range pcgs {
if pcg.FoundationSFID == pcg.ProjectSFID {
return true, nil
}
}

return false, nil
}

// GetClaGroupIDForProject retrieves the CLA Group ID for the project
func (repo *repo) GetClaGroupIDForProject(ctx context.Context, projectSFID string) (*ProjectClaGroup, error) {
f := logrus.Fields{
Expand Down
2 changes: 1 addition & 1 deletion cla-backend-go/v2/cla_manager/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ func (s *service) CreateCLAManager(ctx context.Context, authUser *auth.User, cla
}

// Add CLA Manager to Database
signature, addErr := s.managerService.AddClaManager(ctx, authUser, v1CompanyModel.CompanyID, claGroupID, user.Username, projectSF.Name)
signature, addErr := s.managerService.AddClaManager(ctx, authUser, v1CompanyModel.CompanyID, claGroupID, user.Username, params.ProjectSFID)
if addErr != nil {
msg := buildErrorMessageCreate(params, addErr)
log.WithFields(f).Warn(msg)
Expand Down

0 comments on commit f7fa410

Please sign in to comment.