From 2dff0266368cd86fb89d1fdd3acb54eeb0f620f8 Mon Sep 17 00:00:00 2001
From: Rolson Quadras <rolson.quadras@securekey.com>
Date: Wed, 11 Dec 2019 16:35:21 -0500
Subject: [PATCH] feat: Route Coordination - Structure for Grant and  Keylist
 Update message types

- Implement [Route Grant](https://github.com/hyperledger/aries-rfcs/tree/master/features/0211-route-coordination#route-grant) handler
- Implement [Route Keylist Update Response](https://github.com/hyperledger/aries-rfcs/tree/master/features/0211-route-coordination#keylist-update-response) handler

Signed-off-by: Rolson Quadras <rolson.quadras@securekey.com>
---
 pkg/didcomm/protocol/route/service.go      | 38 +++++++++++++++-
 pkg/didcomm/protocol/route/service_test.go | 52 ++++++++++++++++++++++
 pkg/didcomm/protocol/route/support_test.go | 27 +++++++++++
 3 files changed, 116 insertions(+), 1 deletion(-)

diff --git a/pkg/didcomm/protocol/route/service.go b/pkg/didcomm/protocol/route/service.go
index be9ab9b67..9287664f7 100644
--- a/pkg/didcomm/protocol/route/service.go
+++ b/pkg/didcomm/protocol/route/service.go
@@ -100,9 +100,17 @@ func (s *Service) HandleInbound(msg *service.DIDCommMsg) (string, error) {
 			if err := s.handleRequest(msg); err != nil {
 				logger.Errorf("handle route request error : %s", err)
 			}
+		case GrantMsgType:
+			if err := s.handleGrant(msg); err != nil {
+				logger.Errorf("handle route grant error : %s", err)
+			}
 		case KeylistUpdateMsgType:
 			if err := s.handleKeylistUpdate(msg); err != nil {
-				logger.Errorf("handle route request error : %s", err)
+				logger.Errorf("handle route keylist update error : %s", err)
+			}
+		case KeylistUpdateResponseMsgType:
+			if err := s.handleKeylistUpdateResponse(msg); err != nil {
+				logger.Errorf("handle route keylist update response error : %s", err)
 			}
 		}
 	}()
@@ -157,6 +165,20 @@ func (s *Service) handleRequest(msg *service.DIDCommMsg) error {
 	return s.outbound.Send(grant, "", nil)
 }
 
+func (s *Service) handleGrant(msg *service.DIDCommMsg) error {
+	// unmarshal the payload
+	grant := &Grant{}
+
+	err := json.Unmarshal(msg.Payload, grant)
+	if err != nil {
+		return fmt.Errorf("route grant message unmarshal : %w", err)
+	}
+
+	// TODO https://github.com/hyperledger/aries-framework-go/issues/948 integrate with framework components
+
+	return nil
+}
+
 func (s *Service) handleKeylistUpdate(msg *service.DIDCommMsg) error {
 	// unmarshal the payload
 	keyUpdate := &KeylistUpdate{}
@@ -210,3 +232,17 @@ func (s *Service) handleKeylistUpdate(msg *service.DIDCommMsg) error {
 	// TODO https://github.com/hyperledger/aries-framework-go/issues/725 get destination details from the connection
 	return s.outbound.Send(updateResponse, "", nil)
 }
+
+func (s *Service) handleKeylistUpdateResponse(msg *service.DIDCommMsg) error {
+	// unmarshal the payload
+	resp := &KeylistUpdateResponse{}
+
+	err := json.Unmarshal(msg.Payload, resp)
+	if err != nil {
+		return fmt.Errorf("route keylist update response message unmarshal : %w", err)
+	}
+
+	// TODO https://github.com/hyperledger/aries-framework-go/issues/948 integrate with framework components
+
+	return nil
+}
diff --git a/pkg/didcomm/protocol/route/service_test.go b/pkg/didcomm/protocol/route/service_test.go
index ca797c5c4..be1567a00 100644
--- a/pkg/didcomm/protocol/route/service_test.go
+++ b/pkg/didcomm/protocol/route/service_test.go
@@ -123,6 +123,30 @@ func TestServiceRequestMsg(t *testing.T) {
 	})
 }
 
+func TestServiceGrantMsg(t *testing.T) {
+	t.Run("test service handle inbound grant msg - success", func(t *testing.T) {
+		svc, err := New(&mockProvider{})
+		require.NoError(t, err)
+
+		msgID := randomID()
+
+		id, err := svc.HandleInbound(generateGrantMsgPayload(t, msgID))
+		require.NoError(t, err)
+		require.Equal(t, msgID, id)
+	})
+
+	t.Run("test service handle grant msg - success", func(t *testing.T) {
+		svc, err := New(&mockProvider{})
+		require.NoError(t, err)
+
+		msg := &service.DIDCommMsg{Payload: []byte("invalid json")}
+
+		err = svc.handleGrant(msg)
+		require.Error(t, err)
+		require.Contains(t, err.Error(), "route grant message unmarshal")
+	})
+}
+
 func TestServiceUpdateKeyListMsg(t *testing.T) {
 	t.Run("test service handle inbound key list update msg - success", func(t *testing.T) {
 		svc, err := New(&mockProvider{})
@@ -192,3 +216,31 @@ func TestServiceUpdateKeyListMsg(t *testing.T) {
 		require.NoError(t, err)
 	})
 }
+
+func TestServiceKeylistUpdateResponseMsg(t *testing.T) {
+	t.Run("test service handle inbound key list update response msg - success", func(t *testing.T) {
+		svc, err := New(&mockProvider{})
+		require.NoError(t, err)
+
+		msgID := randomID()
+
+		id, err := svc.HandleInbound(generateKeylistUpdateResponseMsgPayload(t, msgID, []UpdateResponse{{
+			RecipientKey: "ABC",
+			Action:       "add",
+			Result:       success,
+		}}))
+		require.NoError(t, err)
+		require.Equal(t, msgID, id)
+	})
+
+	t.Run("test service handle key list update response msg - success", func(t *testing.T) {
+		svc, err := New(&mockProvider{})
+		require.NoError(t, err)
+
+		msg := &service.DIDCommMsg{Payload: []byte("invalid json")}
+
+		err = svc.handleKeylistUpdateResponse(msg)
+		require.Error(t, err)
+		require.Contains(t, err.Error(), "route keylist update response message unmarshal")
+	})
+}
diff --git a/pkg/didcomm/protocol/route/support_test.go b/pkg/didcomm/protocol/route/support_test.go
index 1fc9fc08d..450320668 100644
--- a/pkg/didcomm/protocol/route/support_test.go
+++ b/pkg/didcomm/protocol/route/support_test.go
@@ -79,6 +79,19 @@ func generateRequestMsgPayload(t *testing.T, id string) *service.DIDCommMsg {
 	return didMsg
 }
 
+func generateGrantMsgPayload(t *testing.T, id string) *service.DIDCommMsg {
+	grantBytes, err := json.Marshal(&Grant{
+		Type: GrantMsgType,
+		ID:   id,
+	})
+	require.NoError(t, err)
+
+	didMsg, err := service.NewDIDCommMsg(grantBytes)
+	require.NoError(t, err)
+
+	return didMsg
+}
+
 func generateKeyUpdateListMsgPayload(t *testing.T, id string, updates []Update) *service.DIDCommMsg {
 	requestBytes, err := json.Marshal(&KeylistUpdate{
 		Type:    KeylistUpdateMsgType,
@@ -93,6 +106,20 @@ func generateKeyUpdateListMsgPayload(t *testing.T, id string, updates []Update)
 	return didMsg
 }
 
+func generateKeylistUpdateResponseMsgPayload(t *testing.T, id string, updates []UpdateResponse) *service.DIDCommMsg {
+	respBytes, err := json.Marshal(&KeylistUpdateResponse{
+		Type:    KeylistUpdateResponseMsgType,
+		ID:      id,
+		Updated: updates,
+	})
+	require.NoError(t, err)
+
+	didMsg, err := service.NewDIDCommMsg(respBytes)
+	require.NoError(t, err)
+
+	return didMsg
+}
+
 func randomID() string {
 	return uuid.New().String()
 }