Skip to content

Commit

Permalink
Merge pull request #4199 from nickmango/bug/docsign-cla-flow
Browse files Browse the repository at this point in the history
Feature/Docusign Request
  • Loading branch information
nickmango authored Nov 30, 2023
2 parents 2e6a248 + 5b65c10 commit f3fe93d
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 60 deletions.
78 changes: 39 additions & 39 deletions cla-backend-go/signatures/dbmodels.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,46 @@ package signatures

// ItemSignature database model
type ItemSignature struct {
SignatureID string `json:"signature_id"`
DateCreated string `json:"date_created"`
DateModified string `json:"date_modified"`
SignatureApproved bool `json:"signature_approved"`
SignatureID string `json:"signature_id"` // No omitempty, always included
DateCreated string `json:"date_created,omitempty"`
DateModified string `json:"date_modified,omitempty"`
SignatureApproved bool `json:"signature_approved,omitempty"`
SignatureSigned bool `json:"signature_signed"`
SignatureDocumentMajorVersion int `json:"signature_document_major_version"`
SignatureDocumentMinorVersion int `json:"signature_document_minor_version"`
SignatureSignURL string `json:"signature_sign_url"`
SignatureReturnURL string `json:"signature_return_url"`
SignatureReturnURLType string `json:"signature_return_url_type"`
SignatureCallbackURL string `json:"signature_callback_url"`
SignatureReferenceID string `json:"signature_reference_id"`
SignatureReferenceName string `json:"signature_reference_name"`
SignatureReferenceNameLower string `json:"signature_reference_name_lower"`
SignatureProjectID string `json:"signature_project_id"`
SignatureReferenceType string `json:"signature_reference_type"`
SignatureType string `json:"signature_type"`
SignatureEnvelopeID string `json:"signature_envelope_id"`
SignatureUserCompanyID string `json:"signature_user_ccla_company_id"`
EmailApprovalList []string `json:"email_whitelist"`
EmailDomainApprovalList []string `json:"domain_whitelist"`
GitHubUsernameApprovalList []string `json:"github_whitelist"`
GitHubOrgApprovalList []string `json:"github_org_whitelist"`
GitlabUsernameApprovalList []string `json:"gitlab_username_approval_list"`
GitlabOrgApprovalList []string `json:"gitlab_org_approval_list"`
SignatureACL []string `json:"signature_acl"`
UserGithubID string `json:"user_github_id"`
UserGithubUsername string `json:"user_github_username"`
UserGitlabID string `json:"user_gitlab_id"`
UserGitlabUsername string `json:"user_gitlab_username"`
UserLFUsername string `json:"user_lf_username"`
UserName string `json:"user_name"`
UserEmail string `json:"user_email"`
SigtypeSignedApprovedID string `json:"sigtype_signed_approved_id"`
SignedOn string `json:"signed_on"`
SignatoryName string `json:"signatory_name"`
UserDocusignName string `json:"user_docusign_name"`
UserDocusignDateSigned string `json:"user_docusign_date_signed"`
AutoCreateECLA bool `json:"auto_create_ecla"`
UserDocusignRawXML string `json:"user_docusign_raw_xml"`
SignatureDocumentMajorVersion int `json:"signature_document_major_version,omitempty"`
SignatureDocumentMinorVersion int `json:"signature_document_minor_version,omitempty"`
SignatureSignURL string `json:"signature_sign_url,omitempty"`
SignatureReturnURL string `json:"signature_return_url,omitempty"`
SignatureReturnURLType string `json:"signature_return_url_type,omitempty"`
SignatureCallbackURL string `json:"signature_callback_url,omitempty"`
SignatureReferenceID string `json:"signature_reference_id,omitempty"`
SignatureReferenceName string `json:"signature_reference_name,omitempty"`
SignatureReferenceNameLower string `json:"signature_reference_name_lower,omitempty"`
SignatureProjectID string `json:"signature_project_id,omitempty"`
SignatureReferenceType string `json:"signature_reference_type,omitempty"`
SignatureType string `json:"signature_type,omitempty"`
SignatureEnvelopeID string `json:"signature_envelope_id,omitempty"`
SignatureUserCompanyID string `json:"signature_user_ccla_company_id,omitempty"`
EmailApprovalList []string `json:"email_whitelist,omitempty"`
EmailDomainApprovalList []string `json:"domain_whitelist,omitempty"`
GitHubUsernameApprovalList []string `json:"github_whitelist,omitempty"`
GitHubOrgApprovalList []string `json:"github_org_whitelist,omitempty"`
GitlabUsernameApprovalList []string `json:"gitlab_username_approval_list,omitempty"`
GitlabOrgApprovalList []string `json:"gitlab_org_approval_list,omitempty"`
SignatureACL []string `json:"signature_acl,omitempty"`
UserGithubID string `json:"user_github_id,omitempty"`
UserGithubUsername string `json:"user_github_username,omitempty"`
UserGitlabID string `json:"user_gitlab_id,omitempty"`
UserGitlabUsername string `json:"user_gitlab_username,omitempty"`
UserLFUsername string `json:"user_lf_username,omitempty"`
UserName string `json:"user_name,omitempty"`
UserEmail string `json:"user_email,omitempty"`
SigtypeSignedApprovedID string `json:"sigtype_signed_approved_id,omitempty"`
SignedOn string `json:"signed_on,omitempty"`
SignatoryName string `json:"signatory_name,omitempty"`
UserDocusignName string `json:"user_docusign_name,omitempty"`
UserDocusignDateSigned string `json:"user_docusign_date_signed,omitempty"`
AutoCreateECLA bool `json:"auto_create_ecla,omitempty"`
UserDocusignRawXML string `json:"user_docusign_raw_xml,omitempty"`
}

// DBManagersModel is a database model for only the ACL/Manager column
Expand Down
39 changes: 37 additions & 2 deletions cla-backend-go/signatures/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ type SignatureRepository interface {
UpdateEnvelopeDetails(ctx context.Context, signatureID, envelopeID string, signURL *string) (*models.Signature, error)
CreateSignature(ctx context.Context, signature *ItemSignature) error
UpdateSignature(ctx context.Context, signatureID string, updates map[string]interface{}) error
SaveOrUpdateSignature(ctx context.Context, signature *ItemSignature) error

GetSignature(ctx context.Context, signatureID string) (*models.Signature, error)
GetActivePullRequestMetadata(ctx context.Context, gitHubAuthorUsername, gitHubAuthorEmail string) (*ActivePullRequest, error)
Expand Down Expand Up @@ -167,6 +168,36 @@ func (repo repository) CreateSignature(ctx context.Context, signature *ItemSigna

}

// SaveOrUpdateSignature either creates or updates the signature record
func (repo repository) SaveOrUpdateSignature(ctx context.Context, signature *ItemSignature) error {
f := logrus.Fields{
"functionName": "v1.signatures.repository.SaveOrUpdateSignature",
utils.XREQUESTID: ctx.Value(utils.XREQUESTID),
}

av, err := dynamodbattribute.MarshalMap(signature)

if err != nil {
log.WithFields(f).Warnf("error marshalling signature, error: %v", err)
return err
}

input := &dynamodb.PutItemInput{
Item: av,
TableName: aws.String(repo.signatureTableName),
}

_, err = repo.dynamoDBClient.PutItem(input)
if err != nil {
log.WithFields(f).Warnf("error adding signature to database, error: %v", err)
return err
}

log.WithFields(f).Debugf("successfully added/updated signature to database")

return nil
}

// UpdateSignature updates an existing signature
func (repo repository) UpdateSignature(ctx context.Context, signatureID string, updates map[string]interface{}) error {
f := logrus.Fields{
Expand Down Expand Up @@ -2735,13 +2766,17 @@ func (repo repository) GetUserSignatures(ctx context.Context, params signatures.
// This is the keys we want to match
condition := expression.Key("signature_reference_id").Equal(expression.Value(params.UserID))

filterExpression := expression.Name("signature_user_ccla_company_id").AttributeNotExists()

// Check for approved signatures
expressionBuilder := expression.NewBuilder().WithKeyCondition(condition).WithProjection(buildProjection())

if projectID != nil {
filterExpression := expression.Name("signature_project_id").Equal(expression.Value(*projectID))
expressionBuilder = expressionBuilder.WithFilter(filterExpression)
filterExpression = filterExpression.And(expression.Name("signature_project_id").Equal(expression.Value(*projectID)))
}

expressionBuilder = expressionBuilder.WithFilter(filterExpression)

// Use the nice builder to create the expression
expr, err := expressionBuilder.Build()
if err != nil {
Expand Down
6 changes: 6 additions & 0 deletions cla-backend-go/signatures/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ type SignatureService interface {
InvalidateProjectRecords(ctx context.Context, projectID, note string) (int, error)
CreateSignature(ctx context.Context, signature *ItemSignature) error
UpdateSignature(ctx context.Context, signatureID string, updates map[string]interface{}) error
SaveOrUpdateSignature(ctx context.Context, signature *ItemSignature) error

GetGithubOrganizationsFromApprovalList(ctx context.Context, signatureID string, githubAccessToken string) ([]models.GithubOrg, error)
AddGithubOrganizationToApprovalList(ctx context.Context, signatureID string, approvalListParams models.GhOrgWhitelist, githubAccessToken string) ([]models.GithubOrg, error)
Expand Down Expand Up @@ -114,6 +115,11 @@ func (s service) GetSignature(ctx context.Context, signatureID string) (*models.
return s.repo.GetSignature(ctx, signatureID)
}

// SaveOrUpdateSignature saves or updates the specified signature
func (s service) SaveOrUpdateSignature(ctx context.Context, signature *ItemSignature) error {
return s.repo.SaveOrUpdateSignature(ctx, signature)
}

// UpdateSignature updates the specified signature
func (s service) UpdateSignature(ctx context.Context, signatureID string, updates map[string]interface{}) error {
return s.repo.UpdateSignature(ctx, signatureID, updates)
Expand Down
35 changes: 16 additions & 19 deletions cla-backend-go/v2/sign/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,16 +399,16 @@ func (s *service) SignedIndividualCallbackGithub(ctx context.Context, payload []

if status == "Completed" {
log.WithFields(f).Debugf("envelope signed - status: %s", status)
updates := map[string]interface{}{
"signature_signed": true,
"date_modified": currentTime,
"signed_on": currentTime,
"user_docusign_raw_xml": string(payload),
"user_docusign_name": fullName,
"user_docusign_date_signed": signedDate,
itemSignature := signatures.ItemSignature{
SignatureID: signatureID,
DateModified: currentTime,
SignatureSigned: true,
UserDocusignRawXML: string(payload),
UserDocusignName: fullName,
UserDocusignDateSigned: signedDate,
}

err = s.signatureService.UpdateSignature(ctx, signatureID, updates)
err := s.signatureService.SaveOrUpdateSignature(ctx, &itemSignature)
if err != nil {
log.WithFields(f).WithError(err).Warnf("unable to update signature record with envelope ID: %s", envelopeID)
return err
Expand Down Expand Up @@ -452,7 +452,7 @@ func (s *service) SignedIndividualCallbackGithub(ctx context.Context, payload []
if claUser.Username == "" {
if fullName != "" {
log.WithFields(f).Debugf("setting username for user with :%s", fullName)
updates = map[string]interface{}{
updates := map[string]interface{}{
"user_name": fullName,
}
log.WithFields(f).Debugf("updating user with username: %s", fullName)
Expand Down Expand Up @@ -754,12 +754,14 @@ func (s *service) RequestIndividualSignature(ctx context.Context, input *models.
signatureID := uuid.Must(uuid.NewV4()).String()
_, currentTime := utils.CurrentTime()
var acl string
if input.ReturnURLType == "github" {
if strings.ToLower(input.ReturnURLType) == utils.GitHubType {
acl = fmt.Sprintf("%s:%s", strings.ToLower(input.ReturnURLType), user.GithubID)
} else if input.ReturnURLType == "gitlab" {
} else if strings.ToLower(input.ReturnURLType) == "gitlab" {
acl = fmt.Sprintf("%s:%s", strings.ToLower(input.ReturnURLType), user.GitlabID)
}

log.WithFields(f).Debugf("acl: %s", acl)

majorVersion, err := strconv.Atoi(document.DocumentMajorVersion)

if err != nil {
Expand All @@ -774,9 +776,6 @@ func (s *service) RequestIndividualSignature(ctx context.Context, input *models.
return nil, err
}

signed := false
approved := true

itemSignature := signatures.ItemSignature{
SignatureID: signatureID,
DateCreated: currentTime,
Expand All @@ -794,8 +793,6 @@ func (s *service) RequestIndividualSignature(ctx context.Context, input *models.
SignatureCallbackURL: callBackURL,
SignatureReferenceType: "user",
SignatureACL: []string{acl},
SigtypeSignedApprovedID: fmt.Sprintf("%s#%v#%v#%s", utils.ClaTypeICLA, signed, approved, signatureID),
SignatureUserCompanyID: user.CompanyID,
SignatureReferenceNameLower: strings.ToLower(getUserName(user)),
}

Expand Down Expand Up @@ -939,6 +936,8 @@ func (s *service) getIndividualSignatureCallbackURL(ctx context.Context, userID
return "", err
}

// s.ClaV4ApiURL = "https://7de6-197-221-137-205.ngrok-free.app"

callbackURL := fmt.Sprintf("%s/v4/signed/individual/%d/%s/%s", s.ClaV4ApiURL, installationId, repositoryID, pullRequestID)

return callbackURL, nil
Expand Down Expand Up @@ -1279,14 +1278,12 @@ func (s *service) populateSignURL(ctx context.Context,
return "", err
}

err = s.signatureService.CreateSignature(ctx, latestSignature)
err = s.signatureService.SaveOrUpdateSignature(ctx, latestSignature)
if err != nil {
log.WithFields(f).WithError(err).Warnf("unable to save signature to database for user: %s", latestSignature.SignatureID)
return "", err
}

log.WithFields(f).Debug("signature saved to database")

log.WithFields(f).Debugf("populate_sign_url - complete: %s", *signatureSignURL)

return *signatureSignURL, nil
Expand Down

0 comments on commit f3fe93d

Please sign in to comment.