< Summary - Heimdall API

Information
Class: ArturRios.Heimdall.Shared.Services.ApplicationManagementAccess
Assembly: ArturRios.Heimdall.Shared
File(s): /home/runner/work/heimdall-api/heimdall-api/src/Application/ArturRios.Heimdall.Shared/Services/ApplicationManagementAccess.cs
Line coverage
100%
Covered lines: 17
Uncovered lines: 0
Coverable lines: 17
Total lines: 74
Line coverage: 100%
Branch coverage
100%
Covered branches: 8
Total branches: 8
Branch coverage: 100%
Method coverage
100%
Covered methods: 1
Fully covered methods: 1
Total methods: 1
Method coverage: 100%
Full method coverage: 100%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
ResolveAsync()100%88100%

File(s)

/home/runner/work/heimdall-api/heimdall-api/src/Application/ArturRios.Heimdall.Shared/Services/ApplicationManagementAccess.cs

#LineLine coverage
 1using ArturRios.Heimdall.Domain.Enums;
 2using Microsoft.EntityFrameworkCore;
 3using Application = ArturRios.Heimdall.Domain.Entities.Application;
 4
 5namespace ArturRios.Heimdall.Shared.Services;
 6
 7/// <summary>The outcome of <see cref="ApplicationManagementAccess.ResolveAsync" />.</summary>
 8public enum ApplicationAccess
 9{
 10    /// <summary>The actor may manage the application.</summary>
 11    Granted,
 12
 13    /// <summary>No live application with that id lives in the addressed, live scope.</summary>
 14    NotFound,
 15
 16    /// <summary>The application exists, but the actor may not manage it.</summary>
 17    Forbidden
 18}
 19
 20/// <summary>The resolved application — only when <see cref="Access" /> is <see cref="ApplicationAccess.Granted" />.</su
 21public sealed record ApplicationAccessResult(ApplicationAccess Access, Application? Application);
 22
 23/// <summary>
 24///     Who may manage an application's credentials (UC-53…UC-55, FR-AP-12): the rule UC-17, UC-18
 25///     and UC-19 already apply to the application itself.
 26/// </summary>
 27/// <remarks>
 28///     <para>
 29///         A System Admin manages any application. A Scope Admin manages one only when they are its
 30///         owner <em>and</em> still own its scope: owning the scope is not grounds to manage another
 31///         owner's application, and an owner UC-22 removed from the scope keeps nothing (AF-17b).
 32///     </para>
 33///     <para>
 34///         Not found is answered before authorization, as UC-17 does, so a missing application and
 35///         one the actor may not touch stay distinguishable to the people allowed to see either. A
 36///         logically deleted application, or one whose scope is logically deleted, is not found:
 37///         its credentials are inert (UC-56, UC-57), so there is nothing to manage.
 38///     </para>
 39/// </remarks>
 40public static class ApplicationManagementAccess
 41{
 42    public static async Task<ApplicationAccessResult> ResolveAsync(
 43        IQueryable<Application> applications,
 44        Guid scopeId,
 45        Guid applicationId,
 46        int actingRole,
 47        Guid actingPersonId)
 48    {
 5949        var application = await applications
 5950            .Include(x => x.Scope)
 5951            .Include(x => x.Owner)
 5952            .ThenInclude(owner => owner.ScopeOwnerships)
 5953            .FirstOrDefaultAsync(x => x.PublicId == applicationId && x.Scope.PublicId == scopeId &&
 5954                                      !x.IsDeleted && !x.Scope.IsDeleted);
 55
 5956        if (application is null)
 57        {
 1058            return new ApplicationAccessResult(ApplicationAccess.NotFound, null);
 59        }
 60
 4961        if (actingRole == (int)Roles.SystemAdmin)
 62        {
 3463            return new ApplicationAccessResult(ApplicationAccess.Granted, application);
 64        }
 65
 1566        var ownsApplicationAndScope =
 1567            application.Owner.PublicId == actingPersonId &&
 2268            application.Owner.ScopeOwnerships.Any(ownership => ownership.ScopeId == application.ScopeId);
 69
 1570        return ownsApplicationAndScope
 1571            ? new ApplicationAccessResult(ApplicationAccess.Granted, application)
 1572            : new ApplicationAccessResult(ApplicationAccess.Forbidden, null);
 5973    }
 74}

Methods/Properties

ResolveAsync()