< Summary - Heimdall API

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

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
ActorMayManageScopeAsync()100%22100%

File(s)

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

#LineLine coverage
 1using ArturRios.Data.Relational.Core.Interfaces;
 2using ArturRios.Heimdall.Domain.Entities;
 3using ArturRios.Heimdall.Domain.Enums;
 4using Microsoft.EntityFrameworkCore;
 5
 6namespace ArturRios.Heimdall.Shared.Services;
 7
 8/// <summary>
 9///     Default <see cref="IScopeOwnershipChecker" />: a System Admin bypasses ownership; any other
 10///     actor is authorized only when a <c>SCOPE_OWNER</c> row links their person id to the scope.
 11/// </summary>
 30012public class ScopeOwnershipChecker(IAsyncReadOnlyRepository<Person, long> personReader) : IScopeOwnershipChecker
 13{
 14    public async Task<bool> ActorMayManageScopeAsync(int actingRole, Guid actingPersonId, long scopeId)
 15    {
 16        // A System Admin bypasses the ownership check entirely (no query needed).
 19017        if (actingRole == (int)Roles.SystemAdmin)
 18        {
 12319            return true;
 20        }
 21
 22        // Otherwise the actor must own the scope. A logically deleted person owns nothing: they can
 23        // no longer authenticate (UC-11 AF-11c), so a token issued before their deletion must not
 24        // keep working until it expires.
 6725        return await personReader.Query().AnyAsync(person =>
 6726            person.PublicId == actingPersonId && !person.IsDeleted &&
 6727            person.ScopeOwnerships.Any(ownership => ownership.ScopeId == scopeId));
 19028    }
 29}