Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Essentials] Remove lock from SecureStorage #13940

Merged
merged 1 commit into from
Mar 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 30 additions & 39 deletions src/Essentials/src/SecureStorage/SecureStorage.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,21 @@ namespace Microsoft.Maui.Storage
{
partial class SecureStorageImplementation : ISecureStorage
{
readonly object locker = new();

Task<string> PlatformGetAsync(string key)
async Task<string> PlatformGetAsync(string key)
{
return Task.Run(() =>
return await Task.Run(() =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be using async/await, or just returning the task?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose since we aren't async all the way up this may be superfluous, I can remove it if we want to.

{
try
{
lock (locker)
{
ISharedPreferences sharedPreferences = GetEncryptedSharedPreferences();
if (sharedPreferences != null)
return sharedPreferences.GetString(key, null);
ISharedPreferences sharedPreferences = GetEncryptedSharedPreferences();
if (sharedPreferences != null)
return sharedPreferences.GetString(key, null);

// TODO: Use Logger here?
System.Diagnostics.Debug.WriteLine(
$"Unable to decrypt key, {key}, which is likely due to key corruption. Removing old key and returning null.");
PlatformRemove(key);
return null;
}
// TODO: Use Logger here?
System.Diagnostics.Debug.WriteLine(
$"Unable to decrypt key, {key}, which is likely due to key corruption. Removing old key and returning null.");
PlatformRemove(key);
return null;
}
catch (GeneralSecurityException)
{
Expand All @@ -49,45 +44,41 @@ Task<string> PlatformGetAsync(string key)
});
}

Task PlatformSetAsync(string key, string data)
async Task PlatformSetAsync(string key, string data)
{
return Task.Run(() =>
await Task.Run(() =>
{
lock (locker)
{
using ISharedPreferencesEditor editor = GetEncryptedSharedPreferences()?.Edit();
if (data == null)
editor?.Remove(key);
else
editor?.PutString(key, data);
using ISharedPreferencesEditor editor = GetEncryptedSharedPreferences()?.Edit();
if (data is null)
editor?.Remove(key);
else
editor?.PutString(key, data);

editor?.Apply();
}
editor?.Apply();
});
}

bool PlatformRemove(string key)
{
lock (locker)
{
using ISharedPreferencesEditor editor = GetEncryptedSharedPreferences()?.Edit();
editor?.Remove(key)?.Apply();
}

using ISharedPreferencesEditor editor = GetEncryptedSharedPreferences()?.Edit();
editor?.Remove(key)?.Apply();
return true;
}

void PlatformRemoveAll()
{
lock (locker)
{
using var editor = PreferencesImplementation.GetSharedPreferences(Alias).Edit();
editor?.Clear()?.Apply();
}
using var editor = PreferencesImplementation.GetSharedPreferences(Alias).Edit();
editor?.Clear()?.Apply();
}

ISharedPreferences _prefs;
ISharedPreferences GetEncryptedSharedPreferences()
{
if (_prefs is not null)
{
return _prefs;
}

try
{
var context = Application.Context;
Expand All @@ -103,7 +94,7 @@ ISharedPreferences GetEncryptedSharedPreferences()
EncryptedSharedPreferences.PrefKeyEncryptionScheme.Aes256Siv,
EncryptedSharedPreferences.PrefValueEncryptionScheme.Aes256Gcm);

return sharedPreferences;
return _prefs = sharedPreferences;
}
catch (InvalidProtocolBufferException)
{
Expand All @@ -115,4 +106,4 @@ ISharedPreferences GetEncryptedSharedPreferences()
}
}
}
}
}
16 changes: 16 additions & 0 deletions src/Essentials/test/DeviceTests/Tests/SecureStorage_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,5 +156,21 @@ await SecureStorage.SetAsync(i.ToString(), i.ToString())
Assert.Equal(i.ToString(), v);
}
}

[Fact]
public async Task Set_Get_Remove_Async_MultipleTimes()
{
await Parallel.ForEachAsync(Enumerable.Range(0, 100), async (i, _) =>
{
var key = $"key{i}";
var value = $"value{i}";
await SecureStorage.SetAsync(key, value);
var fetched = await SecureStorage.GetAsync(key);
Assert.Equal(value, fetched);
SecureStorage.Remove(key);
fetched = await SecureStorage.GetAsync(key);
Assert.Null(fetched);
});
}
}
}