using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using PrivaPub.Api.Mastodon.Infrastructure; using PrivaPub.Api.Mastodon.Mappers; using PrivaPub.Domain.Privacy; using PrivaPub.Domain.Statuses; using PrivaPub.Models.Post; using PrivaPub.StaticServices; using PostEntity = PrivaPub.Models.Post.Post; namespace PrivaPub.Api.Mastodon.Controllers { public class PollsController : MastodonController { readonly DbEntities _dbEntities; readonly MastodonMapper _mapper; readonly IPollService _polls; public PollsController(DbEntities dbEntities, MastodonMapper mapper, IPollService polls) { _dbEntities = dbEntities; _mapper = mapper; _polls = polls; } [HttpGet("/api/v1/polls/{id}"), Scope("read:statuses", requiresUser: false), AllowAnonymous] public async Task Get(string id, CancellationToken token) { var post = await Visible(id, token); return post?.Poll == default ? NotFoundError() : Json(_mapper.Poll(post, MyId, await _polls.OwnVotes(post.ID, MyId, token))); } [HttpPost("/api/v1/polls/{id}/votes"), Scope("write:statuses")] public async Task Vote(string id, CancellationToken token) { var post = await Visible(id, token); if (post?.Poll == default) return NotFoundError(); var choices = Params.List("choices").Select(c => int.TryParse(c, out var index) ? index : -1).ToList(); var outcome = await _polls.Vote(Me, post, choices, token); if (!outcome.Ok) return Error(outcome.Status, outcome.Error); return Json(_mapper.Poll(outcome.Post, MyId, await _polls.OwnVotes(post.ID, MyId, token))); } async Task Visible(string id, CancellationToken token) { var post = await _dbEntities.Posts.Match(p => p.ID == id && !p.DeletedAt.HasValue).ExecuteFirstAsync(token); return post != default && post.Visibility != PostVisibility.LocalGeo && await VisibilityPolicy.CanSee(post, MyId, token) ? post : default; } } }