using FastEndpoints; using Microsoft.EntityFrameworkCore; using Socialize.Api.Data; using Socialize.Api.Infrastructure.Security; using Socialize.Api.Modules.CalendarIntegrations.Data; using Socialize.Api.Modules.CalendarIntegrations.Services; using Socialize.Api.Modules.Organizations.Services; namespace Socialize.Api.Modules.CalendarIntegrations.Handlers; public class RefreshCalendarSourceHandler( AppDbContext dbContext, AccessScopeService accessScopeService, OrganizationAccessService organizationAccessService, CalendarImportSyncService syncService) : EndpointWithoutRequest { public override void Configure() { Post("/api/calendar-integrations/sources/{sourceId:guid}/refresh"); Options(o => o.WithTags("Calendar Integrations")); } public override async Task HandleAsync(CancellationToken ct) { Guid sourceId = Route("sourceId"); CalendarSource? source = await dbContext.CalendarSources.SingleOrDefaultAsync(candidate => candidate.Id == sourceId, ct); if (source is null) { await SendNotFoundAsync(ct); return; } if (!await CanManageExistingSourceAsync(source, User.GetUserId(), ct)) { await SendForbiddenAsync(ct); return; } await syncService.RefreshSourceAsync(source.Id, ct); await dbContext.Entry(source).ReloadAsync(ct); await SendOkAsync(CalendarSourceDto.FromSource(source, isReadOnly: false), ct); } private async Task CanManageExistingSourceAsync( CalendarSource source, Guid currentUserId, CancellationToken ct) { return source.Scope switch { CalendarSourceScopes.Organization when source.OrganizationId.HasValue => await organizationAccessService.HasOrganizationPermissionAsync( User, source.OrganizationId.Value, OrganizationPermissions.ManageConnectors, ct), CalendarSourceScopes.Workspace when source.WorkspaceId.HasValue => await accessScopeService.CanManageWorkspaceAsync(User, source.WorkspaceId.Value, ct), CalendarSourceScopes.User => source.UserId == currentUserId, _ => false, }; } }