Cayaqui.Authorization
0.4.21
dotnet add package Cayaqui.Authorization --version 0.4.21
NuGet\Install-Package Cayaqui.Authorization -Version 0.4.21
<PackageReference Include="Cayaqui.Authorization" Version="0.4.21" />
<PackageVersion Include="Cayaqui.Authorization" Version="0.4.21" />
<PackageReference Include="Cayaqui.Authorization" />
paket add Cayaqui.Authorization --version 0.4.21
#r "nuget: Cayaqui.Authorization, 0.4.21"
#:package Cayaqui.Authorization@0.4.21
#addin nuget:?package=Cayaqui.Authorization&version=0.4.21
#tool nuget:?package=Cayaqui.Authorization&version=0.4.21
Cayaqui.Authorization
Business authorization layer for Cayaqui Blazor apps (.NET 10 Blazor WebApp Interactive Server).
What's included
| Type | Description |
|---|---|
AppUser |
Application user entity (Email, DisplayName, PhotoUrl, ExternalId for Entra ID) |
UserRole |
Role assignment: (UserId, Role, ProjectId?) — null ProjectId = global scope |
CayaquiRoles |
Role name constants: SuperAdmin, Admin, ProjectManager, ProjectController, ProjectEngineer, ProjectViewer |
CayaquiPermissions |
Granular permission constants: Resource.Action (e.g. Projects.Edit, Budget.Approve) |
ICayaquiCurrentUser |
Extended current user: IsAuthenticated, IsSuperAdmin, HasPermission(), IsInRole() |
ICayaquiAuthorizationService |
Load and evaluate role assignments from DB |
ICayaquiUserService |
User CRUD + role assignment |
AuthorizationDbContext |
EF Core context: Users + UserRoles tables |
CayaquiAuthorizeView |
Blazor component: conditionally renders content based on permission/role |
CayaquiAccessDenied |
Blazor component: access-denied page with back button |
Quick start
// Program.cs
using Cayaqui.Authorization.Extensions;
builder.Services.AddCayaquiAuthorization(o =>
o.UseSqlServer(connectionString)); // or UseInMemoryDatabase for dev
// Register your ICayaquiCurrentUser implementation (Scoped)
builder.Services.AddScoped<ICayaquiCurrentUser, YourCurrentUser>();
CayaquiAuthorizeView
@using Cayaqui.Authorization.Domain
<CayaquiAuthorizeView Permission="@CayaquiPermissions.Budget.Approve" ProjectId="@projectId">
<button>Aprobar Presupuesto</button>
</CayaquiAuthorizeView>
<CayaquiAuthorizeView Role="@CayaquiRoles.ProjectManager" ProjectId="@projectId">
<Authorized>
<button>Editar</button>
</Authorized>
<NotAuthorized>
<span>Solo lectura</span>
</NotAuthorized>
</CayaquiAuthorizeView>
Implementing ICayaquiCurrentUser
// Scoped — loaded once per Blazor circuit
public sealed class CurrentUser : ICayaquiCurrentUser
{
private readonly ICayaquiAuthorizationService _authService;
private IReadOnlyList<UserRoleAssignment>? _assignments;
public CurrentUser(IHttpContextAccessor http, ICayaquiAuthorizationService authService)
{
_authService = authService;
var claims = http.HttpContext?.User;
IsAuthenticated = claims?.Identity?.IsAuthenticated ?? false;
Id = IsAuthenticated ? Guid.Parse(claims!.FindFirstValue(ClaimTypes.NameIdentifier)!) : null;
Email = claims?.FindFirstValue(ClaimTypes.Email);
DisplayName = claims?.FindFirstValue("name");
}
public Guid? Id { get; }
public string? Email { get; }
public string? DisplayName { get; }
public string? PhotoUrl { get; set; } // set after photo URL is resolved
public bool IsAuthenticated { get; }
public bool IsSuperAdmin => RoleAssignments.Any(r => r.Role == CayaquiRoles.SuperAdmin);
public IReadOnlyList<UserRoleAssignment> RoleAssignments =>
_assignments ??= Id.HasValue
? _authService.GetUserRolesAsync(Id.Value).GetAwaiter().GetResult()
: [];
public bool IsInRole(string role, Guid? projectId = null) =>
IsSuperAdmin || RoleAssignments.Any(r =>
r.Role == role && (r.ProjectId is null || r.ProjectId == projectId));
public bool HasPermission(string permission, Guid? projectId = null) =>
IsAuthenticated && _authService.HasPermission(RoleAssignments, permission, projectId);
}
Role → Permission matrix
| Permission | SuperAdmin | Admin | ProjectManager | ProjectController | ProjectEngineer | ProjectViewer |
|---|---|---|---|---|---|---|
| Users.ManageRoles | ✓ | ✓ | ||||
| Projects.Create/Delete | ✓ | ✓ | ||||
| Budget.Approve/Baseline | ✓ | ✓ | ✓ | |||
| Evm.Publish | ✓ | ✓ | ✓ | |||
| Schedule.Publish | ✓ | ✓ | ✓ | |||
| ChangeOrders.Approve | ✓ | ✓ | ✓ | |||
| View (all resources) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Auth models
This package is auth-provider agnostic. Two deployment models are supported:
Entra ID: Admin pre-registers email → user logs in with Entra → ICayaquiUserService.FindByEmailAsync provisions the record → photo downloaded via Graph API and stored via Cayaqui.Storage.
Local auth: Standard ASP.NET Core Identity with MFA (Email OTP / SMS OTP / TOTP). Same AppUser entity extended with Identity columns.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Cayaqui.Abstractions (>= 0.4.21)
- Microsoft.AspNetCore.Components.Web (>= 10.0.9)
- Microsoft.EntityFrameworkCore (>= 10.0.9)
- Microsoft.EntityFrameworkCore.Relational (>= 10.0.9)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.9)
- Microsoft.Extensions.DependencyInjection (>= 10.0.9)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.9)
- Microsoft.Extensions.Logging (>= 10.0.9)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.9)
- Microsoft.Extensions.Options (>= 10.0.9)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.9)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.4.21 | 108 | 6/23/2026 |
| 0.4.20 | 100 | 6/23/2026 |
| 0.4.15 | 104 | 6/22/2026 |
| 0.4.14 | 108 | 6/22/2026 |
| 0.4.13 | 104 | 6/22/2026 |
| 0.4.10 | 100 | 6/20/2026 |
| 0.4.5 | 101 | 6/20/2026 |
| 0.4.3 | 97 | 6/20/2026 |
| 0.4.2 | 97 | 6/20/2026 |
| 0.4.1 | 100 | 6/20/2026 |
| 0.3.9 | 104 | 6/19/2026 |
| 0.3.8 | 99 | 6/18/2026 |
| 0.3.7 | 95 | 6/18/2026 |
| 0.3.6 | 109 | 6/18/2026 |
| 0.3.5 | 96 | 6/18/2026 |
| 0.3.4 | 99 | 6/17/2026 |
| 0.1.2 | 105 | 6/16/2026 |
| 0.1.1 | 97 | 6/16/2026 |
| 0.1.0 | 99 | 6/15/2026 |
v0.2.0 — BREAKING rename: IMpsCurrentUser→ICayaquiCurrentUser, IMpsAuthorizationService→ICayaquiAuthorizationService, IMpsUserService→ICayaquiUserService, AddMpsAuthorization→AddCayaquiAuthorization; shims [Obsolete] se mantienen hasta v1.0. v0.1.0 — Initial release: AppUser, UserRole, CayaquiRoles, CayaquiPermissions, ICayaquiCurrentUser, AuthorizationDbContext, AddCayaquiAuthorization() DI extension.