Skip to content

Commit

Permalink
- Improved OASIS Error Handling/Reporting.
Browse files Browse the repository at this point in the history
- Added new HandleError and HandleWarning overloads to ErrorHandling helper that take an optional innerResult param so its InnerMessages, WarningCount etc can be added to the main OASISResult.

- HolonBase constructors no longer automatically create a new id (it needs to be created manually by the caller).

- Added WalletId property to IProviderWallet because the base Id property on HolonBase was not being serialaized.

- Fixed a bug in VerifyEmail method in AvataManager as a side effect from the latest work done in AvatarManager (new optional loadPrivateKeys param being added).

- Removed all private key caches to make it even more secure so private keys are never stored in memory and are only loaded from local storage and decrypted and sent to client per request to remove attack surface area.

- LinkProviderPublicKeyToAvatarById, LinkProviderPublicKeyToAvatarByUsername & LinkProviderPublicKeyToAvatarByEmail methods in KeyManager now load private keys when loading the avatar so when it saves the wallet back to local storage the private keys are not blanked out.

- LinkProviderPublicKeyToAvatar method in KeyManager now sets WalletId, AvatarId, CreatedByAvatarId & CreatedDate properties on new wallets and sets ModifiedByAvatarId and ModifiedDate on existing wallets.

- Fixed a bug in LinkProviderPublicKeyToAvatar method in KeyManager where the avatar was being saved before the local storage wallets (so the private keys were blanked out before they could be saved). It now saves to local storage first.

- LinkProviderPrivateKeyToAvatar method in KeyManager has multiple bugs fixed including checking if a key has already been linked, saving the local storage wallets before saving the avatar, improved error handling, setting WalletId, AvatarId, CreatedByAvatarId & CreatedDate for new wallets and setting ModifiedByAvatarId & ModifiedDate for exisitng wallets.

- Completley re-wrote GetProviderPrivateKeysForAvatarById & GetProviderPrivateKeysForAvatarByUsername methods in KeyManager to work with the new local storage wallets.

- Removed GetAvatarIdForProviderPrivateKey, GetAvatarUsernameForProviderPrivateKey, GetAvatarEmailForProviderPrivateKey & GetAvatarForProviderPrivateKey methods in KeyManager since would be extra work, potential security issue and not sure if there would be a good use case for them?

- Fixed a bug in GetAllProviderPrivateKeysForAvatarById & GetAllProviderPrivateKeysForAvatarByUsername methods in KeyManager.

- Fixed bugs in LoadProviderWalletsForAvatarByUsernameAsync, LoadProviderWalletsForAvatarByUsername, LoadProviderWalletsForAvatarByEmailAsync, LoadProviderWalletsForAvatarByEmail, LoadProviderWalletsForAvatarByUsername, LoadProviderWalletsForAvatarByUsernameAsync,  LoadProviderWalletsForAvatarByEmail, LoadProviderWalletsForAvatarByEmailAsync, SaveProviderWalletsForAvatarByUsername, SaveProviderWalletsForAvatarByUsernameAsync, SaveProviderWalletsForAvatarByEmail, SaveProviderWalletsForAvatarByEmailAsync, SaveProviderWalletsForAvatarByUsername, SaveProviderWalletsForAvatarByUsernameAsync, SaveProviderWalletsForAvatarByEmail, SaveProviderWalletsForAvatarByEmailAsync & GetWalletThatPublicKeyBelongsTo methods where the detailed error message was not being bubbled up correctly.

- Rewrote & improved LoadProviderWalletsForAvatarById, LoadProviderWalletsForAvatarByIdAsync, SaveProviderWalletsForAvatarById & SaveProviderWalletsForAvatarByIdAsync methods in WalletManager.

- Added WalletId to ProviderWallet object.

- Removed GetAvatarIdForProviderPrivateKey, GetAvatarUsernameForProviderPrivateKey &  GetAvatarForProviderPrivateKey methods from KeysController.

- Fixed a bug in Update, UpdateByEmail & UpdateByUsername methods in AvatarService from side-effect of improvements to AvatarManager (new loadPrivateKeys param).

- Fixed a bug in  LoadProviderWalletsForAvatarById & LoadProviderWalletsForAvatarByIdAsync methods in LocalFileOASIS Provider where it was not checking if the wallet file exists.

- Fixed a bug in  SaveProviderWalletsForAvatarById & SaveProviderWalletsForAvatarByIdAsync methods where it was not serializing the wallets correctly (missing WalletId).
  • Loading branch information
dellams committed Jun 6, 2022
1 parent d67da8b commit 8c93ea5
Show file tree
Hide file tree
Showing 10 changed files with 488 additions and 125 deletions.
77 changes: 77 additions & 0 deletions NextGenSoftware.OASIS.API.Core/Helpers/ErrorHandling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ public static class ErrorHandling
public static bool LogAllWarnings { get; set; } = true;

//WARNING: ONLY set includeStackTrace to true for debug/dev mode due to performance overhead. This param should never be needed because the ShowStackTrace flag will be used for Dev/Debug mode.

public static void HandleError<T1, T2>(ref OASISResult<T1> result, string errorMessage, bool log = true, bool includeStackTrace = false, bool throwException = false, bool addToInnerMessages = false, bool incrementErrorCount = true, Exception ex = null, string detailedMessage = "", bool onlyLogToInnerMessages = false, OASISResult<T2> innerResult = null)
{
if (innerResult != null)
{
result.InnerMessages.AddRange(innerResult.InnerMessages);
result.IsWarning = innerResult.IsWarning;
result.WarningCount += innerResult.WarningCount;
}

HandleError(ref result, errorMessage, log, includeStackTrace, throwException, addToInnerMessages, incrementErrorCount, ex, detailedMessage, onlyLogToInnerMessages);
}


public static void HandleError<T>(ref OASISResult<T> result, string errorMessage, bool log = true, bool includeStackTrace = false, bool throwException = false, bool addToInnerMessages = false, bool incrementErrorCount = true, Exception ex = null, string detailedMessage = "", bool onlyLogToInnerMessages = false)
{
//NOTE: If you are throwing an exception then you do not need to show an additional stack trace here because the exception has it already! ;-)
Expand Down Expand Up @@ -61,21 +75,46 @@ public static void HandleError<T>(ref OASISResult<T> result, string errorMessage
HandleError(ref result, errorMessage, true, false, false, false, true, null, "", onlyLogToInnerMessages);
}

public static void HandleError<T1, T2>(ref OASISResult<T1> result, string errorMessage, bool onlyLogToInnerMessages, OASISResult<T2> innerResult)
{
HandleError(ref result, errorMessage, true, false, false, false, true, null, "", onlyLogToInnerMessages, innerResult);
}

public static void HandleError<T>(ref OASISResult<T> result, string errorMessage, Exception ex, bool onlyLogToInnerMessages = false)
{
HandleError(ref result, errorMessage, true, false, false, false, true, ex, "", onlyLogToInnerMessages);
}

public static void HandleError<T1, T2>(ref OASISResult<T1> result, string errorMessage, Exception ex, bool onlyLogToInnerMessages = false, OASISResult<T2> innerResult = null)
{
HandleError(ref result, errorMessage, true, false, false, false, true, ex, "", onlyLogToInnerMessages, innerResult);
}

public static void HandleError<T>(ref OASISResult<T> result, string errorMessage, string detailedMessage, bool onlyLogToInnerMessages = false)
{
HandleError(ref result, errorMessage, true, false, false, false, true, null, detailedMessage, onlyLogToInnerMessages);
}

public static void HandleError<T1, T2>(ref OASISResult<T1> result, string errorMessage, string detailedMessage, OASISResult<T2> innerResult = null)
{
HandleError(ref result, errorMessage, true, false, false, false, true, null, detailedMessage, false, innerResult);
}

public static void HandleError<T1, T2>(ref OASISResult<T1> result, string errorMessage, string detailedMessage, bool onlyLogToInnerMessages = false, OASISResult<T2> innerResult = null)
{
HandleError(ref result, errorMessage, true, false, false, false, true, null, detailedMessage, onlyLogToInnerMessages, innerResult);
}

public static void HandleError<T>(ref OASISResult<T> result, string errorMessage, string detailedMessage, Exception ex, bool onlyLogToInnerMessages = false)
{
HandleError(ref result, errorMessage, true, false, false, false, true, ex, detailedMessage, onlyLogToInnerMessages);
}

public static void HandleError<T1, T2>(ref OASISResult<T1> result, string errorMessage, string detailedMessage, Exception ex, bool onlyLogToInnerMessages = false, OASISResult<T2> innerResult = null)
{
HandleError(ref result, errorMessage, true, false, false, false, true, ex, detailedMessage, onlyLogToInnerMessages, innerResult);
}

public static void HandleWarning<T>(ref OASISResult<T> result, string message, bool log = true, bool includeStackTrace = false, bool throwException = false, bool addToInnerMessages = true, bool incrementWarningCount = true, Exception ex = null, string detailedMessage = "", bool onlyLogToInnerMessages = false)
{
//NOTE: If you are throwing an exception then you do not need to show an additional stack trace here because the exception has it already! ;-)
Expand Down Expand Up @@ -114,24 +153,62 @@ public static void HandleWarning<T>(ref OASISResult<T> result, string message, b
throw new Exception(message, ex);
}


public static void HandleWarning<T1, T2>(ref OASISResult<T1> result, string message, bool log = true, bool includeStackTrace = false, bool throwException = false, bool addToInnerMessages = true, bool incrementWarningCount = true, Exception ex = null, string detailedMessage = "", bool onlyLogToInnerMessages = false, OASISResult<T2> innerResult = null)
{
if (innerResult != null)
{
result.InnerMessages.AddRange(innerResult.InnerMessages);
result.IsWarning = innerResult.IsWarning;
result.WarningCount += innerResult.WarningCount;
}

HandleWarning(ref result, message, log, includeStackTrace, throwException, addToInnerMessages, incrementWarningCount, ex, detailedMessage, onlyLogToInnerMessages);
}

public static void HandleWarning<T>(ref OASISResult<T> result, string message, bool onlyLogToInnerMessages)
{
HandleWarning(ref result, message, true, false, false, true, true, null, "", onlyLogToInnerMessages);
}

public static void HandleWarning<T1, T2>(ref OASISResult<T1> result, string message, bool onlyLogToInnerMessages, OASISResult<T2> innerResult)
{
HandleWarning(ref result, message, true, false, false, true, true, null, "", onlyLogToInnerMessages, innerResult);
}

public static void HandleWarning<T>(ref OASISResult<T> result, string message, Exception ex, bool onlyLogToInnerMessages = false)
{
HandleWarning(ref result, message, true, false, false, true, true, ex, "", onlyLogToInnerMessages);
}

public static void HandleWarning<T1, T2>(ref OASISResult<T1> result, string message, Exception ex, bool onlyLogToInnerMessages = false, OASISResult<T2> innerResult = null)
{
HandleWarning(ref result, message, true, false, false, true, true, ex, "", onlyLogToInnerMessages, innerResult);
}

public static void HandleWarning<T>(ref OASISResult<T> result, string errorMessage, string detailedMessage, bool onlyLogToInnerMessages = false)
{
HandleWarning(ref result, errorMessage, true, false, false, true, true, null, detailedMessage, onlyLogToInnerMessages);
}

public static void HandleWarning<T1, T2>(ref OASISResult<T1> result, string errorMessage, string detailedMessage, OASISResult<T2> innerResult = null)
{
HandleWarning(ref result, errorMessage, true, false, false, true, true, null, detailedMessage, false, innerResult);
}

public static void HandleWarning<T1, T2>(ref OASISResult<T1> result, string errorMessage, string detailedMessage, bool onlyLogToInnerMessages = false, OASISResult<T2> innerResult = null)
{
HandleWarning(ref result, errorMessage, true, false, false, true, true, null, detailedMessage, onlyLogToInnerMessages, innerResult);
}

public static void HandleWarning<T>(ref OASISResult<T> result, string errorMessage, string detailedMessage, Exception ex, bool onlyLogToInnerMessages = false)
{
HandleWarning(ref result, errorMessage, true, false, false, true, true, ex, detailedMessage, onlyLogToInnerMessages);
}

public static void HandleWarning<T1, T2>(ref OASISResult<T1> result, string errorMessage, string detailedMessage, Exception ex, bool onlyLogToInnerMessages = false, OASISResult<T2> innerResult = null)
{
HandleWarning(ref result, errorMessage, true, false, false, true, true, ex, detailedMessage, onlyLogToInnerMessages, innerResult);
}
}
}
4 changes: 2 additions & 2 deletions NextGenSoftware.OASIS.API.Core/Holons/HolonBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ public abstract class HolonBase : IHolonBase, INotifyPropertyChanged
public HolonBase()
{
IsNewHolon = true;
Id = Guid.NewGuid(); //TODO: Not sure if to have this or not?
//Id = Guid.NewGuid(); //TODO: Not sure if to have this or not?
}

public HolonBase(HolonType holonType)
{
IsNewHolon = true;
Id = Guid.NewGuid(); //TODO: Not sure if to have this or not?
//Id = Guid.NewGuid(); //TODO: Not sure if to have this or not?
HolonType = holonType;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

using NextGenSoftware.OASIS.API.Core.Enums;
using NextGenSoftware.OASIS.API.Core.Helpers;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

Expand All @@ -15,6 +16,7 @@ namespace NextGenSoftware.OASIS.API.Core.Interfaces

public interface IProviderWallet : IHolonBase
{
public Guid WalletId { get; set; }
public string PrivateKey { get; set; }
public string PublicKey { get; set; }
public string WalletAddress { get; set; } //Hash of Public Key (shorter version).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ public OASISResult<bool> VerifyEmail(string token)
try
{
//TODO: PERFORMANCE} Implement in Providers so more efficient and do not need to return whole list!
OASISResult<IEnumerable<IAvatar>> avatarsResult = LoadAllAvatars(false);
OASISResult<IEnumerable<IAvatar>> avatarsResult = LoadAllAvatars(false, false);

if (!avatarsResult.IsError && avatarsResult.Result != null)
{
Expand Down Expand Up @@ -4193,7 +4193,7 @@ private async Task<OASISResult<IAvatar>> LoadProviderWalletsAsync(OASISResult<IA
break;
}
else
ErrorHandling.HandleWarning(ref result, $"Error occured in LoadProviderWalletsAsync in AvatarManager loading wallets for provider {type.Name}. Reason: {walletsResult.Message}");
ErrorHandling.HandleWarning(ref result, $"Error occured in LoadProviderWalletsAsync in AvatarManager loading wallets for provider {type.Name}. Reason: {walletsResult.Message}", walletsResult.DetailedMessage);
}

if (walletsResult.IsError)
Expand Down Expand Up @@ -4234,12 +4234,23 @@ private OASISResult<IAvatar> LoadProviderWallets(OASISResult<IAvatar> result)
OASISResult<Dictionary<ProviderType, List<IProviderWallet>>> walletsResult =
WalletManager.Instance.LoadProviderWalletsForAvatarById(result.Result.Id);

if (walletsResult.IsError)
ErrorHandling.HandleError(ref result, $"Error occured in LoadProviderWallets method in AvatarManager loading wallets for avatar {result.Result.Id}. Reason: {walletsResult.Message}");
//This use to be HandleError but if the local wallets could not be loaded for whatever reason such as it was not found (because this is a new avatar for example), then it should just continue and then a new one will be created.
if (walletsResult.IsError || walletsResult.Result == null)
ErrorHandling.HandleWarning(ref result, $"Error occured in LoadProviderWallets method in AvatarManager loading wallets for avatar {result.Result.Id}. Reason: {walletsResult.Message}", walletsResult.DetailedMessage, walletsResult);
else
{
result.Result.ProviderWallets = walletsResult.Result;
result.IsLoaded = true;

result.InnerMessages.AddRange(walletsResult.InnerMessages);
if (walletsResult.WarningCount > 0)
{
result.InnerMessages.Add(walletsResult.Message);
result.InnerMessages.AddRange(walletsResult.InnerMessages);
result.IsWarning = true;
result.WarningCount += walletsResult.WarningCount;
}
}

return result;
}

Expand All @@ -4260,7 +4271,7 @@ private async Task<OASISResult<IEnumerable<IAvatar>>> LoadProviderWalletsForAllA
break;
}
else
ErrorHandling.HandleWarning(ref result, $"Error occured in LoadProviderWalletsForAllAvatarsAsync in AvatarManager loading wallets for avatar {avatar.Id} for provider {type.Name}. Reason: {walletsResult.Message}");
ErrorHandling.HandleWarning(ref result, $"Error occured in LoadProviderWalletsForAllAvatarsAsync in AvatarManager loading wallets for avatar {avatar.Id} for provider {type.Name}. Reason: {walletsResult.Message}", walletsResult.DetailedMessage);
}

if (walletsResult.IsError)
Expand Down Expand Up @@ -4302,7 +4313,7 @@ private OASISResult<IEnumerable<IAvatar>> LoadProviderWalletsForAllAvatars(OASIS
break;
}
else
ErrorHandling.HandleWarning(ref result, $"Error occured in LoadProviderWalletsForAllAvatars in AvatarManager loading wallets for avatar {avatar.Id} for provider {type.Name}. Reason: {walletsResult.Message}");
ErrorHandling.HandleWarning(ref result, $"Error occured in LoadProviderWalletsForAllAvatars in AvatarManager loading wallets for avatar {avatar.Id} for provider {type.Name}. Reason: {walletsResult.Message}", walletsResult.DetailedMessage);
}

if (walletsResult.IsError)
Expand Down
Loading

0 comments on commit 8c93ea5

Please sign in to comment.