using AutoMapper; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.SelfService.Portal.Core.API.Context; using Microsoft.SelfService.Portal.Core.API.Dto.ConfigurationValue.Add; using Microsoft.SelfService.Portal.Core.API.Dto.ConfigurationValue.Get; using Microsoft.SelfService.Portal.Core.API.JsonDocuments; using Microsoft.SelfService.Portal.Core.API.Models; namespace Microsoft.SelfService.Portal.Core.API.Controllers { [Route("api/configuration-values")] [ApiController] public class ConfigurationValueController : Controller { private readonly DataContext _context; private readonly IMapper _mapper; public ConfigurationValueController(DataContext context, IMapper mapper) { _context = context; _mapper = mapper; } [HttpGet] [ProducesResponseType(200, Type = typeof(IEnumerable))] public IActionResult GetConfigurationValues([FromQuery] Guid? definitionId, [FromQuery] string? scopeType, [FromQuery] Guid? scopeId) { var query = _context.ConfigurationValues .AsNoTracking() .Include(value => value.ConfigurationDefinition) .AsQueryable(); if (definitionId.HasValue) query = query.Where(value => value.ConfigurationDefinitionId == definitionId.Value); if (!string.IsNullOrWhiteSpace(scopeType)) query = query.Where(value => value.ScopeType == scopeType); if (scopeId.HasValue) query = query.Where(value => value.ScopeId == scopeId.Value); var values = query .OrderBy(value => value.ScopeType) .ThenBy(value => value.SortOrder) .ThenBy(value => value.ConfigurationDefinition.Name) .ToList(); return Ok(_mapper.Map>(values)); } [HttpPost] [ProducesResponseType(200, Type = typeof(Guid))] [ProducesResponseType(400)] public IActionResult AddConfigurationValue([FromBody] AddConfigurationValueDto configurationValue) { if (configurationValue == null) return BadRequest(ModelState); if (!_context.ConfigurationDefinitions.Any(definition => definition.Id == configurationValue.ConfigurationDefinitionId)) { ModelState.AddModelError(nameof(configurationValue.ConfigurationDefinitionId), "Configuration definition was not found."); return BadRequest(ModelState); } if (!string.IsNullOrWhiteSpace(configurationValue.ValueJson)) { try { configurationValue.ValueJson = ConfigurationDocumentValidator.NormalizeAndValidate( configurationValue.ValueJson, ConfigurationDocumentKind.Metadata).JsonData; } catch (ConfigurationDocumentValidationException ex) { ModelState.AddModelError(nameof(configurationValue.ValueJson), ex.Message); return BadRequest(ModelState); } } var model = _mapper.Map(configurationValue); model.Id = Guid.NewGuid(); model.ValueHash = TemplateVersionModel.ComputeSha256(model.ValueJson ?? model.SourcePath ?? string.Empty); _context.ConfigurationValues.Add(model); _context.SaveChanges(); return Ok(model.Id); } [HttpDelete("{id}")] [ProducesResponseType(204)] [ProducesResponseType(404)] public IActionResult DeleteConfigurationValue(Guid id) { var value = _context.ConfigurationValues.FirstOrDefault(existing => existing.Id == id); if (value == null) return NotFound(); _context.ConfigurationValues.Remove(value); _context.SaveChanges(); return NoContent(); } } }