Skip to content

Commit

Permalink
feat: more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
skynet2 committed Aug 13, 2024
1 parent 24f9989 commit d00bcf3
Show file tree
Hide file tree
Showing 7 changed files with 360 additions and 11 deletions.
2 changes: 2 additions & 0 deletions cmd/vc-rest/startcmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,8 @@ func buildEchoHandler(
PresentationVerifier: verifyPresentationSvc,
CredentialIssuer: prepareCredentialSvc,
IssueCredentialService: issueCredentialSvc,
EventPublisher: eventSvc,
EventTopic: conf.StartupParameters.issuerEventTopic,
})

oidc4civ1.RegisterHandlers(e, oidc4civ1.NewController(&oidc4civ1.Config{
Expand Down
6 changes: 3 additions & 3 deletions pkg/event/spi/spi.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ const (

CredentialStatusStatusUpdated EventType = "issuer.credential-status-updated.v1" //nolint:gosec

CredentialRefreshInitiated EventType = "issuer.credential-refresh-initiated.v1"
CredentialRefreshSuccessful EventType = "issuer.credential-refresh-successful.v1"
CredentialRefreshFailed EventType = "issuer.credential-refresh-failed.v1"
CredentialRefreshInitiated EventType = "issuer.credential-refresh-initiated.v1" //nolint
CredentialRefreshSuccessful EventType = "issuer.credential-refresh-successful.v1" //nolint
CredentialRefreshFailed EventType = "issuer.credential-refresh-failed.v1" //nolint
)

// Payload defines payload.
Expand Down
5 changes: 5 additions & 0 deletions pkg/service/refresh/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/trustbloc/vc-go/verifiable"

"github.com/trustbloc/vcs/pkg/dataprotect"
"github.com/trustbloc/vcs/pkg/event/spi"
profileapi "github.com/trustbloc/vcs/pkg/profile"
"github.com/trustbloc/vcs/pkg/service/issuecredential"
"github.com/trustbloc/vcs/pkg/service/verifypresentation"
Expand Down Expand Up @@ -68,3 +69,7 @@ type IssueCredService interface {
opts ...issuecredential.Opts,
) (*verifiable.Credential, error)
}

type EventPublisher interface {
Publish(ctx context.Context, topic string, messages ...*spi.Event) error
}
121 changes: 115 additions & 6 deletions pkg/service/refresh/refresh.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,30 @@ package refresh

import (
"context"
"encoding/json"
"errors"
"fmt"

"github.com/davecgh/go-spew/spew"
"github.com/google/uuid"
"github.com/samber/lo"
"github.com/trustbloc/logutil-go/pkg/log"
"github.com/trustbloc/vc-go/presexch"
"github.com/trustbloc/vc-go/verifiable"

"github.com/trustbloc/vcs/internal/claims"
"github.com/trustbloc/vcs/internal/logfields"
"github.com/trustbloc/vcs/pkg/event/spi"
"github.com/trustbloc/vcs/pkg/profile"
"github.com/trustbloc/vcs/pkg/service/issuecredential"
)

var logger = log.New("refresh-service")

const (
ServiceComponent = "RefreshService"
)

type Config struct {
VcsAPIURL string
TxStore transactionStore1
Expand All @@ -30,6 +40,8 @@ type Config struct {
PresentationVerifier presentationVerifier
CredentialIssuer credentialIssuer
IssueCredentialService IssueCredService
EventPublisher EventPublisher
EventTopic string
}

type Service struct {
Expand All @@ -42,11 +54,69 @@ func NewRefreshService(cfg *Config) *Service {
}
}

func (s *Service) getEvent(
eventType spi.EventType,
payloadData *Event,
txID string,
) (*spi.Event, error) {
payload, err := json.Marshal(payloadData)
if err != nil {
return nil, err

Check warning on line 64 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L64

Added line #L64 was not covered by tests
}

event := spi.NewEventWithPayload(uuid.NewString(), "RefreshService", eventType, payload)
event.TransactionID = txID

return event, nil
}

func (s *Service) publishEvent(
ctx context.Context,
eventType spi.EventType,
payloadData *Event,
txID string,
) error {
event, err := s.getEvent(eventType, payloadData, txID)
if err != nil {
return err

Check warning on line 81 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L81

Added line #L81 was not covered by tests
}

return s.cfg.EventPublisher.Publish(ctx, s.cfg.EventTopic, event)
}

func (s *Service) tryPublish(
ctx context.Context,
eventType spi.EventType,
payloadData *Event,
txID string,
errSource error,
) {
if errSource != nil {
payloadData.Error = errSource.Error()
payloadData.ErrorComponent = ServiceComponent
}

if err := s.publishEvent(ctx, eventType, payloadData, txID); err != nil {
logger.Errorc(ctx, fmt.Sprintf("failed to publish event: %s", err),
logfields.WithProfileID(payloadData.ProfileID),
logfields.WithTransactionID(txID),
)
}
}

//nolint:funlen
func (s *Service) GetRefreshedCredential(
ctx context.Context,
presentation *verifiable.Presentation,
issuer profile.Issuer,
) (*verifiable.Credential, error) {
resultEvent := &Event{
WebHook: issuer.WebHook,
ProfileID: issuer.ID,
ProfileVersion: issuer.Version,
OrgID: issuer.OrganizationID,
}

verifyResult, _, err := s.cfg.PresentationVerifier.VerifyPresentation(ctx, presentation, nil, &profile.Verifier{
Checks: &profile.VerificationChecks{
Presentation: &profile.PresentationChecks{
Expand All @@ -61,46 +131,69 @@ func (s *Service) GetRefreshedCredential(
},
})
if err != nil {
s.tryPublish(ctx, spi.CredentialRefreshFailed, resultEvent, "", err)

Check warning on line 134 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L134

Added line #L134 was not covered by tests

return nil, err

Check warning on line 136 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L136

Added line #L136 was not covered by tests
}

if len(verifyResult) > 0 {
return nil, fmt.Errorf("presentation verification failed. %s", spew.Sdump(verifyResult))
err = fmt.Errorf("presentation verification failed. %s", spew.Sdump(verifyResult))
s.tryPublish(ctx, spi.CredentialRefreshFailed, resultEvent, "", err)

Check warning on line 141 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L140-L141

Added lines #L140 - L141 were not covered by tests

return nil, err

Check warning on line 143 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L143

Added line #L143 was not covered by tests
}

if len(presentation.Credentials()) == 0 {
return nil, errors.New("no credentials in presentation")
err = errors.New("no credentials in presentation")
s.tryPublish(ctx, spi.CredentialRefreshFailed, resultEvent, "", err)

Check warning on line 148 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L147-L148

Added lines #L147 - L148 were not covered by tests

return nil, err

Check warning on line 150 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L150

Added line #L150 was not covered by tests
}
cred := presentation.Credentials()[0]

template, err := s.findCredentialTemplate(cred.Contents().Types, issuer)
if err != nil {
s.tryPublish(ctx, spi.CredentialRefreshFailed, resultEvent, "", err)

Check warning on line 156 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L156

Added line #L156 was not covered by tests

return nil, err

Check warning on line 158 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L158

Added line #L158 was not covered by tests
}

config, configID := s.findCredConfigSupported(issuer, template.Type)
if config == nil {
return nil, fmt.Errorf("no credential configuration found for credential type %v", template.Type)
err = fmt.Errorf("no credential configuration found for credential type %v", template.Type)
s.tryPublish(ctx, spi.CredentialRefreshFailed, resultEvent, "", err)

Check warning on line 164 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L163-L164

Added lines #L163 - L164 were not covered by tests

return nil, err

Check warning on line 166 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L166

Added line #L166 was not covered by tests
}

tx, err := s.cfg.TxStore.FindByOpState(ctx, s.getOpState(cred.Contents().ID, issuer.ID))
if err != nil {
s.tryPublish(ctx, spi.CredentialRefreshFailed, resultEvent, "", err)

Check warning on line 171 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L171

Added line #L171 was not covered by tests

return nil, err

Check warning on line 173 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L173

Added line #L173 was not covered by tests
}

tempClaimData, err := s.cfg.ClaimsStore.GetAndDelete(ctx, tx.CredentialConfiguration[0].ClaimDataID)
if err != nil {
s.tryPublish(ctx, spi.CredentialRefreshFailed, resultEvent, "", err)

Check warning on line 178 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L178

Added line #L178 was not covered by tests

return nil, err

Check warning on line 180 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L180

Added line #L180 was not covered by tests
}

decryptedClaims, decryptErr := claims.DecryptClaims(ctx, tempClaimData, s.cfg.DataProtector)
if decryptErr != nil {
return nil, fmt.Errorf("decrypt claims: %w", decryptErr)
decryptErr = fmt.Errorf("decrypt claims: %w", decryptErr)
s.tryPublish(ctx, spi.CredentialRefreshFailed, resultEvent, "", decryptErr)

Check warning on line 186 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L185-L186

Added lines #L185 - L186 were not covered by tests

return nil, decryptErr

Check warning on line 188 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L188

Added line #L188 was not covered by tests
}

subj := cred.Contents().Subject
if len(subj) == 0 {
return nil, errors.New("no subject in credential")
err = errors.New("no subject in credential")
s.tryPublish(ctx, spi.CredentialRefreshFailed, resultEvent, "", err)

Check warning on line 194 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L193-L194

Added lines #L193 - L194 were not covered by tests

return nil, err

Check warning on line 196 in pkg/service/refresh/refresh.go

View check run for this annotation

Codecov / codecov/patch

pkg/service/refresh/refresh.go#L196

Added line #L196 was not covered by tests
}

credConfig := tx.CredentialConfiguration[0]
Expand All @@ -125,14 +218,23 @@ func (s *Service) GetRefreshedCredential(
RefreshServiceEnabled: refreshServiceEnabled,
})
if err != nil {
return nil, errors.Join(errors.New("failed to prepare credential"), err)
err = errors.Join(errors.New("failed to prepare credential"), err)
s.tryPublish(ctx, spi.CredentialRefreshFailed, resultEvent, "", err)

return nil, err
}

updatedCred, err = s.cfg.IssueCredentialService.IssueCredential(ctx, updatedCred, &issuer,
issuecredential.WithTransactionID(string(tx.ID)),
issuecredential.WithSkipIDPrefix(),
)

if err != nil {
s.tryPublish(ctx, spi.CredentialRefreshFailed, resultEvent, string(tx.ID), err)
} else {
s.tryPublish(ctx, spi.CredentialRefreshSuccessful, resultEvent, string(tx.ID), nil)
}

return updatedCred, err
}

Expand Down Expand Up @@ -195,6 +297,13 @@ func (s *Service) RequestRefreshStatus(

purpose := "The verifier needs to see your existing credentials to verify your identity"

s.tryPublish(ctx, spi.CredentialRefreshInitiated, &Event{
WebHook: issuer.WebHook,
ProfileID: issuer.ID,
ProfileVersion: issuer.Version,
OrgID: issuer.OrganizationID,
}, string(tx.ID), nil)

return &GetRefreshStateResponse{
RefreshServiceType: ServiceType{
Type: "VerifiableCredentialRefreshService2021",
Expand Down
Loading

0 comments on commit d00bcf3

Please sign in to comment.