github.com/hyperledger/aries-framework-go@v0.3.2/pkg/wallet/invitation.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package wallet
     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  	oobsvc "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/outofband"
    15  	oobv2 "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/outofbandv2"
    16  )
    17  
    18  // rawInvitation can unmarshal either a DIDComm V1 or V2 invitation.
    19  type rawInvitation struct {
    20  	IDv1       string                   `json:"@id"`
    21  	TypeV1     string                   `json:"@type"`
    22  	From       string                   `json:"from,omitempty"`
    23  	Label      string                   `json:"label,omitempty"`
    24  	GoalV1     string                   `json:"goal,omitempty"`
    25  	GoalCodeV1 string                   `json:"goal_code,omitempty"`
    26  	ServicesV1 []interface{}            `json:"services"`
    27  	AcceptV1   []string                 `json:"accept,omitempty"`
    28  	Protocols  []string                 `json:"handshake_protocols,omitempty"`
    29  	RequestsV1 []decorator.Attachment   `json:"request~attach,omitempty"`
    30  	IDv2       string                   `json:"id"`
    31  	TypeV2     string                   `json:"type"`
    32  	Body       oobv2.InvitationBody     `json:"body"`
    33  	RequestsV2 []decorator.AttachmentV2 `json:"attachments,omitempty"`
    34  }
    35  
    36  // GenericInvitation holds either a DIDComm V1 or V2 invitation.
    37  type GenericInvitation struct {
    38  	ID        string                        `json:"id"`
    39  	Type      string                        `json:"type"`
    40  	From      string                        `json:"from,omitempty"`
    41  	Label     string                        `json:"label,omitempty"`
    42  	Goal      string                        `json:"goal,omitempty"`
    43  	GoalCode  string                        `json:"goal_code,omitempty"`
    44  	Services  []interface{}                 `json:"services"`
    45  	Accept    []string                      `json:"accept,omitempty"`
    46  	Protocols []string                      `json:"handshake_protocols,omitempty"`
    47  	Requests  []decorator.GenericAttachment `json:"attachments,omitempty"`
    48  	version   service.Version
    49  }
    50  
    51  // UnmarshalJSON implements json.Unmarshaler interface.
    52  func (gi *GenericInvitation) UnmarshalJSON(data []byte) error {
    53  	raw := rawInvitation{}
    54  
    55  	err := json.Unmarshal(data, &raw)
    56  	if err != nil {
    57  		return err
    58  	}
    59  
    60  	switch raw.version() {
    61  	case service.V1:
    62  		gi.ID = raw.IDv1
    63  		gi.Type = raw.TypeV1
    64  		gi.Label = raw.Label
    65  		gi.Goal = raw.GoalV1
    66  		gi.GoalCode = raw.GoalCodeV1
    67  		gi.Services = raw.ServicesV1
    68  		gi.Accept = raw.AcceptV1
    69  		gi.Protocols = raw.Protocols
    70  		gi.Requests = decorator.V1AttachmentsToGeneric(raw.RequestsV1)
    71  		gi.version = service.V1
    72  	case service.V2:
    73  		gi.ID = raw.IDv2
    74  		gi.Type = raw.TypeV2
    75  		gi.From = raw.From
    76  		gi.Label = raw.Label
    77  		gi.Goal = raw.Body.Goal
    78  		gi.GoalCode = raw.Body.GoalCode
    79  		gi.Services = nil
    80  		gi.Accept = raw.Body.Accept
    81  		gi.Protocols = nil
    82  		gi.Requests = decorator.V2AttachmentsToGeneric(raw.RequestsV2)
    83  		gi.version = service.V2
    84  	}
    85  
    86  	return nil
    87  }
    88  
    89  // MarshalJSON implements json.Marshaler interface.
    90  func (gi *GenericInvitation) MarshalJSON() ([]byte, error) {
    91  	if gi.Version() == service.V2 {
    92  		return json.Marshal(gi.AsV2())
    93  	}
    94  
    95  	return json.Marshal(gi.AsV1())
    96  }
    97  
    98  // Version returns the DIDComm version of this OOB invitation.
    99  func (gi *GenericInvitation) Version() service.Version {
   100  	if gi.version != "" {
   101  		return gi.version
   102  	}
   103  
   104  	if gi.Type == oobv2.InvitationMsgType {
   105  		return service.V2
   106  	}
   107  
   108  	return service.V1
   109  }
   110  
   111  // AsV1 returns this invitation as an OOB V1 invitation.
   112  func (gi *GenericInvitation) AsV1() *oobsvc.Invitation {
   113  	attachments := decorator.GenericAttachmentsToV1(gi.Requests)
   114  
   115  	reqs := make([]*decorator.Attachment, len(attachments))
   116  
   117  	for i := 0; i < len(attachments); i++ {
   118  		reqs[i] = &attachments[i]
   119  	}
   120  
   121  	return &oobsvc.Invitation{
   122  		ID:        gi.ID,
   123  		Type:      gi.Type,
   124  		Label:     gi.Label,
   125  		Goal:      gi.Goal,
   126  		GoalCode:  gi.GoalCode,
   127  		Services:  gi.Services,
   128  		Accept:    gi.Accept,
   129  		Protocols: gi.Protocols,
   130  		Requests:  reqs,
   131  	}
   132  }
   133  
   134  // AsV2 returns this invitation as an OOB V2 invitation.
   135  func (gi *GenericInvitation) AsV2() *oobv2.Invitation {
   136  	attachments := decorator.GenericAttachmentsToV2(gi.Requests)
   137  
   138  	reqs := make([]*decorator.AttachmentV2, len(attachments))
   139  
   140  	for i := 0; i < len(attachments); i++ {
   141  		reqs[i] = &attachments[i]
   142  	}
   143  
   144  	return &oobv2.Invitation{
   145  		ID:    gi.ID,
   146  		Type:  gi.Type,
   147  		From:  gi.From,
   148  		Label: gi.Label,
   149  		Body: &oobv2.InvitationBody{
   150  			Goal:     gi.Goal,
   151  			GoalCode: gi.GoalCode,
   152  			Accept:   gi.Accept,
   153  		},
   154  		Requests: reqs,
   155  	}
   156  }
   157  
   158  func (r *rawInvitation) version() service.Version {
   159  	if r.IDv1 != "" && r.TypeV1 != "" {
   160  		return service.V1
   161  	}
   162  
   163  	if r.IDv2 != "" && r.TypeV2 != "" {
   164  		return service.V2
   165  	}
   166  
   167  	return service.V1
   168  }