Skip to content

Commit 4a7b66e

Browse files
Hardening & E2E updates
Signed-off-by: Lukasz Gryglicki <lgryglicki@cncf.io> Assisted by [OpenAI](https://platform.openai.com/) Assisted by [GitHub Copilot](https://github.com/features/copilot)
1 parent ac34000 commit 4a7b66e

3 files changed

Lines changed: 40 additions & 7 deletions

File tree

cla-backend-go/v2/sign/service.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ func (s *service) SignedIndividualCallbackGithub(ctx context.Context, payload []
465465
var claUser *v1Models.User
466466
if fetchedUser, userErr := s.userService.GetUser(signature.SignatureReferenceID); userErr != nil {
467467
log.WithFields(f).WithError(userErr).Warnf("unable to lookup user by ID before pull request refresh: %s", signature.SignatureReferenceID)
468-
} else {
468+
} else if fetchedUser != nil {
469469
claUser = fetchedUser
470470
if cacheErr := github.UpdateCacheAfterSignature(ctx, claUser, signature.ProjectID); cacheErr != nil {
471471
log.WithFields(f).WithError(cacheErr).Warnf("unable to prime GitHub authorization cache for user: %s", signature.SignatureReferenceID)
@@ -506,6 +506,11 @@ func (s *service) SignedIndividualCallbackGithub(ctx context.Context, payload []
506506
log.WithFields(f).WithError(userErr).Warnf("unable to lookup user by ID: %s", signature.SignatureReferenceID)
507507
return userErr
508508
}
509+
if claUser == nil {
510+
err = fmt.Errorf("user not found: %s", signature.SignatureReferenceID)
511+
log.WithFields(f).WithError(err).Warn("unable to lookup user by ID - user not found")
512+
return err
513+
}
509514
}
510515

511516
if claUser.Username == "" {

cla-backend-go/v2/signatures/converters.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ func v2Signature(src *v1Models.Signature) (*models.Signature, error) {
2323
if err != nil {
2424
return nil, err
2525
}
26+
if dst.Signatures == nil {
27+
dst.Signatures = make([]*models.Signature, 0)
28+
}
2629
return &dst, nil
2730
}
2831

tests/functional/cypress/e2e/v4/signatures.cy.ts

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ describe('To Validate & get list of signatures of ClaGroups via API call', funct
7676
const findProjectCompanySignature = (signatures: any[], signatureID?: string) =>
7777
signatures.find((item: any) => item.signatureID === signatureID) || signatures[0];
7878

79+
const getAllowlistSignatureID = () => signatureCclaID || projectCompanySignatureID || signatureID;
80+
81+
const getSignedDocumentSignatureID = () =>
82+
signatureIclaID || signatureID || signatureCclaID || projectCompanySignatureID;
83+
7984
const extractApprovalValues = (list: any[] = []) =>
8085
list
8186
.map((item: any) => {
@@ -469,24 +474,40 @@ describe('To Validate & get list of signatures of ClaGroups via API call', funct
469474
},
470475
}).then((response) => {
471476
return cy.logJson('response', response).then(() => {
477+
const signatures = response.body.signatures || [];
478+
const normalizedResponse = {
479+
...response,
480+
body: { ...response.body, signatures },
481+
};
482+
472483
validate_200_Status(response);
473-
let signatures = response.body.signatures;
484+
expect(signatures).to.be.an('array');
474485
for (let i = 0; i <= signatures.length - 1; i++) {
475486
// LG: API /signatures/user/{userID} internally skips ECLA records, and for ICLA we never have company
476487
expect(signatures[i].companyName).to.be.undefined;
477488
expect(signatures[i].signatureReferenceType).to.eql('user');
478-
signatureID = signatures[i].signatureID;
489+
if (!signatureID && signatures[i].signatureID) {
490+
signatureID = signatures[i].signatureID;
491+
}
492+
}
493+
if (signatures.length === 0) {
494+
cy.task(
495+
'log',
496+
`No direct user signatures were returned for user ${userID2}. This can happen in dev when the user only has ECLA/employee signatures or no active ICLA.`,
497+
);
479498
}
480-
validateApiResponse('signatures/getProjectCompanySignatures.json', response);
499+
validateApiResponse('signatures/getUserSignatures.json', normalizedResponse);
481500
});
482501
});
483502
});
484503

485504
it('GET: Updates the specified signature GitHub Organization approval list', function () {
505+
const allowlistSignatureID = getAllowlistSignatureID();
506+
expect(allowlistSignatureID, 'signature ID for GitHub organization allowlist').to.not.equal('');
486507
cy.request({
487508
method: 'GET',
488509
// we can't use inclusive name yet as it is inside API URL.
489-
url: `${claEndpoint}signatures/${signatureID}/gh-org-whitelist`,
510+
url: `${claEndpoint}signatures/${allowlistSignatureID}/gh-org-whitelist`,
490511
timeout: timeout,
491512
failOnStatusCode: allowFail,
492513
headers: getXACLHeader(),
@@ -499,10 +520,12 @@ describe('To Validate & get list of signatures of ClaGroups via API call', funct
499520
});
500521

501522
it('POST: Updates the specified signature GitHub organization approval list', function () {
523+
const allowlistSignatureID = getAllowlistSignatureID();
524+
expect(allowlistSignatureID, 'signature ID for GitHub organization allowlist').to.not.equal('');
502525
cy.request({
503526
method: 'POST',
504527
// we can't use inclusive name yet as it is inside API URL.
505-
url: `${claEndpoint}signatures/${signatureID}/gh-org-whitelist`,
528+
url: `${claEndpoint}signatures/${allowlistSignatureID}/gh-org-whitelist`,
506529
timeout: timeout,
507530
failOnStatusCode: false,
508531
headers: getXACLHeader(),
@@ -524,9 +547,11 @@ describe('To Validate & get list of signatures of ClaGroups via API call', funct
524547
});
525548

526549
it('Returns the signature signed document when provided the signature ID', function () {
550+
const signedDocumentSignatureID = getSignedDocumentSignatureID();
551+
expect(signedDocumentSignatureID, 'signature ID for signed document').to.not.equal('');
527552
cy.request({
528553
method: 'GET',
529-
url: `${claEndpoint}signatures/${signatureID}/signed-document`,
554+
url: `${claEndpoint}signatures/${signedDocumentSignatureID}/signed-document`,
530555
timeout: timeout,
531556
failOnStatusCode: allowFail,
532557
headers: getXACLHeader(),

0 commit comments

Comments
 (0)