// ========================================================================== // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex UG (haftungsbeschränkt) // All rights reserved. Licensed under the MIT license. // ========================================================================== using System; using System.IO; using System.Linq; using System.Net.Http; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Squidex.Areas.Api.Controllers.Users.Models; using Squidex.Domain.Users; using Squidex.Infrastructure.Commands; using Squidex.Infrastructure.Log; using Squidex.Shared.Users; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Users { /// /// Readonly API to retrieve information about squidex users. /// [ApiExplorerSettings(GroupName = nameof(Users))] public sealed class UsersController : ApiController { private static readonly byte[] AvatarBytes; private readonly IUserPictureStore userPictureStore; private readonly IUserResolver userResolver; private readonly ISemanticLog log; static UsersController() { var assembly = typeof(UsersController).Assembly; using (var avatarStream = assembly.GetManifestResourceStream("Squidex.Areas.Api.Controllers.Users.Assets.Avatar.png")) { AvatarBytes = new byte[avatarStream.Length]; avatarStream.Read(AvatarBytes, 0, AvatarBytes.Length); } } public UsersController( ICommandBus commandBus, IUserPictureStore userPictureStore, IUserResolver userResolver, ISemanticLog log) : base(commandBus) { this.userPictureStore = userPictureStore; this.userResolver = userResolver; this.log = log; } /// /// Get the user resources. /// /// /// 200 => User resources returned. /// [HttpGet] [Route("/")] [ProducesResponseType(typeof(ResourcesDto), 200)] [ApiPermission] public IActionResult GetUserResources() { var response = ResourcesDto.FromController(this); return Ok(response); } /// /// 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. /// [HttpGet] [Route("users/")] [ProducesResponseType(typeof(UserDto[]), 200)] [ApiPermission] public async Task GetUsers(string query) { try { var entities = await userResolver.QueryByEmailAsync(query); var response = entities.Where(x => !x.IsHidden()).Select(x => UserDto.FromUser(x, this)).ToArray(); return Ok(response); } catch (Exception ex) { log.LogError(ex, w => w .WriteProperty("action", nameof(GetUsers)) .WriteProperty("status", "Failed")); } return Ok(new UserDto[0]); } /// /// Get user by id. /// /// The id of the user (GUID). /// /// 200 => User found. /// 404 => User not found. /// [HttpGet] [Route("users/{id}/")] [ProducesResponseType(typeof(UserDto), 200)] [ApiPermission] public async Task GetUser(string id) { try { var entity = await userResolver.FindByIdOrEmailAsync(id); if (entity != null) { var response = UserDto.FromUser(entity, this); return Ok(response); } } catch (Exception ex) { log.LogError(ex, w => w .WriteProperty("action", nameof(GetUser)) .WriteProperty("status", "Failed")); } return NotFound(); } /// /// 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(typeof(FileResult), 200)] [ResponseCache(Duration = 300)] public async Task GetUserPicture(string id) { try { var entity = await userResolver.FindByIdOrEmailAsync(id); if (entity != null) { if (entity.IsPictureUrlStored()) { return new FileStreamResult(await userPictureStore.DownloadAsync(entity.Id), "image/png"); } using (var client = new HttpClient()) { var url = entity.PictureNormalizedUrl(); if (!string.IsNullOrWhiteSpace(url)) { var response = await client.GetAsync(url); if (response.IsSuccessStatusCode) { var contentType = response.Content.Headers.ContentType.ToString(); return new FileStreamResult(await response.Content.ReadAsStreamAsync(), contentType); } } } } } catch (Exception ex) { log.LogError(ex, w => w .WriteProperty("action", nameof(GetUser)) .WriteProperty("status", "Failed")); } return new FileStreamResult(new MemoryStream(AvatarBytes), "image/png"); } } }