// ==========================================================================
// UsersController.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Squidex.Controllers.Api.Users.Models;
using Squidex.Infrastructure.Reflection;
using Squidex.Pipeline;
using Squidex.Read.Users;
// ReSharper disable InvertIf
namespace Squidex.Controllers.Api.Users
{
///
/// Readonly API to retrieve information about squidex users.
///
[ApiExceptionFilter]
[SwaggerTag("Users")]
public class UsersController : Controller
{
private static readonly byte[] AvatarBytes;
private readonly UserManager userManager;
private readonly IUserPictureStore userPictureStore;
static UsersController()
{
var assembly = typeof(UsersController).GetTypeInfo().Assembly;
using (var avatarStream = assembly.GetManifestResourceStream("Squidex.Controllers.Api.Users.Assets.Avatar.png"))
{
AvatarBytes = new byte[avatarStream.Length];
avatarStream.Read(AvatarBytes, 0, AvatarBytes.Length);
}
}
public UsersController(UserManager userManager, IUserPictureStore userPictureStore)
{
this.userManager = userManager;
this.userPictureStore = userPictureStore;
}
///
/// Get users by query.
///
/// The query to search the user by email address. Case invariant.
///
/// Search the user by query that contains the email address or the part of the email address.
///
///
/// 200 => Users returned.
///
[Authorize]
[HttpGet]
[Route("users")]
[ProducesResponseType(typeof(UserDto[]), 200)]
public async Task GetUsers(string query)
{
var entities = await userManager.QueryByEmailAsync(query ?? string.Empty);
var models = entities.Select(x => SimpleMapper.Map(x, new UserDto { DisplayName = x.DisplayName(), PictureUrl = x.PictureUrl() })).ToArray();
return Ok(models);
}
///
/// Get user by id.
///
/// The id of the user (GUID).
///
/// 200 => User found.
/// 404 => User not found.
///
[Authorize]
[HttpGet]
[Route("users/{id}/")]
[ProducesResponseType(typeof(UserDto), 200)]
public async Task GetUser(string id)
{
var entity = await userManager.FindByIdAsync(id);
if (entity == null)
{
return NotFound();
}
var response = SimpleMapper.Map(entity, new UserDto { DisplayName = entity.DisplayName(), PictureUrl = entity.PictureUrl() });
return Ok(response);
}
///
/// Get user picture by id.
///
/// The id of the user (GUID).
///
/// 200 => User found and image or fallback returned.
/// 404 => User not found.
///
[HttpGet]
[Route("users/{id}/picture")]
[ProducesResponseType(200)]
public async Task GetUserPicture(string id)
{
var entity = await userManager.FindByIdAsync(id);
if (entity == null)
{
return NotFound();
}
try
{
if (entity.IsPictureUrlStored())
{
return new FileStreamResult(await userPictureStore.DownloadAsync(entity.Id), "image/png");
}
}
catch
{
return new FileStreamResult(new MemoryStream(AvatarBytes), "image/png");
}
using (var client = new HttpClient())
{
var url = entity.PictureNormalizedUrl();
if (!string.IsNullOrWhiteSpace(url))
{
var response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
return new FileStreamResult(await response.Content.ReadAsStreamAsync(), response.Content.Headers.ContentType.ToString());
}
}
}
return new FileStreamResult(new MemoryStream(AvatarBytes), "image/png");
}
}
}