MessageStore
This commit is contained in:
parent
ff98f1a5c1
commit
390fd66d97
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace SafeMessageStorage.Encryption.Symmetric
|
||||||
|
{
|
||||||
|
public interface ISymmetricEncryptionEngine
|
||||||
|
{
|
||||||
|
string Encrypt(string content, string key);
|
||||||
|
|
||||||
|
string Decrypt(string cipher, string key);
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,7 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
x:Class="SafeMessageStorage.Pages.AuthorizationPage"
|
x:Class="SafeMessageStorage.Pages.AuthorizationPage"
|
||||||
Title="Authorize">
|
Title="AuthorizeAsync">
|
||||||
<ContentPage.Content>
|
<ContentPage.Content>
|
||||||
<StackLayout VerticalOptions="CenterAndExpand" Padding="40">
|
<StackLayout VerticalOptions="CenterAndExpand" Padding="40">
|
||||||
<Label Text="Enter your security code"
|
<Label Text="Enter your security code"
|
||||||
@ -14,7 +14,7 @@
|
|||||||
<Label x:Name="ErrorMessageLabel"
|
<Label x:Name="ErrorMessageLabel"
|
||||||
TextColor="#d22"
|
TextColor="#d22"
|
||||||
Margin="0,10" HorizontalOptions="Center"/>
|
Margin="0,10" HorizontalOptions="Center"/>
|
||||||
<Button Text="Authorize" Command="{Binding AuthorizeCommand}"/>
|
<Button Text="AuthorizeAsync" Command="{Binding AuthorizeCommand}"/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</ContentPage.Content>
|
</ContentPage.Content>
|
||||||
</ContentPage>
|
</ContentPage>
|
@ -6,12 +6,12 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
<PackageReference Include="Xamarin.Forms" Version="4.6.0.847" />
|
<PackageReference Include="Xamarin.Forms" Version="4.6.0.847" />
|
||||||
<PackageReference Include="Xamarin.Essentials" Version="1.3.1" />
|
<PackageReference Include="Xamarin.Essentials" Version="1.3.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Encryption\Symmetric\" />
|
|
||||||
<Folder Include="Views\" />
|
<Folder Include="Views\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ namespace SafeMessageStorage.Services.AuthorizationService
|
|||||||
{
|
{
|
||||||
public class AuthorizationService : IAuthorizationService
|
public class AuthorizationService : IAuthorizationService
|
||||||
{
|
{
|
||||||
private readonly string _passwordKey = "passwordGUID";
|
private readonly string _passwordKey = "86d9ee32-c00e-4b18-bb1b-a4f7d9e23ec9";
|
||||||
private readonly IHashProvider _hashProvider;
|
private readonly IHashProvider _hashProvider;
|
||||||
|
|
||||||
public AuthorizationService(IHashProvider hashProvider)
|
public AuthorizationService(IHashProvider hashProvider)
|
||||||
@ -17,22 +17,27 @@ namespace SafeMessageStorage.Services.AuthorizationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool IsAuthorized { get; private set; }
|
public bool IsAuthorized { get; private set; }
|
||||||
|
|
||||||
|
public string AuthorizedUserHash { get; private set; }
|
||||||
|
|
||||||
public bool IsPasswordSet => Xamarin.Essentials.SecureStorage.GetAsync(_passwordKey).Result != null;
|
public bool IsPasswordSet => Xamarin.Essentials.SecureStorage.GetAsync(_passwordKey).Result != null;
|
||||||
public async Task<bool> Authorize(string password)
|
public async Task<bool> AuthorizeAsync(string password)
|
||||||
{
|
{
|
||||||
var keyChainPassword = await Xamarin.Essentials.SecureStorage.GetAsync(_passwordKey);
|
var keyChainPassword = await Xamarin.Essentials.SecureStorage.GetAsync(_passwordKey);
|
||||||
var result = keyChainPassword?.Equals(_hashProvider.GetHashString(password)) ?? false;
|
var result = keyChainPassword?.Equals(_hashProvider.GetHashString(password)) ?? false;
|
||||||
IsAuthorized = result;
|
IsAuthorized = result;
|
||||||
|
AuthorizedUserHash = IsAuthorized ? keyChainPassword : null;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<bool> Deauthorize()
|
public Task<bool> DeauthorizeAsync()
|
||||||
{
|
{
|
||||||
IsAuthorized = false;
|
IsAuthorized = false;
|
||||||
|
AuthorizedUserHash = null;
|
||||||
return Task.FromResult(true);
|
return Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> ChangePassword(string currentPassword, string newPassword)
|
public async Task<bool> ChangePasswordAsync(string currentPassword, string newPassword)
|
||||||
{
|
{
|
||||||
var keyChainPassword = await Xamarin.Essentials.SecureStorage.GetAsync(_passwordKey);
|
var keyChainPassword = await Xamarin.Essentials.SecureStorage.GetAsync(_passwordKey);
|
||||||
var passwordMatch = keyChainPassword?.Equals(_hashProvider.GetHashString(currentPassword)) ?? true;
|
var passwordMatch = keyChainPassword?.Equals(_hashProvider.GetHashString(currentPassword)) ?? true;
|
||||||
|
@ -8,18 +8,19 @@ namespace SafeMessageStorage.Services.AuthorizationService
|
|||||||
public class AuthorizationServiceMOCK : IAuthorizationService
|
public class AuthorizationServiceMOCK : IAuthorizationService
|
||||||
{
|
{
|
||||||
public bool IsAuthorized => false;
|
public bool IsAuthorized => false;
|
||||||
|
public string AuthorizedUserHash => "kanapka";
|
||||||
public bool IsPasswordSet => false;
|
public bool IsPasswordSet => false;
|
||||||
public Task<bool> Authorize(string password)
|
public Task<bool> AuthorizeAsync(string password)
|
||||||
{
|
{
|
||||||
return Task.FromResult(false);
|
return Task.FromResult(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<bool> Deauthorize()
|
public Task<bool> DeauthorizeAsync()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<bool> ChangePassword(string currentPassword, string newPassword)
|
public Task<bool> ChangePasswordAsync(string currentPassword, string newPassword)
|
||||||
{
|
{
|
||||||
return Task.FromResult(true);
|
return Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,14 @@ namespace SafeMessageStorage.Services.AuthorizationService
|
|||||||
{
|
{
|
||||||
bool IsAuthorized { get; }
|
bool IsAuthorized { get; }
|
||||||
|
|
||||||
|
string AuthorizedUserHash { get; }
|
||||||
|
|
||||||
bool IsPasswordSet { get; }
|
bool IsPasswordSet { get; }
|
||||||
|
|
||||||
Task<bool> Authorize(string password);
|
Task<bool> AuthorizeAsync(string password);
|
||||||
|
|
||||||
Task<bool> Deauthorize();
|
Task<bool> DeauthorizeAsync();
|
||||||
|
|
||||||
Task<bool> ChangePassword(string currentPassword, string newPassword);
|
Task<bool> ChangePasswordAsync(string currentPassword, string newPassword);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,15 +8,12 @@ namespace SafeMessageStorage.Services.MessageStorageService
|
|||||||
{
|
{
|
||||||
public interface IMessageStorageService
|
public interface IMessageStorageService
|
||||||
{
|
{
|
||||||
Task<bool> IsStorageEmpty { get; }
|
bool IsStorageEmpty { get; }
|
||||||
|
|
||||||
Task<bool> SaveMessage(Message message);
|
|
||||||
|
|
||||||
Task<Message> ReadMessage();
|
|
||||||
|
|
||||||
Task<bool> DeleteMessage();
|
|
||||||
|
|
||||||
|
Task<bool> SaveMessageAsync(Message message);
|
||||||
|
|
||||||
|
Task<Message> ReadMessageAsync();
|
||||||
|
|
||||||
|
Task<bool> DeleteMessageAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using SafeMessageStorage.Encryption.Symmetric;
|
||||||
|
using SafeMessageStorage.Models;
|
||||||
|
using SafeMessageStorage.Services.AuthorizationService;
|
||||||
|
|
||||||
|
namespace SafeMessageStorage.Services.MessageStorageService
|
||||||
|
{
|
||||||
|
public class SafeMessageStorageService : IMessageStorageService
|
||||||
|
{
|
||||||
|
private IAuthorizationService _authorizationService;
|
||||||
|
private ISymmetricEncryptionEngine _encryptionEngine;
|
||||||
|
private readonly string _messageKey = "377f2486-d2c3-48a7-b821-45d7314479cd";
|
||||||
|
|
||||||
|
public bool IsStorageEmpty => Xamarin.Essentials.SecureStorage.GetAsync(_messageKey).Result != null;
|
||||||
|
|
||||||
|
public async Task<bool> SaveMessageAsync(Message message)
|
||||||
|
{
|
||||||
|
CheckIfAuthorized();
|
||||||
|
var encrypyedMessage = _encryptionEngine.Encrypt(JsonConvert.SerializeObject(message), _authorizationService.AuthorizedUserHash);
|
||||||
|
await Xamarin.Essentials.SecureStorage.SetAsync(_messageKey, encrypyedMessage);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Message> ReadMessageAsync()
|
||||||
|
{
|
||||||
|
CheckIfAuthorized();
|
||||||
|
var encryptedMessage =await Xamarin.Essentials.SecureStorage.GetAsync(_messageKey);
|
||||||
|
if (encryptedMessage == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var decryptedMessage = _encryptionEngine.Decrypt(encryptedMessage, _authorizationService.AuthorizedUserHash);
|
||||||
|
return JsonConvert.DeserializeObject<Message>(decryptedMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> DeleteMessageAsync()
|
||||||
|
{
|
||||||
|
CheckIfAuthorized();
|
||||||
|
return Xamarin.Essentials.SecureStorage.Remove(_messageKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckIfAuthorized()
|
||||||
|
{
|
||||||
|
if(!_authorizationService.IsAuthorized)
|
||||||
|
throw new UnauthorizedAccessException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -42,7 +42,7 @@ namespace SafeMessageStorage.ViewModels
|
|||||||
|
|
||||||
private async Task Authorize(string code)
|
private async Task Authorize(string code)
|
||||||
{
|
{
|
||||||
if (await _authorizationService.Authorize(code))
|
if (await _authorizationService.AuthorizeAsync(code))
|
||||||
AuthorizationSucceeded?.Invoke(this, EventArgs.Empty);
|
AuthorizationSucceeded?.Invoke(this, EventArgs.Empty);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -43,7 +43,7 @@ namespace SafeMessageStorage.ViewModels
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(await _authorizationService.ChangePassword(null, password))
|
if(await _authorizationService.ChangePasswordAsync(null, password))
|
||||||
PasswordSetSucceeded?.Invoke(this,EventArgs.Empty);
|
PasswordSetSucceeded?.Invoke(this,EventArgs.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user