< Summary

Information
Class: Anichron.API.Endpoints.UserEndpoints
Assembly: Anichron.API
File(s): /home/runner/work/anichron/anichron/src/Anichron.API/Endpoints/UserEndpoints.cs
Tag: 228_36821334185
Line coverage
60%
Covered lines: 14
Uncovered lines: 9
Coverable lines: 23
Total lines: 54
Line coverage: 60.8%
Branch coverage
100%
Covered branches: 6
Total branches: 6
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
MapUserEndpoints(...)100%210%
GetMeAsync()100%44100%
ChangePasswordAsync()100%22100%

File(s)

/home/runner/work/anichron/anichron/src/Anichron.API/Endpoints/UserEndpoints.cs

#LineLine coverage
 1using Anichron.API.Infrastructure;
 2using Anichron.API.Services;
 3using Anichron.API.Settings;
 4using Anichron.Core.Data.Repository;
 5using Microsoft.Extensions.Options;
 6using System.Security.Claims;
 7
 8namespace Anichron.API.Endpoints;
 9
 10public static class UserEndpoints
 11{
 12    public static IEndpointRouteBuilder MapUserEndpoints(this IEndpointRouteBuilder app)
 013    {
 014        var group = app.MapGroup(ApiPaths.Users.Group).WithTags("Users");
 015        group.MapGet(ApiPaths.Users.Me, GetMeAsync)
 016             .RequireAuthorization();
 017        group.MapPost(ApiPaths.Users.ChangePassword, ChangePasswordAsync)
 018             .RequireAuthorization()
 019             .RequireRateLimiting(AuthRateLimitPolicies.Sensitive);
 020        return app;
 021    }
 22
 23    internal static async Task<IResult> GetMeAsync(
 24        ClaimsPrincipal user,
 25        IUserRepository users,
 26        CancellationToken ct)
 427    {
 428        if (!Guid.TryParse(user.FindFirstValue(ClaimTypes.NameIdentifier), out var userId))
 229            return Results.Unauthorized();
 30
 231        var found = await users.FindByIdAsync(userId, ct);
 232        return found is null
 233            ? Results.NotFound()
 234            : Results.Ok(new UserProfileResponse(found.Id, found.Username, found.Email, found.IsAdmin, found.MustChangeP
 435    }
 36
 37    internal static async Task<IResult> ChangePasswordAsync(
 38        ChangePasswordRequest req,
 39        ClaimsPrincipal user,
 40        IAuthService auth,
 41        IAuthResponseMapper mapper,
 42        IOptions<PasswordPolicy> passwordPolicyOptions,
 43        CancellationToken ct)
 544    {
 545        if (!Guid.TryParse(user.FindFirstValue(ClaimTypes.NameIdentifier), out var userId))
 246            return Results.Unauthorized();
 47
 348        var result = await auth.ChangePasswordAsync(userId, req.CurrentPassword, req.NewPassword, ct);
 349        return mapper.GetChangePasswordResult(result, passwordPolicyOptions.Value);
 550    }
 51}
 52
 53public sealed record ChangePasswordRequest(string CurrentPassword, string NewPassword);
 54public sealed record UserProfileResponse(Guid Id, string Username, string Email, bool IsAdmin, bool MustChangePassword);