feat: Implement API client and token models with hashing and JWT authentication
- Added ApiClientModel and ApiTokenModel for managing API clients and tokens. - Introduced ConfigurationDefinitionModel and ConfigurationValueModel for configuration management. - Created CredentialSecretModel for storing credential secrets. - Developed DeploymentArtifactModel and DeploymentBatchModel for deployment management. - Enhanced DeploymentTargetModel and DeploymentTemplateSelectionModel to support template revisions. - Added TemplateRevisionModel and TemplateVersionModel for versioning templates. - Implemented ApiClientSecretHasher for secure secret hashing. - Created ApiTokenService for generating and validating JWT tokens. - Updated QueueJobService to handle deployment requests with artifacts. - Configured authentication settings in appsettings.json for JWT and Negotiate authentication.
This commit is contained in:
106
Controllers/ConfigurationValueController.cs
Normal file
106
Controllers/ConfigurationValueController.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
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<GetConfigurationValueDto>))]
|
||||
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<List<GetConfigurationValueDto>>(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<ConfigurationValueModel>(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user