58 lines
2.1 KiB
C#
58 lines
2.1 KiB
C#
namespace ZB.MOM.WW.Auth.Ldap.Internal;
|
|
|
|
/// <summary>
|
|
/// Reduces a typed login to the bare account name used by <see cref="Abstractions.Ldap.LdapBindMode.User"/>:
|
|
/// one spelling flows into the bind template, the search filter and the returned username, so audit
|
|
/// rows never carry <c>DOMAIN\jdoe</c> for one sign-in and <c>jdoe</c> for the next.
|
|
/// </summary>
|
|
internal static class LdapUserName
|
|
{
|
|
/// <summary>
|
|
/// Trims <paramref name="input"/> and, when <paramref name="acceptDomainQualified"/>, strips one
|
|
/// leading <c>DOMAIN\</c> or one trailing <c>@suffix</c>. Returns <see langword="false"/> (with
|
|
/// <paramref name="name"/> empty) for blank input, for both forms at once, for a repeated
|
|
/// separator, for an empty side, or for any qualified form when <paramref name="acceptDomainQualified"/>
|
|
/// is <see langword="false"/>.
|
|
/// </summary>
|
|
public static bool TryNormalize(string? input, bool acceptDomainQualified, out string name)
|
|
{
|
|
name = "";
|
|
if (string.IsNullOrWhiteSpace(input))
|
|
return false;
|
|
|
|
var s = input.Trim();
|
|
var slash = s.IndexOf('\\');
|
|
var at = s.IndexOf('@');
|
|
|
|
if (slash >= 0 || at >= 0)
|
|
{
|
|
if (!acceptDomainQualified || (slash >= 0 && at >= 0))
|
|
return false;
|
|
|
|
if (slash >= 0)
|
|
{
|
|
if (slash == 0 || s.IndexOf('\\', slash + 1) >= 0)
|
|
return false;
|
|
s = s[(slash + 1)..];
|
|
}
|
|
else
|
|
{
|
|
// Unlike the slash branch (whose extracted suffix is checked for emptiness by the
|
|
// final length check below), the extracted piece here is the *prefix* — so an empty
|
|
// domain part (a trailing "@", e.g. "jdoe@") must be rejected explicitly.
|
|
if (at == s.Length - 1 || s.IndexOf('@', at + 1) >= 0)
|
|
return false;
|
|
s = s[..at];
|
|
}
|
|
|
|
s = s.Trim();
|
|
}
|
|
|
|
if (s.Length == 0)
|
|
return false;
|
|
|
|
name = s;
|
|
return true;
|
|
}
|
|
}
|