public void InitialCredentialRecordIsOfferedAndHasTag()
        {
            var record = new CredentialRecord();

            Assert.True(record.State == CredentialState.Offered);
            Assert.True(record.GetTag(nameof(CredentialRecord.State)) == CredentialState.Offered.ToString("G"));
        }
        /// <inheritdoc />
        public virtual async Task <string> ProcessOfferAsync(IAgentContext agentContext, CredentialOfferMessage credentialOffer, ConnectionRecord connection)
        {
            var offerJson    = credentialOffer.OfferJson;
            var offer        = JObject.Parse(offerJson);
            var definitionId = offer["cred_def_id"].ToObject <string>();
            var schemaId     = offer["schema_id"].ToObject <string>();
            var nonce        = offer["nonce"].ToObject <string>();

            // Write offer record to local wallet
            var credentialRecord = new CredentialRecord
            {
                Id                     = Guid.NewGuid().ToString(),
                OfferJson              = offerJson,
                ConnectionId           = connection.Id,
                CredentialDefinitionId = definitionId,
                SchemaId               = schemaId,
                State                  = CredentialState.Offered
            };

            credentialRecord.SetTag(TagConstants.Role, TagConstants.Holder);
            credentialRecord.SetTag(TagConstants.Nonce, nonce);

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

            EventAggregator.Publish(new ServiceMessageProcessingEvent
            {
                RecordId    = credentialRecord.Id,
                MessageType = credentialOffer.Type,
            });

            return(credentialRecord.Id);
        }
        public CredentialViewModel(IUserDialogs userDialogs,
                                   INavigationService navigationService,
                                   CredentialRecord credential,
                                   IAgentProvider agentProvider,
                                   ICredentialService credentialService,
                                   IEventAggregator eventAggregator,
                                   IConnectionService connectionService) :
            base(nameof(CredentialViewModel), userDialogs, navigationService)
        {
            _connectionService = connectionService;
            _agentProvider     = agentProvider;
            _credentialService = credentialService;
            _eventAggregator   = eventAggregator;

            Title           = "Credential Detail";
            _credential     = credential;
            _attributes     = credential.CredentialAttributesValues;
            _credId         = _credential.Id;
            _state          = _credential.State;
            _credentialName = ConvertNameFromeSchemaId(_credential.SchemaId).ToTitleCase();
            if (_credential.CreatedAtUtc != null)
            {
                IssuedDate = (DateTime)_credential.CreatedAtUtc;
            }
            someMaterialColor = new Helpers.SomeMaterialColor();
        }
Esempio n. 4
0
        public void InitialCredentialRecordIsOfferedAndHasTag()
        {
            var record = new CredentialRecord();

            Assert.True(record.State == CredentialState.Offered);
            Assert.True(record.Tags[TagConstants.State] == CredentialState.Offered.ToString("G"));
        }
Esempio n. 5
0
        private bool IsCredentialNew(CredentialRecord credential)
        {
            // TODO OS-200, Currently a Placeholder for a mix of new and not new cells
            Random random = new Random();

            return(random.Next(0, 2) == 1);
        }
        public async Task <CredentialViewModel> Assemble(CredentialRecord credentialRecord)
        {
            if (credentialRecord == null)
            {
                return(null);
            }

            var context = await _agentContextProvider.GetContextAsync();

            CredentialViewModel credential = _scope.Resolve <CredentialViewModel>(new NamedParameter("credential", credentialRecord));

            var credentialDefinitionId = CredentialDefinitionId.Parse(credentialRecord.CredentialDefinitionId);

            credential.CredentialName = credentialDefinitionId.Tag;
            var connectionRecord = await _connectionService.GetAsync(context, credentialRecord.ConnectionId);

            credential.CredentialSubtitle = connectionRecord.Alias.Name;
            credential.IssuedAt           = connectionRecord.CreatedAtUtc.HasValue ? connectionRecord.CreatedAtUtc.Value.ToLocalTime() : (DateTime?)null;
            if (credentialRecord.State == CredentialState.Offered)
            {
                var attributes = new List <CredentialAttribute>();
                credential.Attributes = attributes;
                foreach (var credentialPreviewAttribute in credentialRecord.CredentialAttributesValues)
                {
                    var attribute = new CredentialAttribute {
                        Name = credentialPreviewAttribute.Name, Value = credentialPreviewAttribute.Value.ToString(), Type = "Text"
                    };
                    attribute.Type  = attribute.Value != null && (attribute.Value.ToString().StartsWith("data:image/jpeg;base64") || attribute.Value.ToString().StartsWith("data:image/png;base64")) ? "Image" : "Text";
                    attribute.Image = attribute.Value != null && (attribute.Value.ToString().StartsWith("data:image/jpeg;base64") || attribute.Value.ToString().StartsWith("data:image/png;base64")) ? ImageSource.FromStream(() => new MemoryStream(Convert.FromBase64String(attribute.Value.ToString().Replace("data:image/jpeg;base64,", "").Replace("data:image/png;base64,", "")))) : null;
                    attributes.Add(attribute);
                }
            }

            return(credential);
        }
Esempio n. 7
0
        public void CreateWithExistingGuid()
        {
            var customGuid = new Guid();

            _credentialRecord = new CredentialRecord(customGuid);
            Assert.That(_credentialRecord.Id, Is.EqualTo(customGuid));
        }
Esempio n. 8
0
 private bool IsCredentialNew(CredentialRecord credential)
 {
     //// TODO OS-200, Currently a Placeholder for a mix of new and not new cells
     //Random random = new Random();
     //return random.Next(0, 2) == 1;
     return(_credential.State == CredentialState.Offered);
 }
Esempio n. 9
0
        public CredOfferViewModel(IUserDialogs userDialogs,
                                  INavigationService navigationService,
                                  IAgentProvider agentProvider,
                                  ICredentialService credentialService,
                                  IMessageService messageService,
                                  IPoolService poolService,
                                  IWalletRecordService recordService,
                                  IConnectionService connectionService,
                                  IEventAggregator eventAggregator, CredentialRecord credentialOffer) :
            base(nameof(CredOfferViewModel), userDialogs, navigationService)
        {
            _credentialOffer = credentialOffer;

            _agentProvider     = agentProvider;
            _credentialService = credentialService;
            _connectionService = connectionService;
            _messageService    = messageService;
            _poolService       = poolService;
            _recordService     = recordService;
            _eventAggregator   = eventAggregator;
            Title          = "Offer Detail";
            CredentialName = ConvertNameFromeSchemaId(CredentialOffer.SchemaId);

            if (_credentialOffer.CreatedAtUtc != null)
            {
                IssuedDate = (DateTime)_credentialOffer.CreatedAtUtc;
            }
        }
Esempio n. 10
0
        public async Task <IActionResult> SendCredentialProposalAsync(OperationBody body)
        {
            var context = await _agentContextProvider.GetContextAsync();

            var proposal               = body.Data;
            var connectionId           = (string)proposal["connection_id"];
            var credentialPreview      = proposal["credential_proposal"].ToObject <CustomCredentialPreviewMessage>();
            var credentialDefinitionId = (string)proposal["cred_def_id"];
            var schemaId               = (string)proposal["schema_id"];
            var connection             = await _connectionService.GetAsync(context, connectionId); // TODO: Handle AriesFrameworkException if connection not found

            var threadId = Guid.NewGuid().ToString();

            credentialPreview.Attributes = CleanCredentialPreviewAttributes(credentialPreview.Attributes);

            // TODO: add support for v1.1 wich includes 'schema_issuer_did', 'schema_name', 'schema_version', 'issuer_did'
            // TODO: should we support in response to previous message? Not possible with AATH atm I think.
            var credentialProposeMessage = new CustomCredentialProposeMessage
            {
                Id                     = threadId,
                Comment                = (string)proposal["comment"] ?? "hello", // ACA-Py requires comment
                CredentialProposal     = credentialPreview,
                CredentialDefinitionId = credentialDefinitionId,
                SchemaId               = schemaId
            };

            var credentialRecord = new CredentialRecord
            {
                Id           = Guid.NewGuid().ToString(),
                ConnectionId = connectionId,
                CredentialAttributesValues = credentialPreview.Attributes,
                CredentialDefinitionId     = credentialDefinitionId,
                SchemaId = schemaId,
                // State should be proposal-received
                State = CredentialState.Offered
            };

            credentialRecord.SetTag(TagConstants.Role, TagConstants.Holder);
            credentialRecord.SetTag(TagConstants.LastThreadId, threadId);

            await _recordService.AddAsync(context.Wallet, credentialRecord);

            var THCredentialExchange = new TestHarnessCredentialExchange
            {
                RecordId = credentialRecord.Id,
                ThreadId = threadId,
                State    = TestHarnessCredentialExchangeState.ProposalSent,
            };

            _credentialCache.Set(THCredentialExchange.ThreadId, THCredentialExchange);

            // Listen for credential offer to update the state
            UpdateStateOnMessage(THCredentialExchange, TestHarnessCredentialExchangeState.OfferReceived, _ => _.MessageType == MessageTypes.IssueCredentialNames.OfferCredential && _.ThreadId == THCredentialExchange.ThreadId);

            await _messageService.SendAsync(context.Wallet, credentialProposeMessage, connection);

            return(Ok(THCredentialExchange));
        }
Esempio n. 11
0
 public void Setup()
 {
     _credentialRecord = new CredentialRecord
     {
         Username = "******",
         Domain   = "domainHere",
         Password = "******".ConvertToSecureString()
     };
 }
Esempio n. 12
0
        public void AllCredentialsSerialized()
        {
            var cred2 = new CredentialRecord {
                Title = "testcred2", Username = "******", Domain = "otherdomain", Password = "******".ConvertToSecureString()
            };
            var serialized      = _serializer.Serialize(new[] { _cred1, cred2 });
            var serializedCount = XDocument.Parse(serialized).Descendants("Credential").Count();

            Assert.That(serializedCount, Is.EqualTo(2));
        }
        private async Task DisplayCredentialOffer(string recordId)
        {
            IAgentContext context = await _agentContextProvider.GetContextAsync();

            CredentialRecord credentialRecord = await _credentialService.GetAsync(context, recordId);

            CredentialViewModel credential = await _credentialAssembler.Assemble(credentialRecord);

            await NavigationService.NavigateToAsync(credential, null, NavigationType.Modal);
        }
        /// <inheritdoc />
        public async Task <bool> IsRevokedAsync(IAgentContext context, CredentialRecord record)
        {
            if (record.RevocationRegistryId == null)
            {
                return(false);
            }
            if (record.State == CredentialState.Offered || record.State == CredentialState.Requested)
            {
                return(false);
            }
            if (record.State == CredentialState.Revoked || record.State == CredentialState.Rejected)
            {
                return(true);
            }

            var now          = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
            var proofRequest = new ProofRequest
            {
                Name                = "revocation check",
                Version             = "1.0",
                Nonce               = await AnonCreds.GenerateNonceAsync(),
                RequestedAttributes = new Dictionary <string, ProofAttributeInfo>
                {
                    { "referent1", new ProofAttributeInfo {
                          Name = record.CredentialAttributesValues.First().Name
                      } }
                }, NonRevoked = new RevocationInterval
                {
                    From = (uint)now,
                    To   = (uint)now
                }
            };

            var proof = await CreateProofAsync(context, proofRequest, new RequestedCredentials
            {
                RequestedAttributes = new Dictionary <string, RequestedAttribute>
                {
                    { "referent1", new RequestedAttribute {
                          CredentialId = record.CredentialId, Timestamp = now, Revealed = true
                      } }
                }
            });

            var isValid = await VerifyProofAsync(context, proofRequest.ToJson(), proof);

            if (!isValid)
            {
                await record.TriggerAsync(CredentialTrigger.Revoke);

                record.SetTag("LastRevocationCheck", now.ToString());
                await RecordService.UpdateAsync(context.Wallet, record);
            }

            return(!isValid);
        }
Esempio n. 15
0
        /// <inheritdoc />
        public virtual async Task <CredentialOfferMessage> CreateOfferAsync(Wallet wallet, DefaultCreateOfferConfiguration config)
        {
            Logger.LogInformation(LoggingEvents.CreateCredentialOffer, "DefinitionId {0}, ConnectionId {1}, IssuerDid {2}",
                                  config.CredentialDefinitionId, config.ConnectionId, config.IssuerDid);

            var connection = await ConnectionService.GetAsync(wallet, config.ConnectionId);

            var offerJson = await AnonCreds.IssuerCreateCredentialOfferAsync(wallet, config.CredentialDefinitionId);

            var nonce = JObject.Parse(offerJson)["nonce"].ToObject <string>();

            // Write offer record to local wallet
            var credentialRecord = new CredentialRecord
            {
                Id = Guid.NewGuid().ToString(),
                CredentialDefinitionId = config.CredentialDefinitionId,
                OfferJson    = offerJson,
                ValuesJson   = CredentialUtils.FormatCredentialValues(config.CredentialAttributeValues),
                State        = CredentialState.Offered,
                ConnectionId = connection.GetId(),
            };

            credentialRecord.Tags.Add(TagConstants.Nonce, nonce);
            credentialRecord.Tags.Add(TagConstants.Role, TagConstants.Issuer);
            credentialRecord.Tags.Add(TagConstants.ConnectionId, connection.GetId());

            if (!string.IsNullOrEmpty(config.IssuerDid))
            {
                credentialRecord.Tags.Add(TagConstants.IssuerDid, config.IssuerDid);
            }

            if (config.Tags != null)
            {
                foreach (var tag in config.Tags)
                {
                    if (!credentialRecord.Tags.Keys.Contains(tag.Key))
                    {
                        credentialRecord.Tags.Add(tag.Key, tag.Value);
                    }
                }
            }

            await RecordService.AddAsync(wallet, credentialRecord);

            var credentialOffer = await MessageSerializer.PackSealedAsync <CredentialOfferMessage>(
                new CredentialOfferDetails { OfferJson = offerJson },
                wallet,
                connection.MyVk,
                connection.TheirVk);

            credentialOffer.Type = MessageUtils.FormatDidMessageType(connection.TheirDid, MessageTypes.CredentialOffer);

            return(credentialOffer);
        }
 private bool ContainsAttributeName(CredentialRecord credentialRecord)
 {
     foreach (CredentialPreviewAttribute credentialAttribute in credentialRecord.CredentialAttributesValues)
     {
         if (credentialAttribute.Name == _attributeName)
         {
             return(true);
         }
     }
     return(false);
 }
        private void AssignSelectedAttributeValue(CredentialRecord credentialRecord, ProofAttributeViewModel proofAttribute)
        {
            proofAttribute.CredentialId = credentialRecord.Id;

            foreach (CredentialPreviewAttribute credentialPreviewAttribute in credentialRecord.CredentialAttributesValues)
            {
                if (credentialPreviewAttribute.Name == proofAttribute.Name)
                {
                    proofAttribute.Value = credentialPreviewAttribute.Value.ToString();
                }
            }
        }
        private ICredentialRecord BuildCredential(XElement element, ICryptographyProvider cryptographyProvider, SecureString decryptionKey)
        {
            var credential = new CredentialRecord
            {
                Title    = $"{element.Attribute("Username")?.Value}\\{element.Attribute("Domain")?.Value}",
                Username = element.Attribute("Username")?.Value,
                Domain   = element.Attribute("Domain")?.Value,
                Password = cryptographyProvider.Decrypt(element.Attribute("Password")?.Value, decryptionKey).ConvertToSecureString()
            };

            return(credential);
        }
Esempio n. 19
0
        public CredentialViewModel(
            IUserDialogs userDialogs,
            INavigationService navigationService,
            CredentialRecord credential
            ) : base(
                nameof(CredentialViewModel),
                userDialogs,
                navigationService
                )
        {
            _credential = credential;
            _isNew      = IsCredentialNew(_credential);

            #if DEBUG
            _credentialName     = "Credential Name";
            _credentialImageUrl = "http://placekitten.com/g/200/200";
            _credentialSubtitle = "10/22/2017";
            _credentialType     = "Bank Statement";
            _qRImageUrl         = "http://placekitten.com/g/100/100";

            var attributes = new List <CredentialAttribute>(new CredentialAttribute[] {
                new CredentialAttribute
                {
                    Type  = "Text",
                    Name  = "First Name",
                    Value = "Jamie"
                },
                new CredentialAttribute
                {
                    Type  = "Text",
                    Name  = "Last Name",
                    Value = "Doe"
                },
                new CredentialAttribute
                {
                    Type  = "Text",
                    Name  = "Country of Residence",
                    Value = "New Zealand"
                },
                new CredentialAttribute
                {
                    Type    = "File",
                    Name    = "Statement",
                    Value   = "Statement.pdf",
                    FileExt = "PDF",
                    Date    = "05 Aug 2018"
                }
            });
            _attributes = attributes
                          .OrderByDescending(o => o.Type).OrderBy(o => o.Date);
            #endif
        }
        public async Task <GetCredentialResponse> Handle
        (
            GetCredentialRequest aGetCredentialRequest,
            CancellationToken aCancellationToken
        )
        {
            IAgentContext agentContext = await AgentProvider.GetContextAsync();

            CredentialRecord credentialRecord = await CredentialService.GetAsync(agentContext, aGetCredentialRequest.CredentialId);

            var response = new GetCredentialResponse(aGetCredentialRequest.CorrelationId, credentialRecord);

            return(response);
        }
Esempio n. 21
0
 public SSICredentialViewModel(CredentialRecord credential)
 {
     _credential = credential;
     Attributes  = new RangeEnabledObservableCollection <SSICredentialAttribute>();
     foreach (var cred in _credential.CredentialAttributesValues)
     {
         Console.WriteLine("credential-name: " + cred.Name);
         Attributes.Add(new SSICredentialAttribute()
         {
             Name  = cred.Name,
             Value = cred.Value,
         });
     }
 }
        public CredentialViewModel(
            IUserDialogs userDialogs,
            INavigationService navigationService,
            IAgentProvider agentContextProvider,
            ICredentialService credentialService,
            IEventAggregator eventAggregator,
            IMessageService messageService,
            IPoolConfigurator poolConfigurator,
            IConnectionService connectionService,
            CredentialRecord credential
            ) : base(
                "Credential Details",
                userDialogs,
                navigationService
                )
        {
            _credential           = credential;
            _agentContextProvider = agentContextProvider;
            _credentialService    = credentialService;
            _eventAggregator      = eventAggregator;
            _messageService       = messageService;
            _connectionService    = connectionService;
            _isNew            = IsCredentialNew(_credential);
            _poolConfigurator = poolConfigurator;

            if (credential.State == CredentialState.Offered)
            {
                IsPending         = true;
                AreButtonsVisible = true;
            }

            if (credential.State == CredentialState.Issued)
            {
                IsIssued          = true;
                AreButtonsVisible = false;
                if (credential.CredentialAttributesValues != null)
                {
                    Attributes = credential.CredentialAttributesValues
                                 .Select(p =>
                                         new CredentialAttribute()
                    {
                        Name  = p.Name,
                        Value = p.Value?.ToString(),
                        Type  = p.Value != null && (p.Value.ToString().StartsWith("data:image/jpeg;base64") || p.Value.ToString().StartsWith("data:image/png;base64")) ? "Image" : "Text",
                        Image = p.Value != null && (p.Value.ToString().StartsWith("data:image/jpeg;base64") || p.Value.ToString().StartsWith("data:image/png;base64")) ? ImageSource.FromStream(() => new MemoryStream(Convert.FromBase64String(p.Value.ToString().Replace("data:image/jpeg;base64,", "").Replace("data:image/png;base64,", "")))) : null
                    })
                                 .ToList();
                }
            }
        }
Esempio n. 23
0
        public async Task <GetCredentialResponse> Handle
        (
            GetCredentialRequest aGetCredentialRequest,
            CancellationToken aCancellationToken
        )
        {
            IAgentContext agentContext = await AgentProvider.GetContextAsync();

            List <CredentialRecord> credentialRecords = await CredentialService.ListAsync(agentContext);

            CredentialRecord credentialRecord =
                credentialRecords
                .FirstOrDefault(aCredentialRecord => aCredentialRecord.CredentialId == aGetCredentialRequest.CredentialId);

            var response = new GetCredentialResponse(aGetCredentialRequest.CorrelationId, credentialRecord);

            return(response);
        }
Esempio n. 24
0
        /// <inheritdoc />
        public virtual async Task <string> ProcessOfferAsync(Wallet wallet, CredentialOfferMessage credentialOffer)
        {
            var(didOrKey, _) = MessageUtils.ParseMessageType(credentialOffer.Type);

            var connectionSearch =
                await ConnectionService.ListAsync(wallet, new SearchRecordQuery { { TagConstants.MyDid, didOrKey } });

            if (!connectionSearch.Any())
            {
                throw new Exception($"Can't find connection record for type {credentialOffer.Type}");
            }
            var connection = connectionSearch.First();

            var(offerDetails, _) = await MessageSerializer.UnpackSealedAsync <CredentialOfferDetails>(
                credentialOffer.Content, wallet, connection.MyVk);

            var offerJson = offerDetails.OfferJson;

            var offer        = JObject.Parse(offerJson);
            var definitionId = offer["cred_def_id"].ToObject <string>();
            var schemaId     = offer["schema_id"].ToObject <string>();
            var nonce        = offer["nonce"].ToObject <string>();

            // Write offer record to local wallet
            var credentialRecord = new CredentialRecord
            {
                Id                     = Guid.NewGuid().ToString(),
                OfferJson              = offerJson,
                ConnectionId           = connection.GetId(),
                CredentialDefinitionId = definitionId,
                State                  = CredentialState.Offered
            };

            credentialRecord.Tags.Add(TagConstants.ConnectionId, connection.GetId());
            credentialRecord.Tags.Add(TagConstants.Role, TagConstants.Holder);
            credentialRecord.Tags.Add(TagConstants.Nonce, nonce);
            credentialRecord.Tags.Add(TagConstants.SchemaId, schemaId);
            credentialRecord.Tags.Add(TagConstants.DefinitionId, definitionId);

            await RecordService.AddAsync(wallet, credentialRecord);

            return(credentialRecord.GetId());
        }
Esempio n. 25
0
        /// <inheritdoc />
        public async Task <string> ProcessOfferAsync(IAgentContext agentContext, CredentialOfferMessage credentialOffer, ConnectionRecord connection)
        {
            var offerAttachment = credentialOffer.Offers.FirstOrDefault(x => x.Id == "libindy-cred-offer-0")
                                  ?? throw new ArgumentNullException(nameof(CredentialOfferMessage.Offers));

            var offerJson    = offerAttachment.Data.Base64.GetBytesFromBase64().GetUTF8String();
            var offer        = JObject.Parse(offerJson);
            var definitionId = offer["cred_def_id"].ToObject <string>();
            var schemaId     = offer["schema_id"].ToObject <string>();

            // Write offer record to local wallet
            var credentialRecord = new CredentialRecord
            {
                Id                         = Guid.NewGuid().ToString(),
                OfferJson                  = offerJson,
                ConnectionId               = connection.Id,
                CredentialDefinitionId     = definitionId,
                CredentialAttributesValues = credentialOffer.CredentialPreview?.Attributes
                                             .Select(x => new CredentialPreviewAttribute
                {
                    Name     = x.Name,
                    MimeType = x.MimeType,
                    Value    = x.Value
                }).ToArray(),
                SchemaId = schemaId,
                State    = CredentialState.Offered
            };

            credentialRecord.SetTag(TagConstants.Role, TagConstants.Holder);
            credentialRecord.SetTag(TagConstants.LastThreadId, credentialOffer.GetThreadId());

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

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

            return(credentialRecord.Id);
        }
Esempio n. 26
0
 public SSICredentialViewModel(
     INavigationService navigationService,
     CredentialRecord credential
     ) : base(
         nameof(SSICredentialViewModel),
         navigationService
         )
 {
     _credential = credential;
     Console.WriteLine("credential-id:" + credential.Id);
     Preferences.Set("credential-id", credential.Id);
     Attributes = new RangeEnabledObservableCollection <SSICredentialAttribute>();
     foreach (var cred in _credential.CredentialAttributesValues)
     {
         Attributes.Add(new SSICredentialAttribute()
         {
             Name  = cred.Name,
             Value = cred.Value,
         });
     }
 }
        private async Task AcceptCredentialOffer(CredentialRecord credentialRecord)
        {
            if (credentialRecord.State != CredentialState.Offered)
            {
                await DialogService.AlertAsync(string.Format("res-CredentialStateShouldBe", CredentialState.Offered));

                await NavigationService.PopModalAsync();

                return;
            }

            await _poolConfigurator.ConfigurePoolsAsync();

            var context = await _agentContextProvider.GetContextAsync();

            var(msg, rec) = await _credentialService.CreateRequestAsync(context, credentialRecord.Id);

            var connectionRecord = await _connectionService.GetAsync(context, credentialRecord.ConnectionId);

            if (connectionRecord == null)
            {
                //await _messageService.SendAsync(context.Wallet, msg, conectionRecord.TheirVk ?? rec.GetTag("InvitationKey") ?? throw new InvalidOperationException("Cannot locate recipient Key"), conectionRecord.Endpoint.Uri,
                //    conectionRecord.Endpoint?.Verkey == null ? null : conectionRecord.Endpoint.Verkey, conectionRecord.MyVk);
                await DialogService.AlertAsync("Connection-less credentials not supported.");

                return;
            }
            else
            {
                await _messageService.SendAsync(context.Wallet, msg, connectionRecord);
            }

            _eventAggregator.Publish(new ApplicationEvent()
            {
                Type = ApplicationEventType.CredentialUpdated
            });

            await NavigationService.PopModalAsync();
        }
Esempio n. 28
0
        /// <summary>
        /// Processes the agent message
        /// </summary>
        /// <param name="agentContext"></param>
        /// <param name="messageContext">The agent message.</param>
        /// <returns></returns>
        /// <exception cref="AriesFrameworkException">Unsupported message type {messageType}</exception>
        public async Task <AgentMessage> ProcessAsync(IAgentContext agentContext, UnpackedMessageContext messageContext)
        {
            switch (messageContext.GetMessageType())
            {
            case MessageTypes.IssueCredentialNames.ProposeCredential:
            case MessageTypesHttps.IssueCredentialNames.ProposeCredential:
            {
                var credentialProposal = messageContext.GetMessage <CustomCredentialProposeMessage>();

                CredentialRecord credentialRecord;
                TestHarnessCredentialExchange THCredentialExchange;
                try
                {
                    // Credential can be proposed for an existing exchange
                    // so we must first check if the message contains
                    THCredentialExchange = _credentialCache.Get <TestHarnessCredentialExchange>(credentialProposal.GetThreadId());
                    credentialRecord     = await _credentialService.GetByThreadIdAsync(agentContext, THCredentialExchange.ThreadId);

                    // check if the proposal came from the same connection
                    if (messageContext.Connection?.Id != credentialRecord.ConnectionId)
                    {
                        throw new AriesFrameworkException(ErrorCode.RecordInInvalidState, "Connection from credential proposal is not same as previously stored record.");
                    }
                }
                catch
                {
                    // Create new CredentialRecord if no existing credential record exists
                    credentialRecord = new CredentialRecord
                    {
                        Id           = Guid.NewGuid().ToString(),
                        ConnectionId = messageContext.Connection?.Id,
                    };

                    credentialRecord.SetTag(TagConstants.Role, TagConstants.Issuer);
                    credentialRecord.SetTag(TagConstants.LastThreadId, credentialProposal.GetThreadId());

                    await _recordService.AddAsync(agentContext.Wallet, credentialRecord);

                    THCredentialExchange = new TestHarnessCredentialExchange
                    {
                        RecordId = credentialRecord.Id,
                        ThreadId = credentialProposal.GetThreadId(),
                        State    = TestHarnessCredentialExchangeState.ProposalReceived,
                    };
                    _credentialCache.Set(THCredentialExchange.ThreadId, THCredentialExchange);
                }

                // Updates that should be applied both when the credential record already exists or not
                credentialRecord.CredentialDefinitionId = credentialProposal.CredentialDefinitionId;
                credentialRecord.SchemaId = credentialProposal.SchemaId;
                credentialRecord.CredentialAttributesValues = credentialProposal.CredentialProposal?.Attributes
                                                              .Select(x => new CredentialPreviewAttribute
                    {
                        Name     = x.Name,
                        MimeType = x.MimeType,
                        Value    = x.Value
                    }).ToArray();
                // State should be proposal-received
                credentialRecord.State = CredentialState.Offered;

                await _recordService.UpdateAsync(agentContext.Wallet, credentialRecord);

                _eventAggregator.Publish(new ServiceMessageProcessingEvent
                    {
                        RecordId    = credentialRecord.Id,
                        MessageType = credentialProposal.Type,
                        ThreadId    = credentialProposal.GetThreadId()
                    });

                messageContext.ContextRecord = credentialRecord;

                return(null);
            }

            case MessageTypes.IssueCredentialNames.OfferCredential:
            case MessageTypesHttps.IssueCredentialNames.OfferCredential:
            {
                var offer    = messageContext.GetMessage <CredentialOfferMessage>();
                var recordId = await this.ProcessOfferAsync(
                    agentContext, offer, messageContext.Connection);

                messageContext.ContextRecord = await _credentialService.GetAsync(agentContext, recordId);

                return(null);
            }

            case MessageTypes.IssueCredentialNames.RequestCredential:
            case MessageTypesHttps.IssueCredentialNames.RequestCredential:
            {
                var request  = messageContext.GetMessage <CredentialRequestMessage>();
                var recordId = await _credentialService.ProcessCredentialRequestAsync(
                    agentContext : agentContext,
                    credentialRequest : request,
                    connection : messageContext.Connection);

                if (request.ReturnRoutingRequested() && messageContext.Connection == null)
                {
                    var(message, record) = await _credentialService.CreateCredentialAsync(agentContext, recordId);

                    messageContext.ContextRecord = record;
                    return(message);
                }
                else
                {
                    messageContext.ContextRecord = await _credentialService.GetAsync(agentContext, recordId);

                    return(null);
                }
            }

            case MessageTypes.IssueCredentialNames.IssueCredential:
            case MessageTypesHttps.IssueCredentialNames.IssueCredential:
            {
                var credential = messageContext.GetMessage <CredentialIssueMessage>();
                var recordId   = await _credentialService.ProcessCredentialAsync(
                    agentContext, credential, messageContext.Connection);

                messageContext.ContextRecord = await UpdateValuesAsync(
                    credentialId : recordId,
                    credentialIssue : messageContext.GetMessage <CredentialIssueMessage>(),
                    agentContext : agentContext);

                return(null);
            }

            default:
                throw new AriesFrameworkException(ErrorCode.InvalidMessage,
                                                  $"Unsupported message type {messageContext.GetMessageType()}");
            }
        }
Esempio n. 29
0
        /// <summary>
        /// Process an offer, taking previous proposals into account. The framework doesn't fully
        /// support credential proposals, and I don't know how to override one service function
        /// so for now we just use a custom handler and this function.
        /// </summary>
        /// <param name="agentContext"></param>
        /// <param name="credentialOffer"></param>
        /// <param name="connection"></param>
        /// <returns></returns>
        private async Task <string> ProcessOfferAsync(IAgentContext agentContext, CredentialOfferMessage credentialOffer,
                                                      ConnectionRecord connection)
        {
            var offerAttachment = credentialOffer.Offers.FirstOrDefault(x => x.Id == "libindy-cred-offer-0")
                                  ?? throw new ArgumentNullException(nameof(CredentialOfferMessage.Offers));

            var offerJson    = offerAttachment.Data.Base64.GetBytesFromBase64().GetUTF8String();
            var offer        = JObject.Parse(offerJson);
            var definitionId = offer["cred_def_id"].ToObject <string>();
            var schemaId     = offer["schema_id"].ToObject <string>();

            // check if credential already exists
            CredentialRecord credentialRecord;

            try
            {
                credentialRecord = await _credentialService.GetByThreadIdAsync(agentContext, credentialOffer.GetThreadId());

                if (credentialRecord.ConnectionId != connection.Id)
                {
                    throw new AriesFrameworkException(ErrorCode.InvalidRecordData, "Connection from credential offer is not same as previously stored record.");
                }
            }
            catch
            {
                // Write offer record to local wallet
                credentialRecord = new CredentialRecord
                {
                    Id           = Guid.NewGuid().ToString(),
                    ConnectionId = connection?.Id,
                };
                credentialRecord.SetTag(TagConstants.Role, TagConstants.Holder);
                credentialRecord.SetTag(TagConstants.LastThreadId, credentialOffer.GetThreadId());

                await _recordService.AddAsync(agentContext.Wallet, credentialRecord);

                var THCredentialExchange = new TestHarnessCredentialExchange
                {
                    RecordId = credentialRecord.Id,
                    ThreadId = credentialOffer.GetThreadId(),
                    State    = TestHarnessCredentialExchangeState.OfferReceived
                };

                _credentialCache.Set(THCredentialExchange.ThreadId, THCredentialExchange);
            }

            credentialRecord.OfferJson = offerJson;
            credentialRecord.CredentialDefinitionId = definitionId;
            credentialRecord.SchemaId = schemaId;
            credentialRecord.CredentialAttributesValues = credentialOffer.CredentialPreview?.Attributes
                                                          .Select(x => new CredentialPreviewAttribute
            {
                Name     = x.Name,
                MimeType = x.MimeType,
                Value    = x.Value
            }).ToArray();
            credentialRecord.State = CredentialState.Offered;

            await _recordService.UpdateAsync(agentContext.Wallet, credentialRecord);

            _eventAggregator.Publish(new ServiceMessageProcessingEvent
            {
                RecordId    = credentialRecord.Id,
                MessageType = credentialOffer.Type,
                ThreadId    = credentialOffer.GetThreadId()
            });

            return(credentialRecord.Id);
        }
Esempio n. 30
0
        public async Task <(CredentialOfferMessage, CredentialRecord)> CreateOfferV1Async(IAgentContext agentContext, OfferConfiguration config, string connectionId = null)
        {
            Logger.LogInformation(LoggingEvents.CreateCredentialOffer, "DefinitionId {0}, IssuerDid {1}",
                                  config.CredentialDefinitionId, config.IssuerDid);

            var threadId = Guid.NewGuid().ToString();

            if (!string.IsNullOrEmpty(connectionId))
            {
                var connection = await ConnectionService.GetAsync(agentContext, connectionId);

                if (connection.State != ConnectionState.Connected)
                {
                    throw new AgentFrameworkException(ErrorCode.RecordInInvalidState,
                                                      $"Connection state was invalid. Expected '{ConnectionState.Connected}', found '{connection.State}'");
                }
            }

            if (config.CredentialAttributeValues != null && config.CredentialAttributeValues.Any())
            {
                CredentialUtils.ValidateCredentialPreviewAttributes(config.CredentialAttributeValues);
            }

            var offerJson = await AnonCreds.IssuerCreateCredentialOfferAsync(
                agentContext.Wallet, config.CredentialDefinitionId);

            var offerJobj = JObject.Parse(offerJson);
            var schemaId  = offerJobj["schema_id"].ToObject <string>();

            // Write offer record to local wallet
            var credentialRecord = new CredentialRecord
            {
                Id = Guid.NewGuid().ToString(),
                CredentialDefinitionId = config.CredentialDefinitionId,
                OfferJson    = offerJson,
                ConnectionId = connectionId,
                SchemaId     = schemaId,
                CredentialAttributesValues = config.CredentialAttributeValues,
                State = CredentialState.Offered,
            };

            credentialRecord.SetTag(TagConstants.LastThreadId, threadId);
            credentialRecord.SetTag(TagConstants.Role, TagConstants.Issuer);

            if (!string.IsNullOrEmpty(config.IssuerDid))
            {
                credentialRecord.SetTag(TagConstants.IssuerDid, config.IssuerDid);
            }

            if (config.Tags != null)
            {
                foreach (var tag in config.Tags)
                {
                    if (!credentialRecord.Tags.Keys.Contains(tag.Key))
                    {
                        credentialRecord.Tags.Add(tag.Key, tag.Value);
                    }
                }
            }

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

            return(new CredentialOfferMessage
            {
                Id = threadId,
                Offers = new Attachment[]
                {
                    new Attachment
                    {
                        Id = "libindy-cred-offer-0",
                        MimeType = CredentialMimeTypes.ApplicationJsonMimeType,
                        Data = new AttachmentContent
                        {
                            Base64 = offerJson.GetUTF8Bytes().ToBase64String()
                        }
                    }
                },
                CredentialPreview = credentialRecord.CredentialAttributesValues != null ? new CredentialPreviewMessage
                {
                    Attributes = credentialRecord.CredentialAttributesValues.Select(x => new CredentialPreviewAttriubute
                    {
                        Name = x.Name,
                        MimeType = x.MimeType,
                        Value = x.Value?.ToString()
                    }).ToArray()
                } : null
            }, credentialRecord);
        }