using Packt.Shared; // Protector
using System.Security; // SecurityException
using System.Security.Principal; // IPrincipal
using System.Security.Claims; // ClaimsPrincipal, Claim

Protector.Register("Alicja", "Ha$ł0", roles: new[] { "Administratorzy" });

Protector.Register("Bartek", "Ha$ł0",
  roles: new[] { "Sprzedawcy", "Menedżerowie" });

// Ewa nie ma przypisanej żadnej roli.
Protector.Register("Ewa", "Ha$ł0");

// Prośba o wpisanie nazwy i hasła jednego
// z trzech użytkowników.

Write($"Podaj nazwę użytkownika: ");
string? username = ReadLine()!;

Write($"Podaj hasło: ");
string? password = ReadLine()!;

Protector.LogIn(username, password);

if (Thread.CurrentPrincipal == null)
{
  WriteLine("Błąd logowania.");
  return;
}

IPrincipal p = Thread.CurrentPrincipal;

WriteLine($"IsAuthenticated: {p.Identity?.IsAuthenticated}");
WriteLine($"AuthenticationType: {p.Identity?.AuthenticationType}");
WriteLine($"Name: {p.Identity?.Name}");
WriteLine($"IsInRole(\"Administratorzy\"): {p.IsInRole("Administratorzy")}");
WriteLine($"IsInRole(\"Sprzedawcy\"): {p.IsInRole("Sprzedawcy")}");

if (p is ClaimsPrincipal)
{
  WriteLine($"Użytkownik {p.Identity?.Name} posiada następujące oświadczenia:");

  IEnumerable<Claim>? claims = (p as ClaimsPrincipal)?.Claims;

  if (claims is not null)
  {
    foreach (Claim claim in claims)
    {
      WriteLine($"{claim.Type}: {claim.Value}");
    }
  }
}

try
{
  SecureFeature();
}
catch (Exception ex)
{
  WriteLine($"{ex.GetType()}: {ex.Message}");
}

static void SecureFeature()
{
  if (Thread.CurrentPrincipal == null)
  {
    throw new SecurityException(
      "Abyś mógł korzystać z tej funkcjonalności, musisz się zalogować.");
  }

  if (!Thread.CurrentPrincipal.IsInRole("Administratorzy"))
  {
    throw new SecurityException(
      "Abyś mógł korzystać z tej funkcjonalności, musisz mieć przypisaną rolę Administratorzy.");
  }

  WriteLine("Masz dostęp do tej funkcjonalności.");
}
