Skip to content

Commit

Permalink
Merge pull request #1694 from skynet2/compose-improvements
Browse files Browse the repository at this point in the history
feat: compose issuer
  • Loading branch information
fqutishat authored Apr 10, 2024
2 parents 47bbef6 + 808efa3 commit 5faac8c
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 2 deletions.
19 changes: 17 additions & 2 deletions pkg/service/oidc4ci/composer.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"text/template"

"github.com/google/uuid"
util "github.com/trustbloc/did-go/doc/util/time"
"github.com/trustbloc/vc-go/verifiable"
)

Expand All @@ -34,7 +35,10 @@ func (c *CredentialComposer) Compose(
}

if idTemplate := txCredentialConfiguration.CredentialComposeConfiguration.IDTemplate; idTemplate != "" {
id, err := c.renderRaw(idTemplate, c.baseParams(tx))
params := c.baseParams(tx)
params["CredentialID"] = credential.Contents().ID

id, err := c.renderRaw(idTemplate, params)
if err != nil {
return nil, err
}
Expand All @@ -43,7 +47,14 @@ func (c *CredentialComposer) Compose(
}

if txCredentialConfiguration.CredentialComposeConfiguration.OverrideIssuer {
credential = credential.WithModifiedIssuer(&verifiable.Issuer{ID: tx.DID})
issuer := credential.Contents().Issuer
if issuer == nil {
issuer = &verifiable.Issuer{}
}

issuer.ID = tx.DID

credential = credential.WithModifiedIssuer(issuer)
}

if txCredentialConfiguration.CredentialComposeConfiguration.OverrideSubjectDID {
Expand All @@ -57,6 +68,10 @@ func (c *CredentialComposer) Compose(
credential = credential.WithModifiedSubject(newSubjects)
}

if credential.Contents().Expired == nil && txCredentialConfiguration.CredentialExpiresAt != nil {
credential.SetCustomField("expirationDate", util.NewTime(*txCredentialConfiguration.CredentialExpiresAt))
}

return credential, nil
}

Expand Down
70 changes: 70 additions & 0 deletions pkg/service/oidc4ci/composer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ package oidc4ci_test
import (
"context"
"testing"
"time"

"github.com/samber/lo"
"github.com/stretchr/testify/assert"
util "github.com/trustbloc/did-go/doc/util/time"
"github.com/trustbloc/vc-go/verifiable"

"github.com/trustbloc/vcs/pkg/service/oidc4ci"
Expand All @@ -15,10 +18,16 @@ func TestComposer(t *testing.T) {
srv := oidc4ci.NewCredentialComposer()

cred, err := verifiable.CreateCredential(verifiable.CredentialContents{
Types: []string{"VerifiableCredential"},
Context: []string{
"https://www.w3.org/2018/credentials/v1",
},
Subject: []verifiable.Subject{{ID: "xxx:yyy"}},
}, verifiable.CustomFields{})
assert.NoError(t, err)

expectedExpiration := time.Now().UTC()

resp, err := srv.Compose(
context.TODO(),
cred,
Expand All @@ -34,6 +43,7 @@ func TestComposer(t *testing.T) {
OverrideIssuer: true,
OverrideSubjectDID: true,
},
CredentialExpiresAt: &expectedExpiration,
},
&oidc4ci.PrepareCredentialRequest{
DID: "some-awesome-did",
Expand All @@ -43,9 +53,69 @@ func TestComposer(t *testing.T) {
assert.NoError(t, err)
assert.NotNil(t, resp)

credJSON, err := resp.MarshalAsJSONLD()
assert.NoError(t, err)

parsedCred, err := verifiable.ParseCredential(credJSON,
verifiable.WithCredDisableValidation(),
verifiable.WithDisabledProofCheck(),
)
assert.NoError(t, err)

assert.EqualValues(t, "hardcoded:some-awesome-id:suffix", resp.Contents().ID)
assert.EqualValues(t, "did:example:123", resp.Contents().Issuer.ID)
assert.EqualValues(t, "some-awesome-did", resp.Contents().Subject[0].ID)
assert.EqualValues(t, expectedExpiration, parsedCred.Contents().Expired.Time)
})

t.Run("success with prev-id", func(t *testing.T) {
srv := oidc4ci.NewCredentialComposer()

cred, err := verifiable.CreateCredential(verifiable.CredentialContents{
ID: "some-id",
Expired: util.NewTime(time.Now()),
Issuer: &verifiable.Issuer{
ID: "did:example:123",
CustomFields: map[string]interface{}{
"key": "value",
"name": "issuer",
},
},
Subject: []verifiable.Subject{{ID: "xxx:yyy"}},
}, verifiable.CustomFields{})
assert.NoError(t, err)

resp, err := srv.Compose(
context.TODO(),
cred,
&oidc4ci.Transaction{
ID: "some-awesome-id",
TransactionData: oidc4ci.TransactionData{
DID: "did:example:123",
},
},
&oidc4ci.TxCredentialConfiguration{
CredentialComposeConfiguration: &oidc4ci.CredentialComposeConfiguration{
IDTemplate: "{{.CredentialID}}:suffix",
OverrideIssuer: true,
OverrideSubjectDID: true,
},
CredentialExpiresAt: lo.ToPtr(time.Now()),
},
&oidc4ci.PrepareCredentialRequest{
DID: "some-awesome-did",
},
)

assert.NoError(t, err)
assert.NotNil(t, resp)

assert.EqualValues(t, "some-id:suffix", resp.Contents().ID)
assert.EqualValues(t, "did:example:123", resp.Contents().Issuer.ID)
assert.EqualValues(t, "value", resp.Contents().Issuer.CustomFields["key"])
assert.EqualValues(t, "issuer", resp.Contents().Issuer.CustomFields["name"])

assert.EqualValues(t, "some-awesome-did", resp.Contents().Subject[0].ID)
})

t.Run("invalid template", func(t *testing.T) {
Expand Down

0 comments on commit 5faac8c

Please sign in to comment.