Skip to content

Commit

Permalink
Merge pull request stratisproject#334 from codingupastorm/merging-mas…
Browse files Browse the repository at this point in the history
…ter-in

Merging master in
  • Loading branch information
codingupastorm authored Apr 29, 2020
2 parents d8fa2e1 + 87d1758 commit c955f68
Show file tree
Hide file tree
Showing 102 changed files with 2,101 additions and 710 deletions.
31 changes: 21 additions & 10 deletions src/CertificateAuthority.Tests.Common/CaTestHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using CertificateAuthority.Controllers;
using CertificateAuthority.Models;
using FluentAssertions;
Expand All @@ -11,6 +10,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using NLog;
using Stratis.Feature.PoA.Tokenless;

namespace CertificateAuthority.Tests.Common
Expand Down Expand Up @@ -74,24 +74,35 @@ public static CredentialsModel CreateAccount(IWebHost server, AccountAccessFlags
public static void InitializeCa(TestServer server)
{
var network = new TokenlessNetwork();

var certificatesController = (CertificatesController)server.Host.Services.GetService(typeof(CertificatesController));
var model = new InitializeCertificateAuthorityModel(CaMnemonic, CaMnemonicPassword, network.Consensus.CoinType, AdminPassword);
certificatesController.InitializeCertificateAuthority(model);
}

public static IWebHostBuilder CreateWebHostBuilder([CallerMemberName] string callingMethod = null)
public static IWebHostBuilder CreateWebHostBuilder(string dataFolderName)
{
// Create a datafolder path for the CA settings to use
string hash = Guid.NewGuid().ToString("N").Substring(0, 7);
string numberedFolderName = string.Join(
".",
new[] { hash }.Where(s => s != null));
string dataFolderName = Path.Combine(Path.GetTempPath(), callingMethod, numberedFolderName);

// Initialize settings
var settings = new Settings();
settings.Initialize(new string[] { $"-datadir={dataFolderName}", $"-serverurls={BaseAddress}" });

// Create the log folder
string logFolder = Path.Combine(settings.DataDirectory, "Logs");
Directory.CreateDirectory(logFolder);

// Initialize logging for tests.
var config = new NLog.Config.LoggingConfiguration();

// Targets where to log to: File and Console
var logfile = new NLog.Targets.FileTarget("logfile") { FileName = Path.Combine(logFolder, "ca.txt") };
var logconsole = new NLog.Targets.ConsoleTarget("logconsole");

// Rules for mapping loggers to targets
config.AddRule(LogLevel.Info, LogLevel.Fatal, logconsole);
config.AddRule(LogLevel.Debug, LogLevel.Fatal, logfile);

// Apply config
NLog.LogManager.Configuration = config;

IWebHostBuilder builder = WebHost.CreateDefaultBuilder();
builder.UseUrls(settings.ServerUrls);
builder.UseStartup<TestOnlyStartup>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using CertificateAuthority.Controllers;
using CertificateAuthority.Database;
using CertificateAuthority.Models;
Expand All @@ -8,23 +9,29 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.TestHost;
using NBitcoin;
using Stratis.Bitcoin.Tests.Common;
using Xunit;

namespace CertificateAuthority.Tests.FullProjectTests
{
public sealed class AccountsControllerTests
{
private readonly AccountsController accountsController;
private AccountsController accountsController;
private readonly CredentialsModel adminCredentials;
private readonly DataCacheLayer dataCacheLayer;
private readonly TestServer server;
private DataCacheLayer dataCacheLayer;
private TestServer server;

public AccountsControllerTests()
{
IWebHostBuilder builder = CaTestHelper.CreateWebHostBuilder();
this.adminCredentials = new CredentialsModel(Settings.AdminAccountId, CaTestHelper.AdminPassword);
}

private void CreateServer([CallerMemberName] string callingMethod = "")
{
TestBase.GetTestRootFolder(out string testRootFolder, callingMethod);
IWebHostBuilder builder = CaTestHelper.CreateWebHostBuilder(testRootFolder);
this.server = new TestServer(builder);

this.adminCredentials = new CredentialsModel(Settings.AdminAccountId, CaTestHelper.AdminPassword);
this.accountsController = (AccountsController)this.server.Host.Services.GetService(typeof(AccountsController));
this.dataCacheLayer = (DataCacheLayer)this.server.Host.Services.GetService(typeof(DataCacheLayer));

Expand All @@ -34,6 +41,8 @@ public AccountsControllerTests()
[Fact]
public void TestAccountsControllerMethods()
{
CreateServer();

// Just admin on start.
Assert.Single(CaTestHelper.GetValue<List<AccountModel>>(this.accountsController.ListAll(this.adminCredentials)));

Expand Down Expand Up @@ -108,6 +117,8 @@ public void TestAccountsControllerMethods()
[Fact]
public void ListUnapprovedAccounts()
{
CreateServer();

_ = CaTestHelper.CreateAccount(this.server.Host, AccountAccessFlags.BasicAccess, approve: false);
_ = CaTestHelper.CreateAccount(this.server.Host, AccountAccessFlags.BasicAccess);

Expand All @@ -118,6 +129,8 @@ public void ListUnapprovedAccounts()
[Fact]
public void ChangeAccountPassword_CurrentUser_Pass()
{
CreateServer();

CredentialsModel credentials = CaTestHelper.CreateAccount(this.server.Host, AccountAccessFlags.BasicAccess);

var model = new ChangeAccountPasswordModel(credentials.AccountId, credentials.AccountId, credentials.Password, "newpassword");
Expand All @@ -132,6 +145,8 @@ public void ChangeAccountPassword_CurrentUser_Pass()
[Fact]
public void ChangeAccountPassword_CurrentUser_WrongPassword_Fail()
{
CreateServer();

CredentialsModel credentials = CaTestHelper.CreateAccount(this.server.Host, AccountAccessFlags.BasicAccess);

var model = new ChangeAccountPasswordModel(credentials.AccountId, credentials.AccountId, "wrongpassword", "newpassword");
Expand All @@ -146,6 +161,8 @@ public void ChangeAccountPassword_CurrentUser_WrongPassword_Fail()
[Fact]
public void ChangeAccountPassword_AdminUser_Pass()
{
CreateServer();

CredentialsModel userA_Credentials = CaTestHelper.CreateAccount(this.server.Host, AccountAccessFlags.BasicAccess);

var changePasswordModel = new ChangeAccountPasswordModel(this.adminCredentials.AccountId, userA_Credentials.AccountId, this.adminCredentials.Password, "newpassword");
Expand All @@ -160,6 +177,8 @@ public void ChangeAccountPassword_AdminUser_Pass()
[Fact]
public void ChangeAccountPassword_DifferentUser_Fail()
{
CreateServer();

CredentialsModel userA_Credentials = CaTestHelper.CreateAccount(this.server.Host, AccountAccessFlags.BasicAccess);
CredentialsModel userB_Credentials = CaTestHelper.CreateAccount(this.server.Host, AccountAccessFlags.BasicAccess);

Expand All @@ -176,6 +195,8 @@ public void ChangeAccountPassword_DifferentUser_Fail()
[Fact]
public void RejectAccount_Pass()
{
CreateServer();

CredentialsModel userA_Credentials = CaTestHelper.CreateAccount(this.server.Host, AccountAccessFlags.BasicAccess, approve: false);

var model = new CredentialsModelWithTargetId(userA_Credentials.AccountId, this.adminCredentials.AccountId, this.adminCredentials.Password);
Expand All @@ -188,6 +209,8 @@ public void RejectAccount_Pass()
[Fact]
public void RejectAccount_AccountAlreadyApproved_Fail()
{
CreateServer();

CredentialsModel userA_Credentials = CaTestHelper.CreateAccount(this.server.Host, AccountAccessFlags.BasicAccess);

var model = new CredentialsModelWithTargetId(userA_Credentials.AccountId, this.adminCredentials.AccountId, this.adminCredentials.Password);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using NBitcoin;
using Org.BouncyCastle.Pkcs;
using Stratis.Bitcoin.Networks;
using Stratis.Bitcoin.Tests.Common;
using Xunit;

namespace CertificateAuthority.Tests.FullProjectTests
Expand All @@ -26,7 +27,8 @@ public CertificateAuthorityIntegrationTests()
[Fact]
public void CertificateAuthorityTestServerStartsUp()
{
IWebHostBuilder builder = CaTestHelper.CreateWebHostBuilder();
TestBase.GetTestRootFolder(out string testRootFolder);
IWebHostBuilder builder = CaTestHelper.CreateWebHostBuilder(testRootFolder);

var server = new TestServer(builder);
var client = new CaClient(server.BaseAddress, server.CreateClient(), Settings.AdminAccountId, CaTestHelper.AdminPassword);
Expand All @@ -43,7 +45,8 @@ public void CertificateAuthorityTestServerStartsUp()
[Fact]
public void CertificateAuthorityTestServerGetsInitialized()
{
IWebHostBuilder builder = CaTestHelper.CreateWebHostBuilder();
TestBase.GetTestRootFolder(out string testRootFolder);
IWebHostBuilder builder = CaTestHelper.CreateWebHostBuilder(testRootFolder);

var server = new TestServer(builder);
var client = new CaClient(server.BaseAddress, server.CreateClient(), Settings.AdminAccountId, CaTestHelper.AdminPassword);
Expand All @@ -56,7 +59,8 @@ public void CertificateAuthorityTestServerGetsInitialized()
[Fact]
public void CertificateAuthorityCanAddANewAccount()
{
IWebHostBuilder builder = CaTestHelper.CreateWebHostBuilder();
TestBase.GetTestRootFolder(out string testRootFolder);
IWebHostBuilder builder = CaTestHelper.CreateWebHostBuilder(testRootFolder);

var server = new TestServer(builder);
var client = new CaClient(server.BaseAddress, server.CreateClient(), Settings.AdminAccountId, CaTestHelper.AdminPassword);
Expand Down Expand Up @@ -127,7 +131,8 @@ public void CertificateAuthorityCanAddANewAccount()
[Fact]
public void CertificateAuthorityCanGenerateCertificateSigningRequest()
{
IWebHostBuilder builder = CaTestHelper.CreateWebHostBuilder();
TestBase.GetTestRootFolder(out string testRootFolder);
IWebHostBuilder builder = CaTestHelper.CreateWebHostBuilder(testRootFolder);

var server = new TestServer(builder);
var client = new CaClient(server.BaseAddress, server.CreateClient(), Settings.AdminAccountId, CaTestHelper.AdminPassword);
Expand All @@ -154,7 +159,8 @@ public void CertificateAuthorityCanGenerateCertificateSigningRequest()
[Fact]
public void CertificateAuthorityCanIssueCertificate()
{
IWebHostBuilder builder = CaTestHelper.CreateWebHostBuilder();
TestBase.GetTestRootFolder(out string testRootFolder);
IWebHostBuilder builder = CaTestHelper.CreateWebHostBuilder(testRootFolder);

var server = new TestServer(builder);
var client = new CaClient(server.BaseAddress, server.CreateClient(), Settings.AdminAccountId, CaTestHelper.AdminPassword);
Expand Down Expand Up @@ -194,7 +200,8 @@ public void CertificateAuthorityCanIssueCertificate()
[Fact]
public void CertificateAuthorityCanIssueCertificateToMultipleOrganisations()
{
IWebHostBuilder builder = CaTestHelper.CreateWebHostBuilder();
TestBase.GetTestRootFolder(out string testRootFolder);
IWebHostBuilder builder = CaTestHelper.CreateWebHostBuilder(testRootFolder);

var server = new TestServer(builder);
var adminClient = new CaClient(server.BaseAddress, server.CreateClient(), Settings.AdminAccountId, CaTestHelper.AdminPassword);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using CertificateAuthority.Controllers;
using CertificateAuthority.Database;
Expand All @@ -13,6 +14,7 @@
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.X509;
using Stratis.Bitcoin.Tests.Common;
using Xunit;
using AccountAccessFlags = CertificateAuthority.Models.AccountAccessFlags;
using AccountInfo = CertificateAuthority.Models.AccountInfo;
Expand All @@ -23,11 +25,11 @@ namespace CertificateAuthority.Tests.FullProjectTests
{
public sealed class ControllersTests
{
private readonly AccountsController accountsController;
private AccountsController accountsController;
private readonly CredentialsModel adminCredentials;
private readonly CertificatesController certificatesController;
private readonly DataCacheLayer dataCacheLayer;
private readonly TestServer server;
private CertificatesController certificatesController;
private DataCacheLayer dataCacheLayer;
private TestServer server;

private static int transactionSigningIndex = 0;
private static int blockSigningIndex = 1;
Expand All @@ -41,10 +43,14 @@ public sealed class ControllersTests

public ControllersTests()
{
IWebHostBuilder builder = CaTestHelper.CreateWebHostBuilder();
this.server = new TestServer(builder);

this.adminCredentials = new CredentialsModel(Settings.AdminAccountId, CaTestHelper.AdminPassword);
}

private void CreateServer([CallerMemberName] string callingMethod = "")
{
TestBase.GetTestRootFolder(out string testRootFolder, callingMethod);
IWebHostBuilder builder = CaTestHelper.CreateWebHostBuilder(testRootFolder);
this.server = new TestServer(builder);

this.accountsController = (AccountsController)this.server.Host.Services.GetService(typeof(AccountsController));
this.certificatesController = (CertificatesController)this.server.Host.Services.GetService(typeof(CertificatesController));
Expand Down Expand Up @@ -75,6 +81,8 @@ private CredentialsModel GetPrivilegedAccount()
[Fact]
public void TestCertificatesControllerMethods()
{
CreateServer();

CredentialsModel credentials1 = this.GetPrivilegedAccount();

// We need to be absolutely sure that the components of the subject DN are in the same order in a CSR versus the resulting certificate.
Expand Down Expand Up @@ -198,6 +206,8 @@ public void TestCertificatesControllerMethods()
[Fact]
public void CanIssueCertificateViaTemplateCsrFromManager()
{
CreateServer();

CredentialsModel credentials1 = this.GetPrivilegedAccount();

// Check that we can obtain an unsigned CSR template from the CA, which we then sign locally and receive a certificate for.
Expand Down Expand Up @@ -250,6 +260,8 @@ public void CanIssueCertificateViaTemplateCsrFromManager()
[Fact]
public void CanIssueCertificateViaTemplateCsr()
{
CreateServer();

CredentialsModel credentials1 = this.GetPrivilegedAccount();

// Try do the issuance the same way a node would, by populating the relevant model and submitting it to the API.
Expand Down Expand Up @@ -296,6 +308,8 @@ public void CanIssueCertificateViaTemplateCsr()
[Fact]
public void CantRequestCertificateTwiceForSameIdentityAndCanReset()
{
CreateServer();

CredentialsModel credentials1 = this.GetPrivilegedAccount();

// Try do the issuance the same way a node would, by populating the relevant model and submitting it to the API.
Expand Down Expand Up @@ -361,6 +375,8 @@ public void CantRequestCertificateTwiceForSameIdentityAndCanReset()
[Fact]
private void TestAccessLevels()
{
CreateServer();

// Accounts.
this.Returns403IfNoAccess((int accountId, string password) => this.accountsController.GetAccountInfoById(new CredentialsModelWithTargetId(1, accountId, password)),
AccountAccessFlags.AccessAccountInfo);
Expand Down
21 changes: 12 additions & 9 deletions src/CertificateAuthority/CaClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Net.Http;
using System.Net.Http.Headers;
using CertificateAuthority.Models;
using Microsoft.Extensions.Logging;
using NBitcoin;
using Newtonsoft.Json;

Expand Down Expand Up @@ -100,15 +101,15 @@ public List<CertificateInfoModel> GetAllCertificates()
return this.RequestFromCA<List<CertificateInfoModel>>(GetAllCertificatesEndpoint, credentialsModel);
}

public List<PubKey> GetCertificatePublicKeys()
public List<PubKey> GetCertificatePublicKeys(ILogger logger = null)
{
var credentialsModel = new CredentialsModel()
{
AccountId = this.accountId,
Password = this.password
};

List<string> pubKeyList = this.RequestFromCA<List<string>>(GetCertificatePublicKeysEndpoint, credentialsModel);
List<string> pubKeyList = this.RequestFromCA<List<string>>(GetCertificatePublicKeysEndpoint, credentialsModel, logger);

return pubKeyList.Select(x => new PubKey(x)).ToList();
}
Expand Down Expand Up @@ -204,26 +205,28 @@ public bool RevokeCertificate(string thumbprint)
/// <param name="endpoint"></param>
/// <param name="model"></param>
/// <returns></returns>
private T RequestFromCA<T>(string endpoint, object model)
private T RequestFromCA<T>(string endpoint, object model, ILogger logger = null)
{
HttpResponseMessage response;

try
{
response = this.httpClient.PostAsJsonAsync($"{this.baseApiUrl}{endpoint}", model).GetAwaiter()
.GetResult();
if (logger != null)
logger.LogDebug($"Calling {this.baseApiUrl}{endpoint}");

response = this.httpClient.PostAsJsonAsync($"{this.baseApiUrl}{endpoint}", model).GetAwaiter().GetResult();
}
catch (HttpRequestException exception)
{
throw new CaClientException("Failed to connect to the CA.", exception);
throw new CaClientException($"Failed to connect to the CA: '{exception.Message}'");
}

if (!response.IsSuccessStatusCode)
{
string errorMessage = $"Failed to connect to the CA. Response Code: {response.StatusCode}.";
string errorMessage = $"Failed to connect to the CA, response Code: {response.StatusCode}.";

if (response.Content != null)
{
errorMessage += $" Message: {response.Content.ReadAsStringAsync().GetAwaiter().GetResult()}";
}

throw new CaClientException(errorMessage);
}
Expand Down
Loading

0 comments on commit c955f68

Please sign in to comment.