Skip to content

Commit a6fa11b

Browse files
committed
feat: Credential Status API - update vc status
Signed-off-by: Mykhailo Sizov <[email protected]>
1 parent 03e09e9 commit a6fa11b

File tree

20 files changed

+728
-146
lines changed

20 files changed

+728
-146
lines changed

cmd/vc-rest/startcmd/start.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,10 @@ func buildEchoHandler(conf *Configuration, cmd *cobra.Command) (*echo.Echo, erro
275275
verifierv1.RegisterHandlers(e, verifierController)
276276

277277
didConfigSvc := didconfiguration.New(&didconfiguration.Config{
278-
VerifierProfileService: verifierProfileSvc,
279-
IssuerProfileService: issuerProfileSvc,
280-
IssuerCredentialService: issueCredentialSvc,
281-
KmsRegistry: kmsRegistry,
278+
VerifierProfileService: verifierProfileSvc,
279+
IssuerProfileService: issuerProfileSvc,
280+
Crypto: vcCrypto,
281+
KmsRegistry: kmsRegistry,
282282
})
283283

284284
if conf.StartupParameters.devMode {

pkg/doc/vc/crypto/crypto.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,20 @@ type Crypto struct {
150150
documentLoader ld.DocumentLoader
151151
}
152152

153-
// SignCredentialLDP adds verifiable.LinkedDataProofContext to the vc.
154-
func (c *Crypto) SignCredentialLDP(
153+
func (c *Crypto) SignCredential(
154+
signerData *vc.Signer, vc *verifiable.Credential, opts ...SigningOpts) (*verifiable.Credential, error) {
155+
switch signerData.Format {
156+
case vcsverifiable.Jwt:
157+
return c.signCredentialJWT(signerData, vc, opts...)
158+
case vcsverifiable.Ldp:
159+
return c.signCredentialLDP(signerData, vc, opts...)
160+
default:
161+
return nil, fmt.Errorf("unknown signature format %s", signerData.Format)
162+
}
163+
}
164+
165+
// signCredentialLDP adds verifiable.LinkedDataProofContext to the VC.
166+
func (c *Crypto) signCredentialLDP(
155167
signerData *vc.Signer, vc *verifiable.Credential, opts ...SigningOpts) (*verifiable.Credential, error) {
156168
signOpts := &signingOpts{}
157169
// apply opts
@@ -178,8 +190,8 @@ func (c *Crypto) SignCredentialLDP(
178190
return vc, nil
179191
}
180192

181-
// SignCredentialJWT returns vc in JWT format including the signature section.
182-
func (c *Crypto) SignCredentialJWT(
193+
// signCredentialJWT returns vc in JWT format including the signature section.
194+
func (c *Crypto) signCredentialJWT(
183195
signerData *vc.Signer, vc *verifiable.Credential, opts ...SigningOpts) (*verifiable.Credential, error) {
184196
signOpts := &signingOpts{}
185197
// apply opts

pkg/doc/vc/crypto/crypto_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func TestCrypto_SignCredentialLDP(t *testing.T) { //nolint:gocognit
4141
testutil.DocumentLoader(t),
4242
)
4343

44-
signedVC, err := c.SignCredentialLDP(
44+
signedVC, err := c.signCredentialLDP(
4545
getTestSigner(), &verifiable.Credential{ID: "http://example.edu/credentials/1872"})
4646
require.NoError(t, err)
4747
require.Equal(t, 1, len(signedVC.Proofs))
@@ -181,7 +181,7 @@ func TestCrypto_SignCredentialLDP(t *testing.T) { //nolint:gocognit
181181
vcSigner = tc.vcSigner
182182
}
183183

184-
signedVC, err := c.SignCredentialLDP(
184+
signedVC, err := c.signCredentialLDP(
185185
vcSigner, &verifiable.Credential{ID: "http://example.edu/credentials/1872"},
186186
tc.signingOpts...)
187187

@@ -227,7 +227,7 @@ func TestCrypto_SignCredentialLDP(t *testing.T) { //nolint:gocognit
227227
)
228228
p := getTestSigner()
229229
p.Creator = "wrongValue"
230-
signedVC, err := c.SignCredentialLDP(
230+
signedVC, err := c.signCredentialLDP(
231231
p, &verifiable.Credential{ID: "http://example.edu/credentials/1872"})
232232
require.Error(t, err)
233233
require.Contains(t, err.Error(), "verificationMethod value wrongValue should be in did#keyID format")
@@ -239,7 +239,7 @@ func TestCrypto_SignCredentialLDP(t *testing.T) { //nolint:gocognit
239239
&vdrmock.MockVDRegistry{ResolveValue: createDIDDoc("did:trustbloc:abc")},
240240
testutil.DocumentLoader(t),
241241
)
242-
signedVC, err := c.SignCredentialLDP(
242+
signedVC, err := c.signCredentialLDP(
243243
getTestSignerWithCrypto(
244244
&cryptomock.Crypto{SignErr: fmt.Errorf("failed to sign")}),
245245
&verifiable.Credential{ID: "http://example.edu/credentials/1872"})
@@ -254,7 +254,7 @@ func TestCrypto_SignCredentialLDP(t *testing.T) { //nolint:gocognit
254254

255255
p := getTestSigner()
256256

257-
signedVC, err := c.SignCredentialLDP(
257+
signedVC, err := c.signCredentialLDP(
258258
p, &verifiable.Credential{ID: "http://example.edu/credentials/1872"},
259259
WithPurpose("invalid"))
260260
require.Error(t, err)
@@ -268,7 +268,7 @@ func TestCrypto_SignCredentialLDP(t *testing.T) { //nolint:gocognit
268268

269269
p := getTestSigner()
270270

271-
signedVC, err := c.SignCredentialLDP(
271+
signedVC, err := c.signCredentialLDP(
272272
p, &verifiable.Credential{ID: "http://example.edu/credentials/1872"},
273273
WithPurpose(CapabilityInvocation))
274274
require.NoError(t, err)
@@ -281,7 +281,7 @@ func TestCrypto_SignCredentialLDP(t *testing.T) { //nolint:gocognit
281281

282282
p := getTestSigner()
283283

284-
signedVC, err := c.SignCredentialLDP(
284+
signedVC, err := c.signCredentialLDP(
285285
p, &verifiable.Credential{ID: "http://example.edu/credentials/1872"},
286286
WithPurpose(CapabilityInvocation))
287287
require.NoError(t, err)
@@ -296,7 +296,7 @@ func TestCrypto_SignCredentialBBS(t *testing.T) {
296296
testutil.DocumentLoader(t),
297297
)
298298

299-
signedVC, err := c.SignCredentialLDP(
299+
signedVC, err := c.signCredentialLDP(
300300
&vc.Signer{
301301
DID: "did:trustbloc:abc",
302302
SignatureType: "BbsBlsSignature2020",
@@ -683,7 +683,7 @@ func TestCrypto_SignCredentialJWT(t *testing.T) {
683683
vdr: tt.fields.getVDR(),
684684
documentLoader: testutil.DocumentLoader(t),
685685
}
686-
got, err := c.SignCredentialJWT(tt.args.signerData, tt.args.getVC(), tt.args.opts...)
686+
got, err := c.signCredentialJWT(tt.args.signerData, tt.args.getVC(), tt.args.opts...)
687687
if (err != nil) != tt.wantErr {
688688
t.Errorf("SignCredentialJWT() error = %v, wantErr %v", err, tt.wantErr)
689689
return

pkg/doc/vc/signer.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type Signer struct {
2727
Creator string
2828
SignatureType vcsverifiable.SignatureType
2929
KeyType kms.KeyType
30+
Format vcsverifiable.Format // VC format - LDP/JWT.
3031
SignatureRepresentation verifiable.SignatureRepresentation // For LDP only.
3132
KMS keyManager
3233
}

pkg/restapi/v1/issuer/controller.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"context"
1414
"errors"
1515
"fmt"
16+
"net/http"
1617
"strings"
1718
"time"
1819

@@ -69,6 +70,7 @@ type oidc4VCService interface {
6970
type vcStatusManager interface {
7071
GetRevocationListVC(id string) (*verifiable.Credential, error)
7172
GetCredentialStatusURL(issuerProfileURL, issuerProfileID, statusID string) (string, error)
73+
UpdateVCStatus(signer *vc.Signer, profileName, CredentialID, status string) error
7274
}
7375

7476
type Config struct {
@@ -324,5 +326,55 @@ func (c *Controller) GetCredentialsStatus(ctx echo.Context, profileID string, st
324326
// PostCredentialsStatus updates credential status.
325327
// POST /issuer/profiles/{profileID}/credentials/status.
326328
func (c *Controller) PostCredentialsStatus(ctx echo.Context, profileID string) error {
329+
var body UpdateCredentialStatusRequest
330+
331+
if err := util.ReadBody(ctx, &body); err != nil {
332+
return err
333+
}
334+
335+
if err := c.updateCredentialStatus(ctx, &body, profileID); err != nil {
336+
return err
337+
}
338+
339+
return ctx.NoContent(http.StatusOK)
340+
}
341+
342+
func (c *Controller) updateCredentialStatus(ctx echo.Context, body *UpdateCredentialStatusRequest,
343+
profileID string) error {
344+
oidcOrgID, err := util.GetOrgIDFromOIDC(ctx)
345+
if err != nil {
346+
return err
347+
}
348+
349+
profile, err := c.accessOIDCProfile(profileID, oidcOrgID)
350+
if err != nil {
351+
return err
352+
}
353+
354+
keyManager, err := c.kmsRegistry.GetKeyManager(profile.KMSConfig)
355+
if err != nil {
356+
return fmt.Errorf("failed to get kms: %w", err)
357+
}
358+
359+
if body.CredentialStatus.Type != credentialstatus.StatusList2021Entry {
360+
return resterr.NewValidationError(resterr.InvalidValue, "CredentialStatus.Type",
361+
fmt.Errorf("credential status %s not supported", body.CredentialStatus.Type))
362+
}
363+
364+
signer := &vc.Signer{
365+
Format: profile.VCConfig.Format,
366+
DID: profile.SigningDID.DID,
367+
Creator: profile.SigningDID.Creator,
368+
SignatureType: profile.VCConfig.SigningAlgorithm,
369+
KeyType: profile.VCConfig.KeyType,
370+
KMS: keyManager,
371+
SignatureRepresentation: profile.VCConfig.SignatureRepresentation,
372+
}
373+
374+
err = c.vcStatusManager.UpdateVCStatus(signer, profile.Name, body.CredentialID, body.CredentialStatus.Status)
375+
if err != nil {
376+
return resterr.NewSystemError("VCStatusManager", "UpdateVCStatus", err)
377+
}
378+
327379
return nil
328380
}

0 commit comments

Comments
 (0)