示例#1
0
        public void Messages()
        {
            var msg = new ChadderMessage();

            msg.Type      = MESSAGE_TYPE.TEXT;
            msg.Body      = "Testing messages";
            msg.myMessage = true;
            msg.fromId    = Guid.NewGuid().ToString();
            msg.messageId = Guid.NewGuid().ToString();

            var packed = new ChadderPackedMessageText(msg);
            var serial = packed.Serialize();

            var packed2 = ChadderEncryptedContent.Deserialize(serial) as ChadderPackedMessageText;

            Assert.NotNull(packed2);
            Assert.AreEqual(packed.Id, packed2.Id);
            Assert.AreEqual(packed.Group, packed2.Group);
            Assert.AreEqual(packed.Time, packed2.Time);
            Assert.AreEqual(packed.From, packed2.From);
            Assert.AreEqual(packed.Body, packed2.Body);

            packed = new ChadderPackedMessageText(msg);
            serial = packed.Serialize();

            packed2 = ChadderEncryptedContent.Deserialize(serial) as ChadderPackedMessageText;
            Assert.NotNull(packed2);
            Assert.AreEqual(packed.Id, packed2.Id);
            Assert.AreEqual(packed.Group, packed2.Group);
            Assert.AreEqual(packed.Time, packed2.Time);
            Assert.AreEqual(packed.From, packed2.From);
            Assert.AreEqual(packed.Body, packed2.Body);
        }
        protected async Task SendPendingMessages()
        {
            ChadderMessage msg = null;

            try
            {
                var backoff = new ExponentialBackoff(1000, 5000);
                while (PendingMessages.Count > 0)
                {
                    if (PendingMessages.TryPeek(out msg) && msg.Status != ChadderMessage.MESSAGE_STATUS.SENT)
                    {
                        var conversation = db.GetConversation(msg.ConversationId);
                        if (await SendMessageToServer(msg, conversation) == ChadderError.OK)
                        {
                            while (PendingMessages.TryDequeue(out msg))
                            {
                                ;
                            }
                            backoff.Reset();
                        }
                        else
                        {
                            await backoff.Failed();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Insight.Track("SendPendingMessages safe try-catch");
                Insight.Report(ex);
            }
            SendPendingMessagesTask = null;
        }
 public void AddPendingMessage(ChadderMessage msg, bool start = true)
 {
     PendingMessages.Enqueue(msg);
     if (start)
     {
         StartSendPendingMessages();
     }
 }
示例#4
0
        public async Task TakeBack(ChadderMessage msg, ChadderConversation conversation)
        {
            ChadderApp.UIHelper.ShowLoading();
            var result = await Source.TakeMessageBack(msg, conversation);

            ChadderApp.UIHelper.HideLoading();
            ShowErrorIfNotOk(result);
        }
        public async Task <ChadderMessage> SendMessage(string txt, ChadderConversation conversation)
        {
            var msg = ChadderMessage.Create(conversation, db.LocalUser, ChadderMessage.MESSAGE_TYPE.TEXT);

            msg.Body = txt;

            await db.AddMessage(msg, conversation);

            AddPendingMessage(msg);
            return(msg);
        }
示例#6
0
        public async void NewMessageProtocolTransition()
        {
            var source1 = await CreateAccount();

            var source2 = await CreateAccount();

            await source2.ChangeShareName(true);

            var result = await source1.addContact(source2.database.profile.myId);

            await source2.ChangeShareName(false);

            Ok(result.Item1);

            var contact1 = source1.database.getContact(source2.database.profile.myId);

            Assert.NotNull(contact1);
            source1.database.conversations.Clear();
            var conversation1 = await source1.database.GetConversationByContact(contact1);

            Assert.Null(conversation1);

            var contact2 = source2.database.getContact(source1.database.profile.myId);

            Assert.NotNull(contact2);
            var conversation2 = await source2.database.GetConversationByContact(contact2);

            Assert.NotNull(conversation2);

            var body = "Testing";
            var msg  = new ChadderMessage()
            {
                Type      = MESSAGE_TYPE.TEXT,
                messageId = Guid.NewGuid().ToString(),
                myMessage = true,
                Body      = "Test",
                fromId    = source1.database.profile.myId,
                LocalTime = DateTime.UtcNow,
                Status    = MESSAGE_STATUS.SENDING
            };
            var packed    = new ChadderPackedMessageText(msg);
            var key       = new ChadderECDHUserUserLegacy(source1.database, contact1);
            var encrypted = await ChadderAESEncryptedContent.Encrypt(source1, key, packed);

            await source2.SendNewMessage(conversation2, body);

            await Task.Delay(1000);

            Assert.AreEqual(2, conversation2.messages.Count);
        }
        public async void SendPicture(byte[] data, ChadderConversation conversation)
        {
            var record = new ChadderSQLPicture()
            {
                ToBeUploaded = true,
                Bin          = data,
                PictureId    = Guid.NewGuid().ToString()// Temporary
            };

            await sqlDB.InsertAsync(record);

            var picture = await db.LoadPicture(record, true);

            var msg = ChadderMessage.Create(conversation, db.LocalUser, ChadderMessage.MESSAGE_TYPE.PICTURE);

            msg.PictureId = record.PictureId;
            msg.Picture   = picture;

            await db.AddMessage(msg, conversation);

            AddPendingMessage(msg);
        }
        public async Task <ChadderError> TakeMessageBack(ChadderMessage msg, ChadderConversation conversation)
        {
            var package = new TakeMessageBackContent(msg.MessageId);
            var content = await EncryptForUser(package, conversation.Contact);

            var result = await AuthorizedRequest <BasicResponse>(Connection.ChatHub, "TakeMessageBack", msg.ReferenceId);

            if (result.Error == ChadderError.OK)
            {
                var request = new SendPackageParameter()
                {
                    UserId = conversation.ContactUserId,
                    Data   = content.Serialize()
                };
                result = await AuthorizedRequest <BasicResponse <string> >(Connection.ChatHub, "SendPackageToUser", request);

                if (result.Error == ChadderError.OK)
                {
                    await db.DeleteMessage(msg, conversation);
                }
            }
            return(result.Error);
        }
        protected async Task <ChadderError> SendMessageToServer(ChadderMessage msg, ChadderConversation conversation)
        {
            try
            {
                BasicMessage package = null;
                if (msg.Type == ChadderMessage.MESSAGE_TYPE.TEXT)
                {
                    package = new TextMessage()
                    {
                        Body = msg.Body
                    };
                }
                else if (msg.Type == ChadderMessage.MESSAGE_TYPE.PICTURE)
                {
                    if (msg.Picture.ToBeUploaded)
                    {
                        var record = await sqlDB.GetPicture(msg.Picture.RecordId);

                        var presult = await UploadPicture(record);

                        if (presult.Error == ChadderError.OK)
                        {
                            msg.PictureId = record.PictureId;
                            await sqlDB.UpdateAsync(msg);
                        }
                        else
                        {
                            return(presult.Error);
                        }
                    }
                    package = new ImageMessage()
                    {
                        PictureId = msg.PictureId
                    };
                }
                else
                {
                    Insight.Track("Invalid Message Type in SendMessageToServer");
                    return(ChadderError.INVALID_INPUT);
                }
                package.Id         = msg.MessageId;
                package.Group      = null;
                package.TimeSent   = msg.TimeSent.Value;
                package.Expiration = msg.Expiration.Value;

                var content = await EncryptForUser(package, conversation.Contact);

                var request = new SendPackageParameter()
                {
                    UserId = conversation.ContactUserId,
                    Data   = content.Serialize()
                };
                var result = await AuthorizedRequest <BasicResponse <string> >(Connection.ChatHub, "SendPackageToUser", request);

                if (result.Error == ChadderError.OK)
                {
                    msg.Status      = ChadderMessage.MESSAGE_STATUS.SENT;
                    msg.TimeServer  = result.Time;
                    msg.ReferenceId = result.Extra;
                    await sqlDB.UpdateAsync(msg);
                }
                return(result.Error);
            }
            catch (Exception ex)
            {
                Insight.Report(ex);
                return(ChadderError.GENERAL_EXCEPTION);
            }
        }
示例#10
0
        public virtual async Task <bool> ProcessPackage(Package package)
        {
            var content    = Content.Deserialize(package.Data);
            var identifier = await content.Find <ECDH>(this);

            string fromId = null;
            string toId   = null;

            if (identifier != null)
            {
                fromId = identifier.SourceId;
                toId   = identifier.TargetId;
            }
            if (content == null)
            {
                return(false);
            }
            // If multiple layer of encryption were to be supported there should be a loop around this section
            if (content is IContentWrapper) // Decrypt section
            {
                content = await(content as IContentWrapper).GetContent(this);
            }

            // This has to be the clear content
            if (content is UserPublicKey)
            {
                if (package.OwnerId != null)
                {
                    Insight.Track("Non-server trying to update client id");
                }
                else
                {
                    await ProcessUserPublicKey(content as UserPublicKey);
                }
            }
            else if (content is DevicePublicKey)
            {
                if (package.OwnerId != null)
                {
                    Insight.Track("Non-server trying to update device id");
                    return(true);
                }
                var device = db.GetDevice((content as DevicePublicKey).DeviceId);
                var pbk    = (content as DevicePublicKey).PublicKeyData;
                if (device == null)
                {
                    if (pbk != null)
                    {
                        device = new ChadderUserDevice()
                        {
                            DeviceId          = (content as DevicePublicKey).DeviceId,
                            PublicKeyBookData = pbk,
                            Name          = "Temp",
                            HasUserKey    = false,
                            CurrentDevice = false
                        };
                        await db.AddDevice(device);
                    }
                }
                else
                {
                    if (pbk == null)
                    {
                        db.LocalUser.Devices.Remove(device);
                        await sqlDB.DeleteAsync(device);
                    }
                    else
                    {
                        device.PublicKeyBookData = pbk;
                        await sqlDB.UpdateAsync(device);
                    }
                }
            }
            else if (content is PairDeviceContent)
            {
                if (package.OwnerId != db.LocalUser.UserId)
                {
                    Insight.Track("Not this user trying to pair device");
                    return(true);
                }
                db.LocalUser.PrivateKeyBookData = (content as PairDeviceContent).Book.Serialize();
                await sqlDB.UpdateAsync(db.LocalUser);

                return(true);
            }
            else if (content is TakeMessageBackContent)
            {
                await ProcessTakeBack(content as TakeMessageBackContent, fromId, toId);
            }
            else if (content is BasicMessage) // Process section
            {
                var msg = content as BasicMessage;
                ChadderConversation conversation = null;
                if (fromId == db.LocalUser.UserId)
                {
                    conversation = db.GetContactConversation(toId);
                }
                else
                {
                    conversation = db.GetContactConversation(package.OwnerId);
                }
                if (conversation.Messages.FirstOrDefault(i => i.MessageId == msg.Id) == null)
                {
                    var record = new ChadderMessage()
                    {
                        MessageId      = msg.Id,
                        Type           = ChadderMessage.MESSAGE_TYPE.TEXT,
                        Status         = ChadderMessage.MESSAGE_STATUS.SENT,
                        Expiration     = msg.Expiration,
                        TimeSent       = msg.TimeSent,
                        TimeReceived   = DateTime.UtcNow,
                        TimeServer     = package.Time,
                        MyMessage      = false,
                        ConversationId = conversation.recordId,
                        Sender         = conversation.Contact,
                    };

                    if (conversation.ContactUserId != fromId)
                    {
                        record.MyMessage = true;
                        record.Sender    = db.LocalUser;
                    }
                    record.UserId = record.Sender.UserId;

                    if (content is TextMessage)
                    {
                        record.Body = (content as TextMessage).Body;
                    }

                    await db.AddMessage(record, conversation);
                }
                else
                {
                    Insight.Track("Repeated Message GUID");
                }
            }
            else
            {
                return(false);
            }
            return(true);
        }
示例#11
0
 public async Task DeleteMessage(ChadderMessage msg, ChadderConversation conversation)
 {
     //++await Source.DeleteMessage(msg, conversation);
     await Source.DeleteAllMessages();
 }
示例#12
0
        public async Task BasicSystemTest()
        {
            var random   = new Random();
            var source1  = CreateSource(0);
            var username = Guid.NewGuid().ToString("N").Substring(0, 20);
            var name     = string.Format("AutoTest{0}", random.Next());

            Assert.AreEqual(ChadderError.OK, await source1.CreateUser(name, username, username));

            // Login with user on a second device
            var source2 = CreateSource(1);

            using (var await1 = new AwaitUpdate(source1))
                Assert.AreEqual(ChadderError.OK, await source2.Login(username, username));
            Assert.AreEqual(source1.db.LocalUser.UserId, source2.db.LocalUser.UserId);
            Assert.AreEqual(2, source2.db.LocalUser.Devices.Count);
            Assert.AreEqual(2, source1.db.LocalUser.Devices.Count);
            Assert.AreEqual(ChadderError.OK, await source2.CreateNewKey());

            // Test Logout (Logout Source1, check source2 devices, Login source1)
            using (var await2 = new AwaitUpdate(source2))
                Assert.AreEqual(ChadderError.OK, await source1.Logout());
            Assert.AreEqual(1, source2.db.LocalUser.Devices.Count);
            using (var await2 = new AwaitUpdate(source2))
                Assert.AreEqual(ChadderError.OK, await source1.Login(username, username));

            // Pair Previous Device
            var source2_device1 = source2.db.LocalUser.Devices.FirstOrDefault(i => i.DeviceId == source1.db.LocalDevice.DeviceId);

            using (var await1 = new AwaitUpdate(source1))
                Assert.AreEqual(ChadderError.OK, await source2.PairDevice(source2_device1));
            Assert.AreEqual(2, source1.db.LocalUser.Devices.Count);
            Assert.IsTrue(source1.db.LocalUser.PrivateKeyBookData.SequenceEqual(source2.db.LocalUser.PrivateKeyBookData));

            // Create a second user
            var source3 = CreateSource(0); // Other user will share same device with source1
            var name2   = string.Format("AutoTest{0}", random.Next());

            Assert.AreEqual(ChadderError.OK, await source3.CreateUser(name2));

            // Find first user
            var list = await source3.FindUser(name);

            Assert.AreEqual(ChadderError.OK, list.Error);
            Assert.IsNotNull(list.List.FirstOrDefault(i => i.UserId == source1.db.LocalUser.UserId));

            // Add second user
            using (var await2 = new AwaitUpdate(source2))
                using (var await3 = new AwaitUpdate(source3))
                {
                    var result = await source1.AddContact(source3.db.LocalUser.UserId);

                    Assert.AreEqual(ChadderError.OK, result.Error);
                }
            Assert.AreEqual(1, source3.db.Contacts.Count);
            Assert.AreEqual(1, source2.db.Contacts.Count);
            Assert.AreEqual(1, source1.db.Contacts.Count);

            ChadderMessage msg = null;

            // Send message From User1
            using (var await2 = new AwaitUpdate(source2))
                using (var await3 = new AwaitUpdate(source3))
                {
                    msg = await source1.SendMessage("Testing", source1.db.Conversations[0]);
                    await WaitUntilCondition(2000, "Too long to send a message", () => msg.Status == ChadderMessage.MESSAGE_STATUS.SENT);
                }
            // Check if all three devices have the same message
            Assert.AreEqual(1, source1.db.Conversations[0].Messages.Count);
            Assert.AreEqual(1, source2.db.Conversations[0].Messages.Count);
            Assert.AreEqual(1, source3.db.Conversations[0].Messages.Count);
            Assert.IsTrue(source1.db.Conversations[0].Messages[0].MyMessage);
            Assert.IsTrue(source2.db.Conversations[0].Messages[0].MyMessage);
            Assert.IsFalse(source3.db.Conversations[0].Messages[0].MyMessage);
            Assert.AreEqual(msg.Body, source2.db.Conversations[0].Messages[0].Body);
            Assert.AreEqual(msg.Body, source3.db.Conversations[0].Messages[0].Body);

            // Check TakeBack feature
            using (var await2 = new AwaitUpdate(source2))
                using (var await3 = new AwaitUpdate(source3))
                    Assert.AreEqual(ChadderError.OK, await source1.TakeMessageBack(source1.db.Conversations[0].Messages[0], source1.db.Conversations[0]));
            Assert.AreEqual(0, source1.db.Conversations[0].Messages.Count);
            Assert.AreEqual(0, source2.db.Conversations[0].Messages.Count);
            Assert.AreEqual(0, source3.db.Conversations[0].Messages.Count);

            // Change name
            name = string.Format("AutoTest{0}", random.Next());
            using (var await2 = new AwaitUpdate(source2))
                using (var await3 = new AwaitUpdate(source3))
                    Assert.AreEqual(ChadderError.OK, await source1.ChangeName(name));
            Assert.AreEqual(name, source1.db.LocalUser.Name);
            Assert.AreEqual(name, source2.db.LocalUser.Name);
            Assert.AreEqual(name, source3.db.Contacts[0].Name);

            // Change Picture, and download
            byte[] data = new byte[256 * 256];
            random.NextBytes(data);
            using (var await2 = new AwaitUpdate(source2))
                using (var await3 = new AwaitUpdate(source3))
                    Assert.AreEqual(ChadderError.OK, await source1.ChangePicture(data));
            Assert.AreEqual(source1.db.LocalUser.PictureId, source2.db.LocalUser.PictureId);
            Assert.AreEqual(source1.db.LocalUser.PictureId, source3.db.Contacts[0].PictureId);
            await source2.db.LocalUser.Picture.LoadPictureAsync(false);

            await source3.db.Contacts[0].Picture.LoadPictureAsync(false);

            Assert.IsTrue(data.SequenceEqual((await source2.sqlDB.GetPicture(source2.db.LocalUser.Picture.RecordId)).Bin));
            Assert.IsTrue(data.SequenceEqual((await source3.sqlDB.GetPicture(source3.db.Contacts[0].Picture.RecordId)).Bin));

            {   // Test Delete Contact
                using (var await2 = new AwaitUpdate(source2))
                    Assert.AreEqual(ChadderError.OK, await source1.DeleteContact(source1.db.Contacts[0]));
                Assert.AreEqual(0, source1.db.Contacts.Count);
                Assert.AreEqual(0, source2.db.Contacts.Count);
                Assert.AreEqual(1, source3.db.Contacts.Count);

                // Add the user again after deleting
                list = await source1.FindUser(name2);

                Assert.AreEqual(ChadderError.OK, list.Error);
                Assert.IsNotNull(list.List.FirstOrDefault(i => i.UserId == source3.db.LocalUser.UserId));

                using (var await2 = new AwaitUpdate(source2))
                {
                    var result = await source1.AddContact(source3.db.LocalUser.UserId);

                    Assert.AreEqual(ChadderError.OK, result.Error);
                }
                Assert.AreEqual(1, source1.db.Contacts.Count);
                Assert.AreEqual(1, source2.db.Contacts.Count);
                Assert.AreEqual(1, source3.db.Contacts.Count);
            }

            {   // Test generate new keys
                Assert.AreEqual(PublicKeyStatus.NOT_VERIFIED, source3.db.Contacts[0].KeyStatus);
                using (var await3 = new AwaitUpdate(source3))
                    Assert.AreEqual(ChadderError.OK, await source1.RefreshKeys());
                Assert.AreEqual(PublicKeyStatus.NOT_VERIFIED, source3.db.Contacts[0].KeyStatus);
                using (var await3 = new AwaitUpdate(source3))
                    Assert.AreEqual(ChadderError.OK, await source1.CreateNewKey());
                Assert.AreEqual(PublicKeyStatus.CHANGED, source3.db.Contacts[0].KeyStatus);
            }
        }