Skip to content
This repository has been archived by the owner on Apr 6, 2020. It is now read-only.

Moved CertificateQueryService to base project #68

Merged
merged 2 commits into from
Nov 30, 2017
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
18 changes: 18 additions & 0 deletions Neo.Gui.Base/BaseRegistrationModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Autofac;
using Neo.Gui.Base.Certificates;

namespace Neo.Gui.Base
{
public class BaseRegistrationModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder
.RegisterType<CertificateQueryService>()
.As<ICertificateQueryService>()
.SingleInstance();

base.Load(builder);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Security.Cryptography.X509Certificates;

namespace Neo.Gui.Wpf.Certificates
namespace Neo.Gui.Base.Certificates
{
public class CertificateQueryResult : IDisposable
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Neo.Gui.Wpf.Certificates
namespace Neo.Gui.Base.Certificates
{
public enum CertificateQueryResultType
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,65 +5,51 @@
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using Neo.Core;
using Neo.Gui.Wpf.Properties;
using Neo.SmartContract;
using Neo.Wallets;
using ECCurve = Neo.Cryptography.ECC.ECCurve;
using ECPoint = Neo.Cryptography.ECC.ECPoint;

namespace Neo.Gui.Wpf.Certificates
namespace Neo.Gui.Base.Certificates
{
public static class CertificateQueryService
internal class CertificateQueryService : ICertificateQueryService
{
private static readonly Dictionary<UInt160, CertificateQueryResult> Results = new Dictionary<UInt160, CertificateQueryResult>();
private readonly Dictionary<UInt160, CertificateQueryResult> results = new Dictionary<UInt160, CertificateQueryResult>();

static CertificateQueryService()
{
Directory.CreateDirectory(Settings.Default.CertCachePath);
}
private string certCachePath;
private bool initialized;

private static void Web_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
public void Initialize(string certificateCachePath)
{
using ((WebClient) sender)
{
var hash = (UInt160) e.UserState;
if (e.Cancelled || e.Error != null)
{
lock (Results)
{
Results[hash].Type = CertificateQueryResultType.Missing;
}
}
else
{
var address = Wallet.ToAddress(hash);
var path = Path.Combine(Settings.Default.CertCachePath, $"{address}.cer");
File.WriteAllBytes(path, e.Result);
lock (Results)
{
UpdateResultFromFile(hash);
}
}
}
this.certCachePath = certificateCachePath;

Directory.CreateDirectory(this.certCachePath);

this.initialized = true;
}

public static CertificateQueryResult Query(ECPoint pubkey)
public CertificateQueryResult Query(ECPoint pubkey)
{
return Query(Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash());
}

public static CertificateQueryResult Query(UInt160 hash)
public CertificateQueryResult Query(UInt160 hash)
{
lock (Results)
if (!this.initialized)
{
throw new Exception("Service has not been initialized!");
}

lock (results)
{
if (Results.ContainsKey(hash)) return Results[hash];
Results[hash] = new CertificateQueryResult { Type = CertificateQueryResultType.Querying };
if (results.ContainsKey(hash)) return results[hash];
results[hash] = new CertificateQueryResult { Type = CertificateQueryResultType.Querying };
}
var address = Wallet.ToAddress(hash);
var path = Path.Combine(Settings.Default.CertCachePath, $"{address}.cer");
var path = Path.Combine(this.certCachePath, $"{address}.cer");
if (File.Exists(path))
{
lock (Results)
lock (results)
{
UpdateResultFromFile(hash);
}
Expand All @@ -72,51 +58,82 @@ public static CertificateQueryResult Query(UInt160 hash)
{
var url = $"http://cert.onchain.com/antshares/{address}.cer";
var web = new WebClient();
web.DownloadDataCompleted += Web_DownloadDataCompleted;
web.DownloadDataCompleted += this.Web_DownloadDataCompleted;
web.DownloadDataAsync(new Uri(url), hash);
}
return Results[hash];
return results[hash];
}

private static void UpdateResultFromFile(UInt160 hash)
#region Private methods

private void UpdateResultFromFile(UInt160 hash)
{
var address = Wallet.ToAddress(hash);
X509Certificate2 cert;
try
{
cert = new X509Certificate2(Path.Combine(Settings.Default.CertCachePath, $"{address}.cer"));
cert = new X509Certificate2(Path.Combine(this.certCachePath, $"{address}.cer"));
}
catch (CryptographicException)
{
Results[hash].Type = CertificateQueryResultType.Missing;
results[hash].Type = CertificateQueryResultType.Missing;
return;
}
if (cert.PublicKey.Oid.Value != "1.2.840.10045.2.1")
{
Results[hash].Type = CertificateQueryResultType.Missing;
results[hash].Type = CertificateQueryResultType.Missing;
return;
}
if (!hash.Equals(Contract.CreateSignatureRedeemScript(ECPoint.DecodePoint(cert.PublicKey.EncodedKeyValue.RawData, ECCurve.Secp256r1)).ToScriptHash()))
{
Results[hash].Type = CertificateQueryResultType.Missing;
results[hash].Type = CertificateQueryResultType.Missing;
return;
}
using (var chain = new X509Chain())
{
Results[hash].Certificate = cert;
results[hash].Certificate = cert;
if (chain.Build(cert))
{
Results[hash].Type = CertificateQueryResultType.Good;
results[hash].Type = CertificateQueryResultType.Good;
}
else if (chain.ChainStatus.Length == 1 && chain.ChainStatus[0].Status == X509ChainStatusFlags.NotTimeValid)
{
Results[hash].Type = CertificateQueryResultType.Expired;
results[hash].Type = CertificateQueryResultType.Expired;
}
else
{
results[hash].Type = CertificateQueryResultType.Invalid;
}
}
}

private void Web_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
if (!this.initialized) return;

using ((WebClient)sender)
{
var hash = (UInt160)e.UserState;
if (e.Cancelled || e.Error != null)
{
lock (results)
{
results[hash].Type = CertificateQueryResultType.Missing;
}
}
else
{
Results[hash].Type = CertificateQueryResultType.Invalid;
var address = Wallet.ToAddress(hash);
var path = Path.Combine(this.certCachePath, $"{address}.cer");
File.WriteAllBytes(path, e.Result);
lock (results)
{
this.UpdateResultFromFile(hash);
}
}
}
}

#endregion
}
}
13 changes: 13 additions & 0 deletions Neo.Gui.Base/Certificates/ICertificateQueryService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using ECPoint = Neo.Cryptography.ECC.ECPoint;

namespace Neo.Gui.Base.Certificates
{
public interface ICertificateQueryService
{
void Initialize(string certificateCachePath);

CertificateQueryResult Query(ECPoint pubkey);

CertificateQueryResult Query(UInt160 hash);
}
}
5 changes: 5 additions & 0 deletions Neo.Gui.Base/Neo.Gui.Base.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Autofac" Version="4.6.2" />
<PackageReference Include="Neo" Version="2.4.0" />
<PackageReference Include="Neo.VM" Version="2.0.3" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.1" />
Expand All @@ -25,4 +26,8 @@
</EmbeddedResource>
</ItemGroup>

<ItemGroup>
<Folder Include="Services\" />
</ItemGroup>

</Project>
11 changes: 8 additions & 3 deletions Neo.Gui.Base/Theming/Theme.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@ namespace Neo.Gui.Base.Theming
{
public class Theme
{
// TODO Add default theme colors to a config file so the default values can be changed by the user
private const string DefaultHighlightColorHex = "#76B466";
private const string DefaultAccentBaseColorHex = "#3DA43C";
private const string DefaultWindowBorderColorHex = "#9EAF99";

public static readonly Theme Default = new Theme
{
Style = Style.Light,
HighlightColor = "#76B466".HexToColor(),
AccentBaseColor = "#3DA43C".HexToColor(),
WindowBorderColor = "#9EAF99".HexToColor()
HighlightColor = DefaultHighlightColorHex.HexToColor(),
AccentBaseColor = DefaultAccentBaseColorHex.HexToColor(),
WindowBorderColor = DefaultWindowBorderColorHex.HexToColor()
};

public Style Style { get; set; }
Expand Down
2 changes: 2 additions & 0 deletions Neo.Gui.Wpf/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Threading.Tasks;
using System.Windows;
using Autofac;
using Neo.Gui.Base;
using Neo.Gui.Base.Controllers.Interfaces;
using Neo.Gui.Base.Helpers.Interfaces;
using Neo.Gui.Base.Messages;
Expand Down Expand Up @@ -124,6 +125,7 @@ private static ILifetimeScope BuildContainer()
{
var autoFacContainerBuilder = new ContainerBuilder();

autoFacContainerBuilder.RegisterModule<BaseRegistrationModule>();
autoFacContainerBuilder.RegisterModule<ViewModelsRegistrationModule>();
autoFacContainerBuilder.RegisterModule<MessagingRegistrationModule>();
autoFacContainerBuilder.RegisterModule<ControllersRegistrationModule>();
Expand Down
8 changes: 7 additions & 1 deletion Neo.Gui.Wpf/Controllers/WalletController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Security.Cryptography;
using System.Timers;
using Neo.Core;
using Neo.Gui.Base.Certificates;
using Neo.Gui.Base.Controllers;
using Neo.Gui.Base.Controllers.Interfaces;
using Neo.Gui.Base.Data;
Expand Down Expand Up @@ -38,6 +39,7 @@ public class WalletController :
#region Private Fields

private readonly IBlockChainController blockChainController;
private readonly ICertificateQueryService certificateQueryService;
private readonly INotificationHelper notificationHelper;
private readonly IMessagePublisher messagePublisher;

Expand All @@ -64,11 +66,13 @@ public class WalletController :

public WalletController(
IBlockChainController blockChainController,
ICertificateQueryService certificateQueryService,
INotificationHelper notificationHelper,
IMessagePublisher messagePublisher,
IMessageSubscriber messageSubscriber)
{
this.blockChainController = blockChainController;
this.certificateQueryService = certificateQueryService;
this.notificationHelper = notificationHelper;
this.messagePublisher = messagePublisher;

Expand All @@ -87,6 +91,8 @@ public class WalletController :

public void Initialize()
{
this.certificateQueryService.Initialize(Settings.Default.CertCachePath);

// Setup automatic refresh timer
this.refreshTimer = new Timer
{
Expand Down Expand Up @@ -1015,7 +1021,7 @@ private CertificateQueryResult GetCertificateQueryResult(AssetState asset)
{
if (!this.certificateQueryResultCache.ContainsKey(asset.Owner))
{
result = CertificateQueryService.Query(asset.Owner);
result = this.certificateQueryService.Query(asset.Owner);

if (result == null) return null;

Expand Down
3 changes: 0 additions & 3 deletions Neo.Gui.Wpf/Neo.Gui.Wpf.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,6 @@
<Compile Include="Helpers\DispatchHelper.cs" />
<Compile Include="RegistrationModules\MessagingRegistrationModule.cs" />
<Compile Include="Certificates\RootCertificate.cs" />
<Compile Include="Certificates\CertificateQueryResult.cs" />
<Compile Include="Certificates\CertificateQueryResultType.cs" />
<Compile Include="Certificates\CertificateQueryService.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
Expand Down