Refactor: standardize namespace and using directive style
Refactored all C# test files to use explicit namespace declarations and moved all using directives inside the namespace block for consistency. Updated assembly info and cache files to reflect the new build. Adjusted MvcTestingAppManifest.json to use fully qualified assembly names. No functional changes; all updates are related to code style, organization, and project metadata.
This commit is contained in:
@@ -4,213 +4,212 @@
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using global::System;
|
||||
using global::System.Collections.Generic;
|
||||
using global::System.Text;
|
||||
|
||||
namespace MediaBrowser.Model.Cryptography
|
||||
{
|
||||
// Defined from this hash storage spec
|
||||
// https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md
|
||||
// $<id>[$<param>=<value>(,<param>=<value>)*][$<salt>[$<hash>]]
|
||||
// with one slight amendment to ease the transition, we're writing out the bytes in hex
|
||||
// rather than making them a BASE64 string with stripped padding
|
||||
public class PasswordHash
|
||||
{
|
||||
private readonly Dictionary<string, string> _parameters;
|
||||
private readonly byte[] _salt;
|
||||
private readonly byte[] _hash;
|
||||
namespace MediaBrowser.Model.Cryptography;
|
||||
|
||||
public PasswordHash(string id, byte[] hash)
|
||||
: this(id, hash, Array.Empty<byte>())
|
||||
{
|
||||
}
|
||||
// Defined from this hash storage spec
|
||||
// https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md
|
||||
// $<id>[$<param>=<value>(,<param>=<value>)*][$<salt>[$<hash>]]
|
||||
// with one slight amendment to ease the transition, we're writing out the bytes in hex
|
||||
// rather than making them a BASE64 string with stripped padding
|
||||
public class PasswordHash
|
||||
{
|
||||
private readonly Dictionary<string, string> _parameters;
|
||||
private readonly byte[] _salt;
|
||||
private readonly byte[] _hash;
|
||||
|
||||
public PasswordHash(string id, byte[] hash, byte[] salt)
|
||||
: this(id, hash, salt, new Dictionary<string, string>())
|
||||
{
|
||||
}
|
||||
public PasswordHash(string id, byte[] hash)
|
||||
: this(id, hash, Array.Empty<byte>())
|
||||
{
|
||||
}
|
||||
|
||||
public PasswordHash(string id, byte[] hash, byte[] salt, Dictionary<string, string> parameters)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrEmpty(id);
|
||||
public PasswordHash(string id, byte[] hash, byte[] salt)
|
||||
: this(id, hash, salt, new Dictionary<string, string>())
|
||||
{
|
||||
}
|
||||
|
||||
Id = id;
|
||||
_hash = hash;
|
||||
_salt = salt;
|
||||
_parameters = parameters;
|
||||
}
|
||||
public PasswordHash(string id, byte[] hash, byte[] salt, Dictionary<string, string> parameters)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrEmpty(id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the symbolic name for the function used.
|
||||
/// </summary>
|
||||
/// <value>Returns the symbolic name for the function used.</value>
|
||||
public string Id { get; }
|
||||
Id = id;
|
||||
_hash = hash;
|
||||
_salt = salt;
|
||||
_parameters = parameters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the additional parameters used by the hash function.
|
||||
/// </summary>
|
||||
public IReadOnlyDictionary<string, string> Parameters => _parameters;
|
||||
/// <summary>
|
||||
/// Gets the symbolic name for the function used.
|
||||
/// </summary>
|
||||
/// <value>Returns the symbolic name for the function used.</value>
|
||||
public string Id { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the salt used for hashing the password.
|
||||
/// </summary>
|
||||
/// <value>Returns the salt used for hashing the password.</value>
|
||||
public ReadOnlySpan<byte> Salt => _salt;
|
||||
/// <summary>
|
||||
/// Gets the additional parameters used by the hash function.
|
||||
/// </summary>
|
||||
public IReadOnlyDictionary<string, string> Parameters => _parameters;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the hashed password.
|
||||
/// </summary>
|
||||
/// <value>Return the hashed password.</value>
|
||||
public ReadOnlySpan<byte> Hash => _hash;
|
||||
/// <summary>
|
||||
/// Gets the salt used for hashing the password.
|
||||
/// </summary>
|
||||
/// <value>Returns the salt used for hashing the password.</value>
|
||||
public ReadOnlySpan<byte> Salt => _salt;
|
||||
|
||||
public static PasswordHash Parse(ReadOnlySpan<char> hashString)
|
||||
{
|
||||
if (hashString.IsEmpty)
|
||||
{
|
||||
throw new ArgumentException("String can't be empty", nameof(hashString));
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the hashed password.
|
||||
/// </summary>
|
||||
/// <value>Return the hashed password.</value>
|
||||
public ReadOnlySpan<byte> Hash => _hash;
|
||||
|
||||
if (hashString[0] != '$')
|
||||
{
|
||||
throw new FormatException("Hash string must start with a $");
|
||||
}
|
||||
public static PasswordHash Parse(ReadOnlySpan<char> hashString)
|
||||
{
|
||||
if (hashString.IsEmpty)
|
||||
{
|
||||
throw new ArgumentException("String can't be empty", nameof(hashString));
|
||||
}
|
||||
|
||||
// Ignore first $
|
||||
hashString = hashString[1..];
|
||||
if (hashString[0] != '$')
|
||||
{
|
||||
throw new FormatException("Hash string must start with a $");
|
||||
}
|
||||
|
||||
int nextSegment = hashString.IndexOf('$');
|
||||
if (hashString.IsEmpty || nextSegment == 0)
|
||||
{
|
||||
throw new FormatException("Hash string must contain a valid id");
|
||||
}
|
||||
// Ignore first $
|
||||
hashString = hashString[1..];
|
||||
|
||||
if (nextSegment == -1)
|
||||
{
|
||||
return new PasswordHash(hashString.ToString(), Array.Empty<byte>());
|
||||
}
|
||||
int nextSegment = hashString.IndexOf('$');
|
||||
if (hashString.IsEmpty || nextSegment == 0)
|
||||
{
|
||||
throw new FormatException("Hash string must contain a valid id");
|
||||
}
|
||||
|
||||
ReadOnlySpan<char> id = hashString[..nextSegment];
|
||||
hashString = hashString[(nextSegment + 1)..];
|
||||
Dictionary<string, string>? parameters = null;
|
||||
if (nextSegment == -1)
|
||||
{
|
||||
return new PasswordHash(hashString.ToString(), Array.Empty<byte>());
|
||||
}
|
||||
|
||||
nextSegment = hashString.IndexOf('$');
|
||||
ReadOnlySpan<char> id = hashString[..nextSegment];
|
||||
hashString = hashString[(nextSegment + 1)..];
|
||||
Dictionary<string, string>? parameters = null;
|
||||
|
||||
// Optional parameters
|
||||
ReadOnlySpan<char> parametersSpan = nextSegment == -1 ? hashString : hashString[..nextSegment];
|
||||
if (parametersSpan.Contains('='))
|
||||
{
|
||||
while (!parametersSpan.IsEmpty)
|
||||
{
|
||||
ReadOnlySpan<char> parameter;
|
||||
int index = parametersSpan.IndexOf(',');
|
||||
if (index == -1)
|
||||
{
|
||||
parameter = parametersSpan;
|
||||
parametersSpan = ReadOnlySpan<char>.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
parameter = parametersSpan[..index];
|
||||
parametersSpan = parametersSpan[(index + 1)..];
|
||||
}
|
||||
nextSegment = hashString.IndexOf('$');
|
||||
|
||||
int splitIndex = parameter.IndexOf('=');
|
||||
if (splitIndex == -1 || splitIndex == 0 || splitIndex == parameter.Length - 1)
|
||||
{
|
||||
throw new FormatException("Malformed parameter in password hash string");
|
||||
}
|
||||
// Optional parameters
|
||||
ReadOnlySpan<char> parametersSpan = nextSegment == -1 ? hashString : hashString[..nextSegment];
|
||||
if (parametersSpan.Contains('='))
|
||||
{
|
||||
while (!parametersSpan.IsEmpty)
|
||||
{
|
||||
ReadOnlySpan<char> parameter;
|
||||
int index = parametersSpan.IndexOf(',');
|
||||
if (index == -1)
|
||||
{
|
||||
parameter = parametersSpan;
|
||||
parametersSpan = ReadOnlySpan<char>.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
parameter = parametersSpan[..index];
|
||||
parametersSpan = parametersSpan[(index + 1)..];
|
||||
}
|
||||
|
||||
(parameters ??= new Dictionary<string, string>()).Add(
|
||||
parameter[..splitIndex].ToString(),
|
||||
parameter[(splitIndex + 1)..].ToString());
|
||||
}
|
||||
int splitIndex = parameter.IndexOf('=');
|
||||
if (splitIndex == -1 || splitIndex == 0 || splitIndex == parameter.Length - 1)
|
||||
{
|
||||
throw new FormatException("Malformed parameter in password hash string");
|
||||
}
|
||||
|
||||
if (nextSegment == -1)
|
||||
{
|
||||
// parameters can't be null here
|
||||
return new PasswordHash(id.ToString(), Array.Empty<byte>(), Array.Empty<byte>(), parameters!);
|
||||
}
|
||||
(parameters ??= new Dictionary<string, string>()).Add(
|
||||
parameter[..splitIndex].ToString(),
|
||||
parameter[(splitIndex + 1)..].ToString());
|
||||
}
|
||||
|
||||
hashString = hashString[(nextSegment + 1)..];
|
||||
nextSegment = hashString.IndexOf('$');
|
||||
}
|
||||
if (nextSegment == -1)
|
||||
{
|
||||
// parameters can't be null here
|
||||
return new PasswordHash(id.ToString(), Array.Empty<byte>(), Array.Empty<byte>(), parameters!);
|
||||
}
|
||||
|
||||
if (nextSegment == 0)
|
||||
{
|
||||
throw new FormatException("Hash string contains an empty segment");
|
||||
}
|
||||
hashString = hashString[(nextSegment + 1)..];
|
||||
nextSegment = hashString.IndexOf('$');
|
||||
}
|
||||
|
||||
byte[] hash;
|
||||
byte[] salt;
|
||||
if (nextSegment == 0)
|
||||
{
|
||||
throw new FormatException("Hash string contains an empty segment");
|
||||
}
|
||||
|
||||
if (nextSegment == -1)
|
||||
{
|
||||
salt = Array.Empty<byte>();
|
||||
hash = Convert.FromHexString(hashString);
|
||||
}
|
||||
else
|
||||
{
|
||||
salt = Convert.FromHexString(hashString[..nextSegment]);
|
||||
hashString = hashString[(nextSegment + 1)..];
|
||||
nextSegment = hashString.IndexOf('$');
|
||||
if (nextSegment != -1)
|
||||
{
|
||||
throw new FormatException("Hash string contains too many segments");
|
||||
}
|
||||
byte[] hash;
|
||||
byte[] salt;
|
||||
|
||||
if (hashString.IsEmpty)
|
||||
{
|
||||
throw new FormatException("Hash segment is empty");
|
||||
}
|
||||
if (nextSegment == -1)
|
||||
{
|
||||
salt = Array.Empty<byte>();
|
||||
hash = Convert.FromHexString(hashString);
|
||||
}
|
||||
else
|
||||
{
|
||||
salt = Convert.FromHexString(hashString[..nextSegment]);
|
||||
hashString = hashString[(nextSegment + 1)..];
|
||||
nextSegment = hashString.IndexOf('$');
|
||||
if (nextSegment != -1)
|
||||
{
|
||||
throw new FormatException("Hash string contains too many segments");
|
||||
}
|
||||
|
||||
hash = Convert.FromHexString(hashString);
|
||||
}
|
||||
if (hashString.IsEmpty)
|
||||
{
|
||||
throw new FormatException("Hash segment is empty");
|
||||
}
|
||||
|
||||
return new PasswordHash(id.ToString(), hash, salt, parameters ?? new Dictionary<string, string>());
|
||||
}
|
||||
hash = Convert.FromHexString(hashString);
|
||||
}
|
||||
|
||||
private void SerializeParameters(StringBuilder stringBuilder)
|
||||
{
|
||||
if (_parameters.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
return new PasswordHash(id.ToString(), hash, salt, parameters ?? new Dictionary<string, string>());
|
||||
}
|
||||
|
||||
stringBuilder.Append('$');
|
||||
foreach (var pair in _parameters)
|
||||
{
|
||||
stringBuilder.Append(pair.Key)
|
||||
.Append('=')
|
||||
.Append(pair.Value)
|
||||
.Append(',');
|
||||
}
|
||||
private void SerializeParameters(StringBuilder stringBuilder)
|
||||
{
|
||||
if (_parameters.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove last ','
|
||||
stringBuilder.Length -= 1;
|
||||
}
|
||||
stringBuilder.Append('$');
|
||||
foreach (var pair in _parameters)
|
||||
{
|
||||
stringBuilder.Append(pair.Key)
|
||||
.Append('=')
|
||||
.Append(pair.Value)
|
||||
.Append(',');
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
var str = new StringBuilder()
|
||||
.Append('$')
|
||||
.Append(Id);
|
||||
SerializeParameters(str);
|
||||
// Remove last ','
|
||||
stringBuilder.Length -= 1;
|
||||
}
|
||||
|
||||
if (_salt.Length != 0)
|
||||
{
|
||||
str.Append('$')
|
||||
.Append(Convert.ToHexString(_salt));
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
var str = new StringBuilder()
|
||||
.Append('$')
|
||||
.Append(Id);
|
||||
SerializeParameters(str);
|
||||
|
||||
if (_hash.Length != 0)
|
||||
{
|
||||
str.Append('$')
|
||||
.Append(Convert.ToHexString(_hash));
|
||||
}
|
||||
if (_salt.Length != 0)
|
||||
{
|
||||
str.Append('$')
|
||||
.Append(Convert.ToHexString(_salt));
|
||||
}
|
||||
|
||||
return str.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_hash.Length != 0)
|
||||
{
|
||||
str.Append('$')
|
||||
.Append(Convert.ToHexString(_hash));
|
||||
}
|
||||
|
||||
return str.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user