Skip to content

Commit

Permalink
Keep encryption for Dictionary exports
Browse files Browse the repository at this point in the history
Fixed #28
  • Loading branch information
AndreasReitberger committed Mar 20, 2024
1 parent 8d98179 commit a6269d0
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 57 deletions.
24 changes: 23 additions & 1 deletion src/MauiSettings.Example/MainPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiSettings.Example.MainPage"
xmlns:viewModels="clr-namespace:MauiSettings.Example.ViewModels"

xmlns:settings="clr-namespace:MauiSettings.Example.Models.Settings"
x:DataType="viewModels:MainPageViewModel"
>

Expand Down Expand Up @@ -59,6 +59,28 @@
Text="To dictionary"
Command="{Binding ToDictionaryCommand}"
HorizontalOptions="Fill" />

<CollectionView
ItemsSource="{Binding Settings}"
>
<CollectionView.ItemTemplate>
<DataTemplate
x:DataType="settings:SettingsItem"
>
<Grid
ColumnDefinitions="*,*"
>
<Label
Text="{Binding Key}"
/>
<Label
Grid.Column="1"
Text="{Binding Value}"
/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</VerticalStackLayout>
</ScrollView>

Expand Down
13 changes: 13 additions & 0 deletions src/MauiSettings.Example/Models/Settings/SettingsItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using CommunityToolkit.Mvvm.ComponentModel;

namespace MauiSettings.Example.Models.Settings
{
public partial class SettingsItem : ObservableObject
{
[ObservableProperty]
string key = string.Empty;

[ObservableProperty]
string value = string.Empty;
}
}
17 changes: 14 additions & 3 deletions src/MauiSettings.Example/ViewModels/MainPageViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MauiSettings.Example.Models.Settings;
using System.Collections.ObjectModel;

namespace MauiSettings.Example.ViewModels
{
Expand All @@ -25,6 +26,8 @@ partial void OnLicenseInfoChanged(string value)
}
}

[ObservableProperty]
ObservableCollection<SettingsItem> settings = [];
#endregion

#region Ctor
Expand Down Expand Up @@ -52,8 +55,15 @@ void LoadSettings()
[RelayCommand]
async Task LoadSettingsFromDevice()
{
await SettingsApp.LoadSettingsAsync(key: App.Hash);
LoadSettings();
try
{
await SettingsApp.LoadSettingsAsync(key: App.Hash);
LoadSettings();
}
catch(Exception)
{
// Throus if the key missmatches
}
}

[RelayCommand]
Expand All @@ -69,7 +79,8 @@ async Task ExchangeHashKey()
async Task ToDictionary()
{
// All "SkipForExport" should be missing here.
var dict = await SettingsApp.ToDictionaryAsync();
Dictionary<string, Tuple<object, Type>> dict = await SettingsApp.ToDictionaryAsync();
Settings = [.. dict.Select(kp => new SettingsItem() { Key = kp.Key, Value = kp.Value.Item1.ToString() })];
}
#endregion
}
Expand Down
6 changes: 3 additions & 3 deletions src/MauiSettings/Helper/MauiSettingsMemberInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ namespace AndreasReitberger.Maui.Helper
internal class MauiSettingsMemberInfo
{
#region Properties
public object OrignalSettingsObject { get; set; }
public MemberInfo Info { get; set; }
public Type SettingsType { get; set; }
public object? OrignalSettingsObject { get; set; }
public MemberInfo? Info { get; set; }
public Type? SettingsType { get; set; }
#endregion
}
}
3 changes: 2 additions & 1 deletion src/MauiSettings/MauiSettings.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@
<ImplicitUsings>enable</ImplicitUsings>
<PublishReadyToRun>false</PublishReadyToRun>
<Nullable>enable</Nullable>

<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">14.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>

<RootNamespace>AndreasReitberger.Maui</RootNamespace>
<Copyright>Andreas Reitberger</Copyright>
<PackageProjectUrl>https://github.com/AndreasReitberger/MauiSettings</PackageProjectUrl>
Expand Down
77 changes: 28 additions & 49 deletions src/MauiSettings/MauiSettingsGeneric.cs
Original file line number Diff line number Diff line change
Expand Up @@ -222,83 +222,66 @@ public static void LoadObjectDefaultSetting<T>(object settings, Expression<Func<
public static Task<Dictionary<string, Tuple<object, Type>>> ToDictionaryAsync()
=> ToDictionaryAsync(settings: SettingsObject);

public static async Task<Dictionary<string, Tuple<object, Type>>> ToDictionaryAsync(object settings)
public static Task<Dictionary<string, Tuple<object, Type>>> ToDictionaryAsync(bool secureOnly = false, string? key = null)
=> ToDictionaryAsync(settings: SettingsObject, secureOnly: secureOnly, key: key);

public static async Task<Dictionary<string, Tuple<object, Type>>> ToDictionaryAsync(object? settings, bool secureOnly = false, string? key = null)
{
if (true)
{
Dictionary<string, Tuple<object, Type>> setting = [];
IEnumerable<MemberInfo> declaredMembers = settings.GetType().GetTypeInfo().DeclaredMembers;
IEnumerable<MemberInfo>? declaredMembers = settings?.GetType().GetTypeInfo().DeclaredMembers;

MauiSettingsMemberInfo settingsObjectInfo = new();
MauiSettingsInfo settingsInfo = new();
if (declaredMembers is null) return setting;

foreach (MemberInfo mInfo in declaredMembers)
{
settingsObjectInfo.OrignalSettingsObject = settings;
settingsObjectInfo.Info = mInfo;
// Handles saving the settings to the Maui.Storage.Preferences
MauiSettingsInfo settingsPair = await ProcessSettingsInfoAsKeyValuePairAsync(settingsObjectInfo, settingsInfo);
MauiSettingsInfo? settingsPair = await ProcessSettingsInfoAsKeyValuePairAsync(settingsObjectInfo, settingsInfo, secureOnly: secureOnly, key: key, keeyEncrypted: true);
if (settingsPair != null && !settingsPair.SkipForExport)
{
setting.TryAdd(settingsPair.Name, new Tuple<object, Type>(settingsPair.Value ?? settingsPair.Default, settingsPair.SettingsType));
}
}
/*
members?.ForEach(member =>
{
settingsObjectInfo.OrignalSettingsObject = settings;
settingsObjectInfo.Info = member;
var settingsPair = ProcessSettingsInfoAsKeyValuePair(settingsObjectInfo, settingsInfo);
if (settingsPair != null)
{
setting.TryAdd(settingsPair.Name, new Tuple<object, Type>(settingsPair.Value ?? settingsPair.Default, settingsPair.SettingsType));
}
});
*/
return setting;
}
}

public static Task<ConcurrentDictionary<string, Tuple<object, Type>>> ToConcurrentDictionaryAsync()
=> ToConcurrentDictionaryAsync(settings: SettingsObject);
public static Task<ConcurrentDictionary<string, Tuple<object, Type>>> ToConcurrentDictionaryAsync(bool secureOnly = false, string? key = null)
=> ToConcurrentDictionaryAsync(settings: SettingsObject, secureOnly: secureOnly, key: key);

public static async Task<ConcurrentDictionary<string, Tuple<object, Type>>> ToConcurrentDictionaryAsync(object settings)
public static async Task<ConcurrentDictionary<string, Tuple<object, Type>>> ToConcurrentDictionaryAsync(object? settings, bool secureOnly = false, string? key = null)
{
ConcurrentDictionary<string, Tuple<object, Type>> setting = new();
List<MemberInfo> members = GetClassMetaAsList(settings);
List<MemberInfo>? members = GetClassMetaAsList(settings);

MauiSettingsMemberInfo settingsObjectInfo = new();
MauiSettingsInfo settingsInfo = new();
if (members is null) return setting;

foreach (MemberInfo mInfo in members)
{
settingsObjectInfo.OrignalSettingsObject = settings;
settingsObjectInfo.Info = mInfo;
// Handles saving the settings to the Maui.Storage.Preferences
MauiSettingsInfo settingsPair = await ProcessSettingsInfoAsKeyValuePairAsync(settingsObjectInfo, settingsInfo);
MauiSettingsInfo? settingsPair = await ProcessSettingsInfoAsKeyValuePairAsync(settingsObjectInfo, settingsInfo, secureOnly: secureOnly, key: key, keeyEncrypted: true);
if (settingsPair != null && !settingsPair.SkipForExport)
{
setting.TryAdd(settingsPair.Name, new Tuple<object, Type>(settingsPair.Value ?? settingsPair.Default, settingsPair.SettingsType));
}
}
/*
members?.ForEach(member =>
{
settingsObjectInfo.OrignalSettingsObject = settings;
settingsObjectInfo.Info = member;
var settingsPair = ProcessSettingsInfoAsKeyValuePair(settingsObjectInfo, settingsInfo);
if(settingsPair != null)
{
setting.TryAdd(settingsPair.Name, new Tuple<object, Type>(settingsPair.Value ?? settingsPair.Default, settingsPair.SettingsType));
}
});
*/
return setting;
}

public static Task<Tuple<string, Tuple<object, Type>>> ToSettingsTupleAsync<T>(Expression<Func<SO, T>> value) => ToSettingsTupleAsync(settings: SettingsObject, value: value);

public static async Task<Tuple<string, Tuple<object, Type>>> ToSettingsTupleAsync<T>(object settings, Expression<Func<SO, T>> value)
public static async Task<Tuple<string, Tuple<object, Type>>> ToSettingsTupleAsync<T>(object? settings, Expression<Func<SO, T>> value)
{
MauiSettingsInfo? info = await GetExpressionMetaAsKeyValuePairAsync(settings: settings, value: value);
return new(info.Name, new(info.Value, info.SettingsType));
Expand All @@ -317,12 +300,13 @@ public static Task ExhangeKeyAsync(string? newKey = null, string? oldKey = null)
#endregion

#region Private
static List<MemberInfo>? GetClassMetaAsList(object settings)
static List<MemberInfo>? GetClassMetaAsList(object? settings)
{
if (settings is null) return null;
lock (lockObject)
{
// Get all member infos from the passed settingsObject
IEnumerable<MemberInfo> declaredMembers = settings.GetType().GetTypeInfo().DeclaredMembers;
IEnumerable<MemberInfo>? declaredMembers = settings?.GetType().GetTypeInfo().DeclaredMembers;

MauiSettingsMemberInfo settingsObjectInfo = new();
MauiSettingsInfo settingsInfo = new();
Expand Down Expand Up @@ -439,7 +423,7 @@ static async Task GetExpressionMetaAsync<T>(object settings, Expression<Func<SO,
}
}

static async Task<MauiSettingsInfo?> GetExpressionMetaAsKeyValuePairAsync<T>(object settings, Expression<Func<SO, T>> value, string? key = null)
static async Task<MauiSettingsInfo?> GetExpressionMetaAsKeyValuePairAsync<T>(object? settings, Expression<Func<SO, T>> value, string? key = null)
{
if (value.Body is MemberExpression memberExpression)
{
Expand Down Expand Up @@ -608,7 +592,7 @@ List<MauiSettingAttribute> settingBaseAttributes
return true;
}

static async Task<bool> ProcessSettingsInfoAsync(MauiSettingsMemberInfo settingsObjectInfo, MauiSettingsInfo settingsInfo, MauiSettingsActions mode, MauiSettingsTarget target, bool secureOnly = false, bool useValueFromSettingsInfo = false, string? key = null)
static async Task<bool> ProcessSettingsInfoAsync(MauiSettingsMemberInfo settingsObjectInfo, MauiSettingsInfo settingsInfo, MauiSettingsActions mode, MauiSettingsTarget target, bool secureOnly = false, bool useValueFromSettingsInfo = false, string? key = null, bool keepEncrypted = false)
{
settingsInfo ??= new();
MauiSettingBaseAttribute? settingBaseAttribute = null;
Expand All @@ -623,9 +607,9 @@ List<MauiSettingAttribute> settingBaseAttributes
return false;
}
settingBaseAttribute = settingBaseAttributes?.FirstOrDefault();
}
if (settingsObjectInfo.Info is not null)
{
//}
//if (settingsObjectInfo.Info is not null)
//{
settingsInfo.Name = MauiSettingNameFormater.GetFullSettingName(settingsObjectInfo.OrignalSettingsObject.GetType(), settingsObjectInfo.Info, settingBaseAttribute);
settingsInfo.SettingsType = (settingsInfo.SettingsType = MauiSettingsObjectHelper.GetSettingType(settingsObjectInfo.Info));
settingsInfo.Default = MauiSettingsObjectHelper.GetDefaultValue(settingBaseAttribute, settingsInfo.SettingsType);
Expand Down Expand Up @@ -704,7 +688,7 @@ List<MauiSettingAttribute> settingBaseAttributes
{
object defaultValue = MauiSettingsObjectHelper.GetDefaultValue(settingBaseAttribute, settingsInfo.SettingsType);
}
if (secure && settingsInfo.Encrypt && !string.IsNullOrEmpty(key))
if (secure && settingsInfo.Encrypt && !string.IsNullOrEmpty(key) && !keepEncrypted)
{
if (settingsInfo.Value is string secureString)
{
Expand All @@ -716,7 +700,6 @@ List<MauiSettingAttribute> settingBaseAttributes
}
// Sets the loaded value back to the settingsObject
MauiSettingsObjectHelper.SetSettingValue(settingsObjectInfo.Info, settingsObjectInfo.OrignalSettingsObject, settingsInfo.Value, settingsInfo.SettingsType);

break;
case MauiSettingsActions.Save:
// Get the value from the settingsObject
Expand Down Expand Up @@ -854,7 +837,7 @@ List<MauiSettingAttribute> settingBaseAttributes
return true;
}

static async Task<MauiSettingsInfo?> ProcessSettingsInfoAsKeyValuePairAsync(MauiSettingsMemberInfo settingsObjectInfo, MauiSettingsInfo settingsInfo, bool secureOnly = false, string? key = null)
static async Task<MauiSettingsInfo?> ProcessSettingsInfoAsKeyValuePairAsync(MauiSettingsMemberInfo settingsObjectInfo, MauiSettingsInfo settingsInfo, bool secureOnly = false, string? key = null, bool keeyEncrypted = false)
{
settingsInfo ??= new();
MauiSettingBaseAttribute? settingBaseAttribute = null;
Expand All @@ -869,16 +852,12 @@ List<MauiSettingAttribute> settingBaseAttributes
return null;
}
settingBaseAttribute = settingBaseAttributes?.FirstOrDefault();
}
if (settingsObjectInfo.Info is not null)
{
//}
//if (settingsObjectInfo.Info is not null)
//{
settingsInfo.Name = MauiSettingNameFormater.GetFullSettingName(settingsObjectInfo.OrignalSettingsObject.GetType(), settingsObjectInfo.Info, settingBaseAttribute);
settingsInfo.SettingsType = (settingsInfo.SettingsType = MauiSettingsObjectHelper.GetSettingType(settingsObjectInfo.Info));

settingsInfo.Default = MauiSettingsObjectHelper.GetDefaultValue(settingBaseAttribute, settingsInfo.SettingsType);
//Type type = (settingsInfo.SettingsType = MauiSettingsObjectHelper.GetSettingType(settingsObjectInfo.Info));
//settingsInfo.Value = MauiSettingsObjectHelper.GetSettingValue(settingsObjectInfo.Info, settingsObjectInfo.OrignalSettingsObject);
//settingsInfo.Value = MauiSettingsHelper.GetSettingsValue(settingsInfo.Name, settingsInfo.Default);
}
if (settingBaseAttribute is MauiSettingAttribute settingAttribute)
{
Expand All @@ -897,7 +876,7 @@ List<MauiSettingAttribute> settingBaseAttributes
else if (settingsInfo.SettingsType == typeof(string))
{
settingsInfo.Value = await MauiSettingsHelper.GetSecureSettingsValueAsync(settingsInfo.Name, settingsInfo.Default as string);
if (settingsInfo.Encrypt && !string.IsNullOrEmpty(key))
if (settingsInfo.Encrypt && !string.IsNullOrEmpty(key) && !keeyEncrypted)
{
// Decrypt string
string decryptedString = EncryptionManager.DecryptStringFromBase64String(settingsInfo.Value as string, key);
Expand Down

0 comments on commit a6269d0

Please sign in to comment.