diff --git a/ChatController/ChatController.csproj b/ChatController/ChatController.csproj index 2fd8096..9df76a0 100644 --- a/ChatController/ChatController.csproj +++ b/ChatController/ChatController.csproj @@ -76,6 +76,7 @@ + diff --git a/ChatController/ChatKlassen/ChatMessage.cs b/ChatController/ChatKlassen/ChatMessage.cs index dd0ea6c..a1a6be3 100644 --- a/ChatController/ChatKlassen/ChatMessage.cs +++ b/ChatController/ChatKlassen/ChatMessage.cs @@ -3,6 +3,7 @@ using System.ComponentModel; using System.Text.RegularExpressions; using System.Windows; using System.Windows.Media; +using ChatController.Core; using ChatController.Utilities; using static System.Windows.HorizontalAlignment; @@ -73,7 +74,16 @@ namespace ChatController.ChatKlassen FilePath = pUrl; - Thumbnail = Utils.CreateImageSourceFromPath(pSmallerImagePath); + var cache = OwnChatCache.GetInstance(); + + var imgSrc = cache.GetImageSourceFromCache($"group-{pGroupId}"); + + if(imgSrc == null) + { + imgSrc = Utils.CreateImageSourceFromPath(pSmallerImagePath); + } + + Thumbnail = imgSrc; GroupId = pGroupId; diff --git a/ChatController/ChatMainControl.xaml.cs b/ChatController/ChatMainControl.xaml.cs index 66f2002..885eb92 100644 --- a/ChatController/ChatMainControl.xaml.cs +++ b/ChatController/ChatMainControl.xaml.cs @@ -755,7 +755,11 @@ namespace ChatController if(senderId != receiverId && (_IsInBackground || receiverGroupId != selectedGroupId)) { - ContainingWindow.Icon = Utils.GetImageSourceFromIcon(Resource.oC_favico_NewMessage); + if(ContainingWindow != null) + { + ContainingWindow.Icon = Utils.GetImageSourceFromIcon(Resource.oC_favico_NewMessage); + } + ShowNotification(newContact.Name, newContact.ReceivedMessage, newContact.GroupId); } diff --git a/ChatController/Core/OwnChatCache.cs b/ChatController/Core/OwnChatCache.cs new file mode 100644 index 0000000..4bd43f1 --- /dev/null +++ b/ChatController/Core/OwnChatCache.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Media; + +namespace ChatController.Core +{ + public class OwnChatCache + { + // Key-> "group-127" oder "user-938" + private Dictionary _ImageSources = new Dictionary(); + + // Key-> "group-127" oder "user-938" + private Dictionary _Bitmaps = new Dictionary(); + + private static OwnChatCache _Instance; + + private OwnChatCache() { } + + public static OwnChatCache GetInstance() + { + return _Instance ?? (_Instance = new OwnChatCache()); + } + + public void ClearAll() + { + ClearImageSources(); + ClearBitmaps(); + } + + public void ClearImageSources() + { + _ImageSources.Clear(); + } + + public void ClearBitmaps() + { + _Bitmaps.Clear(); + } + + public ImageSource GetImageSourceFromCache(string key) + { + if(key == null || _ImageSources == null || !_ImageSources.ContainsKey(key)) + { + return null; + } + + var imageSourceCacheObject = _ImageSources[key]; + + var expirationDate = imageSourceCacheObject.ExpirationDate; + + return expirationDate < DateTime.Now ? null : imageSourceCacheObject.Image; + } + + public void AddImageToCache(string key, ImageSource imageSource) + { + if(_ImageSources == null) + { + _ImageSources = new Dictionary(); + } + + var newImageSourceCacheObject = new ImageSourceCacheObject(imageSource); + + if(_ImageSources.ContainsKey(key)) + { + _ImageSources[key] = newImageSourceCacheObject; + } + else + { + _ImageSources.Add(key, newImageSourceCacheObject); + } + } + + public Bitmap GetBitmapFromCache(string key) + { + if(key == null || _Bitmaps == null || !_Bitmaps.ContainsKey(key)) + { + return null; + } + + var bitmapCacheObject = _Bitmaps[key]; + + var expirationDate = bitmapCacheObject.ExpirationDate; + + return expirationDate < DateTime.Now ? null : bitmapCacheObject.Bitmap; + } + + public void AddBitmapToCache(string key, Bitmap bitmap) + { + if(_Bitmaps == null) + { + _Bitmaps = new Dictionary(); + } + + var newBitmapCacheObject = new BitmapCacheObject(bitmap); + + if(_Bitmaps.ContainsKey(key)) + { + _Bitmaps[key] = newBitmapCacheObject; + } + else + { + _Bitmaps.Add(key, newBitmapCacheObject); + } + } + } + + public class ImageSourceCacheObject + { + public DateTime ExpirationDate { get; } + + public ImageSource Image { get; } + + public ImageSourceCacheObject(ImageSource imageSource) + { + ExpirationDate = DateTime.Now.AddYears(1); + Image = imageSource; + } + } + + public class BitmapCacheObject + { + public DateTime ExpirationDate { get; } + + public Bitmap Bitmap { get; } + + public BitmapCacheObject(Bitmap bitmap) + { + ExpirationDate = DateTime.Now.AddYears(1); + Bitmap = bitmap; + } + } +} diff --git a/ChatController/HauptKlassen/Chat.cs b/ChatController/HauptKlassen/Chat.cs index 952bbb4..0a5daf8 100644 --- a/ChatController/HauptKlassen/Chat.cs +++ b/ChatController/HauptKlassen/Chat.cs @@ -3,20 +3,21 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; -using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Net; using System.Net.Http; -using System.Text; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Windows; using System.Windows.Data; using System.Windows.Forms; using System.Windows.Media; using System.Windows.Media.Imaging; +using ChatController.Core; using ChatController.LoginKlassen; using ChatController.Utilities; using ChatController.Utilities.Extensions; @@ -55,8 +56,53 @@ namespace ChatController.HauptKlassen ChatDaten = chatDaten; ExceptionCallback = exceptionCallback; ThreadExceptionCallback = threadExceptionCallback; + + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; + + PinCertificate(); } + private static void PinCertificate() + { + ServicePointManager.ServerCertificateValidationCallback = PinPublicKey; + } + + private static bool PinPublicKey(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslpolicyerrors) + { + try + { + if(certificate == null || chain == null) + { + return false; + } + + var chainContainsPk = false; + + foreach(var element in chain.ChainElements) + { + var pk = element.Certificate.GetPublicKeyString(); + if(pk == PubKeyX3 || pk == PubKeyR3 || pk == PubKeyE1) + { + chainContainsPk = true; + } + } + + var subjectAccepted = certificate.Subject.Trim().ToLower().EndsWith(".bewoplaner.de") || certificate.Subject.Trim().ToLower().EndsWith(".ownchat.de"); + + return chainContainsPk && subjectAccepted; + } + catch(Exception) + { + return false; + } + } + + private const string PubKeyX3 = "3082010A02820101009CD30CF05AE52E47B7725D3783B3686330EAD735261925E1BDBE35F170922FB7B84B4105ABA99E350858ECB12AC468870BA3E375E4E6F3A76271BA7981601FD7919A9FF3D0786771C8690E9591CFFEE699E9603C48CC7ECA4D7712249D471B5AEBB9EC1E37001C9CAC7BA705EACE4AEBBD41E53698B9CBFD6D3C9668DF232A42900C867467C87FA59AB8526114133F65E98287CBDBFA0E56F68689F3853F9786AFB0DC1AEF6B0D95167DC42BA065B299043675806BAC4AF31B9049782FA2964F2A20252904C674C0D031CD8F31389516BAA833B843F1B11FC3307FA27931133D2D36F8E3FCF2336AB93931C5AFC48D0D1D641633AAFA8429B6D40BC0D87DC3930203010001"; + + private const string PubKeyR3 = "3082010A0282010100BB021528CCF6A094D30F12EC8D5592C3F882F199A67A4288A75D26AAB52BB9C54CB1AF8E6BF975C8A3D70F4794145535578C9EA8A23919F5823C42A94E6EF53BC32EDB8DC0B05CF35938E7EDCF69F05A0B1BBEC094242587FA3771B313E71CACE19BEFDBE43B45524596A9C153CE34C852EEB5AEED8FDE6070E2A554ABB66D0E97A540346B2BD3BC66EB66347CFA6B8B8F572999F830175DBA726FFB81C5ADD286583D17C7E709BBF12BF786DCC1DA715DD446E3CCAD25C188BC60677566B3F118F7A25CE653FF3A88B647A5FF1318EA9809773F9D53F9CF01E5F5A6701714AF63A4FF99B3939DDC53A706FE48851DA169AE2575BB13CC5203F5ED51A18BDB150203010001"; + + private const string PubKeyE1 = "04245C2DA22AFD1C4BA65D97732731ACB2A06962EF65E8A6B0F0AC4B9FFF1C0B700FD3982F4DFC0F009B37F074055732972E05EF2A4325A3FB6E342713F64F7E69D302995EEB244792C1249BE6B1218FC12481FC68CC1F69BA58F51922F774C616"; + // WebRequest public List AddContacts() { @@ -79,7 +125,6 @@ namespace ChatController.HauptKlassen } // WebRequest - // TODO: Auth-Token zum Header hinzufügen private ImageSource DownloadImage(string pUri) { try @@ -144,7 +189,6 @@ namespace ChatController.HauptKlassen if (!string.IsNullOrEmpty(serverResponse)) { - Debug.WriteLine(serverResponse); _UserMessages = JsonConvert.DeserializeObject(serverResponse); if (_UserMessages.Response.HasMorePages) @@ -905,7 +949,7 @@ namespace ChatController.HauptKlassen var imageName = Utils.GenerateTempName() + ".jpg"; - System.Drawing.Image image = bitmap; + Image image = bitmap; AddMediumContextDerNachrichtView(Utils.ImageToByteArray(image), imageName, pGroupOid); @@ -1147,11 +1191,27 @@ namespace ChatController.HauptKlassen } } - var avatar = Utils.AvatarToImageSourceConverter(groupInput.Avatar, groupInput.OnlyEmployees, groupInput.Users.Length > 2); + var key = $"group-{groupInput.Oid}"; - var profilePicture = Utils.ConvertAvatarToBitmap(groupInput.Avatar, groupInput.OnlyEmployees, groupInput.Users.Length > 2); + var cacheInstance = OwnChatCache.GetInstance(); - contacts.Add(new Contact(groupInput.Name, groupInput.LastMessage, formattedTime, groupInput.Oid, userIdManage, groupInput.OnlyEmployees, groupInput.Users.Length, groupInput.CanWrite, groupInput.AccentColor, profilePicture, avatar)); + var imgSrc = cacheInstance.GetImageSourceFromCache(key); + + if(imgSrc == null) + { + imgSrc = Utils.AvatarToImageSourceConverter(groupInput.Avatar, groupInput.OnlyEmployees, groupInput.Users.Length > 2); + cacheInstance.AddImageToCache(key, imgSrc); + } + + var bmp = cacheInstance.GetBitmapFromCache(key); + + if(bmp == null) + { + bmp = Utils.ConvertAvatarToBitmap(groupInput.Avatar, groupInput.OnlyEmployees, groupInput.Users.Length > 2); + cacheInstance.AddBitmapToCache(key, bmp); + } + + contacts.Add(new Contact(groupInput.Name, groupInput.LastMessage, formattedTime, groupInput.Oid, userIdManage, groupInput.OnlyEmployees, groupInput.Users.Length, groupInput.CanWrite, groupInput.AccentColor, bmp, imgSrc)); if(pShouldUpdateLastTimeStamp) { diff --git a/ChatController/LoginKlassen/ChatGruppenDaten.cs b/ChatController/LoginKlassen/ChatGruppenDaten.cs index ffc784d..7cef755 100644 --- a/ChatController/LoginKlassen/ChatGruppenDaten.cs +++ b/ChatController/LoginKlassen/ChatGruppenDaten.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.ComponentModel; using System.IO; using Newtonsoft.Json; @@ -25,7 +26,8 @@ namespace ChatController.LoginKlassen [JsonProperty("accent_color")] public string AccentColor { get; set; } - [JsonProperty("i_can_write")] + [DefaultValue(true)] + [JsonProperty("i_can_write", DefaultValueHandling = DefaultValueHandling.Populate)] public bool CanWrite { get; set; } [JsonProperty("i_can_see_participants")] diff --git a/ChatController/Utilities/Utils.cs b/ChatController/Utilities/Utils.cs index 21a8ddc..1874955 100644 --- a/ChatController/Utilities/Utils.cs +++ b/ChatController/Utilities/Utils.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.IO; @@ -36,6 +37,8 @@ namespace ChatController.Utilities if(!string.IsNullOrWhiteSpace(linkToPicture)) { + Debug.WriteLine("Lade Bitmap herunter..."); + var client = new RestClient(linkToPicture); var request = new RestRequest(Method.GET) @@ -132,6 +135,8 @@ namespace ChatController.Utilities { if (!string.IsNullOrEmpty(pPathToImageFile)) { + Debug.WriteLine("Lade Bild herunter..."); + Bitmap bitmap = null; var client = new RestClient(pPathToImageFile);