// Copyright Epic Games, Inc. All Rights Reserved. using HordeServer.Api; using HordeServer.Collections; using HordeServer.Models; using HordeServer.Notifications.Impl; using HordeServer.Services; using HordeServer.Utilities; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using MongoDB.Bson; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace HordeServer.Controllers { /// /// Controller for the /api/v1/users endpoint /// [ApiController] [Authorize] [Route("[controller]")] public class UsersController : ControllerBase { /// /// The user collection instance /// IUserCollection UserCollection { get; set; } /// /// The avatar service /// IAvatarService? AvatarService { get; set; } /// /// Constructor /// /// /// public UsersController(IUserCollection UserCollection, IAvatarService? AvatarService) { this.UserCollection = UserCollection; this.AvatarService = AvatarService; } /// /// Gets information about a user by id, specify "current" for id to get the currently logged in user /// /// Http result code [HttpGet] [Route("/api/v1/users/{Id}")] [ProducesResponseType(typeof(List), 200)] public async Task> GetUserAsync(string Id, [FromQuery] PropertyFilter? Filter = null) { IUser? User = await GetUserInternalAsync(Id); if (User == null) { return NotFound(); } IAvatar? Avatar = (AvatarService == null) ? (IAvatar?)null : await AvatarService.GetAvatarAsync(User); IUserClaims? Claims = await UserCollection.GetClaimsAsync(User.Id); IUserSettings? Settings = await UserCollection.GetSettingsAsync(User.Id); return PropertyFilter.Apply(new GetUserResponse(User, Avatar, Claims, Settings), Filter); } /// /// Gets a list of users /// /// List of user responses [HttpGet] [Route("/api/v1/users")] [ProducesResponseType(typeof(List), 200)] public async Task>> FindUsersAsync( [FromQuery] string[]? Ids = null, [FromQuery] string? NameRegex = null, [FromQuery] int Index = 0, [FromQuery] int Count = 100, [FromQuery] bool IncludeClaims = false, [FromQuery] bool IncludeAvatar = false) { ObjectId[]? UserIds = null; if (Ids != null && Ids.Length > 0) { UserIds = Ids.Select(x => new ObjectId(x)).ToArray(); } List Users = await UserCollection.FindUsersAsync(UserIds, NameRegex, Index, Count); List Response = new List(); foreach (IUser User in Users) { IAvatar? Avatar = (AvatarService == null || !IncludeAvatar) ? (IAvatar?)null : await AvatarService.GetAvatarAsync(User); IUserClaims? Claims = (!IncludeClaims) ? null : await UserCollection.GetClaimsAsync(User.Id); Response.Add(new GetUserResponse(User, Avatar, Claims, null)); } return Response; } async Task GetUserInternalAsync(string Id) { ObjectId? UserId = ParseUserId(Id); if(UserId == null) { return null; } return await UserCollection.GetUserAsync(UserId.Value); } ObjectId? ParseUserId(string Id) { if (Id.Equals("current", StringComparison.OrdinalIgnoreCase)) { return User.GetUserId(); } else if(ObjectId.TryParse(Id, out ObjectId Result)) { return Result; } return null; } } }