0% found this document useful (0 votes)
21 views76 pages

Admin Role and User Management API

using flexible uthorization on ASP.NET Core

Uploaded by

saidmtanzania
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views76 pages

Admin Role and User Management API

using flexible uthorization on ASP.NET Core

Uploaded by

saidmtanzania
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

using [Link].

Models;
using [Link];
using [Link];
using [Link];
using [Link];
using [Link];

namespace [Link];

public class ApplicationUserClaimsPrincipalFactory :


UserClaimsPrincipalFactory<User, Role>
{
public ApplicationUserClaimsPrincipalFactory(
UserManager<User> userManager,
RoleManager<Role> roleManager,
IOptions<IdentityOptions> optionsAccessor)
: base(userManager, roleManager, optionsAccessor)
{ }

protected override async Task<ClaimsIdentity> GenerateClaimsAsync(User user)


{
var identity = await [Link](user);

var userRoleNames = await [Link](user) ??


[Link]<string>();

var userRoles = await [Link](r =>


[Link]([Link]!)).ToListAsync();

var userPermissions = [Link];

foreach (var role in userRoles)


userPermissions |= [Link];

var permissionsValue = (int)userPermissions;

[Link](
new Claim([Link],
[Link]()));

return identity;
}
}

using [Link];
using [Link];
using [Link];
using [Link];
using [Link];
using [Link];
namespace [Link];

[ApiController]
[Route("api/Admin/[controller]")]
public class AccessControlController : ControllerBase
{
private readonly RoleManager<Role> _roleManager;

public AccessControlController(RoleManager<Role> roleManager)


{
_roleManager = roleManager;
}

[HttpGet]
[Authorize([Link])]
public async Task<ActionResult<AccessControlVm>> GetConfiguration()
{
var roles = await _roleManager.Roles
.ToListAsync();

var roleDtos = roles


.Select(r => new RoleDto([Link], [Link] ?? [Link],
[Link]))
.OrderBy(r => [Link])
.ToList();

return new AccessControlVm(roleDtos);


}

[HttpPut]
[Authorize([Link])]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> UpdateConfiguration(RoleDto updatedRole)
{
var role = await _roleManager.FindByIdAsync([Link]);

if (role != null)
{
[Link] = [Link];

await _roleManager.UpdateAsync(role);
}

return NoContent();
}
}

using [Link];
using [Link];
using [Link];
using [Link];
using [Link];
using [Link];

namespace [Link];

[ApiController]
[Route("api/Admin/[controller]")]
public class RolesController : ControllerBase
{
private readonly RoleManager<Role> _roleManager;

public RolesController(RoleManager<Role> roleManager)


{
_roleManager = roleManager;
}

// GET: api/Admin/Roles
[HttpGet]
[Authorize([Link])]
public async Task<ActionResult<IEnumerable<RoleDto>>> GetRoles()
{
var roles = await _roleManager.Roles
.OrderBy(r => [Link])
.ToListAsync();

return roles
.Select(r => new RoleDto([Link], [Link] ?? [Link],
[Link]))
.ToList();
}

// POST: api/Admin/Roles
// To protect from overposting attacks, see
[Link]
[HttpPost]
[Authorize([Link])]
public async Task<ActionResult<RoleDto>> PostRole(RoleDto newRole)
{
var role = new Role { Name = [Link] };

await _roleManager.CreateAsync(role);

return new RoleDto([Link], [Link], [Link]);


}

// PUT: api/Admin/Roles/5
// To protect from overposting attacks, see
[Link]
[HttpPut("{id}")]
[Authorize([Link])]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> PutRole(string id, RoleDto updatedRole)
{
if (id != [Link])
{
return BadRequest();
}

var role = await _roleManager.FindByIdAsync(id);

if (role == null)
{
return NotFound();
}

[Link] = [Link];

await _roleManager.UpdateAsync(role);

if (role == null)
{
return NotFound();
}

return NoContent();
}

// DELETE: api/Admin/Roles/5
[HttpDelete("{id}")]
[Authorize([Link])]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> DeleteRole(string id)
{
var role = await _roleManager.FindByIdAsync(id);
if (role == null)
{
return NotFound();
}

await _roleManager.DeleteAsync(role);

return NoContent();
}
}

using [Link];
using [Link];
using [Link];
using [Link];
using [Link];
using [Link];

namespace [Link]
{
[ApiController]
[Route("api/Admin/[controller]")]
public class UsersController : ControllerBase
{
private readonly UserManager<User> _userManager;

public UsersController(UserManager<User> userManager)


{
_userManager = userManager;
}

// GET: api/Admin/Users
[HttpGet]
[Authorize([Link] | [Link])]
public async Task<ActionResult<IEnumerable<UserDto>>> GetUsers()
{
return await _userManager.Users
.OrderBy(r => [Link])
.Select(u => new UserDto([Link], [Link] ?? [Link],
[Link] ?? [Link]))
.ToListAsync();
}

// GET: api/Admin/Users/5
[HttpGet("{id}")]
[Authorize([Link])]
public async Task<ActionResult<UserDto>> GetUser(string id)
{
var user = await _userManager.FindByIdAsync(id);

if (user == null)
{
return NotFound();
}

var dto = new UserDto([Link], [Link] ?? [Link],


[Link] ?? [Link]);

var roles = await _userManager.GetRolesAsync(user);

[Link](roles);

return dto;
}

// PUT: api/Admin/Users/5
// To protect from overposting attacks, see
[Link]
[HttpPut("{id}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[Authorize([Link])]
public async Task<IActionResult> PutUser(string id, UserDto updatedUser)
{
if (id != [Link])
{
return BadRequest();
}

var user = await _userManager.FindByIdAsync(id);

if (user == null)
{
return NotFound();
}

[Link] = [Link];
[Link] = [Link];

await _userManager.UpdateAsync(user);

var currentRoles = await _userManager.GetRolesAsync(user);


var addedRoles = [Link](currentRoles);
var removedRoles = [Link]([Link]);

if ([Link]())
{
await _userManager.AddToRolesAsync(user, addedRoles);
}

if ([Link]())
{
await _userManager.RemoveFromRolesAsync(user, removedRoles);
}

return NoContent();
}
}
}

using [Link];
using [Link];

namespace [Link];

[ApiExplorerSettings(IgnoreApi = true)]
public class OidcConfigurationController : Controller
{
private readonly ILogger<OidcConfigurationController> _logger;

public OidcConfigurationController(IClientRequestParametersProvider
clientRequestParametersProvider, ILogger<OidcConfigurationController> logger)
{
ClientRequestParametersProvider = clientRequestParametersProvider;
_logger = logger;
}

public IClientRequestParametersProvider ClientRequestParametersProvider {


get; }

[HttpGet("_configuration/{clientId}")]
public IActionResult GetClientRequestParameters([FromRoute] string clientId)
{
var parameters =
[Link](HttpContext, clientId);
return Ok(parameters);
}
}

using [Link];
using [Link];
using [Link];

namespace [Link];

[Authorize([Link])]
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot",
"Sweltering", "Scorching"
};

private readonly ILogger<WeatherForecastController> _logger;

public WeatherForecastController(ILogger<WeatherForecastController> logger)


{
_logger = logger;
}

[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
return [Link](1, 5).Select(index => new WeatherForecast
{
Date = [Link](index),
TemperatureC = [Link](-20, 55),
Summary = Summaries[[Link]([Link])]
})
.ToArray();
}
}

using [Link];
using [Link];
using [Link];
using [Link];
using [Link];
using [Link];
using [Link];
using [Link];

namespace [Link];

// Based on
[Link]
tityServer/src/Data/[Link]
// Customised to add TRole.
public class ApiAuthorizationDbContext<TUser, TRole> : IdentityDbContext<TUser,
TRole, string>, IPersistedGrantDbContext where TUser : IdentityUser where TRole :
IdentityRole
{
private readonly IOptions<OperationalStoreOptions> _operationalStoreOptions;

/// <summary>
/// Initializes a new instance of <see
cref="ApiAuthorizationDbContext{TUser}"/>.
/// </summary>
/// <param name="options">The <see cref="DbContextOptions"/>.</param>
/// <param name="operationalStoreOptions">The <see
cref="IOptions{OperationalStoreOptions}"/>.</param>
public ApiAuthorizationDbContext(
DbContextOptions options,
IOptions<OperationalStoreOptions> operationalStoreOptions)
: base(options)
{
_operationalStoreOptions = operationalStoreOptions;
}

/// <summary>
/// Gets or sets the <see cref="DbSet{PersistedGrant}"/>.
/// </summary>
public DbSet<PersistedGrant> PersistedGrants { get; set; }

/// <summary>
/// Gets or sets the <see cref="DbSet{DeviceFlowCodes}"/>.
/// </summary>
public DbSet<DeviceFlowCodes> DeviceFlowCodes { get; set; }

/// <summary>
/// Gets or sets the <see cref="DbSet{Key}"/>.
/// </summary>
public DbSet<Key> Keys { get; set; }

Task<int> [Link]() =>


[Link]();

/// <inheritdoc />


protected override void OnModelCreating(ModelBuilder builder)
{
[Link](builder);
[Link](_operationalStoreOptions.Value);
}
}

using [Link];
using [Link];
using [Link];
using [Link];
using [Link];

namespace [Link]
{
public class ApplicationDbContext : ApiAuthorizationDbContext<User, Role>
{
public ApplicationDbContext(
DbContextOptions options,
IOptions<OperationalStoreOptions> operationalStoreOptions) :
base(options, operationalStoreOptions)
{
}

protected override void OnModelCreating(ModelBuilder builder)


{
[Link](builder);

[Link]([Link]());
}
}
}
using [Link];
using [Link];
using [Link];
using [Link];

namespace [Link];
public class DbInitializer
{
private readonly ApplicationDbContext _context;
private readonly UserManager<User> _userManager;
private readonly RoleManager<Role> _roleManager;

private const string AdministratorsRole = "Administrators";


private const string AccountsRole = "Accounts";
private const string OperationsRole = "Operations";

private const string DefaultPassword = "Password123!";

public DbInitializer(
ApplicationDbContext context,
UserManager<User> userManager,
RoleManager<Role> roleManager)
{
_context = context;
_userManager = userManager;
_roleManager = roleManager;
}

public async Task RunAsync()


{
_context.[Link]();

// Create roles
await _roleManager.CreateAsync(
new Role
{
Name = AdministratorsRole,
NormalizedName = [Link](),
Permissions = [Link]
});

await _roleManager.CreateAsync(
new Role
{
Name = AccountsRole,
NormalizedName = [Link](),
Permissions =
[Link] |
[Link]
});

await _roleManager.CreateAsync(
new Role
{
Name = OperationsRole,
NormalizedName = [Link](),
Permissions =
[Link] |
[Link]
});

// Ensure admin role has all permissions


var adminRole = await _roleManager.FindByNameAsync(AdministratorsRole);
adminRole!.Permissions = [Link];
await _roleManager.UpdateAsync(adminRole);

// Create default admin user


var adminUserName = "admin@localhost";
var adminUser = new User { UserName = adminUserName, Email =
adminUserName };
await _userManager.CreateAsync(adminUser, DefaultPassword);

adminUser = await _userManager.FindByNameAsync(adminUserName);


if (adminUser != null)
{
await _userManager.AddToRoleAsync(adminUser, AdministratorsRole);
}

// Create default auditor user


var auditorUserName = "auditor@localhost";
var auditorUser = new User { UserName = auditorUserName, Email =
auditorUserName };
await _userManager.CreateAsync(auditorUser, DefaultPassword);

await _context.SaveChangesAsync();
}
}

using [Link];
using [Link];

namespace [Link];

public class Role : IdentityRole


{
public Permissions Permissions { get; set; }
}

using [Link];
using [Link];

namespace [Link];

public class User : IdentityUser


{
}
@page
@model [Link]

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0,
maximum-scale=1.0, user-scalable=no" />
<title>Error</title>
<link href="~/css/bootstrap/[Link]" rel="stylesheet" />
<link href="~/css/[Link]" rel="stylesheet" asp-append-version="true" />
</head>

<body>
<div class="main">
<div class="content px-4">
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your
request.</h2>

@if ([Link])
{
<p>
<strong>Request ID:</strong> <code>@[Link]</code>
</p>
}

<h3>Development Mode</h3>
<p>
Swapping to the <strong>Development</strong> environment displays
detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for
deployed applications.</strong>
It can result in displaying sensitive information from exceptions
to end users.
For local debugging, enable the <strong>Development</strong>
environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment
variable to <strong>Development</strong>
and restarting the app.
</p>
</div>
</div>
</body>

</html>
using [Link];
using [Link];
using [Link];

namespace [Link]
{
[ResponseCache(Duration = 0, Location = [Link], NoStore =
true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
public string? RequestId { get; set; }

public bool ShowRequestId => ![Link](RequestId);

private readonly ILogger<ErrorModel> _logger;

public ErrorModel(ILogger<ErrorModel> logger)


{
_logger = logger;
}

public void OnGet()


{
RequestId = [Link]?.Id ?? [Link];
}
}
}
using [Link];
using [Link];
using [Link];
using [Link];
using [Link];
using [Link];
using [Link];
using [Link];

var builder = [Link](args);

// Add services to the container.


var connectionString =
[Link]("DefaultConnection");
[Link]<ApplicationDbContext>(options =>
[Link](connectionString));
[Link]();

[Link]
.AddDefaultIdentity<User>(options => [Link] =
false)
.AddRoles<Role>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddClaimsPrincipalFactory<ApplicationUserClaimsPrincipalFactory>();
[Link]()
.AddApiAuthorization<User, ApplicationDbContext>(options =>
{
[Link]["openid"].[Link]("role");
[Link]().[Link]("role");
[Link]["openid"].[Link]("permissions");
[Link]().[Link]("permissions");
});

[Link]("role");

[Link]()
.AddIdentityServerJwt();

[Link]();
[Link]();

[Link](configure =>
{
[Link] = "FlexibleAuth";
});

[Link]<DbInitializer>();

[Link]<IAuthorizationHandler,
PermissionAuthorizationHandler>();
[Link]<IAuthorizationPolicyProvider,
FlexibleAuthorizationPolicyProvider>();

var app = [Link]();

// Configure the HTTP request pipeline.


if ([Link]())
{
[Link]();
[Link]();

using var scope = [Link]();

var services = [Link];

var initializer = [Link]<DbInitializer>();

await [Link]();
}
else
{
[Link]("/Error");
// The default HSTS value is 30 days. You may want to change this for
production scenarios, see [Link]
[Link]();
}

[Link]();

[Link]();
[Link]();

[Link]();

[Link]();
app.UseSwaggerUi3();

[Link]();
[Link]();
[Link]();

[Link]();
[Link]();
[Link]("[Link]");

[Link]();

namespace [Link];

public class AuthorizeAttribute :


[Link]
{
public AuthorizeAttribute() { }

public AuthorizeAttribute(string policy) : base(policy) { }

public AuthorizeAttribute(Permissions permission)


{
Permissions = permission;
}

public Permissions Permissions


{
get
{
return ![Link](Policy)
? [Link](Policy)
: [Link];
}
set
{
Policy = value != [Link]
? [Link](value)
: [Link];
}
}
}

namespace [Link];

public static class CustomClaimTypes


{
public const string Permissions = "permissions";
}

using [Link];
using [Link];

namespace [Link];

public class FlexibleAuthorizationPolicyProvider :


DefaultAuthorizationPolicyProvider
{
private readonly AuthorizationOptions _options;

public FlexibleAuthorizationPolicyProvider(IOptions<AuthorizationOptions>
options)
: base(options)
{
_options = [Link];
}

public override async Task<AuthorizationPolicy?> GetPolicyAsync(string


policyName)
{
var policy = await [Link](policyName);

if (policy == null && [Link](policyName))


{
var permissions = [Link](policyName);

policy = new AuthorizationPolicyBuilder()


.AddRequirements(new
PermissionAuthorizationRequirement(permissions))
.Build();

_options.AddPolicy(policyName!, policy);
}

return policy;
}
}

using [Link];
using [Link];
using [Link];
namespace [Link];

public static class IAuthorizationServiceExtensions


{
public static Task<AuthorizationResult> AuthorizeAsync(this
IAuthorizationService service, ClaimsPrincipal user, Permissions permissions)
{
return [Link](user,
[Link](permissions));
}
}

using [Link];
using [Link];

namespace [Link];

public class PermissionAuthorizationHandler :


AuthorizationHandler<PermissionAuthorizationRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext
context, PermissionAuthorizationRequirement requirement)
{
var permissionClaim = [Link](
c => [Link] == [Link]);

if (permissionClaim == null)
{
return [Link];
}

if (![Link]([Link], out int permissionClaimValue))


{
return [Link];
}

var userPermissions = (Permissions)permissionClaimValue;

if ((userPermissions & [Link]) != 0)


{
[Link](requirement);
return [Link];
}

return [Link];
}
}

using [Link];
namespace [Link];

public class PermissionAuthorizationRequirement : IAuthorizationRequirement


{
public PermissionAuthorizationRequirement(Permissions permission)
{
Permissions = permission;
}

public Permissions Permissions { get; }


}

namespace [Link];

[Flags]
public enum Permissions
{
None = 0,
ViewRoles = 1,
ManageRoles = 2,
ViewUsers = 4,
ManageUsers = 8,
ConfigureAccessControl = 16,
Counter = 32,
Forecast = 64,
ViewAccessControl = 128,
All = ~None
}
namespace [Link];

public static class PermissionsProvider


{
public static List<Permissions> GetAll()
{
return [Link](typeof(Permissions))
.OfType<Permissions>()
.ToList();
}
}

namespace [Link];

public static class PolicyNameHelper


{
public const string Prefix = "Permissions";

public static bool IsValidPolicyName(string? policyName)


{
return policyName != null && [Link](Prefix,
[Link]);
}
public static string GeneratePolicyNameFor(Permissions permissions)
{
return $"{Prefix}{(int)permissions}";
}

public static Permissions GetPermissionsFrom(string policyName)


{
var permissionsValue = [Link](policyName[[Link]..]!);

return (Permissions)permissionsValue;
}
}

using [Link];

namespace [Link];

public class AccessControlVm


{
internal AccessControlVm() { }

public AccessControlVm(List<RoleDto> roles)


{
Roles = roles;

foreach(var permission in [Link]())


{
if (permission == [Link]) continue;

[Link](permission);
}
}

public List<RoleDto> Roles { get; set; } = new();

public List<Permissions> AvailablePermissions { get; set; } = new();


}

using [Link];

namespace [Link];

public class RoleDto


{
public RoleDto()
{
Id = [Link];
Name = [Link];
Permissions = [Link];
}
public RoleDto(string id, string name, Permissions permissions)
{
Id = id;
Name = name;
Permissions = permissions;
}

public string Id { get; set; }

public string Name { get; set; }

public Permissions Permissions { get; set; }

public bool Has(Permissions permission)


{
return [Link](permission);;
}

public void Set(Permissions permission, bool granted)


{
if (granted)
{
Grant(permission);
}
else
{
Revoke(permission);
}
}

public void Grant(Permissions permission)


{
Permissions |= permission;
}

public void Revoke(Permissions permission)


{
Permissions ^= permission;
}
}
namespace [Link];

public class UserDto


{
public UserDto() : this([Link], [Link], [Link]) { }

public UserDto(string id, string userName, string email)


{
Id = id;
UserName = userName;
Email = email;
}

public string Id { get; set; }

public string UserName { get; set; }

public string Email { get; set; }

public List<string> Roles { get; set; } = new();


}

namespace [Link];

public class WeatherForecast


{
public DateTime Date { get; set; }

public int TemperatureC { get; set; }

public string? Summary { get; set; }

public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);


}

@using [Link]
@using [Link]
@inject SignInManager<User> SignInManager
@inject UserManager<User> UserManager
@addTagHelper *, [Link]

@{
var returnUrl = "/";
if ([Link]("returnUrl", out var existingUrl)) {
returnUrl = existingUrl;
}
}

<ul class="navbar-nav">
@if ([Link](User))
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-
page="/Account/Manage/Index" title="Manage">Hello @[Link]?.Name!</a>
</li>
<li class="nav-item">
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout"
asp-route-returnUrl="/" method="post">
<button type="submit" class="nav-link btn btn-link text-
dark">Logout</button>
</form>
</li>
}
else
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-
page="/Account/Register" asp-route-returnUrl="@returnUrl">Register</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-
page="/Account/Login" asp-route-returnUrl="@returnUrl">Login</a>
</li>
}
</ul>

using [Link];
using [Link];
using [Link];
using [Link];

namespace [Link];

public class CustomAccountClaimsPrincipalFactory :


AccountClaimsPrincipalFactory<RemoteUserAccount>
{
public CustomAccountClaimsPrincipalFactory(IAccessTokenProviderAccessor
accessor)
: base(accessor)
{
}
public async override ValueTask<ClaimsPrincipal> CreateUserAsync(
RemoteUserAccount account,
RemoteAuthenticationUserOptions options)
{
var user = await [Link](account, options);

var identity = (ClaimsIdentity)[Link]!;

if (account != null)
{
foreach (var property in [Link])
{
var key = [Link];
var value = [Link];

if (value != null &&


value is JsonElement element && [Link] ==
[Link])
{
[Link]([Link]([Link]));
var claims = [Link]()
.Select(x => new Claim([Link], [Link]()));

[Link](claims);
}
}
}

return user;
}
}

@page "/admin/access-control"
@attribute [Authorize([Link] |
[Link])]

<PageTitle>Access Control</PageTitle>

<h1>Access Control</h1>

<p>This is a description.</p>

@if (_vm == null) return;

<table class="table table-hover">


<thead>
<tr>
<th>Permissions</th>
@foreach(var role in _vm.Roles)
{
<th>@[Link]</th>
}
</tr>
</thead>
<tbody>
@foreach(var permission in _vm.AvailablePermissions)
{
<tr>
<th>@[Link]()</th>
@foreach(var role in _vm.Roles)
{
<th>
<FlexibleAuthorizeView
Permissions="@[Link]">
<Authorized>
<input
type="checkbox"
class="form-check-input"
checked="@[Link](permission)"
@onchange="(args) =>
Set(role, permission, (bool)[Link]!)"
/>
</Authorized>
<NotAuthorized>
<input
type="checkbox"
class="form-check-input"
checked="@[Link](permission)"
disabled="disabled" />
</NotAuthorized>
</FlexibleAuthorizeView>
</th>
}
</tr>
}
</tbody>
</table>
using [Link];
using [Link];
using [Link];
using [Link];

namespace [Link];

public partial class Index


{
[Inject]
private IAccessControlClient AccessControlClient { get; set; } = null!;

private AccessControlVm? _vm;

protected override async Task OnInitializedAsync()


{
_vm = await [Link]();
}

private async Task Set(RoleDto role, Permissions permission, bool granted)


{
[Link](permission, granted);

await [Link](role);
}
}

@page "/admin/roles"
@attribute [Authorize([Link])]

<PageTitle>Roles</PageTitle>

<h1>Roles</h1>
<p>This is a description.</p>

<table class="table table-striped table-hover w-50">


<thead>
<tr>
<th>Name</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var role in Roles)
{
@if (role != roleToEdit)
{
<tr>
<td>
<input type="text" id="name" class="form-control-
plaintext" style="padding-left: 0.75rem" value="@[Link]" />
</td>
<td>
<FlexibleAuthorizeView
Permissions="@[Link]">
<button type="button" class="btn btn-secondary"
@onclick="() => EditRole(role)">
<span class="oi oi-pencil"></span>
</button>
<button type="button" class="btn btn-secondary"
@onclick="() => DeleteRole(role)">
<span class="oi oi-x"></span>
</button>
</FlexibleAuthorizeView>
</td>
</tr>
}
else
{
<tr>
<td>
<input type="text" id="name" class="form-control"
@bind="@[Link]" />
</td>
<td>
<FlexibleAuthorizeView
Permissions="@[Link]">
<button type="button" class="btn btn-secondary"
@onclick="() => UpdateRole()">
<span class="oi oi-check"></span>
</button>
<button type="button" class="btn btn-secondary"
@onclick="() => CancelEditRole()">
<span class="oi oi-action-undo"></span>
</button>
</FlexibleAuthorizeView>
</td>
</tr>
}
}
</tbody>
<FlexibleAuthorizeView Permissions="@[Link]">
<tfoot>
<tr>
<td>
<input type="text" id="name" class="form-control"
placeholder="New Role..." @bind="newRoleName" />
</td>
<td>
<button type="button" class="btn btn-primary"
@onclick="AddRole">
<span class="oi oi-plus"></span>
</button>
</td>
</tr>
</tfoot>
</FlexibleAuthorizeView>
</table>
using [Link];
using [Link];
using [Link];
using [Link];

namespace [Link];

public partial class Index


{
[Inject]
public IRolesClient RolesClient { get; set; } = null!;

public ICollection<RoleDto> Roles { get; set; } = new List<RoleDto>();

private string newRoleName = [Link];

private RoleDto? roleToEdit;

protected override async Task OnInitializedAsync()


{
Roles = await [Link]();
}

private async Task AddRole()


{
if (![Link](newRoleName))
{
var role = await [Link](
new RoleDto("", newRoleName, [Link]));

[Link](role);
}

newRoleName = [Link];
}

private void EditRole(RoleDto role)


{
roleToEdit = role;
}

private void CancelEditRole()


{
roleToEdit = null;
}

private async Task UpdateRole()


{
await [Link](roleToEdit!.Id, roleToEdit);

roleToEdit = null;
}

private async Task DeleteRole(RoleDto role)


{
await [Link]([Link]);
[Link](role);
}
}

@page "/admin/users/{userId}"
@attribute [Authorize([Link])]

<PageTitle>Users - Edit</PageTitle>

<h1>Edit</h1>

<h2>User</h2>

@if (User != null)


{
<div class="row">
<div class="col-md-4">

<EditForm Model="@User" OnValidSubmit="UpdateUser">

<div class="form-group">
<label for="username">Username</label>
<InputText id="username" @bind-Value="[Link]"
class="form-control-plaintext" />
</div>

<div class="form-group">
<label for="email">Email</label>
<InputText id="email" @bind-Value="[Link]" class="form-
control-plaintext" />
</div>

<div class="form-group">
<label for="roles">Roles</label>
@foreach (var role in Roles)
{
<div class="form-check">
<input type="checkbox" class="form-check-input"
id="@($"role{[Link]}")" checked="@[Link]([Link])"
@onchange="(args) => ToggleSelectedRole([Link])" />
<label class="form-check-label"
for="@($"role{[Link]}")">
@[Link]
</label>
</div>
}
</div>

<button type="submit" class="btn btn-primary">Save</button>


</EditForm>
</div>
</div>
}

<div>
<a href="/admin/users">Back to List</a>
</div>
using [Link];
using [Link];
using [Link];
using [Link];

namespace [Link];

public partial class Edit


{
[Parameter]
public string UserId { get; set; } = null!;

[Inject]
public IUsersClient UsersClient { get; set; } = null!;

[Inject]
public IRolesClient RolesClient { get; set; } = null!;

[Inject]
public NavigationManager Navigation { get; set; } = null!;

public UserDto User { get; set; } = new();

public ICollection<RoleDto> Roles { get; set; } = new List<RoleDto>();

protected override async Task OnParametersSetAsync()


{
Roles = await [Link]();

User = await [Link](UserId);


}

public void ToggleSelectedRole(string roleName)


{
if ([Link](roleName))
{
[Link](roleName);
}
else
{
[Link](roleName);
}

StateHasChanged();
}

public async Task UpdateUser()


{
await [Link]([Link], User);

[Link]("/admin/users");
}
}

@page "/admin/users"
@attribute [Authorize([Link] | [Link])]

<PageTitle>Users</PageTitle>

<h1>Users</h1>

<p>This is a description.</p>

<table class="table table-striped table-hover w-75">


<thead>
<tr>
<th>Username</th>
<th>Email</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var user in Users)
{
<tr>
<td>@[Link]</td>
<td>@[Link]</td>
<td>
<FlexibleAuthorizeView
Permissions="@[Link]">
<a href="/admin/users/@[Link]">Edit</a>
</FlexibleAuthorizeView>
</td>
</tr>
}
</tbody>
</table>
using [Link];
using [Link];
using [Link];

namespace [Link];

public partial class Index


{
[Inject] public IUsersClient UsersClient { get; set; } = null!;

public ICollection<UserDto> Users { get; set; } = new List<UserDto>();

protected override async Task OnInitializedAsync()


{
Users = await [Link]();
}
}

@page "/authentication/{action}"
@using [Link]
<RemoteAuthenticatorView Action="@Action" />

@code{
[Parameter] public string? Action { get; set; }
}

@page "/claims"
@attribute [Authorize]

<PageTitle>Claims</PageTitle>
<h1>Claims</h1>

<p>This component displays available claims.</p>

<AuthorizeView>
<ul>
@foreach (var claim in [Link])
{
<li><b>@[Link]</b>: @[Link]</li>
}
</ul>
</AuthorizeView>
@page "/counter"
@attribute [Authorize([Link])]

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
private int currentCount = 0;

private void IncrementCount()


{
currentCount++;
}
}

@page "/fetchdata"
@attribute [Authorize([Link])]

@inject HttpClient Http

<PageTitle>Weather forecast</PageTitle>

<h1>Weather forecast</h1>

<p>This component demonstrates fetching data from the server.</p>

@if (forecasts == null)


{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@[Link]()</td>
<td>@[Link]</td>
<td>@[Link]</td>
<td>@[Link]</td>
</tr>
}
</tbody>
</table>
}

@code {
private WeatherForecast[]? forecasts;

protected override async Task OnInitializedAsync()


{
try
{
forecasts = await
[Link]<WeatherForecast[]>("WeatherForecast");
}
catch (AccessTokenNotAvailableException exception)
{
[Link]();
}
}
}

@page "/"

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

//----------------------
// <auto-generated>
// Generated using the NSwag toolchain v13.18.2.0 (NJsonSchema v10.8.0.0
([Link] v13.0.0.0)) ([Link]
// </auto-generated>
//----------------------

using [Link];
using [Link];

#pragma warning disable 108 // Disable "CS0108 '{derivedDto}.ToJson()' hides inherited


member '{dtoBase}.ToJson()'. Use the new keyword if hiding was intended."
#pragma warning disable 114 // Disable "CS0114
'{derivedDto}.RaisePropertyChanged(String)' hides inherited member
'[Link](String)'. To make the current member override that
implementation, add the override keyword. Otherwise add the new keyword."
#pragma warning disable 472 // Disable "CS0472 The result of the expression is always
'false' since a value of type 'Int32' is never equal to 'null' of type 'Int32?'
#pragma warning disable 1573 // Disable "CS1573 Parameter '...' has no matching param tag
in the XML comment for ...
#pragma warning disable 1591 // Disable "CS1591 Missing XML comment for publicly visible
type or member ..."
#pragma warning disable 8073 // Disable "CS8073 The result of the expression is always
'false' since a value of type 'T' is never equal to 'null' of type 'T?'"
#pragma warning disable 3016 // Disable "CS3016 Arrays as attribute arguments is not CLS-
compliant"
#pragma warning disable 8603 // Disable "CS8603 Possible null reference return"

namespace [Link]
{
using System = global::System;

[[Link]("NSwag", "[Link] (NJsonSchema


v10.8.0.0 ([Link] v13.0.0.0))")]
public partial interface IWeatherForecastClient
{
/// <exception cref="ApiException">A server side error occurred.</exception>

[Link]<[Link]<WeatherForecast>>
GetAsync();

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>

[Link]<[Link]<WeatherForecast>>
GetAsync([Link] cancellationToken);

}
[[Link]("NSwag", "[Link] (NJsonSchema
v10.8.0.0 ([Link] v13.0.0.0))")]
public partial class WeatherForecastClient : IWeatherForecastClient
{
private [Link] _httpClient;
private [Link]<[Link]> _settings;

public WeatherForecastClient([Link] httpClient)


{
_httpClient = httpClient;
_settings = new
[Link]<[Link]>(CreateSerializerSettings);
}

private [Link] CreateSerializerSettings()


{
var settings = new [Link]();
UpdateJsonSerializerSettings(settings);
return settings;
}

protected [Link] JsonSerializerSettings { get { return


_settings.Value; } }

partial void UpdateJsonSerializerSettings([Link]


settings);

partial void PrepareRequest([Link] client,


[Link] request, string url);
partial void PrepareRequest([Link] client,
[Link] request, [Link] urlBuilder);
partial void ProcessResponse([Link] client,
[Link] response);

/// <exception cref="ApiException">A server side error occurred.</exception>


public virtual
[Link]<[Link]<WeatherForecast>>
GetAsync()
{
return GetAsync([Link]);
}

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
public virtual async
[Link]<[Link]<WeatherForecast>>
GetAsync([Link] cancellationToken)
{
var urlBuilder_ = new [Link]();
urlBuilder_.Append("WeatherForecast");

var client_ = _httpClient;


var disposeClient_ = false;
try
{
using (var request_ = new [Link]())
{
request_.Method = new [Link]("GET");

request_.[Link]([Link]
[Link]("application/json"));

PrepareRequest(client_, request_, urlBuilder_);

var url_ = urlBuilder_.ToString();


request_.RequestUri = new [Link](url_, [Link]);

PrepareRequest(client_, request_, url_);

var response_ = await client_.SendAsync(request_,


[Link],
cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = [Link](response_.Headers, h_
=> h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.[Link] != null)
{
foreach (var item_ in response_.[Link])
headers_[item_.Key] = item_.Value;
}

ProcessResponse(client_, response_);

var status_ = (int)response_.StatusCode;


if (status_ == 200)
{
var objectResponse_ = await
ReadObjectResponseAsync<[Link]<WeatherForecast>>(res
ponse_, headers_, cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.",
status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}
else
{
var responseData_ = response_.Content == null ? null : await
response_.[Link]().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not
expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}

protected struct ObjectResponseResult<T>


{
public ObjectResponseResult(T responseObject, string responseText)
{
[Link] = responseObject;
[Link] = responseText;
}

public T Object { get; }

public string Text { get; }


}

public bool ReadResponseAsString { get; set; }

protected virtual async [Link]<ObjectResponseResult<T>>


ReadObjectResponseAsync<T>([Link] response,
[Link]<string,
[Link]<string>> headers,
[Link] cancellationToken)
{
if (response == null || [Link] == null)
{
return new ObjectResponseResult<T>(default(T), [Link]);
}

if (ReadResponseAsString)
{
var responseText = await
[Link]().ConfigureAwait(false);
try
{
var typedBody =
[Link]<T>(responseText, JsonSerializerSettings);
return new ObjectResponseResult<T>(typedBody, responseText);
}
catch ([Link] exception)
{
var message = "Could not deserialize the response body string as " +
typeof(T).FullName + ".";
throw new ApiException(message, (int)[Link], responseText,
headers, exception);
}
}
else
{
try
{
using (var responseStream = await
[Link]().ConfigureAwait(false))
using (var streamReader = new [Link](responseStream))
using (var jsonTextReader = new
[Link](streamReader))
{
var serializer = [Link](JsonSerializerSettings);
var typedBody = [Link]<T>(jsonTextReader);
return new ObjectResponseResult<T>(typedBody, [Link]);
}
}
catch ([Link] exception)
{
var message = "Could not deserialize the response body stream as " +
typeof(T).FullName + ".";
throw new ApiException(message, (int)[Link], [Link],
headers, exception);
}
}
}

private string ConvertToString(object value, [Link]


cultureInfo)
{
if (value == null)
{
return "";
}

if (value is [Link])
{
var name = [Link]([Link](), value);
if (name != null)
{
var field =
[Link]([Link]()).GetDeclaredField(
name);
if (field != null)
{
var attribute =
[Link](field,
typeof([Link]))
as [Link];
if (attribute != null)
{
return [Link] != null ? [Link] : name;
}
}

var converted = [Link]([Link](value,


[Link]([Link]()), cultureInfo));
return converted == null ? [Link] : converted;
}
}
else if (value is bool)
{
return [Link]((bool)value, cultureInfo).ToLowerInvariant();
}
else if (value is byte[])
{
return [Link].ToBase64String((byte[]) value);
}
else if ([Link]().IsArray)
{
var array = [Link]<object>(([Link]) value);
return [Link](",", [Link](array, o =>
ConvertToString(o, cultureInfo)));
}

var result = [Link](value, cultureInfo);


return result == null ? "" : result;
}
}

[[Link]("NSwag", "[Link] (NJsonSchema


v10.8.0.0 ([Link] v13.0.0.0))")]
public partial interface IAccessControlClient
{
/// <exception cref="ApiException">A server side error occurred.</exception>
[Link]<AccessControlVm> GetConfigurationAsync();

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
[Link]<AccessControlVm>
GetConfigurationAsync([Link] cancellationToken);

/// <exception cref="ApiException">A server side error occurred.</exception>


[Link] UpdateConfigurationAsync(RoleDto updatedRole);

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
[Link] UpdateConfigurationAsync(RoleDto updatedRole,
[Link] cancellationToken);

[[Link]("NSwag", "[Link] (NJsonSchema


v10.8.0.0 ([Link] v13.0.0.0))")]
public partial class AccessControlClient : IAccessControlClient
{
private [Link] _httpClient;
private [Link]<[Link]> _settings;

public AccessControlClient([Link] httpClient)


{
_httpClient = httpClient;
_settings = new
[Link]<[Link]>(CreateSerializerSettings);
}
private [Link] CreateSerializerSettings()
{
var settings = new [Link]();
UpdateJsonSerializerSettings(settings);
return settings;
}

protected [Link] JsonSerializerSettings { get { return


_settings.Value; } }

partial void UpdateJsonSerializerSettings([Link]


settings);

partial void PrepareRequest([Link] client,


[Link] request, string url);
partial void PrepareRequest([Link] client,
[Link] request, [Link] urlBuilder);
partial void ProcessResponse([Link] client,
[Link] response);

/// <exception cref="ApiException">A server side error occurred.</exception>


public virtual [Link]<AccessControlVm> GetConfigurationAsync()
{
return GetConfigurationAsync([Link]);
}

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
public virtual async [Link]<AccessControlVm>
GetConfigurationAsync([Link] cancellationToken)
{
var urlBuilder_ = new [Link]();
urlBuilder_.Append("api/Admin/AccessControl");

var client_ = _httpClient;


var disposeClient_ = false;
try
{
using (var request_ = new [Link]())
{
request_.Method = new [Link]("GET");

request_.[Link]([Link]
[Link]("application/json"));
PrepareRequest(client_, request_, urlBuilder_);

var url_ = urlBuilder_.ToString();


request_.RequestUri = new [Link](url_, [Link]);

PrepareRequest(client_, request_, url_);

var response_ = await client_.SendAsync(request_,


[Link],
cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = [Link](response_.Headers, h_
=> h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.[Link] != null)
{
foreach (var item_ in response_.[Link])
headers_[item_.Key] = item_.Value;
}

ProcessResponse(client_, response_);

var status_ = (int)response_.StatusCode;


if (status_ == 200)
{
var objectResponse_ = await
ReadObjectResponseAsync<AccessControlVm>(response_, headers_,
cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.",
status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}
else
{
var responseData_ = response_.Content == null ? null : await
response_.[Link]().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not
expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}

/// <exception cref="ApiException">A server side error occurred.</exception>


public virtual [Link] UpdateConfigurationAsync(RoleDto
updatedRole)
{
return UpdateConfigurationAsync(updatedRole,
[Link]);
}

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
public virtual async [Link] UpdateConfigurationAsync(RoleDto
updatedRole, [Link] cancellationToken)
{
if (updatedRole == null)
throw new [Link]("updatedRole");

var urlBuilder_ = new [Link]();


urlBuilder_.Append("api/Admin/AccessControl");

var client_ = _httpClient;


var disposeClient_ = false;
try
{
using (var request_ = new [Link]())
{
var json_ = [Link](updatedRole,
_settings.Value);
var content_ = new [Link](json_);
content_.[Link] =
[Link]("application/json");
request_.Content = content_;
request_.Method = new [Link]("PUT");

PrepareRequest(client_, request_, urlBuilder_);


var url_ = urlBuilder_.ToString();
request_.RequestUri = new [Link](url_, [Link]);

PrepareRequest(client_, request_, url_);

var response_ = await client_.SendAsync(request_,


[Link],
cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = [Link](response_.Headers, h_
=> h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.[Link] != null)
{
foreach (var item_ in response_.[Link])
headers_[item_.Key] = item_.Value;
}

ProcessResponse(client_, response_);

var status_ = (int)response_.StatusCode;


if (status_ == 204)
{
return;
}
else
{
var responseData_ = response_.Content == null ? null : await
response_.[Link]().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not
expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}
protected struct ObjectResponseResult<T>
{
public ObjectResponseResult(T responseObject, string responseText)
{
[Link] = responseObject;
[Link] = responseText;
}

public T Object { get; }

public string Text { get; }


}

public bool ReadResponseAsString { get; set; }

protected virtual async [Link]<ObjectResponseResult<T>>


ReadObjectResponseAsync<T>([Link] response,
[Link]<string,
[Link]<string>> headers,
[Link] cancellationToken)
{
if (response == null || [Link] == null)
{
return new ObjectResponseResult<T>(default(T), [Link]);
}

if (ReadResponseAsString)
{
var responseText = await
[Link]().ConfigureAwait(false);
try
{
var typedBody =
[Link]<T>(responseText, JsonSerializerSettings);
return new ObjectResponseResult<T>(typedBody, responseText);
}
catch ([Link] exception)
{
var message = "Could not deserialize the response body string as " +
typeof(T).FullName + ".";
throw new ApiException(message, (int)[Link], responseText,
headers, exception);
}
}
else
{
try
{
using (var responseStream = await
[Link]().ConfigureAwait(false))
using (var streamReader = new [Link](responseStream))
using (var jsonTextReader = new
[Link](streamReader))
{
var serializer = [Link](JsonSerializerSettings);
var typedBody = [Link]<T>(jsonTextReader);
return new ObjectResponseResult<T>(typedBody, [Link]);
}
}
catch ([Link] exception)
{
var message = "Could not deserialize the response body stream as " +
typeof(T).FullName + ".";
throw new ApiException(message, (int)[Link], [Link],
headers, exception);
}
}
}

private string ConvertToString(object value, [Link]


cultureInfo)
{
if (value == null)
{
return "";
}

if (value is [Link])
{
var name = [Link]([Link](), value);
if (name != null)
{
var field =
[Link]([Link]()).GetDeclaredField(
name);
if (field != null)
{
var attribute =
[Link](field,
typeof([Link]))
as [Link];
if (attribute != null)
{
return [Link] != null ? [Link] : name;
}
}

var converted = [Link]([Link](value,


[Link]([Link]()), cultureInfo));
return converted == null ? [Link] : converted;
}
}
else if (value is bool)
{
return [Link]((bool)value, cultureInfo).ToLowerInvariant();
}
else if (value is byte[])
{
return [Link].ToBase64String((byte[]) value);
}
else if ([Link]().IsArray)
{
var array = [Link]<object>(([Link]) value);
return [Link](",", [Link](array, o =>
ConvertToString(o, cultureInfo)));
}

var result = [Link](value, cultureInfo);


return result == null ? "" : result;
}
}

[[Link]("NSwag", "[Link] (NJsonSchema


v10.8.0.0 ([Link] v13.0.0.0))")]
public partial interface IRolesClient
{
/// <exception cref="ApiException">A server side error occurred.</exception>
[Link]<[Link]<RoleDto>>
GetRolesAsync();

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
[Link]<[Link]<RoleDto>>
GetRolesAsync([Link] cancellationToken);

/// <exception cref="ApiException">A server side error occurred.</exception>


[Link]<RoleDto> PostRoleAsync(RoleDto newRole);
/// <param name="cancellationToken">A cancellation token that can be used by other
objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
[Link]<RoleDto> PostRoleAsync(RoleDto newRole,
[Link] cancellationToken);

/// <exception cref="ApiException">A server side error occurred.</exception>


[Link] PutRoleAsync(string id, RoleDto updatedRole);

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
[Link] PutRoleAsync(string id, RoleDto updatedRole,
[Link] cancellationToken);

/// <exception cref="ApiException">A server side error occurred.</exception>


[Link] DeleteRoleAsync(string id);

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
[Link] DeleteRoleAsync(string id,
[Link] cancellationToken);

[[Link]("NSwag", "[Link] (NJsonSchema


v10.8.0.0 ([Link] v13.0.0.0))")]
public partial class RolesClient : IRolesClient
{
private [Link] _httpClient;
private [Link]<[Link]> _settings;

public RolesClient([Link] httpClient)


{
_httpClient = httpClient;
_settings = new
[Link]<[Link]>(CreateSerializerSettings);
}

private [Link] CreateSerializerSettings()


{
var settings = new [Link]();
UpdateJsonSerializerSettings(settings);
return settings;
}
protected [Link] JsonSerializerSettings { get { return
_settings.Value; } }

partial void UpdateJsonSerializerSettings([Link]


settings);

partial void PrepareRequest([Link] client,


[Link] request, string url);
partial void PrepareRequest([Link] client,
[Link] request, [Link] urlBuilder);
partial void ProcessResponse([Link] client,
[Link] response);

/// <exception cref="ApiException">A server side error occurred.</exception>


public virtual
[Link]<[Link]<RoleDto>>
GetRolesAsync()
{
return GetRolesAsync([Link]);
}

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
public virtual async
[Link]<[Link]<RoleDto>>
GetRolesAsync([Link] cancellationToken)
{
var urlBuilder_ = new [Link]();
urlBuilder_.Append("api/Admin/Roles");

var client_ = _httpClient;


var disposeClient_ = false;
try
{
using (var request_ = new [Link]())
{
request_.Method = new [Link]("GET");

request_.[Link]([Link]
[Link]("application/json"));

PrepareRequest(client_, request_, urlBuilder_);

var url_ = urlBuilder_.ToString();


request_.RequestUri = new [Link](url_, [Link]);
PrepareRequest(client_, request_, url_);

var response_ = await client_.SendAsync(request_,


[Link],
cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = [Link](response_.Headers, h_
=> h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.[Link] != null)
{
foreach (var item_ in response_.[Link])
headers_[item_.Key] = item_.Value;
}

ProcessResponse(client_, response_);

var status_ = (int)response_.StatusCode;


if (status_ == 200)
{
var objectResponse_ = await
ReadObjectResponseAsync<[Link]<RoleDto>>(response_,
headers_, cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.",
status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}
else
{
var responseData_ = response_.Content == null ? null : await
response_.[Link]().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not
expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}

/// <exception cref="ApiException">A server side error occurred.</exception>


public virtual [Link]<RoleDto> PostRoleAsync(RoleDto newRole)
{
return PostRoleAsync(newRole, [Link]);
}

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
public virtual async [Link]<RoleDto> PostRoleAsync(RoleDto
newRole, [Link] cancellationToken)
{
if (newRole == null)
throw new [Link]("newRole");

var urlBuilder_ = new [Link]();


urlBuilder_.Append("api/Admin/Roles");

var client_ = _httpClient;


var disposeClient_ = false;
try
{
using (var request_ = new [Link]())
{
var json_ = [Link](newRole,
_settings.Value);
var content_ = new [Link](json_);
content_.[Link] =
[Link]("application/json");
request_.Content = content_;
request_.Method = new [Link]("POST");

request_.[Link]([Link]
[Link]("application/json"));

PrepareRequest(client_, request_, urlBuilder_);

var url_ = urlBuilder_.ToString();


request_.RequestUri = new [Link](url_, [Link]);

PrepareRequest(client_, request_, url_);


var response_ = await client_.SendAsync(request_,
[Link],
cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = [Link](response_.Headers, h_
=> h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.[Link] != null)
{
foreach (var item_ in response_.[Link])
headers_[item_.Key] = item_.Value;
}

ProcessResponse(client_, response_);

var status_ = (int)response_.StatusCode;


if (status_ == 200)
{
var objectResponse_ = await
ReadObjectResponseAsync<RoleDto>(response_, headers_,
cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.",
status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}
else
{
var responseData_ = response_.Content == null ? null : await
response_.[Link]().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not
expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}

/// <exception cref="ApiException">A server side error occurred.</exception>


public virtual [Link] PutRoleAsync(string id, RoleDto
updatedRole)
{
return PutRoleAsync(id, updatedRole, [Link]);
}

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
public virtual async [Link] PutRoleAsync(string id, RoleDto
updatedRole, [Link] cancellationToken)
{
if (updatedRole == null)
throw new [Link]("updatedRole");

var urlBuilder_ = new [Link]();


urlBuilder_.Append("api/Admin/Roles/{id}");
urlBuilder_.Replace("{id}", [Link](ConvertToString(id,
[Link])));

var client_ = _httpClient;


var disposeClient_ = false;
try
{
using (var request_ = new [Link]())
{
var json_ = [Link](updatedRole,
_settings.Value);
var content_ = new [Link](json_);
content_.[Link] =
[Link]("application/json");
request_.Content = content_;
request_.Method = new [Link]("PUT");

PrepareRequest(client_, request_, urlBuilder_);

var url_ = urlBuilder_.ToString();


request_.RequestUri = new [Link](url_, [Link]);

PrepareRequest(client_, request_, url_);


var response_ = await client_.SendAsync(request_,
[Link],
cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = [Link](response_.Headers, h_
=> h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.[Link] != null)
{
foreach (var item_ in response_.[Link])
headers_[item_.Key] = item_.Value;
}

ProcessResponse(client_, response_);

var status_ = (int)response_.StatusCode;


if (status_ == 204)
{
return;
}
else
if (status_ == 400)
{
var objectResponse_ = await
ReadObjectResponseAsync<ProblemDetails>(response_, headers_,
cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.",
status_, objectResponse_.Text, headers_, null);
}
throw new ApiException<ProblemDetails>("A server side error occurred.",
status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
}
else
{
var responseData_ = response_.Content == null ? null : await
response_.[Link]().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not
expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}

/// <exception cref="ApiException">A server side error occurred.</exception>


public virtual [Link] DeleteRoleAsync(string id)
{
return DeleteRoleAsync(id, [Link]);
}

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
public virtual async [Link] DeleteRoleAsync(string id,
[Link] cancellationToken)
{
var urlBuilder_ = new [Link]();
urlBuilder_.Append("api/Admin/Roles/{id}");
urlBuilder_.Replace("{id}", [Link](ConvertToString(id,
[Link])));

var client_ = _httpClient;


var disposeClient_ = false;
try
{
using (var request_ = new [Link]())
{
request_.Method = new [Link]("DELETE");

PrepareRequest(client_, request_, urlBuilder_);

var url_ = urlBuilder_.ToString();


request_.RequestUri = new [Link](url_, [Link]);

PrepareRequest(client_, request_, url_);

var response_ = await client_.SendAsync(request_,


[Link],
cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = [Link](response_.Headers, h_
=> h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.[Link] != null)
{
foreach (var item_ in response_.[Link])
headers_[item_.Key] = item_.Value;
}

ProcessResponse(client_, response_);

var status_ = (int)response_.StatusCode;


if (status_ == 204)
{
return;
}
else
if (status_ == 404)
{
var objectResponse_ = await
ReadObjectResponseAsync<ProblemDetails>(response_, headers_,
cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.",
status_, objectResponse_.Text, headers_, null);
}
throw new ApiException<ProblemDetails>("A server side error occurred.",
status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
}
else
{
var responseData_ = response_.Content == null ? null : await
response_.[Link]().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not
expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}

protected struct ObjectResponseResult<T>


{
public ObjectResponseResult(T responseObject, string responseText)
{
[Link] = responseObject;
[Link] = responseText;
}

public T Object { get; }

public string Text { get; }


}

public bool ReadResponseAsString { get; set; }

protected virtual async [Link]<ObjectResponseResult<T>>


ReadObjectResponseAsync<T>([Link] response,
[Link]<string,
[Link]<string>> headers,
[Link] cancellationToken)
{
if (response == null || [Link] == null)
{
return new ObjectResponseResult<T>(default(T), [Link]);
}

if (ReadResponseAsString)
{
var responseText = await
[Link]().ConfigureAwait(false);
try
{
var typedBody =
[Link]<T>(responseText, JsonSerializerSettings);
return new ObjectResponseResult<T>(typedBody, responseText);
}
catch ([Link] exception)
{
var message = "Could not deserialize the response body string as " +
typeof(T).FullName + ".";
throw new ApiException(message, (int)[Link], responseText,
headers, exception);
}
}
else
{
try
{
using (var responseStream = await
[Link]().ConfigureAwait(false))
using (var streamReader = new [Link](responseStream))
using (var jsonTextReader = new
[Link](streamReader))
{
var serializer = [Link](JsonSerializerSettings);
var typedBody = [Link]<T>(jsonTextReader);
return new ObjectResponseResult<T>(typedBody, [Link]);
}
}
catch ([Link] exception)
{
var message = "Could not deserialize the response body stream as " +
typeof(T).FullName + ".";
throw new ApiException(message, (int)[Link], [Link],
headers, exception);
}
}
}

private string ConvertToString(object value, [Link]


cultureInfo)
{
if (value == null)
{
return "";
}

if (value is [Link])
{
var name = [Link]([Link](), value);
if (name != null)
{
var field =
[Link]([Link]()).GetDeclaredField(
name);
if (field != null)
{
var attribute =
[Link](field,
typeof([Link]))
as [Link];
if (attribute != null)
{
return [Link] != null ? [Link] : name;
}
}

var converted = [Link]([Link](value,


[Link]([Link]()), cultureInfo));
return converted == null ? [Link] : converted;
}
}
else if (value is bool)
{
return [Link]((bool)value, cultureInfo).ToLowerInvariant();
}
else if (value is byte[])
{
return [Link].ToBase64String((byte[]) value);
}
else if ([Link]().IsArray)
{
var array = [Link]<object>(([Link]) value);
return [Link](",", [Link](array, o =>
ConvertToString(o, cultureInfo)));
}

var result = [Link](value, cultureInfo);


return result == null ? "" : result;
}
}

[[Link]("NSwag", "[Link] (NJsonSchema


v10.8.0.0 ([Link] v13.0.0.0))")]
public partial interface IUsersClient
{
/// <exception cref="ApiException">A server side error occurred.</exception>
[Link]<[Link]<UserDto>>
GetUsersAsync();

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
[Link]<[Link]<UserDto>>
GetUsersAsync([Link] cancellationToken);

/// <exception cref="ApiException">A server side error occurred.</exception>


[Link]<UserDto> GetUserAsync(string id);

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
[Link]<UserDto> GetUserAsync(string id,
[Link] cancellationToken);

/// <exception cref="ApiException">A server side error occurred.</exception>


[Link] PutUserAsync(string id, UserDto updatedUser);

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
[Link] PutUserAsync(string id, UserDto updatedUser,
[Link] cancellationToken);

[[Link]("NSwag", "[Link] (NJsonSchema


v10.8.0.0 ([Link] v13.0.0.0))")]
public partial class UsersClient : IUsersClient
{
private [Link] _httpClient;
private [Link]<[Link]> _settings;

public UsersClient([Link] httpClient)


{
_httpClient = httpClient;
_settings = new
[Link]<[Link]>(CreateSerializerSettings);
}

private [Link] CreateSerializerSettings()


{
var settings = new [Link]();
UpdateJsonSerializerSettings(settings);
return settings;
}

protected [Link] JsonSerializerSettings { get { return


_settings.Value; } }
partial void UpdateJsonSerializerSettings([Link]
settings);

partial void PrepareRequest([Link] client,


[Link] request, string url);
partial void PrepareRequest([Link] client,
[Link] request, [Link] urlBuilder);
partial void ProcessResponse([Link] client,
[Link] response);

/// <exception cref="ApiException">A server side error occurred.</exception>


public virtual
[Link]<[Link]<UserDto>>
GetUsersAsync()
{
return GetUsersAsync([Link]);
}

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
public virtual async
[Link]<[Link]<UserDto>>
GetUsersAsync([Link] cancellationToken)
{
var urlBuilder_ = new [Link]();
urlBuilder_.Append("api/Admin/Users");

var client_ = _httpClient;


var disposeClient_ = false;
try
{
using (var request_ = new [Link]())
{
request_.Method = new [Link]("GET");

request_.[Link]([Link]
[Link]("application/json"));

PrepareRequest(client_, request_, urlBuilder_);

var url_ = urlBuilder_.ToString();


request_.RequestUri = new [Link](url_, [Link]);

PrepareRequest(client_, request_, url_);


var response_ = await client_.SendAsync(request_,
[Link],
cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = [Link](response_.Headers, h_
=> h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.[Link] != null)
{
foreach (var item_ in response_.[Link])
headers_[item_.Key] = item_.Value;
}

ProcessResponse(client_, response_);

var status_ = (int)response_.StatusCode;


if (status_ == 200)
{
var objectResponse_ = await
ReadObjectResponseAsync<[Link]<UserDto>>(response_,
headers_, cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.",
status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}
else
{
var responseData_ = response_.Content == null ? null : await
response_.[Link]().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not
expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}

/// <exception cref="ApiException">A server side error occurred.</exception>


public virtual [Link]<UserDto> GetUserAsync(string id)
{
return GetUserAsync(id, [Link]);
}

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
public virtual async [Link]<UserDto> GetUserAsync(string id,
[Link] cancellationToken)
{
var urlBuilder_ = new [Link]();
urlBuilder_.Append("api/Admin/Users/{id}");
urlBuilder_.Replace("{id}", [Link](ConvertToString(id,
[Link])));

var client_ = _httpClient;


var disposeClient_ = false;
try
{
using (var request_ = new [Link]())
{
request_.Method = new [Link]("GET");

request_.[Link]([Link]
[Link]("application/json"));

PrepareRequest(client_, request_, urlBuilder_);

var url_ = urlBuilder_.ToString();


request_.RequestUri = new [Link](url_, [Link]);

PrepareRequest(client_, request_, url_);

var response_ = await client_.SendAsync(request_,


[Link],
cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = [Link](response_.Headers, h_
=> h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.[Link] != null)
{
foreach (var item_ in response_.[Link])
headers_[item_.Key] = item_.Value;
}

ProcessResponse(client_, response_);

var status_ = (int)response_.StatusCode;


if (status_ == 200)
{
var objectResponse_ = await
ReadObjectResponseAsync<UserDto>(response_, headers_,
cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.",
status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}
else
{
var responseData_ = response_.Content == null ? null : await
response_.[Link]().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not
expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}

/// <exception cref="ApiException">A server side error occurred.</exception>


public virtual [Link] PutUserAsync(string id, UserDto
updatedUser)
{
return PutUserAsync(id, updatedUser, [Link]);
}

/// <param name="cancellationToken">A cancellation token that can be used by other


objects or threads to receive notice of cancellation.</param>
/// <exception cref="ApiException">A server side error occurred.</exception>
public virtual async [Link] PutUserAsync(string id, UserDto
updatedUser, [Link] cancellationToken)
{
if (updatedUser == null)
throw new [Link]("updatedUser");

var urlBuilder_ = new [Link]();


urlBuilder_.Append("api/Admin/Users/{id}");
urlBuilder_.Replace("{id}", [Link](ConvertToString(id,
[Link])));

var client_ = _httpClient;


var disposeClient_ = false;
try
{
using (var request_ = new [Link]())
{
var json_ = [Link](updatedUser,
_settings.Value);
var content_ = new [Link](json_);
content_.[Link] =
[Link]("application/json");
request_.Content = content_;
request_.Method = new [Link]("PUT");

PrepareRequest(client_, request_, urlBuilder_);

var url_ = urlBuilder_.ToString();


request_.RequestUri = new [Link](url_, [Link]);

PrepareRequest(client_, request_, url_);

var response_ = await client_.SendAsync(request_,


[Link],
cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = [Link](response_.Headers, h_
=> h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.[Link] != null)
{
foreach (var item_ in response_.[Link])
headers_[item_.Key] = item_.Value;
}

ProcessResponse(client_, response_);

var status_ = (int)response_.StatusCode;


if (status_ == 204)
{
return;
}
else
if (status_ == 400)
{
var objectResponse_ = await
ReadObjectResponseAsync<ProblemDetails>(response_, headers_,
cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.",
status_, objectResponse_.Text, headers_, null);
}
throw new ApiException<ProblemDetails>("A server side error occurred.",
status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
}
else
{
var responseData_ = response_.Content == null ? null : await
response_.[Link]().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not
expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}
protected struct ObjectResponseResult<T>
{
public ObjectResponseResult(T responseObject, string responseText)
{
[Link] = responseObject;
[Link] = responseText;
}

public T Object { get; }

public string Text { get; }


}

public bool ReadResponseAsString { get; set; }

protected virtual async [Link]<ObjectResponseResult<T>>


ReadObjectResponseAsync<T>([Link] response,
[Link]<string,
[Link]<string>> headers,
[Link] cancellationToken)
{
if (response == null || [Link] == null)
{
return new ObjectResponseResult<T>(default(T), [Link]);
}

if (ReadResponseAsString)
{
var responseText = await
[Link]().ConfigureAwait(false);
try
{
var typedBody =
[Link]<T>(responseText, JsonSerializerSettings);
return new ObjectResponseResult<T>(typedBody, responseText);
}
catch ([Link] exception)
{
var message = "Could not deserialize the response body string as " +
typeof(T).FullName + ".";
throw new ApiException(message, (int)[Link], responseText,
headers, exception);
}
}
else
{
try
{
using (var responseStream = await
[Link]().ConfigureAwait(false))
using (var streamReader = new [Link](responseStream))
using (var jsonTextReader = new
[Link](streamReader))
{
var serializer = [Link](JsonSerializerSettings);
var typedBody = [Link]<T>(jsonTextReader);
return new ObjectResponseResult<T>(typedBody, [Link]);
}
}
catch ([Link] exception)
{
var message = "Could not deserialize the response body stream as " +
typeof(T).FullName + ".";
throw new ApiException(message, (int)[Link], [Link],
headers, exception);
}
}
}

private string ConvertToString(object value, [Link]


cultureInfo)
{
if (value == null)
{
return "";
}

if (value is [Link])
{
var name = [Link]([Link](), value);
if (name != null)
{
var field =
[Link]([Link]()).GetDeclaredField(
name);
if (field != null)
{
var attribute =
[Link](field,
typeof([Link]))
as [Link];
if (attribute != null)
{
return [Link] != null ? [Link] : name;
}
}

var converted = [Link]([Link](value,


[Link]([Link]()), cultureInfo));
return converted == null ? [Link] : converted;
}
}
else if (value is bool)
{
return [Link]((bool)value, cultureInfo).ToLowerInvariant();
}
else if (value is byte[])
{
return [Link].ToBase64String((byte[]) value);
}
else if ([Link]().IsArray)
{
var array = [Link]<object>(([Link]) value);
return [Link](",", [Link](array, o =>
ConvertToString(o, cultureInfo)));
}

var result = [Link](value, cultureInfo);


return result == null ? "" : result;
}
}

[[Link]("NSwag", "[Link] (NJsonSchema


v10.8.0.0 ([Link] v13.0.0.0))")]
public partial class ApiException : [Link]
{
public int StatusCode { get; private set; }

public string Response { get; private set; }

public [Link]<string,
[Link]<string>> Headers { get; private set; }

public ApiException(string message, int statusCode, string response,


[Link]<string,
[Link]<string>> headers, [Link]
innerException)
: base(message + "\n\nStatus: " + statusCode + "\nResponse: \n" + ((response == null)
? "(null)" : [Link](0, [Link] >= 512 ? 512 : [Link])),
innerException)
{
StatusCode = statusCode;
Response = response;
Headers = headers;
}

public override string ToString()


{
return [Link]("HTTP Response: \n\n{0}\n\n{1}", Response, [Link]());
}
}

[[Link]("NSwag", "[Link] (NJsonSchema


v10.8.0.0 ([Link] v13.0.0.0))")]
public partial class ApiException<TResult> : ApiException
{
public TResult Result { get; private set; }

public ApiException(string message, int statusCode, string response,


[Link]<string,
[Link]<string>> headers, TResult result, [Link]
innerException)
: base(message, statusCode, response, headers, innerException)
{
Result = result;
}
}

#pragma warning restore 1591


#pragma warning restore 1573
#pragma warning restore 472
#pragma warning restore 114
#pragma warning restore 108
#pragma warning restore 3016
#pragma warning restore 8603using [Link];
using [Link];

namespace [Link];

public class FlexibleAuthorizeView :


[Link]
{
[Parameter]
public Permissions Permissions
{
get
{
return [Link](Policy) ? [Link] :
[Link](Policy);
}
set
{
Policy = [Link](value);
}
}
}

@using [Link]
@using [Link]

@inject NavigationManager Navigation

<AuthorizeView>
<Authorized>
<a href="authentication/profile">Hello, @[Link]?.Name!</a>
<button class="nav-link btn btn-link" @onclick="BeginLogOut">Log
out</button>
</Authorized>
<NotAuthorized>
<a href="authentication/register">Register</a>
<a href="authentication/login">Log in</a>
</NotAuthorized>
</AuthorizeView>

@code{
private void BeginLogOut()
{
[Link]("authentication/logout");
}
}

@inherits LayoutComponentBase

<div class="page">
<div class="sidebar">
<NavMenu />
</div>

<main>
<div class="top-row px-4 auth">
<LoginDisplay />
<a href="[Link]
target="_blank">About</a>
</div>

<article class="content px-4">


@Body
</article>
</main>
</div>

.page {
position: relative;
display: flex;
flex-direction: column;
}

main {
flex: 1;
}

.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}

.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}

.top-row ::deep a, .top-row ::deep .btn-link {


white-space: nowrap;
margin-left: 1.5rem;
text-decoration: none;
}

.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {


text-decoration: underline;
}

.top-row ::deep a:first-child {


overflow: hidden;
text-overflow: ellipsis;
}

@media (max-width: 640.98px) {


.top-row:not(.auth) {
display: none;
}

.[Link] {
justify-content: space-between;
}

.top-row ::deep a, .top-row ::deep .btn-link {


margin-left: 0;
}
}

@media (min-width: 641px) {


.page {
flex-direction: row;
}

.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}

.top-row {
position: sticky;
top: 0;
z-index: 1;
}

.[Link] ::deep a:first-child {


flex: 1;
text-align: right;
width: 0;
}

.top-row, article {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}

@using [Link]
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">FlexibleAuth</a>
<button title="Navigation menu" class="navbar-toggler"
@onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
</div>
</div>
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="[Link]">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</div>
<FlexibleAuthorizeView Permissions="@[Link]">
<div class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="oi oi-plus" aria-hidden="true"></span> Counter
</NavLink>
</div>
</FlexibleAuthorizeView>
<FlexibleAuthorizeView Permissions="@[Link]">
<div class="nav-item px-3">
<NavLink class="nav-link" href="fetchdata">
<span class="oi oi-list-rich" aria-hidden="true"></span>
Fetch data
</NavLink>
</div>
</FlexibleAuthorizeView>
<FlexibleAuthorizeView Permissions="@([Link] |
[Link])">
<div class="nav-item px-3">
<NavLink class="nav-link" href="/admin/users">
<span class="oi oi-people" aria-hidden="true"></span> Users
</NavLink>
</div>
</FlexibleAuthorizeView>
<AuthorizeView>
<div class="nav-item px-3">
<NavLink class="nav-link" href="claims">
<span class="oi oi-document" aria-hidden="true"></span>
Claims
</NavLink>
</div>
</AuthorizeView>
<FlexibleAuthorizeView Permissions="@([Link] |
[Link])">
<div class="nav-item px-3">
<NavLink class="nav-link" href="admin/roles">
<span class="oi oi-badge" aria-hidden="true"></span> Roles
</NavLink>
</div>
</FlexibleAuthorizeView>
<FlexibleAuthorizeView Permissions="@([Link] |
[Link])">
<div class="nav-item px-3">
<NavLink class="nav-link" href="admin/access-control">
<span class="oi oi-lock-locked" aria-hidden="true"></span>
Access Control
</NavLink>
</div>
</FlexibleAuthorizeView>
</nav>
</div>

@code {
private bool collapseNavMenu = true;

private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;

private void ToggleNavMenu()


{
collapseNavMenu = !collapseNavMenu;
}
}

.navbar-toggler {
background-color: rgba(255, 255, 255, 0.1);
}

.top-row {
height: 3.5rem;
background-color: rgba(0,0,0,0.4);
}

.navbar-brand {
font-size: 1.1rem;
}

.oi {
width: 2rem;
font-size: 1.1rem;
vertical-align: text-top;
top: -2px;
}

.nav-item {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}

.nav-item:first-of-type {
padding-top: 1rem;
}

.nav-item:last-of-type {
padding-bottom: 1rem;
}
.nav-item ::deep a {
color: #d7d7d7;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
}

.nav-item ::deep [Link] {


background-color: rgba(255,255,255,0.25);
color: white;
}

.nav-item ::deep a:hover {


background-color: rgba(255,255,255,0.1);
color: white;
}

@media (min-width: 641px) {


.navbar-toggler {
display: none;
}

.collapse {
/* Never collapse the sidebar for wide screens */
display: block;
}
}

@inject NavigationManager Navigation

@code {
protected override void OnInitialized()
{

[Link]($"authentication/login?returnUrl={[Link](Navi
[Link])}");
}
}
<div class="alert alert-secondary mt-4">
<span class="oi oi-pencil me-2" aria-hidden="true"></span>
<strong>@Title</strong>

<span class="text-nowrap">
Please take our
<a target="_blank" class="font-weight-bold link-dark"
href="[Link] survey</a>
</span>
and tell us what you think.
</div>

@code {
// Demonstrates how a parent component can supply parameters
[Parameter]
public string? Title { get; set; }
}

using [Link];
using [Link];
using [Link];
using [Link];
using [Link];
using [Link];
using [Link];
using [Link];

var builder = [Link](args);


[Link]<App>("#app");
[Link]<HeadOutlet>("head::after");

[Link]("[Link]", client =>


[Link] = new Uri([Link]))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

// Supply HttpClient instances that include access tokens when making requests to
the server project
[Link](sp =>
[Link]<IHttpClientFactory>().CreateClient("[Link]"
));

[Link]
.AddApiAuthorization()
.AddAccountClaimsPrincipalFactory<CustomAccountClaimsPrincipalFactory>();

[Link]<IAuthorizationHandler,
PermissionAuthorizationHandler>();
[Link]<IAuthorizationPolicyProvider,
FlexibleAuthorizationPolicyProvider>();

[Link](scan => scan


.FromAssemblyOf<IAccessControlClient>()
.AddClasses(classes =>
[Link]<IAccessControlClient>())
.AsImplementedInterfaces()
.WithScopedLifetime());

await [Link]().RunAsync();

Common questions

Powered by AI

The `AccessControlClient` is configured with an `HttpClient` and JSON settings initialized through a lazy-loaded `JsonSerializerSettings`. It prepares requests using helper methods, sends HTTP requests to endpoints like 'api/Admin/AccessControl', and processes server responses. For managing configurations, it calls `GetConfigurationAsync` for fetching and `UpdateConfigurationAsync` for updating roles' permissions .

The `FlexibleAuthorizeView` component is used to conditionally render UI elements based on user's permissions. It allows the application to show or hide controls based on whether a user is authorized for specific permissions, such as editing roles or permissions, ensuring role-based access at the UI level .

The `AccessControlVm` class initializes available permissions by retrieving them via `PermissionsProvider.GetAll` and excludes `Permissions.None`. It sets roles through a list of `RoleDto` objects during construction. This initialization centralizes permissions management, facilitating the consistent application of roles and permissions across the system .

The `DbInitializer` class creates three default roles in the initialization process: 'Administrators', 'Accounts', and 'Operations'. The 'Administrators' role is created with all permissions. The 'Accounts' role has permissions for `ViewUsers` and `Counter`. The 'Operations' role has permissions for `ViewUsers` and `Forecast` .

The `RoleDto` class manages permissions using a bitwise flag enum (`Permissions`). It provides methods such as `Has` to check if a permission is set, `Set` to grant or revoke permissions, `Grant` to add a permission, and `Revoke` to remove a permission. Permissions can be modified programmatically by using these methods .

The `CustomAccountClaimsPrincipalFactory` extends the `AccountClaimsPrincipalFactory` to modify user claims. It inspects additional properties in `RemoteUserAccount` and adds them as claims to the user's identity. This is particularly useful for handling arrays and complex properties in claims, enhancing the customization of user authentication and authorization in applications .

To configure identity services and permissions, use `WebApplication.CreateBuilder` to setup the application. Add the database context using `AddDbContext`. Configure identity with `AddDefaultIdentity` and add roles using `AddRoles`. Include IdentityServer for API authorization via `AddIdentityServer`, customizing identity and API resources to include claims like 'role' and 'permissions'. Lastly, configure authentication with `AddIdentityServerJwt` and define policies and handlers for permissions .

In the `Edit` page model, user roles are managed through a form allowing administrators to view and modify assigned roles. It supports operations such as toggling roles for a user and saving these changes. Roles retrieved from the role collection can be added or removed through checkbox input, enabling dynamic role management .

In development environments, the `ErrorModel` class exposes detailed exception information by setting the `ASPNETCORE_ENVIRONMENT` environment variable to `Development`. This enables developers to view detailed error messages for debugging. In production environments, detailed error information is not displayed to avoid showing sensitive information to end users .

Removing claims from `JwtSecurityTokenHandler.DefaultInboundClaimTypeMap` such as 'role' has significance in preventing automatic mapping of claim types to proprietary claim types within the application. This provides flexibility in how claims are handled and ensures custom claim types are retained throughout application processing, which is crucial for precise authorization and authentication logic .

You might also like