This commit is contained in:
Bartosz Chyży 2020-06-21 02:07:07 +02:00
parent c2e22ac73f
commit baa2eac499
9 changed files with 141 additions and 40 deletions

View File

@ -1,7 +1,9 @@
using System;
using SafeMessageStorage.Encryption.Hash.Providers;
using SafeMessageStorage.Encryption.Symmetric;
using SafeMessageStorage.Pages;
using SafeMessageStorage.Services.AuthorizationService;
using SafeMessageStorage.Services.MessageStorageService;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace SafeMessageStorage
@ -12,7 +14,9 @@ namespace SafeMessageStorage
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new AuthorizationPage(new AuthorizationService(new Sha256HashProvider())));
var authorizationService = new AuthorizationService(new Sha256HashProvider());
var messageStorageService = new SafeMessageStorageService(authorizationService, new SymmetricEncryptionEngine());
MainPage = new NavigationPage(new AuthorizationPage(authorizationService,messageStorageService));
}
protected override void OnStart()

View File

@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace SafeMessageStorage.Encryption.Symmetric
{
public class SymmetricEncryptionEngine : ISymmetricEncryptionEngine
{
public string Encrypt(string content, string key)
{
byte[] iv = new byte[16];
byte[] array;
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key).Take(16).ToArray();
aes.IV = iv;
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))
{
streamWriter.Write(content);
}
array = memoryStream.ToArray();
}
}
}
return Convert.ToBase64String(array);
}
public string Decrypt(string cipher, string key)
{
byte[] iv = new byte[16];
byte[] buffer = Convert.FromBase64String(cipher);
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key).Take(16).ToArray();
aes.IV = iv;
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
using (MemoryStream memoryStream = new MemoryStream(buffer))
{
using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, decryptor, CryptoStreamMode.Read))
{
using (StreamReader streamReader = new StreamReader((Stream)cryptoStream))
{
return streamReader.ReadToEnd();
}
}
}
}
}
}
}

View File

@ -19,13 +19,13 @@ namespace SafeMessageStorage.Models
}
public string Id { get; }
public string Id { get; set; }
public string Title { get; }
public string Title { get; set; }
public string Content { get; }
public string Content { get; set; }
public DateTimeOffset TimeOfCreation { get; }
public DateTimeOffset TimeOfCreation { get; set; }
}
}

View File

@ -13,20 +13,38 @@ namespace SafeMessageStorage.Pages
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class AddMessagePage : ContentPage
{
//private IMessageStorageService _messageStorage;
private IMessageStorageService _messageStorage;
public AddMessagePage(/*IMessageStorageService messageStorageService*/)
public AddMessagePage(IMessageStorageService messageStorageService)
{
InitializeComponent();
_messageStorage = messageStorageService;
}
private async void Button_OnClicked(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(TitleEntry.Text))
{
await DisplayAlert("Message not valid", "Title cannot be empty", "ok");
return;
}
if (string.IsNullOrWhiteSpace(ContentEntry.Text))
{
await DisplayAlert("Message not valid", "Content cannot be empty", "ok");
return;
}
var message = new Message(TitleEntry.Text,ContentEntry.Text);
//if(await _messageStorage.SaveMessageAsync(message))
MessageAdded?.Invoke(this,message);
if (await _messageStorage.SaveMessageAsync(message))
{
MessageAdded?.Invoke(this, message);
await Navigation.PopAsync();
}
else
{
await DisplayAlert("Failed", "Unable to add message, try again", "ok");
}
}
public event EventHandler<Message> MessageAdded;

View File

@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SafeMessageStorage.Services.AuthorizationService;
using SafeMessageStorage.Services.MessageStorageService;
using SafeMessageStorage.ViewModels;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
@ -15,11 +16,13 @@ namespace SafeMessageStorage.Pages
{
private AuthorizationPageViewModel _viewModel => this.BindingContext as AuthorizationPageViewModel;
private IAuthorizationService _authorizationService;
public AuthorizationPage(IAuthorizationService authorizationService)
private IMessageStorageService _messageStorage;
public AuthorizationPage(IAuthorizationService authorizationService, IMessageStorageService messageStorage)
{
InitializeComponent();
BindingContext = new AuthorizationPageViewModel(authorizationService);
_authorizationService = authorizationService;
_messageStorage = messageStorage;
_viewModel.AuthorizationFailed += _viewModel_AuthorizationFailed;
_viewModel.AuthorizationSucceeded += _viewModel_AuthorizationSucceeded;
@ -38,7 +41,7 @@ namespace SafeMessageStorage.Pages
private async void _viewModel_AuthorizationSucceeded(object sender, EventArgs e)
{
await Navigation.PushAsync(new MessagesListPage());
await Navigation.PushAsync(new MessagesListPage(_messageStorage));
}
private async void _viewModel_AuthorizationFailed(object sender, string e)

View File

@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SafeMessageStorage.Models;
using SafeMessageStorage.Services.MessageStorageService;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
@ -13,12 +14,12 @@ namespace SafeMessageStorage.Pages
public partial class MessageDetailPage : ContentPage
{
private string _messageId;
public MessageDetailPage(Message message)
private IMessageStorageService _messageStorage;
public MessageDetailPage(Message message, IMessageStorageService messageStorage)
{
InitializeComponent();
_messageId = message.Id;
_messageStorage = messageStorage;
Title = message.Title;
MessageContent.Text = message.Content;
@ -27,11 +28,10 @@ namespace SafeMessageStorage.Pages
private async void DeleteMessage()
{
MessageDeleted?.Invoke(this,_messageId);
await Navigation.PopAsync();
if (await _messageStorage.DeleteMessageAsync(_messageId))
await Navigation.PopAsync();
else
await DisplayAlert("Unable to delete messafe", "please try again", "ok");
}
public event EventHandler<string> MessageDeleted;
}
}

View File

@ -4,7 +4,8 @@
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="SafeMessageStorage.Pages.MessagesListPage">
x:Class="SafeMessageStorage.Pages.MessagesListPage"
Title="Messages">
<StackLayout>
<ListView x:Name="MyListView"
ItemsSource="{Binding Messages}"

View File

@ -4,6 +4,7 @@ using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using SafeMessageStorage.Models;
using SafeMessageStorage.Services.MessageStorageService;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
@ -12,27 +13,37 @@ namespace SafeMessageStorage.Pages
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MessagesListPage : ContentPage
{
private IMessageStorageService _messageStorage;
private bool _initialized;
public ObservableCollection<Message> Messages { get; set; }
public MessagesListPage()
public MessagesListPage(IMessageStorageService messageStorage)
{
InitializeComponent();
Messages = new ObservableCollection<Message>()
{
new Message("Siemano","jakas wiadomosc"),
new Message("Kanapka","elo")
};
_messageStorage = messageStorage;
Messages = new ObservableCollection<Message>();
BindingContext = this;
}
protected override async void OnAppearing()
{
base.OnAppearing();
Messages.Clear();
var messages = await _messageStorage.ReadMessagesAsync();
foreach (var message in messages)
{
Messages.Add(message);
}
}
async void Handle_ItemTapped(object sender, ItemTappedEventArgs e)
{
if (e.Item == null)
return;
var message = ((ListView) sender).SelectedItem as Message;
var detailPage = new MessageDetailPage(message);
detailPage.MessageDeleted += (sender, messageId) => OnMessageDeleted(messageId);
var detailPage = new MessageDetailPage(message, _messageStorage);
//detailPage.MessageDeleted += (sender, messageId) => OnMessageDeleted(messageId);
await Navigation.PushAsync(detailPage);
////Deselect Item
@ -41,17 +52,10 @@ namespace SafeMessageStorage.Pages
private async void Button_OnClicked(object sender, EventArgs e)
{
var addMessagePage = new AddMessagePage();
addMessagePage.MessageAdded+= (o, message) => Dispatcher.BeginInvokeOnMainThread(()=>Messages.Add(message));
var addMessagePage = new AddMessagePage(_messageStorage);
//addMessagePage.MessageAdded+= (o, message) => Dispatcher.BeginInvokeOnMainThread(()=>Messages.Add(message));
await Navigation.PushAsync(addMessagePage);
}
private void OnMessageDeleted(string messageId)
{
var toRemove = Messages.FirstOrDefault(m => m.Id == messageId);
Messages.Remove(toRemove);
}
}
}

View File

@ -16,6 +16,12 @@ namespace SafeMessageStorage.Services.MessageStorageService
private ISymmetricEncryptionEngine _encryptionEngine;
private readonly string _messagesKey = "377f2486-d2c3-48a7-b821-45d7314479cd";
public SafeMessageStorageService(IAuthorizationService authorizationService, ISymmetricEncryptionEngine encryptionEngine)
{
_authorizationService = authorizationService;
_encryptionEngine = encryptionEngine;
}
public bool IsStorageEmpty => Xamarin.Essentials.SecureStorage.GetAsync(_messagesKey).Result != null;
public async Task<bool> SaveMessageAsync(Message message)
@ -34,10 +40,10 @@ namespace SafeMessageStorage.Services.MessageStorageService
CheckIfAuthorized();
var encryptedMessage =await Xamarin.Essentials.SecureStorage.GetAsync(_messagesKey);
if (encryptedMessage == null)
return null;
return new List<Message>();
var decryptedMessage = _encryptionEngine.Decrypt(encryptedMessage, _authorizationService.AuthorizedUserHash);
return JsonConvert.DeserializeObject<List<Message>>(decryptedMessage);
return JsonConvert.DeserializeObject<List<Message>>(decryptedMessage).Where(x=>x.Id!=null);
}
public async Task<bool> DeleteMessageAsync(string messageId)