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

Connection string parts validation #276

Merged
merged 5 commits into from
Sep 20, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// This source code is licensed under the MIT license.

using Microsoft.Extensions.Configuration;
using System;
using System.Linq;

namespace NBB.MultiTenancy.Abstractions.Configuration;
Expand Down Expand Up @@ -43,22 +44,54 @@ private static T getValueOrComplexObject<T>(IConfiguration config, string key)
/// <returns></returns>
public static string GetConnectionString(this ITenantConfiguration config, string name)
{
var splitted = config.GetValue<ConnectionStringDetails>($"ConnectionStrings:{name}");
if (splitted != null)
var connStrBuilder = config.GetValue<TenantConnectionStringBuilder>($"ConnectionStrings:{name}");
if (connStrBuilder != null)
{
return
$"Server={splitted.Server};Database={splitted.Database};User Id={splitted.UserName};Password={splitted.Password};{splitted.OtherParams}";
return connStrBuilder.Build();
}

return config.GetValue<string>($"ConnectionStrings:{name}");
}

private class ConnectionStringDetails
/// <summary>
/// Exception thrown when connection string builder is not properly configured
/// </summary>
public class TenantConnectionStringBuilderException : Exception
{
public TenantConnectionStringBuilderException(string message) : base(message)
{
}
}

private class TenantConnectionStringBuilder
{
public string Server { get; set; }
public string Database { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string OtherParams { get; set; }

public string Build()
{
Validate();

return $"Server={Server};Database={Database};User Id={UserName};Password={Password};{OtherParams}";
}

private static void CheckMandatoryField(string fieldValue, string fieldName)
{
if (string.IsNullOrWhiteSpace(fieldValue))
{
throw new TenantConnectionStringBuilderException($"Connection string part {fieldName} is not provided!");
}
}

private void Validate()
{
CheckMandatoryField(Server, nameof(Server));
CheckMandatoryField(Database, nameof(Database));
CheckMandatoryField(UserName, nameof(UserName));
CheckMandatoryField(Password, nameof(Password));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using System.IO;
using System.Text;
using Xunit;
using static NBB.MultiTenancy.Abstractions.Configuration.TenantConfigurationExtensions;

namespace NBB.MultiTenancy.Abstractions.Tests
{
Expand Down Expand Up @@ -209,6 +210,7 @@ public void load_connectionString_splitted_without_defaults()
""Server"": ""server1"",
""Database"": ""db1"",
""UserName"": ""web"",
""Password"": ""pass"",
""OtherParams"": ""MultipleActiveResultSets=true""
}
}
Expand Down Expand Up @@ -242,7 +244,7 @@ public void load_connectionString_splitted_without_defaults()

// Assert
tenantConfig.GetConnectionString("ConnectionString_").Should().BeNull();
tenantConfig.GetConnectionString("Leasing_Database").Should().Be("Server=server1;Database=db1;User Id=web;Password=;MultipleActiveResultSets=true");
tenantConfig.GetConnectionString("Leasing_Database").Should().Be("Server=server1;Database=db1;User Id=web;Password=pass;MultipleActiveResultSets=true");
tenantConfig.GetValue<string>("TenantId").Should().Be("68a448a2-e7d8-4875-8127-f18668217eb6");
}

Expand All @@ -258,7 +260,8 @@ public void load_connectionString_splitted_from_default()
""Leasing_Database"": {
""Server"": ""cf-erp17\\mama"",
""Database"": ""db1"",
""UserName"": ""web""
""UserName"": ""web"",
""Password"": ""pass""
}
}
},
Expand Down Expand Up @@ -303,7 +306,7 @@ public void load_connectionString_splitted_from_default()

// Assert
tenantConfig.GetConnectionString("ConnectionString_").Should().BeNull();
tenantConfig.GetConnectionString("Leasing_Database").Should().Be("Server=cf-erp17\\mama;Database=db1;User Id=web;Password=;");
tenantConfig.GetConnectionString("Leasing_Database").Should().Be("Server=cf-erp17\\mama;Database=db1;User Id=web;Password=pass;");
tenantConfig.GetValue<string>("TenantId").Should().Be("ef8d5362-9969-4e02-8794-0d1af56816f6");
}

Expand Down Expand Up @@ -383,6 +386,7 @@ public void load_connectionString_with_concatenated_defaults()
""Server"": ""server1"",
""Database"": ""db1"",
""UserName"": ""web"",
""Password"": ""pass"",
""OtherParams"": ""MultipleActiveResultSets=true""
}
}
Expand Down Expand Up @@ -416,7 +420,7 @@ public void load_connectionString_with_concatenated_defaults()

// Assert
tenantConfig.GetConnectionString("ConnectionString_").Should().BeNull();
tenantConfig.GetConnectionString("Leasing_Database").Should().Be("Server=server1;Database=db1;User Id=web;Password=;MultipleActiveResultSets=true");
tenantConfig.GetConnectionString("Leasing_Database").Should().Be("Server=server1;Database=db1;User Id=web;Password=pass;MultipleActiveResultSets=true");
tenantConfig.GetValue<string>("TenantId").Should().Be("68a448a2-e7d8-4875-8127-f18668217eb6");
}

Expand Down Expand Up @@ -476,6 +480,54 @@ public void load_connectionString_concatenated_with_splitted_defaults()
tenantConfig.GetValue<string>("TenantId").Should().Be("68a448a2-e7d8-4875-8127-f18668217eb6");
}


[Fact]
public void load_connectionString_splitted_tenant1_missing_database()
{
// Arrange
var myConfiguration = @"{
""MultiTenancy"": {
""Tenants"": {
""MBFS"": {
""TenantId"": ""68a448a2-e7d8-4875-8127-f18668217eb6"",
""ConnectionStrings"": {
""Leasing_Database"": {
""Server"": ""server1"",
""Database"": """",
""UserName"": ""web"",
""OtherParams"": ""MultipleActiveResultSets=true""
}
}
},
""BCR"": {
""TenantId"": ""ef8d5362-9969-4e02-8794-0d1af56816f6"",
""Code"": ""BCR""
},
""DEV"": {
""TenantId"": ""da84628a-2925-4b69-9116-a90dd5a72b1f"",
""Code"": ""DEV""
}
}
}
}";

var configuration = new ConfigurationBuilder()
.AddInMemoryCollection()
.AddJsonStream(new MemoryStream(Encoding.UTF8.GetBytes(myConfiguration)))
.Build();

var tid = Guid.Parse("68a448a2-e7d8-4875-8127-f18668217eb6");
var tca = new TenantContextAccessor();

tca.TenantContext = new TenantContext(new Tenant(tid, "MBFS"));
var tenantConfig = new TenantConfiguration(configuration,
new OptionsWrapper<TenancyHostingOptions>(new TenancyHostingOptions()
{ TenancyType = TenancyType.MultiTenant }), tca);

// Act
Action act = () => tenantConfig.GetConnectionString("Leasing_Database");

// Assert
act.Should().Throw<TenantConnectionStringBuilderException>().WithMessage("Connection string part Database is not provided!");
}
}
}
Loading