106 lines
3.1 KiB
C#
106 lines
3.1 KiB
C#
using Hutopy.Infrastructure.Security;
|
|
using Hutopy.Modules.Creators.Data;
|
|
|
|
namespace Hutopy.Modules.Creators.Features;
|
|
|
|
[PublicAPI]
|
|
public sealed class GetCreatorBySlugRequest
|
|
{
|
|
public required string Name { get; set; }
|
|
}
|
|
|
|
[PublicAPI]
|
|
public record GetCreatorBySlugResponse
|
|
{
|
|
public Guid Id { get; init; }
|
|
public Guid CreatedBy { get; init; }
|
|
public DateTimeOffset CreatedAt { get; init; }
|
|
public Guid? DeletedBy { get; init; }
|
|
public DateTimeOffset? DeletedAt { get; init; }
|
|
public bool IsDeleted { get; init; }
|
|
public bool Verified { get; init; }
|
|
public bool AcceptDonation { get; init; }
|
|
public string? BannerUrl { get; init; }
|
|
public string? PortraitUrl { get; init; }
|
|
public required string Slug { get; init; }
|
|
public required string Name { get; init; }
|
|
public string? Title { get; init; }
|
|
public Socials? Socials { get; init; }
|
|
public Presentation? Presentation { get; init; }
|
|
}
|
|
|
|
[UsedImplicitly]
|
|
public sealed class GetCreatorBySlugRequestValidator
|
|
: Validator<GetCreatorBySlugRequest>
|
|
{
|
|
public GetCreatorBySlugRequestValidator()
|
|
{
|
|
RuleFor(r => r.Name)
|
|
.NotNull().WithMessage("You should specify the Name")
|
|
.NotEmpty().WithMessage("You should specify a valid/not empty Name");
|
|
}
|
|
}
|
|
|
|
[PublicAPI]
|
|
public class GetCreatorBySlugHandler(
|
|
CreatorsDbContext context)
|
|
: Endpoint<GetCreatorBySlugRequest, GetCreatorBySlugResponse>
|
|
{
|
|
public override void Configure()
|
|
{
|
|
Get("/api/creators/@{Name}");
|
|
Options((o => o.WithTags("Creators")));
|
|
AllowAnonymous();
|
|
}
|
|
|
|
public override async Task HandleAsync(
|
|
GetCreatorBySlugRequest req,
|
|
CancellationToken ct)
|
|
{
|
|
var creatorName = req.Name.ToLower();
|
|
|
|
var response = await context
|
|
.Creators
|
|
.IgnoreQueryFilters()
|
|
.Where(c => EF.Functions.ILike(c.Slug, creatorName))
|
|
.AsNoTracking()
|
|
.Select(c => new GetCreatorBySlugResponse
|
|
{
|
|
Id = c.Id,
|
|
CreatedBy = c.CreatedBy,
|
|
CreatedAt = c.CreatedAt,
|
|
DeletedBy = c.DeletedBy,
|
|
DeletedAt = c.DeletedAt,
|
|
IsDeleted = c.IsDeleted,
|
|
Verified = c.Verified,
|
|
BannerUrl = c.BannerUrl,
|
|
PortraitUrl = c.PortraitUrl,
|
|
Slug = c.Slug,
|
|
Name = c.Name,
|
|
Title = c.Title,
|
|
AcceptDonation = c.IsStripeChargesEnabled && c.IsStripePayoutReady,
|
|
Socials = c.Socials,
|
|
Presentation = c.Presentation
|
|
})
|
|
.SingleOrDefaultAsync(ct);
|
|
|
|
if (response is null)
|
|
{
|
|
await SendNotFoundAsync(ct);
|
|
return;
|
|
}
|
|
|
|
bool isOwner = User.Identity?.IsAuthenticated == true
|
|
&& User.GetUserId() == response.CreatedBy;
|
|
|
|
if (response.IsDeleted && !isOwner)
|
|
{
|
|
await SendNotFoundAsync(ct);
|
|
}
|
|
else
|
|
{
|
|
await SendAsync(response, cancellation: ct);
|
|
}
|
|
}
|
|
}
|