// Copyright Epic Games, Inc. All Rights Reserved. using HordeServer.Api; using HordeServer.Models; using HordeServer.Services; using HordeServer.Utilities; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using MongoDB.Bson; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; namespace HordeServer.Controllers { using ProjectId = StringId; /// /// Controller for the /api/v1/projects endpoint /// [ApiController] [Authorize] [Route("[controller]")] public class ProjectsController : ControllerBase { /// /// Singleton instance of the project service /// private readonly ProjectService ProjectService; /// /// Singleton instance of the stream service /// private readonly StreamService StreamService; /// /// Constructor /// /// The project service /// The stream service public ProjectsController(ProjectService ProjectService, StreamService StreamService) { this.ProjectService = ProjectService; this.StreamService = StreamService; } /// /// Query all the projects /// /// Whether to include streams in the response /// Whether to include categories in the response /// Filter for the properties to return /// Information about all the projects [HttpGet] [Route("/api/v1/projects")] [ProducesResponseType(typeof(List), 200)] public async Task>> GetProjectsAsync([FromQuery(Name = "Streams")] bool IncludeStreams = false, [FromQuery(Name = "Categories")] bool IncludeCategories = false, [FromQuery] PropertyFilter? Filter = null) { List Projects = await ProjectService.GetProjectsAsync(); ProjectPermissionsCache PermissionsCache = new ProjectPermissionsCache(); List? Streams = null; if (IncludeStreams || IncludeCategories) { Streams = await StreamService.GetStreamsAsync(); } List Responses = new List(); foreach (IProject Project in Projects) { if (await ProjectService.AuthorizeAsync(Project, AclAction.ViewProject, User, PermissionsCache)) { bool bIncludeAcl = await ProjectService.AuthorizeAsync(Project, AclAction.ViewPermissions, User, PermissionsCache); Responses.Add(Project.ToResponse(IncludeStreams, IncludeCategories, Streams, bIncludeAcl).ApplyFilter(Filter)); } } return Responses; } /// /// Retrieve information about a specific project /// /// Id of the project to get information about /// Filter for the properties to return /// Information about the requested project [HttpGet] [Route("/api/v1/projects/{ProjectId}")] [ProducesResponseType(typeof(List), 200)] public async Task> GetProjectAsync(string ProjectId, [FromQuery] PropertyFilter? Filter = null) { ProjectId ProjectIdValue = new ProjectId(ProjectId); IProject? Project = await ProjectService.GetProjectAsync(ProjectIdValue); if (Project == null) { return NotFound(); } ProjectPermissionsCache Cache = new ProjectPermissionsCache(); if (!await ProjectService.AuthorizeAsync(Project, AclAction.ViewProject, User, Cache)) { return Forbid(); } bool bIncludeStreams = PropertyFilter.Includes(Filter, nameof(GetProjectResponse.Streams)); bool bIncludeCategories = PropertyFilter.Includes(Filter, nameof(GetProjectResponse.Categories)); List? VisibleStreams = null; if (bIncludeStreams || bIncludeCategories) { VisibleStreams = new List(); List Streams = await StreamService.GetStreamsAsync(Project.Id); foreach (IStream Stream in Streams) { if (await StreamService.AuthorizeAsync(Stream, AclAction.ViewStream, User, Cache)) { VisibleStreams.Add(Stream); } } } bool bIncludeAcl = await ProjectService.AuthorizeAsync(Project, AclAction.ViewPermissions, User, Cache); return Project.ToResponse(bIncludeStreams, bIncludeCategories, VisibleStreams, bIncludeAcl).ApplyFilter(Filter); } /// /// Retrieve information about a specific project /// /// Id of the project to get information about /// Information about the requested project [HttpGet] [Route("/api/v1/projects/{ProjectId}/logo")] public async Task> GetProjectLogoAsync(string ProjectId) { ProjectId ProjectIdValue = new ProjectId(ProjectId); IProject? Project = await ProjectService.GetProjectAsync(ProjectIdValue); if (Project == null) { return NotFound(); } if (!await ProjectService.AuthorizeAsync(Project, AclAction.ViewProject, User, null)) { return Forbid(); } IProjectLogo? ProjectLogo = await ProjectService.Collection.GetLogoAsync(ProjectIdValue); if (ProjectLogo == null) { return NotFound(); } return new FileContentResult(ProjectLogo.Data, ProjectLogo.MimeType); } } }