52 lines
1.7 KiB
C#
52 lines
1.7 KiB
C#
using System.Globalization;
|
|
using System.Security.Cryptography;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using Tiku.Domain.Tenancy;
|
|
|
|
namespace Tiku.Infrastructure.Tenancy;
|
|
|
|
internal static class TenantDomainProvisioning
|
|
{
|
|
public static TenantDomain CreatePrimary(Guid tenantId, string host)
|
|
{
|
|
return new TenantDomain
|
|
{
|
|
TenantId = tenantId,
|
|
Host = NormalizeHost(host),
|
|
DomainType = TenantDomainType.Custom,
|
|
Status = TenantDomainStatus.Pending,
|
|
IsPrimary = true,
|
|
VerificationToken = Base64UrlEncoder.Encode(RandomNumberGenerator.GetBytes(32))
|
|
};
|
|
}
|
|
|
|
public static string NormalizeHost(string value)
|
|
{
|
|
var candidate = value.Trim().TrimEnd('.');
|
|
if (candidate.Length == 0 || candidate.Contains('/') || candidate.Contains(':') || candidate.Contains('*'))
|
|
{
|
|
throw new ArgumentException("A DNS host without scheme, port, path or wildcard is required.", nameof(value));
|
|
}
|
|
|
|
string ascii;
|
|
try
|
|
{
|
|
ascii = new IdnMapping().GetAscii(candidate).ToLowerInvariant();
|
|
}
|
|
catch (ArgumentException)
|
|
{
|
|
throw new ArgumentException("The domain host is invalid.", nameof(value));
|
|
}
|
|
|
|
if (ascii.Length > 253 || ascii.Split('.').Length < 2 ||
|
|
ascii.Split('.').Any(label => label.Length is 0 or > 63 ||
|
|
label.StartsWith('-') || label.EndsWith('-') ||
|
|
label.Any(character => !char.IsAsciiLetterOrDigit(character) && character != '-')))
|
|
{
|
|
throw new ArgumentException("The domain host is invalid.", nameof(value));
|
|
}
|
|
|
|
return ascii;
|
|
}
|
|
}
|