public ChangeGroupResponse ChangeGroup(ISession session, ChangeGroupRequest request) { var response = request.CreateResponse <ChangeGroupResponse>(); var groupChat = _groupChatsRepository.GetChat(request.GroupId); if (!HasAccess(groupChat, session.UserId)) { response.Success = false; response.Error = Errors.OperationIsNotPermitted; return(response); } if (groupChat.Avatar != request.NewGroupAvatar) { groupChat.Avatar = request.NewGroupAvatar; _groupChatsRepository.UpdateOrCreateGroup(groupChat); foreach (var participant in groupChat.Participants) { _groupChangedEventManager.DeliverEventToDevices(participant.Devices, () => new GroupChangedEvent { ChangesAuthorId = session.UserId, GroupId = request.GroupId, Avatar = request.NewGroupAvatar, Type = GroupChangedEvent.ChangesType.NewAvatar }); } } if (groupChat.Name != request.NewGroupName) { groupChat.Name = request.NewGroupName; _groupChatsRepository.UpdateOrCreateGroup(groupChat); foreach (var participant in groupChat.Participants) { _groupChangedEventManager.DeliverEventToDevices(participant.Devices, () => new GroupChangedEvent { ChangesAuthorId = session.UserId, GroupId = request.GroupId, Name = request.NewGroupName, Type = GroupChangedEvent.ChangesType.NewName }); } } return(response); }
public SendMessageResponse SendMessage(ISession session, SendMessageRequest request) { var response = request.CreateResponse <SendMessageResponse>(); Logger.Info("SendMessage from Id={0} (Device={1}) to Id={2} ({3} devices)", session.UserId, session.DeviceId.Cut(), request.ReceiverUserId, request.Keys != null ? request.Keys.Count : -1); Dictionary <string, long> actualMessageReceiversDevices = null; Dictionary <string, byte[]> keys = request.Keys; if (request.GroupId != Guid.Empty)// group conversation { var groupChat = _groupChatsRepository.GetChat(request.GroupId); //sender is in the group? if (groupChat.Participants.All(i => i.UserId != session.UserId)) { response.Success = false; response.Error = Errors.YouAreNotParticipantOfThatGroup; return(response); } if (keys == null) //means not encrypted { keys = groupChat.Participants .SelectMany(p => p.Devices) .Where(p => p != session.DeviceId) .Distinct() .ToDictionary <string, string, byte[]>(k => k, v => null); //null value means unencrypted } else { //it means we will check all provided devices below (see if (actualMessageReceiversDevices != null)) -- just to avoid copy-paste actualMessageReceiversDevices = new Dictionary <string, long>(); foreach (var groupChatParticipant in groupChat.Participants) { foreach (var device in groupChatParticipant.Devices) { actualMessageReceiversDevices[device] = groupChatParticipant.UserId; } } } } else // private conversation { if (request.ReceiverUserId == session.UserId) { response.Success = false; response.Error = Errors.SendMessage_ReceiverAndSenderAreSame; return(response); } if (keys == null)//means not encrypted { keys = _devicesRepository.GetDevices(request.ReceiverUserId).ToDictionary <string, string, byte[]>(k => k, v => null); } else { //it means we will check all provided devices below (see if (actualMessageReceiversDevices != null)) -- just to avoid copy-paste actualMessageReceiversDevices = _devicesRepository.GetDevices(request.ReceiverUserId).ToDictionary(k => k, v => request.ReceiverUserId); } } if (actualMessageReceiversDevices != null) //TODO: uncoment later { var providedDevices = keys.Select(i => i.Key); List <string> union; List <string> notProvidedDevices; //conversation has more devices than user provided as targets List <string> wrongDevices; //some of the devices user provided are not members of that conversation actualMessageReceiversDevices.Select(i => i.Key) .FindIntersectionAndDifference(providedDevices, out union, out notProvidedDevices, out wrongDevices); if (notProvidedDevices.Any()) { response.Success = false; response.Error = Errors.SendMessage_ProvideKeysForTheseDevices; //we will help the user - provide public keys as well response.MissedDevicesWithPublicKeysToReEncrypt = notProvidedDevices .Where(d => session.DeviceId != d) .Select(d => new PublicKeyInfo { DeviceId = d, PublicKey = _devicesRepository.GetPublicKeyForDevice(d), UserId = actualMessageReceiversDevices[d] }) .ToList(); return(response); } //cut receivers not in the conversation //TODO: uncomment it later /*foreach (var key in wrongDevices) * { * keys.Remove(key); * }*/ } keys.Remove(session.DeviceId); if (keys.Count < 1) { response.Success = false; response.Error = Errors.SendMessage_ReceiversNotFound; return(response); } foreach (var key in keys) { var innerMsg = new Message { SenderAccessToken = session.AccessToken, Text = request.Message, GroupId = request.GroupId, SenderId = session.UserId, SenderDeviceId = session.DeviceId, SenderName = request.SenderName, ReceiverId = request.ReceiverUserId, MessageTypeId = (int)request.MessageType, Thumbnail = request.Thumbnail, ReceiverDeviceId = key.Key, EncryptionKey = key.Value, MessageToken = request.MessageToken, }; _messageEventManager.DeliverEventToDevice(innerMsg); } return(response); }