Skip to content

Commit

Permalink
[communitybridge#4002] Feature/Docusign API - Golang
Browse files Browse the repository at this point in the history
- Implemented new API for icla sign request in golang

Signed-off-by: Harold Wanyama <hwanyama@contractor.linuxfoundation.org>
  • Loading branch information
nickmango committed Oct 12, 2023
1 parent 90aeb74 commit 0f67b26
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 10 deletions.
3 changes: 2 additions & 1 deletion cla-backend-go/v2/sign/docusign.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"strings"
Expand Down Expand Up @@ -41,7 +42,7 @@ func (s *service) getAccessToken(ctx context.Context) (string, error) {
return "", err
}

url := utils.GetProperty("DOCUSIGN_AUTH_SERVER") + "/oauth/token"
url := fmt.Sprintf("https://%s/oauth/token", utils.GetProperty("DOCUSIGN_AUTH_SERVER"))
req, err := http.NewRequest("POST", url, strings.NewReader(string(tokenRequestBodyJSON)))
if err != nil {
log.WithFields(f).WithError(err).Warnf("problem creating the HTTP request")
Expand Down
16 changes: 13 additions & 3 deletions cla-backend-go/v2/sign/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,20 @@ func Configure(api *operations.EasyclaAPI, service Service) {
"returnURLType": params.Input.ReturnURLType,
"userID": params.Input.UserID,
}
log.WithFields(f).Debug("processing request")
resp, err := service.RequestIndividualSignature(ctx, params.Input)
var resp *models.IndividualSignatureOutput
var err error
if strings.ToLower(params.Input.ReturnURLType) == "github" || strings.ToLower(params.Input.ReturnURLType) == "gitlab" {
log.WithFields(f).Debug("requesting individual signature for github/gitlab")
resp, err = service.RequestIndividualSignature(ctx, params.Input)
} else if strings.ToLower(params.Input.ReturnURLType) == "gerrit" {
log.WithFields(f).Debug("requesting individual signature for gerrit")
resp, err = service.RequestIndividualSignatureGerrit(ctx, params.Input)
} else {
msg := fmt.Sprintf("invalid return URL type: %s", params.Input.ReturnURLType)
log.WithFields(f).Warn(msg)
return sign.NewRequestIndividualSignatureBadRequest().WithPayload(errorResponse(reqId, errors.New(msg)))
}
if err != nil {
log.WithFields(f).WithError(err).Warn("problem requesting individual signature")
return sign.NewRequestIndividualSignatureBadRequest().WithPayload(errorResponse(reqId, err))
}
return sign.NewRequestIndividualSignatureOK().WithPayload(resp)
Expand Down
46 changes: 40 additions & 6 deletions cla-backend-go/v2/sign/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"strings"

"github.com/communitybridge/easycla/cla-backend-go/projects_cla_groups"
"github.com/communitybridge/easycla/cla-backend-go/users"
"github.com/communitybridge/easycla/cla-backend-go/v2/cla_groups"

"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -55,6 +56,7 @@ type ProjectRepo interface {
type Service interface {
RequestCorporateSignature(ctx context.Context, lfUsername string, authorizationHeader string, input *models.CorporateSignatureInput) (*models.CorporateSignatureOutput, error)
RequestIndividualSignature(ctx context.Context, input *models.IndividualSignatureInput) (*models.IndividualSignatureOutput, error)
RequestIndividualSignatureGerrit(ctx context.Context, input *models.IndividualSignatureInput) (*models.IndividualSignatureOutput, error)
}

// service
Expand All @@ -66,10 +68,11 @@ type service struct {
companyService company.IService
claGroupService cla_groups.Service
docsignPrivateKey string
userService users.Service
}

// NewService returns an instance of v2 project service
func NewService(apiURL string, compRepo company.IRepository, projectRepo ProjectRepo, pcgRepo projects_cla_groups.Repository, compService company.IService, claGroupService cla_groups.Service, docsignPrivateKey string) Service {
func NewService(apiURL string, compRepo company.IRepository, projectRepo ProjectRepo, pcgRepo projects_cla_groups.Repository, compService company.IService, claGroupService cla_groups.Service, docsignPrivateKey string, userService users.Service) Service {
return &service{
ClaV1ApiURL: apiURL,
companyRepo: compRepo,
Expand All @@ -78,6 +81,7 @@ func NewService(apiURL string, compRepo company.IRepository, projectRepo Project
companyService: compService,
claGroupService: claGroupService,
docsignPrivateKey: docsignPrivateKey,
userService: userService,
}
}

Expand Down Expand Up @@ -315,13 +319,43 @@ func (s *service) RequestIndividualSignature(ctx context.Context, input *models.
"userID": input.UserID,
}

log.WithFields(f).Debug("Get Access Token for DocuSign")
accessToken, err := s.getAccessToken(ctx)
if err != nil {
log.WithFields(f).WithError(err).Warn("unable to get access token")
/**
1. Ensure this is a valid user
2. Ensure this is a valid project
3. Check for active signature object with this project. If the user has signed the most recent version they should not be able to sign again.
4. Generate signature callback url
5. Get signature return URL
6. Get latest document
7. if the CCLA/ICLA template is missing we wont have a document and return an error
8. Create new signature object
9. Set signature ACL
10. Populate sign url
11. Save signature
**/

// 1. Ensure this is a valid user
log.WithFields(f).Debugf("looking up user by ID: %s", *input.UserID)
user, err := s.userService.GetUser(*input.UserID)
if err != nil || user == nil {
log.WithFields(f).WithError(err).Warnf("unable to lookup user by ID: %s", *input.UserID)
return nil, err
}
log.WithFields(f).Debugf("access token: %s", accessToken)

// 2. Ensure this is a valid project
log.WithFields(f).Debugf("looking up project by ID: %s", *input.ProjectID)
claGroup, err := s.claGroupService.GetCLAGroup(ctx, *input.ProjectID)
if err != nil || claGroup == nil {
log.WithFields(f).WithError(err).Warnf("unable to lookup project by ID: %s", *input.ProjectID)
return nil, err
}

// 3. Check for active signature object with this project. If the user has signed the most recent version they should not be able to sign again.
log.WithFields(f).Debugf("checking for active signature object with this project...")

return nil, nil
}

func (s *service) RequestIndividualSignatureGerrit(ctx context.Context, input *models.IndividualSignatureInput) (*models.IndividualSignatureOutput, error) {
return nil, nil
}

Expand Down

0 comments on commit 0f67b26

Please sign in to comment.