예제 #1
0
 /// <summary>
 /// Constructs their DID doc in a pairwise relationship from a connection record.
 /// </summary>
 /// <param name="connection">Connectio record.</param>
 /// <returns>DID Doc</returns>
 public static DidDoc TheirDidDoc(this ConnectionRecord connection)
 {
     return(new DidDoc
     {
         Keys = new List <DidDocKey>
         {
             new DidDocKey
             {
                 Id = $"{connection.MyDid}#keys-1",
                 Type = DefaultKeyType,
                 Controller = connection.TheirDid,
                 PublicKeyBase58 = connection.TheirVk
             }
         },
         Services = new List <IDidDocServiceEndpoint>
         {
             new IndyAgentDidDocService
             {
                 Id = $"{connection.MyDid};indy",
                 ServiceEndpoint = connection.Endpoint.Verkey,
                 RecipientKeys = connection.TheirVk != null ? new[] { connection.TheirVk } : new string[0],
                 RoutingKeys = connection.Endpoint?.Verkey != null ? new[] { connection.Endpoint.Verkey } : new string[0]
             }
         }
     });
 }
예제 #2
0
        /// <summary>
        /// Constructs my DID doc in a pairwise relationship from a connection record and the agents provisioning record.
        /// </summary>
        /// <param name="connection">Connection record.</param>
        /// <param name="provisioningRecord">Provisioning record.</param>
        /// <returns>DID Doc</returns>
        public static DidDoc MyDidDoc(this ConnectionRecord connection, ProvisioningRecord provisioningRecord)
        {
            var doc = new DidDoc
            {
                Keys = new List <DidDocKey>
                {
                    new DidDocKey
                    {
                        Id              = $"{connection.MyDid}#keys-1",
                        Type            = DefaultKeyType,
                        Controller      = connection.MyDid,
                        PublicKeyBase58 = connection.MyVk
                    }
                }
            };

            if (!string.IsNullOrEmpty(provisioningRecord.Endpoint.Uri))
            {
                doc.Services = new List <IDidDocServiceEndpoint>
                {
                    new IndyAgentDidDocService
                    {
                        Id = $"{connection.MyDid};indy",
                        ServiceEndpoint = provisioningRecord.Endpoint.Uri,
                        RecipientKeys   = connection.MyVk != null ? new[] { connection.MyVk } : new string[0],
                        RoutingKeys     = provisioningRecord.Endpoint?.Verkey != null ? new[] { provisioningRecord.Endpoint.Verkey } : new string[0]
                    }
                };
            }

            return(doc);
        }
        /// <inheritdoc />
        public virtual async Task <(ConnectionInvitationMessage, ConnectionRecord)> CreateInvitationAsync(IAgentContext agentContext,
                                                                                                          InviteConfiguration config = null)
        {
            var connectionId = !string.IsNullOrEmpty(config?.ConnectionId)
                ? config.ConnectionId
                : Guid.NewGuid().ToString();

            config = config ?? new InviteConfiguration();

            Logger.LogInformation(LoggingEvents.CreateInvitation, "ConnectionId {0}", connectionId);

            var connectionKey = await Crypto.CreateKeyAsync(agentContext.Wallet, "{}");

            var connection = new ConnectionRecord {
                Id = connectionId
            };

            connection.SetTag(TagConstants.ConnectionKey, connectionKey);

            if (config.AutoAcceptConnection)
            {
                connection.SetTag(TagConstants.AutoAcceptConnection, "true");
            }

            connection.MultiPartyInvitation = config.MultiPartyInvitation;

            if (!config.MultiPartyInvitation)
            {
                connection.Alias = config.TheirAlias;
                if (!string.IsNullOrEmpty(config.TheirAlias.Name))
                {
                    connection.SetTag(TagConstants.Alias, config.TheirAlias.Name);
                }
            }

            foreach (var tag in config.Tags)
            {
                connection.SetTag(tag.Key, tag.Value);
            }

            var provisioning = await ProvisioningService.GetProvisioningAsync(agentContext.Wallet);

            if (string.IsNullOrEmpty(provisioning.Endpoint.Uri))
            {
                throw new AriesFrameworkException(ErrorCode.RecordInInvalidState, "Provision record has no endpoint information specified");
            }

            await RecordService.AddAsync(agentContext.Wallet, connection);

            return(new ConnectionInvitationMessage
            {
                ServiceEndpoint = provisioning.Endpoint.Uri,
                RoutingKeys = provisioning.Endpoint.Verkey != null ? provisioning.Endpoint.Verkey : null,
                RecipientKeys = new[] { connectionKey },
                Label = config.MyAlias.Name ?? provisioning.Owner.Name,
                ImageUrl = config.MyAlias.ImageUrl ?? provisioning.Owner.ImageUrl
            }, connection);
        }
        /// <inheritdoc />
        public virtual async Task <string> ProcessResponseAsync(IAgentContext agentContext, ConnectionResponseMessage response, ConnectionRecord connection)
        {
            Logger.LogTrace(LoggingEvents.AcceptConnectionResponse, "To {1}", connection.MyDid);

            //TODO throw exception or a problem report if the connection request features a did doc that has no indy agent did doc convention featured
            //i.e there is no way for this agent to respond to messages. And or no keys specified
            var connectionObj = await SignatureUtils.UnpackAndVerifyAsync <Connection>(response.ConnectionSig);

            await Did.StoreTheirDidAsync(agentContext.Wallet,
                                         new { did = connectionObj.Did, verkey = connectionObj.DidDoc.Keys[0].PublicKeyBase58 }.ToJson());

            connection.TheirDid = connectionObj.Did;
            connection.TheirVk  = connectionObj.DidDoc.Keys[0].PublicKeyBase58;

            connection.SetTag(TagConstants.LastThreadId, response.GetThreadId());

            if (connectionObj.DidDoc.Services[0] is IndyAgentDidDocService service)
            {
                connection.Endpoint = new AgentEndpoint(service.ServiceEndpoint, null, service.RoutingKeys != null && service.RoutingKeys.Count > 0 ? service.RoutingKeys.ToArray() : null);
            }

            await connection.TriggerAsync(ConnectionTrigger.Response);

            await RecordService.UpdateAsync(agentContext.Wallet, connection);

            EventAggregator.Publish(new ServiceMessageProcessingEvent
            {
                RecordId    = connection.Id,
                MessageType = response.Type,
                ThreadId    = response.GetThreadId()
            });

            return(connection.Id);
        }
        /// <inheritdoc />
        public virtual async Task <string> ProcessRequestAsync(IAgentContext agentContext, ConnectionRequestMessage request, ConnectionRecord connection)
        {
            Logger.LogInformation(LoggingEvents.ProcessConnectionRequest, "Did {0}", request.Connection.Did);

            var my = await Did.CreateAndStoreMyDidAsync(agentContext.Wallet, "{}");

            //TODO throw exception or a problem report if the connection request features a did doc that has no indy agent did doc convention featured
            //i.e there is no way for this agent to respond to messages. And or no keys specified
            await Did.StoreTheirDidAsync(agentContext.Wallet, new { did = request.Connection.Did, verkey = request.Connection.DidDoc.Keys[0].PublicKeyBase58 }.ToJson());

            if (request.Connection.DidDoc.Services != null &&
                request.Connection.DidDoc.Services.Count > 0 &&
                request.Connection.DidDoc.Services[0] is IndyAgentDidDocService service)
            {
                connection.Endpoint = new AgentEndpoint(service.ServiceEndpoint, null, service.RoutingKeys != null && service.RoutingKeys.Count > 0 ? service.RoutingKeys.ToArray() : null);
            }

            connection.TheirDid = request.Connection.Did;
            connection.TheirVk  = request.Connection.DidDoc.Keys[0].PublicKeyBase58;
            connection.MyDid    = my.Did;
            connection.MyVk     = my.VerKey;

            connection.SetTag(TagConstants.LastThreadId, request.Id);

            if (connection.Alias == null)
            {
                connection.Alias = new ConnectionAlias();
            }

            if (!string.IsNullOrEmpty(request.Label) && string.IsNullOrEmpty(connection.Alias.Name))
            {
                connection.Alias.Name = request.Label;
            }

            if (!string.IsNullOrEmpty(request.ImageUrl) && string.IsNullOrEmpty(connection.Alias.ImageUrl))
            {
                connection.Alias.ImageUrl = request.ImageUrl;
            }

            if (!connection.MultiPartyInvitation)
            {
                await connection.TriggerAsync(ConnectionTrigger.InvitationAccept);

                await RecordService.UpdateAsync(agentContext.Wallet, connection);

                EventAggregator.Publish(new ServiceMessageProcessingEvent
                {
                    RecordId    = connection.Id,
                    MessageType = request.Type,
                    ThreadId    = request.GetThreadId()
                });

                return(connection.Id);
            }

            var newConnection = connection.DeepCopy();

            newConnection.Id = Guid.NewGuid().ToString();
            newConnection.MultiPartyInvitation = false;

            await newConnection.TriggerAsync(ConnectionTrigger.InvitationAccept);

            await RecordService.AddAsync(agentContext.Wallet, newConnection);

            EventAggregator.Publish(new ServiceMessageProcessingEvent
            {
                RecordId    = newConnection.Id,
                MessageType = request.Type,
                ThreadId    = request.GetThreadId()
            });
            return(newConnection.Id);
        }
        /// <inheritdoc />
        public virtual async Task <(ConnectionRequestMessage, ConnectionRecord)> CreateRequestAsync(IAgentContext agentContext, ConnectionInvitationMessage invitation)
        {
            Logger.LogInformation(LoggingEvents.AcceptInvitation, "Key {0}, Endpoint {1}",
                                  invitation.RecipientKeys[0], invitation.ServiceEndpoint);

            var my = await Did.CreateAndStoreMyDidAsync(agentContext.Wallet, "{}");

            var connection = new ConnectionRecord
            {
                Endpoint = new AgentEndpoint(invitation.ServiceEndpoint, null, invitation.RoutingKeys != null && invitation.RoutingKeys.Count != 0 ? invitation.RoutingKeys.ToArray() : null),
                MyDid    = my.Did,
                MyVk     = my.VerKey,
                Id       = Guid.NewGuid().ToString().ToLowerInvariant()
            };

            connection.SetTag("InvitationKey", invitation.RecipientKeys.First());

            if (!string.IsNullOrEmpty(invitation.Label) || !string.IsNullOrEmpty(invitation.ImageUrl))
            {
                connection.Alias = new ConnectionAlias
                {
                    Name     = invitation.Label,
                    ImageUrl = invitation.ImageUrl
                };

                if (string.IsNullOrEmpty(invitation.Label))
                {
                    connection.SetTag(TagConstants.Alias, invitation.Label);
                }
            }

            await connection.TriggerAsync(ConnectionTrigger.InvitationAccept);

            var provisioning = await ProvisioningService.GetProvisioningAsync(agentContext.Wallet);

            var request = new ConnectionRequestMessage
            {
                Connection = new Connection
                {
                    Did    = connection.MyDid,
                    DidDoc = connection.MyDidDoc(provisioning)
                },
                Label    = provisioning.Owner?.Name,
                ImageUrl = provisioning.Owner?.ImageUrl
            };

            // also set image as attachment
            if (provisioning.Owner?.ImageUrl != null)
            {
                request.AddAttachment(new Attachment
                {
                    Nickname = "profile-image",
                    Data     = new AttachmentContent {
                        Links = new[] { provisioning.Owner.ImageUrl }
                    }
                });
            }

            await RecordService.AddAsync(agentContext.Wallet, connection);

            return(request, connection);
        }