diff --git a/cla-backend-go/go.sum b/cla-backend-go/go.sum index ad6e7314b..0574d172f 100644 --- a/cla-backend-go/go.sum +++ b/cla-backend-go/go.sum @@ -66,6 +66,7 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/communitybridge/easycla v1.0.99 h1:PkmkMV7cLH2Q2YNSFiGGmlyrHBXVYdsWMwbXNuMAyqw= +github.com/communitybridge/easycla v1.0.106 h1:NLYUZUZtp9DQ0dHEQkhz9h9EMzLRmuh9udsPZk8oLoQ= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= diff --git a/cla-backend-go/swagger/cla.v2.yaml b/cla-backend-go/swagger/cla.v2.yaml index def1edb62..480d7009d 100644 --- a/cla-backend-go/swagger/cla.v2.yaml +++ b/cla-backend-go/swagger/cla.v2.yaml @@ -3486,6 +3486,12 @@ parameters: description: the Salesforce ID of the Foundation in: query type: string + signingEntityName: + name: signingEntityName + description: The signing entity name of a Company (Salesforce and EasyCLA) + in: query + type: string + required: true path-claGroupID: name: claGroupID description: ID of the CLA Group @@ -4428,8 +4434,16 @@ definitions: description: CLA Manager email name: type: string - + company-project-cla-list: + type: object + properties: + list: + type: array + items: + $ref: '#/definitions/company-project-cla' + + company-project-cla: type: object properties: signed_cla_list: @@ -4470,6 +4484,16 @@ definitions: title: unsigned project description: details of unsigned project properties: + company_name: + type: string + description: The company name + x-omitempty: false + example: "The Linux Foundation" + signing_entity_name: + type: string + description: The company signing entity name + x-omitempty: false + example: "The Linux Foundation Subsidiary 1" cla_group_id: type: string x-omitempty: false @@ -4505,6 +4529,16 @@ definitions: title: Active CLA of the company description: Details of the active CLA Group properties: + company_name: + type: string + description: The company name + x-omitempty: false + example: "The Linux Foundation" + signing_entity_name: + type: string + description: The company signing entity name + x-omitempty: false + example: "The Linux Foundation Subsidiary 1" signed_on: type: string x-omitempty: false diff --git a/cla-backend-go/v2/company/service.go b/cla-backend-go/v2/company/service.go index 498db2319..09026f158 100644 --- a/cla-backend-go/v2/company/service.go +++ b/cla-backend-go/v2/company/service.go @@ -309,7 +309,7 @@ func (s *service) GetCompanyProjectActiveCLAs(ctx context.Context, companyID str activeCla := &models.ActiveCla{} out.List = append(out.List, activeCla) go func(swg *sync.WaitGroup, signature *v1Models.Signature, acla *models.ActiveCla) { - s.fillActiveCLA(swg, signature, acla, claGroups) + s.fillActiveCLA(ctx, swg, signature, acla, claGroups, companyID) }(&wg, sig, activeCla) } wg.Wait() @@ -756,12 +756,11 @@ func (s *service) GetCompanyProjectCLA(ctx context.Context, authUser *auth.User, // Attempt to locate the company model in our database log.WithFields(f).Debug("locating company by SF ID") var companyModel *v1Models.Company - companyModel, companyErr := s.companyRepo.GetCompanyByExternalID(ctx, companySFID) + companies, companyErr := s.companyRepo.GetCompaniesByExternalID(ctx, companySFID) if companyErr != nil { // If we were unable to find the company/org in our local database, try to auto-create based // on the existing SF record if companyErr == company.ErrCompanyDoesNotExist { - log.WithFields(f).Debug("company not found in EasyCLA database - attempting to auto-create from platform organization service record") var createCompanyErr error companyModel, createCompanyErr = s.autoCreateCompany(ctx, companySFID) @@ -786,40 +785,51 @@ func (s *service) GetCompanyProjectCLA(ctx context.Context, authUser *auth.User, return nil, err } - activeCLAList, err := s.GetCompanyProjectActiveCLAs(ctx, companyModel.CompanyID, projectSFID) - if err != nil { - log.WithFields(f).Warnf("problem fetching company project active CLAs, error: %+v", err) - return nil, err - } - - resp := &models.CompanyProjectClaList{ - SignedClaList: activeCLAList.List, - UnsignedProjectList: make([]*models.UnsignedProject, 0), - } - - for _, activeCLA := range activeCLAList.List { - // remove cla groups for which we have signed cla - log.WithFields(f).Debugf("removing CLA Groups with active CLA, CLA Group: %+v, error: %+v", activeCLA, err) - delete(claGroups, activeCLA.ProjectID) - } - - // fill details for not signed cla - for claGroupID, claGroup := range claGroups { - unsignedProject := &models.UnsignedProject{ - CanSign: canSign, - ClaGroupID: claGroupID, - ClaGroupName: claGroup.ClaGroupName, - ProjectName: claGroup.ProjectName, - ProjectSfid: claGroup.ProjectSFID, - SubProjects: claGroup.SubProjects, - IclaEnabled: claGroup.IclaEnabled, - CclaEnabled: claGroup.CclaEnabled, + var companyProjectClaList = make([]*models.CompanyProjectCla, 0) + for _, company := range companies { + activeCLAList, err := s.GetCompanyProjectActiveCLAs(ctx, company.CompanyID, projectSFID) + if err != nil { + log.WithFields(f).Warnf("problem fetching company project active CLAs, error: %+v", err) + return nil, err + } + var companyProjectCLA = &models.CompanyProjectCla{ + SignedClaList: activeCLAList.List, + UnsignedProjectList: make([]*models.UnsignedProject, 0), + } + for _, activeCLA := range activeCLAList.List { + // remove cla groups for which we have signed cla + log.WithFields(f).Debugf("removing CLA Groups with active CLA, CLA Group: %+v, error: %+v", activeCLA, err) + delete(claGroups, activeCLA.ProjectID) } - log.WithFields(f).Debugf("adding unsigned CLA Group: %+v, error: %+v", unsignedProject, err) - resp.UnsignedProjectList = append(resp.UnsignedProjectList, unsignedProject) + // Get Company details + company, compErr := s.GetCompanyByID(ctx, company.CompanyID) + if compErr != nil { + log.WithFields(f).WithError(compErr).Warnf("unable to fetch company by ID: %s ", company.CompanyID) + return nil, compErr + } + // fill details for not signed cla + for claGroupID, claGroup := range claGroups { + unsignedProject := &models.UnsignedProject{ + CompanyName: company.CompanyName, + SigningEntityName: company.SigningEntityName, + CanSign: canSign, + ClaGroupID: claGroupID, + ClaGroupName: claGroup.ClaGroupName, + ProjectName: claGroup.ProjectName, + ProjectSfid: claGroup.ProjectSFID, + SubProjects: claGroup.SubProjects, + IclaEnabled: claGroup.IclaEnabled, + CclaEnabled: claGroup.CclaEnabled, + } + log.WithFields(f).Debugf("adding unsigned CLA Group: %+v, error: %+v", unsignedProject, err) + companyProjectCLA.UnsignedProjectList = append(companyProjectCLA.UnsignedProjectList, unsignedProject) + } + companyProjectClaList = append(companyProjectClaList, companyProjectCLA) } - return resp, nil + return &models.CompanyProjectClaList{ + List: companyProjectClaList, + }, nil } // GetCompanyCLAGroupManagers when provided the internal company ID and CLA Groups ID, this routine returns the list of @@ -1086,7 +1096,10 @@ func fillProjectInfo(claManagers []*models.CompanyClaManager, claGroups map[stri } } -func (s *service) fillActiveCLA(wg *sync.WaitGroup, sig *v1Models.Signature, activeCla *models.ActiveCla, claGroups map[string]*claGroupModel) { +func (s *service) fillActiveCLA(ctx context.Context, wg *sync.WaitGroup, sig *v1Models.Signature, activeCla *models.ActiveCla, claGroups map[string]*claGroupModel, companyID string) { + f := logrus.Fields{ + "functionName": "fillActiveCLA", + } defer wg.Done() cg, ok := claGroups[sig.ProjectID] if !ok { @@ -1094,7 +1107,20 @@ func (s *service) fillActiveCLA(wg *sync.WaitGroup, sig *v1Models.Signature, act return } + // Get Company details + company, compErr := s.GetCompanyByID(ctx, companyID) + if compErr != nil { + log.WithFields(f).WithError(compErr).Warnf("unable to fetch company by ID: %s ", companyID) + return + } + // fill details from dynamodb + activeCla.CompanyName = company.CompanyName + if company.SigningEntityName == "" { + activeCla.SigningEntityName = company.CompanyName + } else { + activeCla.SigningEntityName = company.SigningEntityName + } activeCla.ProjectID = sig.ProjectID if sig.SignedOn == "" { activeCla.SignedOn = sig.SignatureCreated @@ -1133,13 +1159,13 @@ func (s *service) fillActiveCLA(wg *sync.WaitGroup, sig *v1Models.Signature, act } usc := v2UserService.GetClient() if len(sig.SignatureACL) == 0 { - log.Warnf("signature : %s have empty signature_acl", sig.SignatureID) + log.WithFields(f).Warnf("signature : %s have empty signature_acl", sig.SignatureID) return } lfUsername := sig.SignatureACL[0].LfUsername user, err := usc.GetUserByUsername(lfUsername) if err != nil { - log.Warnf("unable to get user with lf username : %s", lfUsername) + log.WithFields(f).WithError(err).Warnf("unable to get user with lf username : %s", lfUsername) return } signatoryName = user.Name @@ -1310,7 +1336,8 @@ func (s service) autoCreateCompany(ctx context.Context, companySFID string) (*v1 companyModel, companyCreateErr := s.companyRepo.CreateCompany(ctx, &v1Models.Company{ CompanyExternalID: companySFID, CompanyName: sfOrgModel.Name, - Note: "created on-demand by v4 service based on SF Organization Service record", + + Note: "created on-demand by v4 service based on SF Organization Service record", }) if companyCreateErr != nil || companyModel == nil {