feat(api): List + GetById usuarios — handlers, repo, endpoints [UDT-008]

This commit is contained in:
2026-04-15 17:46:23 -03:00
parent 9dcd63543e
commit 2925336783
29 changed files with 1210 additions and 6 deletions

View File

@@ -0,0 +1,43 @@
using System.Security.Cryptography;
using System.Text;
namespace SIGCM2.Application.Common;
/// <summary>
/// Generates cryptographically secure temporary passwords.
/// Excludes visually ambiguous characters (I, O, l, o, 0, 1).
/// </summary>
public static class TempPasswordGenerator
{
private const string UpperChars = "ABCDEFGHJKLMNPQRSTUVWXYZ"; // no I, O
private const string LowerChars = "abcdefghijkmnpqrstuvwxyz"; // no l, o
private const string DigitChars = "23456789"; // no 0, 1
private const string SymbolChars = "!@#$%&*+-=?"; // copy-paste safe
private const string Charset = UpperChars + LowerChars + DigitChars + SymbolChars;
public static string Generate(int length = 12)
{
if (length < 8)
throw new ArgumentOutOfRangeException(nameof(length), "Password length must be at least 8.");
// SECURITY: NEVER log the result of this method
Span<byte> bytes = stackalloc byte[length];
RandomNumberGenerator.Fill(bytes);
var sb = new StringBuilder(length);
for (int i = 0; i < length; i++)
sb.Append(Charset[bytes[i] % Charset.Length]);
var result = sb.ToString();
// Guarantee diversity: at least 1 upper, 1 lower, 1 digit, 1 symbol
return HasDiversity(result) ? result : Generate(length);
}
private static bool HasDiversity(string pwd)
=> pwd.Any(c => UpperChars.Contains(c))
&& pwd.Any(c => LowerChars.Contains(c))
&& pwd.Any(c => DigitChars.Contains(c))
&& pwd.Any(c => SymbolChars.Contains(c));
}

View File

@@ -0,0 +1,7 @@
namespace SIGCM2.Application.Common;
/// <summary>Represents the absence of a meaningful return value.</summary>
public readonly struct Unit
{
public static readonly Unit Value = default;
}