github.com/hyperledger/aries-framework-go@v0.3.2/pkg/didcomm/protocol/issuecredential/params.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package issuecredential
     8  
     9  import (
    10  	"encoding/json"
    11  
    12  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
    13  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
    14  )
    15  
    16  // ProposeCredentialParams holds parameters for a credential proposal message.
    17  type ProposeCredentialParams struct {
    18  	Type               string
    19  	ID                 string
    20  	Comment            string
    21  	Attachments        []decorator.GenericAttachment
    22  	CredentialProposal PreviewCredential
    23  	Formats            []Format
    24  	GoalCode           string
    25  	CredentialPreview  interface{}
    26  	InvitationID       string
    27  }
    28  
    29  // AsV2 translates this credential proposal into an issue credential 2.0 proposal message.
    30  func (p *ProposeCredentialParams) AsV2() *ProposeCredentialV2 {
    31  	return &ProposeCredentialV2{
    32  		Type:               p.Type,
    33  		Comment:            p.Comment,
    34  		CredentialProposal: p.CredentialProposal,
    35  		Formats:            p.Formats,
    36  		FiltersAttach:      decorator.GenericAttachmentsToV1(p.Attachments),
    37  		InvitationID:       p.InvitationID,
    38  	}
    39  }
    40  
    41  // AsV3 translates this credential proposal into an issue credential 3.0 proposal message.
    42  func (p *ProposeCredentialParams) AsV3() *ProposeCredentialV3 {
    43  	return &ProposeCredentialV3{
    44  		Type:         p.Type,
    45  		ID:           p.ID,
    46  		InvitationID: p.InvitationID,
    47  		Body: ProposeCredentialV3Body{
    48  			GoalCode:          p.GoalCode,
    49  			Comment:           p.Comment,
    50  			CredentialPreview: p.CredentialPreview,
    51  		},
    52  		Attachments: decorator.GenericAttachmentsToV2(p.Attachments),
    53  	}
    54  }
    55  
    56  // FromV2 initializes this credential proposal from an issue credential 2.0 proposal.
    57  func (p *ProposeCredentialParams) FromV2(v2 *ProposeCredentialV2) {
    58  	p.Type = v2.Type
    59  	p.ID = ""
    60  	p.Comment = v2.Comment
    61  	p.Attachments = decorator.V1AttachmentsToGeneric(v2.FiltersAttach)
    62  
    63  	p.CredentialProposal = v2.CredentialProposal
    64  	p.Formats = v2.Formats
    65  	p.InvitationID = v2.InvitationID
    66  
    67  	p.GoalCode = ""
    68  	p.CredentialPreview = nil
    69  }
    70  
    71  // FromV3 initializes this credential proposal from an issue credential 3.0 proposal.
    72  func (p *ProposeCredentialParams) FromV3(v3 *ProposeCredentialV3) {
    73  	p.Type = v3.Type
    74  	p.ID = v3.ID
    75  	p.Comment = v3.Body.Comment
    76  	p.Attachments = decorator.V2AttachmentsToGeneric(v3.Attachments)
    77  
    78  	p.CredentialProposal = PreviewCredential{}
    79  	p.Formats = nil
    80  
    81  	p.GoalCode = v3.Body.GoalCode
    82  	p.CredentialPreview = v3.Body.CredentialPreview
    83  	p.InvitationID = v3.InvitationID
    84  }
    85  
    86  // UnmarshalJSON implements json.Unmarshaler.
    87  func (p *ProposeCredentialParams) UnmarshalJSON(b []byte) error {
    88  	raw := rawPropose{}
    89  
    90  	err := json.Unmarshal(b, &raw)
    91  	if err != nil {
    92  		return err
    93  	}
    94  
    95  	if raw.isV3() {
    96  		p.FromV3(&raw.ProposeCredentialV3)
    97  	} else {
    98  		p.FromV2(&raw.ProposeCredentialV2)
    99  	}
   100  
   101  	return nil
   102  }
   103  
   104  // FromDIDCommMsgMap implements service.MsgMapDecoder.
   105  func (p *ProposeCredentialParams) FromDIDCommMsgMap(msgMap service.DIDCommMsgMap) error {
   106  	isV2, _ := service.IsDIDCommV2(&msgMap) // nolint:errcheck
   107  	if isV2 {
   108  		proposeV3 := &ProposeCredentialV3{}
   109  
   110  		err := msgMap.Decode(proposeV3)
   111  		if err != nil {
   112  			return err
   113  		}
   114  
   115  		p.FromV3(proposeV3)
   116  	} else {
   117  		proposeV2 := &ProposeCredentialV2{}
   118  
   119  		err := msgMap.Decode(proposeV2)
   120  		if err != nil {
   121  			return err
   122  		}
   123  
   124  		p.FromV2(proposeV2)
   125  	}
   126  
   127  	return nil
   128  }
   129  
   130  type rawPropose struct {
   131  	ProposeCredentialV2
   132  	ProposeCredentialV3
   133  }
   134  
   135  func (p *ProposeCredentialV2) notEmpty() bool {
   136  	return p.Type != "" ||
   137  		p.Comment != "" ||
   138  		p.CredentialProposal.Type != "" ||
   139  		len(p.CredentialProposal.Attributes) != 0 ||
   140  		len(p.Formats) != 0 ||
   141  		len(p.FiltersAttach) != 0
   142  }
   143  
   144  func (p *ProposeCredentialV3) notEmpty() bool {
   145  	return p.ID != "" ||
   146  		p.Type != "" ||
   147  		p.Body.GoalCode != "" ||
   148  		p.Body.Comment != "" ||
   149  		p.Body.CredentialPreview != nil ||
   150  		len(p.Attachments) != 0
   151  }
   152  
   153  func (r *rawPropose) isV3() bool {
   154  	if r.ProposeCredentialV2.notEmpty() {
   155  		return false
   156  	}
   157  
   158  	if r.ProposeCredentialV3.notEmpty() {
   159  		return true
   160  	}
   161  
   162  	return false
   163  }
   164  
   165  // OfferCredentialParams holds parameters for a credential offer message.
   166  type OfferCredentialParams struct {
   167  	Type              string
   168  	ID                string
   169  	Comment           string
   170  	Attachments       []decorator.GenericAttachment
   171  	Formats           []Format
   172  	GoalCode          string
   173  	ReplacementID     string
   174  	CredentialPreview interface{}
   175  }
   176  
   177  // AsV2 translates this credential offer into an issue credential 2.0 offer message.
   178  func (p *OfferCredentialParams) AsV2() *OfferCredentialV2 {
   179  	preview, ok := p.CredentialPreview.(PreviewCredential)
   180  	if !ok {
   181  		preview = PreviewCredential{}
   182  	}
   183  
   184  	return &OfferCredentialV2{
   185  		Type:              p.Type,
   186  		Comment:           p.Comment,
   187  		CredentialPreview: preview,
   188  		Formats:           p.Formats,
   189  		OffersAttach:      decorator.GenericAttachmentsToV1(p.Attachments),
   190  	}
   191  }
   192  
   193  // AsV3 translates this credential offer into an issue credential 3.0 offer message.
   194  func (p *OfferCredentialParams) AsV3() *OfferCredentialV3 {
   195  	return &OfferCredentialV3{
   196  		Type: p.Type,
   197  		ID:   p.ID,
   198  		Body: OfferCredentialV3Body{
   199  			GoalCode:          p.GoalCode,
   200  			Comment:           p.Comment,
   201  			ReplacementID:     p.ReplacementID,
   202  			CredentialPreview: p.CredentialPreview,
   203  		},
   204  		Attachments: decorator.GenericAttachmentsToV2(p.Attachments),
   205  	}
   206  }
   207  
   208  // FromV2 initializes this credential offer from an issue credential 2.0 offer message.
   209  func (p *OfferCredentialParams) FromV2(v2 *OfferCredentialV2) {
   210  	p.Type = v2.Type
   211  	p.ID = ""
   212  	p.Comment = v2.Comment
   213  
   214  	p.Attachments = decorator.V1AttachmentsToGeneric(v2.OffersAttach)
   215  	p.CredentialPreview = v2.CredentialPreview
   216  	p.Formats = v2.Formats
   217  
   218  	p.GoalCode = ""
   219  	p.ReplacementID = ""
   220  }
   221  
   222  // FromV3 initializes this credential offer from an issue credential 3.0 offer message.
   223  func (p *OfferCredentialParams) FromV3(v3 *OfferCredentialV3) {
   224  	p.Type = v3.Type
   225  	p.ID = v3.ID
   226  	p.Comment = v3.Body.Comment
   227  
   228  	p.Attachments = decorator.V2AttachmentsToGeneric(v3.Attachments)
   229  	p.CredentialPreview = v3.Body.CredentialPreview
   230  	p.Formats = nil
   231  
   232  	p.GoalCode = v3.Body.GoalCode
   233  	p.ReplacementID = v3.Body.ReplacementID
   234  }
   235  
   236  // UnmarshalJSON implements json.Unmarshaler.
   237  func (p *OfferCredentialParams) UnmarshalJSON(b []byte) error {
   238  	raw := rawOffer{}
   239  
   240  	err := json.Unmarshal(b, &raw)
   241  	if err != nil {
   242  		return err
   243  	}
   244  
   245  	if raw.isV3() {
   246  		p.FromV3(&raw.OfferCredentialV3)
   247  	} else {
   248  		p.FromV2(&raw.OfferCredentialV2)
   249  	}
   250  
   251  	return nil
   252  }
   253  
   254  // FromDIDCommMsgMap implements service.MsgMapDecoder.
   255  func (p *OfferCredentialParams) FromDIDCommMsgMap(msgMap service.DIDCommMsgMap) error {
   256  	isV2, _ := service.IsDIDCommV2(&msgMap) // nolint:errcheck
   257  	if isV2 {
   258  		msgV3 := &OfferCredentialV3{}
   259  
   260  		err := msgMap.Decode(msgV3)
   261  		if err != nil {
   262  			return err
   263  		}
   264  
   265  		p.FromV3(msgV3)
   266  	} else {
   267  		msgV2 := &OfferCredentialV2{}
   268  
   269  		err := msgMap.Decode(msgV2)
   270  		if err != nil {
   271  			return err
   272  		}
   273  
   274  		p.FromV2(msgV2)
   275  	}
   276  
   277  	return nil
   278  }
   279  
   280  type rawOffer struct {
   281  	OfferCredentialV2
   282  	OfferCredentialV3
   283  }
   284  
   285  func (o *OfferCredentialV2) notEmpty() bool {
   286  	return o.Type != "" ||
   287  		o.Comment != "" ||
   288  		o.CredentialPreview.Type != "" ||
   289  		len(o.Formats) != 0 ||
   290  		len(o.OffersAttach) != 0 ||
   291  		len(o.CredentialPreview.Attributes) != 0
   292  }
   293  
   294  func (o *OfferCredentialV3) notEmpty() bool {
   295  	return o.ID != "" ||
   296  		o.Type != "" ||
   297  		o.Body.Comment != "" ||
   298  		o.Body.GoalCode != "" ||
   299  		o.Body.ReplacementID != "" ||
   300  		o.Body.CredentialPreview != nil ||
   301  		len(o.Attachments) != 0
   302  }
   303  
   304  func (r *rawOffer) isV3() bool {
   305  	if r.OfferCredentialV2.notEmpty() {
   306  		return false
   307  	}
   308  
   309  	if r.OfferCredentialV3.notEmpty() {
   310  		return true
   311  	}
   312  
   313  	return false
   314  }
   315  
   316  // RequestCredentialParams holds parameters for a credential request message.
   317  type RequestCredentialParams struct {
   318  	ID          string
   319  	Type        string
   320  	Comment     string
   321  	Formats     []Format
   322  	GoalCode    string
   323  	Attachments []decorator.GenericAttachment
   324  }
   325  
   326  // AsV2 translates this credential request into an issue credential 2.0 request message.
   327  func (p *RequestCredentialParams) AsV2() *RequestCredentialV2 {
   328  	return &RequestCredentialV2{
   329  		Type:           p.Type,
   330  		Comment:        p.Comment,
   331  		Formats:        p.Formats,
   332  		RequestsAttach: decorator.GenericAttachmentsToV1(p.Attachments),
   333  	}
   334  }
   335  
   336  // AsV3 translates this credential request into an issue credential 3.0 request message.
   337  func (p *RequestCredentialParams) AsV3() *RequestCredentialV3 {
   338  	return &RequestCredentialV3{
   339  		ID:   p.ID,
   340  		Type: p.Type,
   341  		Body: RequestCredentialV3Body{
   342  			Comment:  p.Comment,
   343  			GoalCode: p.GoalCode,
   344  		},
   345  		Attachments: decorator.GenericAttachmentsToV2(p.Attachments),
   346  	}
   347  }
   348  
   349  // FromV2 initializes this credential request from an issue credential 2.0 request message.
   350  func (p *RequestCredentialParams) FromV2(v2 *RequestCredentialV2) {
   351  	p.ID = ""
   352  	p.Type = v2.Type
   353  	p.Comment = v2.Comment
   354  	p.Formats = v2.Formats
   355  	p.GoalCode = ""
   356  	p.Attachments = decorator.V1AttachmentsToGeneric(v2.RequestsAttach)
   357  }
   358  
   359  // FromV3 initialized this credential request from an issue credential 3.0 request message.
   360  func (p *RequestCredentialParams) FromV3(v3 *RequestCredentialV3) {
   361  	p.ID = v3.ID
   362  	p.Type = v3.Type
   363  	p.Comment = v3.Body.Comment
   364  	p.Formats = nil
   365  	p.GoalCode = v3.Body.GoalCode
   366  	p.Attachments = decorator.V2AttachmentsToGeneric(v3.Attachments)
   367  }
   368  
   369  type rawRequest struct {
   370  	RequestCredentialV2
   371  	RequestCredentialV3
   372  }
   373  
   374  func (r *RequestCredentialV2) notEmpty() bool {
   375  	return r.Type != "" ||
   376  		r.Comment != "" ||
   377  		len(r.Formats) != 0 ||
   378  		len(r.RequestsAttach) != 0
   379  }
   380  
   381  func (r *RequestCredentialV3) notEmpty() bool {
   382  	return r.ID != "" ||
   383  		r.Type != "" ||
   384  		r.Body.GoalCode != "" ||
   385  		r.Body.Comment != "" ||
   386  		len(r.Attachments) != 0
   387  }
   388  
   389  func (r *rawRequest) isV3() bool {
   390  	if r.RequestCredentialV2.notEmpty() {
   391  		return false
   392  	}
   393  
   394  	if r.RequestCredentialV3.notEmpty() {
   395  		return true
   396  	}
   397  
   398  	return false
   399  }
   400  
   401  // UnmarshalJSON implements json.Unmarshaler.
   402  func (p *RequestCredentialParams) UnmarshalJSON(b []byte) error {
   403  	raw := rawRequest{}
   404  
   405  	err := json.Unmarshal(b, &raw)
   406  	if err != nil {
   407  		return err
   408  	}
   409  
   410  	if raw.isV3() {
   411  		p.FromV3(&raw.RequestCredentialV3)
   412  	} else {
   413  		p.FromV2(&raw.RequestCredentialV2)
   414  	}
   415  
   416  	return nil
   417  }
   418  
   419  // FromDIDCommMsgMap implements service.MsgMapDecoder.
   420  func (p *RequestCredentialParams) FromDIDCommMsgMap(msgMap service.DIDCommMsgMap) error {
   421  	isV2, _ := service.IsDIDCommV2(&msgMap) // nolint:errcheck
   422  	if isV2 {
   423  		msgV3 := &RequestCredentialV3{}
   424  
   425  		err := msgMap.Decode(msgV3)
   426  		if err != nil {
   427  			return err
   428  		}
   429  
   430  		p.FromV3(msgV3)
   431  	} else {
   432  		msgV2 := &RequestCredentialV2{}
   433  
   434  		err := msgMap.Decode(msgV2)
   435  		if err != nil {
   436  			return err
   437  		}
   438  
   439  		p.FromV2(msgV2)
   440  	}
   441  
   442  	return nil
   443  }
   444  
   445  // IssueCredentialParams holds parameters for a credential issuance message.
   446  type IssueCredentialParams struct { // nolint: golint
   447  	Type          string
   448  	ID            string
   449  	Comment       string
   450  	Formats       []Format
   451  	Attachments   []decorator.GenericAttachment
   452  	GoalCode      string
   453  	ReplacementID string
   454  	WebRedirect   *decorator.WebRedirect
   455  }
   456  
   457  // AsV2 translates this credential issuance into an issue credential 2.0 issuance message.
   458  func (p *IssueCredentialParams) AsV2() *IssueCredentialV2 {
   459  	return &IssueCredentialV2{
   460  		Type:              p.Type,
   461  		Comment:           p.Comment,
   462  		Formats:           p.Formats,
   463  		CredentialsAttach: decorator.GenericAttachmentsToV1(p.Attachments),
   464  		WebRedirect:       p.WebRedirect,
   465  	}
   466  }
   467  
   468  // AsV3 translates this credential issuance into an issue credential 3.0 issuance message.
   469  func (p *IssueCredentialParams) AsV3() *IssueCredentialV3 {
   470  	return &IssueCredentialV3{
   471  		ID:   p.ID,
   472  		Type: p.Type,
   473  		Body: IssueCredentialV3Body{
   474  			GoalCode:      p.GoalCode,
   475  			ReplacementID: p.ReplacementID,
   476  			Comment:       p.Comment,
   477  		},
   478  		Attachments: decorator.GenericAttachmentsToV2(p.Attachments),
   479  		WebRedirect: p.WebRedirect,
   480  	}
   481  }
   482  
   483  // FromV2 initializes this credential issuance from an issue credential 2.0 issuance message.
   484  func (p *IssueCredentialParams) FromV2(v2 *IssueCredentialV2) {
   485  	p.ID = ""
   486  	p.Type = v2.Type
   487  	p.Comment = v2.Comment
   488  	p.Formats = v2.Formats
   489  	p.GoalCode = ""
   490  	p.ReplacementID = ""
   491  	p.Attachments = decorator.V1AttachmentsToGeneric(v2.CredentialsAttach)
   492  	p.WebRedirect = v2.WebRedirect
   493  }
   494  
   495  // FromV3 initialized this credential issuance from an issue credential 3.0 issuance message.
   496  func (p *IssueCredentialParams) FromV3(v3 *IssueCredentialV3) {
   497  	p.ID = v3.ID
   498  	p.Type = v3.Type
   499  	p.Comment = v3.Body.Comment
   500  	p.Formats = nil
   501  	p.GoalCode = v3.Body.GoalCode
   502  	p.ReplacementID = v3.Body.ReplacementID
   503  	p.Attachments = decorator.V2AttachmentsToGeneric(v3.Attachments)
   504  	p.WebRedirect = v3.WebRedirect
   505  }
   506  
   507  type rawIssuance struct {
   508  	IssueCredentialV2
   509  	IssueCredentialV3
   510  }
   511  
   512  func (o *IssueCredentialV2) notEmpty() bool {
   513  	return o.Type != "" ||
   514  		o.Comment != "" ||
   515  		len(o.Formats) != 0 ||
   516  		len(o.CredentialsAttach) != 0
   517  }
   518  
   519  func (o *IssueCredentialV3) notEmpty() bool {
   520  	return o.ID != "" ||
   521  		o.Type != "" ||
   522  		o.Body.Comment != "" ||
   523  		o.Body.GoalCode != "" ||
   524  		o.Body.ReplacementID != "" ||
   525  		len(o.Attachments) != 0
   526  }
   527  
   528  func (r *rawIssuance) isV3() bool {
   529  	if r.IssueCredentialV2.notEmpty() {
   530  		return false
   531  	}
   532  
   533  	if r.IssueCredentialV3.notEmpty() {
   534  		return true
   535  	}
   536  
   537  	return false
   538  }
   539  
   540  // UnmarshalJSON implements json.Unmarshaler.
   541  func (p *IssueCredentialParams) UnmarshalJSON(b []byte) error {
   542  	raw := rawIssuance{}
   543  
   544  	err := json.Unmarshal(b, &raw)
   545  	if err != nil {
   546  		return err
   547  	}
   548  
   549  	if raw.isV3() {
   550  		p.FromV3(&raw.IssueCredentialV3)
   551  	} else {
   552  		p.FromV2(&raw.IssueCredentialV2)
   553  	}
   554  
   555  	return nil
   556  }
   557  
   558  // FromDIDCommMsgMap implements service.MsgMapDecoder.
   559  func (p *IssueCredentialParams) FromDIDCommMsgMap(msgMap service.DIDCommMsgMap) error {
   560  	isV2, _ := service.IsDIDCommV2(&msgMap) // nolint:errcheck
   561  	if isV2 {
   562  		msgV3 := &IssueCredentialV3{}
   563  
   564  		err := msgMap.Decode(msgV3)
   565  		if err != nil {
   566  			return err
   567  		}
   568  
   569  		p.FromV3(msgV3)
   570  	} else {
   571  		msgV2 := &IssueCredentialV2{}
   572  
   573  		err := msgMap.Decode(msgV2)
   574  		if err != nil {
   575  			return err
   576  		}
   577  
   578  		p.FromV2(msgV2)
   579  	}
   580  
   581  	return nil
   582  }