async Task <bool> PublishIdentity() { try { var profile = await this.repo.GetProfile(); var identityToPublish = new XIdentity { Id = this.ownChatId, PublicIdentityKey = profile.PublicKey, LastSeenUTC = DateTime.UtcNow }; var response = await this.chatClient.PublishIdentityAsync(identityToPublish); if (response.IsSuccess) { if (response.Result == this.ownChatId) { profile.IsIdentityPublished = true; Debug.Assert(profile.Id == "1"); await this.repo.UpdateProfile(profile); return(true); } throw new Exception($"The server did not confirm the identity was published. Server error: {response.Result}"); // SQL Server firewall...? } } catch (Exception e) { this.logger.LogError(e.Message); } return(false); }
internal async Task VerifyContactInAddedStateAsync(Identity addedContact) { Debug.Assert(addedContact.ContactState == ContactState.Added); Debug.Assert(Guid.TryParse(addedContact.Id, out var isGuid)); var response = await this.chatClient.GetIdentityAsync(addedContact.UnverifiedId); if (!response.IsSuccess) { throw new InvalidOperationException($"ChatClient could not download identity: {response.Error}"); } XIdentity contactAdded = response.Result; if (contactAdded.ContactState == ContactState.Valid) { // It's on the server marked as valid, check if the public key resolves to the expected chat id if (contactAdded.Id != null && contactAdded.PublicIdentityKey != null && ChatId.GenerateChatId(contactAdded.PublicIdentityKey) == contactAdded.Id) { await this.repo.UpdateAddedContactWithPublicKey(contactAdded, addedContact.Id); await this.contactListManager.ChatWorker_ContactUpdateReceived(null, addedContact.Id); return; } } throw new InvalidOperationException("VerifyContactInAddedStateAsync failed."); }
private static Student MergeIdentities(IEnumerable <XIdentity> primitives) { XIdentity first = primitives.First(); if (primitives.Count() > 1 && !( primitives.All(primitive => primitive.BaseName == first.BaseName) && primitives.All(primitive => primitive.BaseNeptun == first.BaseNeptun) && primitives.All(primitive => primitive.BaseEducationProgram == first.BaseEducationProgram) && primitives.All(primitive => primitive.OriginalEducationProgram == first.OriginalEducationProgram) && primitives.All(primitive => primitive.EffectiveSemester == first.EffectiveSemester ))) { Log.Write("HIBALEHETŐSÉG: A hallgató adatai között ütközés van."); } Student student = new Student(); student.Neptun = first.BaseNeptun; student.Name = first.BaseName; student.EducationProgram = first.BaseEducationProgram; student.OriginalEducationProgram = first.OriginalEducationProgram; student.EffectiveSemester = first.EffectiveSemester; student.Emails = primitives .Select(primitive => primitive.Email) .Distinct() .ToArray(); return(student); }
public bool Equals(XIdentity identity) { return (base.Equals(identity) && this.EffectiveSemester == identity.EffectiveSemester && this.Email == identity.Email && this.Phone == identity.Phone); }
public async Task <string> AddIdentity(XIdentity identity, Action <string, byte[]> initTlsUser) { await SemaphoreSlim.WaitAsync(); try { if (identity == null) { throw new ArgumentNullException(nameof(XIdentity)); } if (identity.Id == null) { throw new ArgumentNullException(nameof(XIdentity.Id)); } if (identity.PublicIdentityKey == null) { throw new ArgumentNullException(nameof(XIdentity.PublicIdentityKey)); } if (ChatId.GenerateChatId(identity.PublicIdentityKey) != identity.Id) { throw new Exception("Id and public key are unrelated."); } identity.ContactState = ContactState.Valid; XIdentity existing = await this.identitiesRepository.Get(identity.Id); if (existing == null) { await this.identitiesRepository.Add(identity); } else { if (!ByteArrays.AreAllBytesEqual(identity.PublicIdentityKey, existing.PublicIdentityKey)) { throw new Exception($"Different new PublicKey for {identity.Id}. Ignoring request!"); } existing.LastSeenUTC = DateTime.UtcNow; await this.identitiesRepository.Update(existing); } if (initTlsUser != null) // TLS { initTlsUser(identity.Id, identity.PublicIdentityKey); } this.logger.LogInformation($"Identity {identity.Id} was published.", nameof(MessageNodeRepository)); return(identity.Id); } finally { SemaphoreSlim.Release(); } }
public async Task <byte[]> ExecutePublishIdentityAsync(Command command, Action <string, byte[]> initTlsUser) { if (command.CommandId != CommandId.PublishIdentity) { throw new InvalidOperationException(); } XIdentity identityBeingPublished = command.CommandData.DeserializeXIdentityCore(); string result = await this.messageNodeRepository.AddIdentity(identityBeingPublished, initTlsUser); return(new RequestCommand(CommandId.PublishIdentity_Response, result).Serialize(CommandHeader.Yes)); }
public async Task UpdateAddedContactWithPublicKey(XIdentity identity, string guidId) { Guid.Parse(guidId); if (identity == null) { throw new ArgumentNullException(nameof(identity)); } if (identity.ContactState != ContactState.Valid) { throw new Exception($"Expected IdentityState.Added but was {identity.ContactState}"); } if (identity.PublicIdentityKey == null) { throw new Exception("The public key must not be null"); } await SemaphoreSlim.WaitAsync(); try { var contact = await this.contacts.Get(guidId); if (contact != null) { // do not ovwerwrite the name and the image of the contact from the repository! contact.UnverifiedId = null; contact.FirstSeenUtc = identity.FirstSeenUTC; contact.LastSeenUtc = identity.LastSeenUTC; contact.StaticPublicKey = identity.PublicIdentityKey; contact.ContactState = identity.ContactState; await this.contacts.Update(contact); } } finally { SemaphoreSlim.Release(); } }
public async Task <Response <string> > PublishIdentityAsync(XIdentity identity) { var response = new Response <string>(); try { var requestCommand = new RequestCommand(CommandId.PublishIdentity, identity).Serialize(CommandHeader.Yes); var tlsResponse = await this.networkClient.SendRequestAsync(requestCommand, Transport.TCP); AssertOneItem(tlsResponse); response.Result = tlsResponse[0].CommandData.DeserializeStringCore(); response.SetSuccess(); } catch (Exception e) { this.logger.LogError(e.Message); response.SetError(e); } return(response); }
public async Task <byte[]> ExecuteAuthenticatedRequestAsync(Command command) { switch (command.CommandId) { case CommandId.AnyNews: { string recipientId = command.CommandData.DeserializeStringCore(); var result = await this.messageNodeRepository.AnyNews(recipientId); return(new RequestCommand(CommandId.AnyNews_Response, result).Serialize(CommandHeader.Yes)); // only when the client receives it via UDP a header is needed. } case CommandId.CheckForResendRequest: { XResendRequest resendRequestQuery = command.CommandData.DeserializeResendRequest(); byte result = await this.messageNodeRepository.CheckForResendRequest(resendRequestQuery); return(new RequestCommand(CommandId.CheckForResendRequest_Response, result).Serialize(CommandHeader.Yes)); } case CommandId.DownloadMessages: { string recipientId = command.CommandData.DeserializeStringCore(); var messages = await this.messageNodeRepository.GetMessages(recipientId); if (messages.Count == 0) { throw new CommandProtocolException("No message to download, please check with CommandId.AnyNews first."); // connected clients get this error information } return(new RequestCommand(CommandId.DownloadMessage_Response, messages).Serialize(CommandHeader.Yes)); } case CommandId.UploadMessage: { XMessage message = command.CommandData.DeserializeMessage(); // Deserialize only what's needed, blob-store the rest string ack = await this.messageNodeRepository.AddMessage(message); return(new RequestCommand(CommandId.UploadMessage_Response, ack).Serialize(CommandHeader.Yes)); } case CommandId.UploadResendRequest: { XResendRequest resendRequest = command.CommandData.DeserializeResendRequest(); var resendRequestAck = await this.messageNodeRepository.AddResendRequest(resendRequest); return(new RequestCommand(CommandId.UploadResendRequest_Response, resendRequestAck).Serialize(CommandHeader.Yes)); } case CommandId.GetIdentity: { var addedContactId = command.CommandData.DeserializeStringCore(); XIdentity identity = await this.messageNodeRepository.GetIdentityAsync(addedContactId); return(new RequestCommand(CommandId.GetIdentity_Response, identity).Serialize(CommandHeader.Yes)); } case CommandId.PublishIdentity: { XIdentity identityBeingPublished = command.CommandData.DeserializeXIdentityCore(); string result = await this.messageNodeRepository.AddIdentity(identityBeingPublished, null); return(new RequestCommand(CommandId.PublishIdentity_Response, result).Serialize(CommandHeader.Yes)); } default: throw new CommandProtocolException($"Unknown CommandId {command.CommandId}."); } }