// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using EpicGames.Horde.Users;
using HordeServer.Utilities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace HordeServer.Users
{
///
/// Controller for the /api/v1/users endpoint
///
[ApiController]
[Authorize]
[Route("[controller]")]
public class UsersController : HordeControllerBase
{
///
/// The user collection instance
///
IUserCollection UserCollection { get; set; }
///
/// The avatar service
///
IAvatarService? AvatarService { get; set; }
///
/// Constructor
///
///
///
public UsersController(IUserCollection userCollection, IAvatarService? avatarService)
{
UserCollection = userCollection;
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, CancellationToken cancellationToken = default)
{
UserId? userId = ParseUserId(id);
if (userId == null)
{
return BadRequest("Invalid user id '{Id}'", id);
}
IUser? user = await UserCollection.GetUserAsync(userId.Value, cancellationToken);
if (user == null)
{
return NotFound(userId.Value);
}
IAvatar? avatar = (AvatarService == null) ? (IAvatar?)null : await AvatarService.GetAvatarAsync(user, cancellationToken);
IUserClaims? claims = await UserCollection.GetClaimsAsync(user.Id, cancellationToken);
IUserSettings? settings = await UserCollection.GetSettingsAsync(user.Id, cancellationToken);
return PropertyFilter.Apply(user.ToApiResponse(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,
CancellationToken cancellationToken = default)
{
UserId[]? userIds = null;
if (ids != null && ids.Length > 0)
{
userIds = ids.Select(x => UserId.Parse(x)).ToArray();
}
IReadOnlyList users = await UserCollection.FindUsersAsync(userIds, nameRegex, index, count, cancellationToken);
List response = new List();
foreach (IUser user in users)
{
IAvatar? avatar = (AvatarService == null || !includeAvatar) ? (IAvatar?)null : await AvatarService.GetAvatarAsync(user, cancellationToken);
IUserClaims? claims = (!includeClaims) ? null : await UserCollection.GetClaimsAsync(user.Id, cancellationToken);
response.Add(user.ToApiResponse(avatar, claims, null));
}
return response;
}
UserId? ParseUserId(string id)
{
if (id.Equals("current", StringComparison.OrdinalIgnoreCase))
{
return User.GetUserId();
}
else if (UserId.TryParse(id, out UserId result))
{
return result;
}
return null;
}
}
}