diff --git a/src/Squidex.Domain.Apps.Core.Model/Apps/AppPattern.cs b/src/Squidex.Domain.Apps.Core.Model/Apps/AppPattern.cs index a893f5f8e..cfd0e6e8e 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Apps/AppPattern.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Apps/AppPattern.cs @@ -6,23 +6,16 @@ // All rights reserved. // ========================================================================== -using System; using System.Diagnostics.Contracts; using Squidex.Infrastructure; namespace Squidex.Domain.Apps.Core.Apps { - public class AppPattern + public sealed class AppPattern { - private readonly Guid id; private readonly string name; private readonly string pattern; - private readonly string defaultMessage; - - public Guid Id - { - get { return id; } - } + private readonly string message; public string Name { @@ -34,29 +27,25 @@ namespace Squidex.Domain.Apps.Core.Apps get { return pattern; } } - public string DefaultMessage + public string Message { - get { return defaultMessage; } + get { return message; } } - public AppPattern(Guid id, string name, string pattern, string defaultMessage) + public AppPattern(string name, string pattern, string message) { Guard.NotNullOrEmpty(name, nameof(name)); Guard.NotNullOrEmpty(pattern, nameof(pattern)); - this.id = id; this.name = name; this.pattern = pattern; - this.defaultMessage = defaultMessage; + this.message = message; } [Pure] public AppPattern Update(string name, string pattern, string defaultMessage) { - Guard.NotNullOrEmpty(name, nameof(name)); - Guard.NotNullOrEmpty(pattern, nameof(pattern)); - - return new AppPattern(this.id, name, pattern, defaultMessage); + return new AppPattern(name, pattern, defaultMessage); } } } diff --git a/src/Squidex.Domain.Apps.Core.Model/Apps/AppPatterns.cs b/src/Squidex.Domain.Apps.Core.Model/Apps/AppPatterns.cs index 465c2cf67..459ecc4a6 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Apps/AppPatterns.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Apps/AppPatterns.cs @@ -27,9 +27,9 @@ namespace Squidex.Domain.Apps.Core.Apps } [Pure] - public AppPatterns Add(Guid id, string name, string pattern, string defaultMessage) + public AppPatterns Add(Guid id, string name, string pattern, string message) { - var newPattern = new AppPattern(id, name, pattern, defaultMessage); + var newPattern = new AppPattern(name, pattern, message); return new AppPatterns(Inner.Add(id, newPattern)); } @@ -41,7 +41,7 @@ namespace Squidex.Domain.Apps.Core.Apps } [Pure] - public AppPatterns Update(Guid id, string name, string pattern, string defaultMessage) + public AppPatterns Update(Guid id, string name, string pattern, string message) { Guard.NotNullOrEmpty(name, nameof(name)); Guard.NotNullOrEmpty(pattern, nameof(pattern)); @@ -51,7 +51,7 @@ namespace Squidex.Domain.Apps.Core.Apps return this; } - return new AppPatterns(Inner.SetItem(id, appPattern.Update(name, pattern, defaultMessage))); + return new AppPatterns(Inner.SetItem(id, appPattern.Update(name, pattern, message))); } } } diff --git a/src/Squidex.Domain.Apps.Core.Model/Apps/Json/JsonAppPattern.cs b/src/Squidex.Domain.Apps.Core.Model/Apps/Json/JsonAppPattern.cs index 4b30d9e15..9c52a8198 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Apps/Json/JsonAppPattern.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Apps/Json/JsonAppPattern.cs @@ -23,7 +23,7 @@ namespace Squidex.Domain.Apps.Core.Apps.Json public string Pattern { get; set; } [JsonProperty] - public string DefaultMessage { get; set; } + public string Message { get; set; } public JsonAppPattern() { @@ -36,7 +36,7 @@ namespace Squidex.Domain.Apps.Core.Apps.Json public AppPattern ToPattern() { - return new AppPattern(Id, Name, Pattern, DefaultMessage); + return new AppPattern(Name, Pattern, Message); } } } diff --git a/src/Squidex.Domain.Apps.Entities/Apps/Commands/AddPattern.cs b/src/Squidex.Domain.Apps.Entities/Apps/Commands/AddPattern.cs index 7432c4d81..12df12042 100644 --- a/src/Squidex.Domain.Apps.Entities/Apps/Commands/AddPattern.cs +++ b/src/Squidex.Domain.Apps.Entities/Apps/Commands/AddPattern.cs @@ -18,7 +18,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Commands public string Pattern { get; set; } - public string DefaultMessage { get; set; } + public string Message { get; set; } public AddPattern() { diff --git a/src/Squidex.Domain.Apps.Entities/Apps/Commands/UpdatePattern.cs b/src/Squidex.Domain.Apps.Entities/Apps/Commands/UpdatePattern.cs index 20a436ba3..da4b7f097 100644 --- a/src/Squidex.Domain.Apps.Entities/Apps/Commands/UpdatePattern.cs +++ b/src/Squidex.Domain.Apps.Entities/Apps/Commands/UpdatePattern.cs @@ -18,6 +18,6 @@ namespace Squidex.Domain.Apps.Entities.Apps.Commands public string Pattern { get; set; } - public string DefaultMessage { get; set; } + public string Message { get; set; } } } diff --git a/src/Squidex.Domain.Apps.Entities/Apps/State/AppState.cs b/src/Squidex.Domain.Apps.Entities/Apps/State/AppState.cs index 917140969..b44ca76bf 100644 --- a/src/Squidex.Domain.Apps.Entities/Apps/State/AppState.cs +++ b/src/Squidex.Domain.Apps.Entities/Apps/State/AppState.cs @@ -82,7 +82,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.State protected void On(AppPatternAdded @event) { - Patterns = Patterns.Add(@event.Id, @event.Name, @event.Pattern, @event.DefaultMessage); + Patterns = Patterns.Add(@event.Id, @event.Name, @event.Pattern, @event.Message); } protected void On(AppPatternDeleted @event) @@ -92,7 +92,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.State protected void On(AppPatternUpdated @event) { - Patterns = Patterns.Update(@event.Id, @event.Name, @event.Pattern, @event.DefaultMessage); + Patterns = Patterns.Update(@event.Id, @event.Name, @event.Pattern, @event.Message); } protected void On(AppLanguageAdded @event) diff --git a/src/Squidex.Domain.Apps.Events/Apps/AppPatternAdded.cs b/src/Squidex.Domain.Apps.Events/Apps/AppPatternAdded.cs index bbd6fd0be..dd37f4ec7 100644 --- a/src/Squidex.Domain.Apps.Events/Apps/AppPatternAdded.cs +++ b/src/Squidex.Domain.Apps.Events/Apps/AppPatternAdded.cs @@ -20,6 +20,6 @@ namespace Squidex.Domain.Apps.Events.Apps public string Pattern { get; set; } - public string DefaultMessage { get; set; } + public string Message { get; set; } } } diff --git a/src/Squidex.Domain.Apps.Events/Apps/AppPatternUpdated.cs b/src/Squidex.Domain.Apps.Events/Apps/AppPatternUpdated.cs index 1f5908b87..c24da6327 100644 --- a/src/Squidex.Domain.Apps.Events/Apps/AppPatternUpdated.cs +++ b/src/Squidex.Domain.Apps.Events/Apps/AppPatternUpdated.cs @@ -20,6 +20,6 @@ namespace Squidex.Domain.Apps.Events.Apps public string Pattern { get; set; } - public string DefaultMessage { get; set; } + public string Message { get; set; } } } diff --git a/src/Squidex/Areas/Api/Controllers/Apps/AppPatternsController.cs b/src/Squidex/Areas/Api/Controllers/Apps/AppPatternsController.cs new file mode 100644 index 000000000..934a07ce5 --- /dev/null +++ b/src/Squidex/Areas/Api/Controllers/Apps/AppPatternsController.cs @@ -0,0 +1,127 @@ +// ========================================================================== +// AppPatternsController.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using NSwag.Annotations; +using Squidex.Areas.Api.Controllers.Apps.Models; +using Squidex.Domain.Apps.Entities.Apps.Commands; +using Squidex.Infrastructure.Commands; +using Squidex.Infrastructure.Reflection; +using Squidex.Pipeline; + +namespace Squidex.Areas.Api.Controllers.Apps +{ + /// + /// Manages and configures app patterns. + /// + [ApiAuthorize] + [MustBeAppDeveloper] + [ApiExceptionFilter] + [AppApi] + [SwaggerTag(nameof(Apps))] + public sealed class AppPatternsController : ApiController + { + public AppPatternsController(ICommandBus commandBus) + : base(commandBus) + { + } + + /// + /// Get app patterns. + /// + /// The name of the app. + /// + /// 200 => Patterns returned. + /// 404 => App not found. + /// + /// + /// Gets all configured regex patterns for the app with the specified name. + /// + [HttpGet] + [Route("apps/{app}/patterns/")] + [ProducesResponseType(typeof(AppPatternDto[]), 200)] + [ApiCosts(1)] + public IActionResult GetPatterns(string app) + { + var response = + App.Patterns.Select(x => SimpleMapper.Map(x.Value, new AppPatternDto { Id = x.Key })).OrderBy(x => x.Name).ToList(); + + return Ok(response); + } + + /// + /// Create a new app patterm. + /// + /// The name of the app. + /// Pattern to be added to the app. + /// + /// 201 => Pattern generated. + /// 404 => App not found. + /// + [HttpPost] + [Route("apps/{app}/patterns/")] + [ProducesResponseType(typeof(AppPatternDto), 201)] + [ApiCosts(1)] + public async Task PostPattern(string app, [FromBody] UpdatePatternDto request) + { + var command = SimpleMapper.Map(request, new AddPattern()); + + await CommandBus.PublishAsync(command); + + return CreatedAtAction(nameof(GetPatterns), new { app }, request); + } + + /// + /// Update an existing app patterm. + /// + /// The name of the app. + /// The id of the pattern to be updated. + /// Pattern to be updated for the app. + /// + /// 204 => Pattern updated. + /// 404 => App not found or pattern not found. + /// + [HttpPut] + [Route("apps/{app}/patterns/{name}")] + [ProducesResponseType(typeof(AppPatternDto), 201)] + [ApiCosts(1)] + public async Task UpdatePattern(string app, Guid id, [FromBody] UpdatePatternDto request) + { + var command = SimpleMapper.Map(request, new UpdatePattern { Id = id }); + + await CommandBus.PublishAsync(command); + + return NoContent(); + } + + /// + /// Revoke an app client + /// + /// The name of the app. + /// The id of the pattern to be deleted. + /// + /// 204 => Pattern removed. + /// 404 => App or pattern not found. + /// + /// + /// Schemas using this pattern will still function using the same Regular Expression + /// + [HttpDelete] + [Route("apps/{app}/patterns/{id}/")] + [ApiCosts(1)] + public async Task DeletePattern(string app, Guid id) + { + await CommandBus.PublishAsync(new DeletePattern { Id = id }); + + return NoContent(); + } + } +} diff --git a/src/Squidex/Areas/Api/Controllers/Apps/Models/AppPatternDto.cs b/src/Squidex/Areas/Api/Controllers/Apps/Models/AppPatternDto.cs new file mode 100644 index 000000000..9fb65d14d --- /dev/null +++ b/src/Squidex/Areas/Api/Controllers/Apps/Models/AppPatternDto.cs @@ -0,0 +1,38 @@ +// ========================================================================== +// AppPatternDto.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using System.ComponentModel.DataAnnotations; + +namespace Squidex.Areas.Api.Controllers.Apps.Models +{ + public sealed class AppPatternDto + { + /// + /// Identifier for Pattern + /// + public Guid Id { get; set; } + + /// + /// The name of the suggestion. + /// + [Required] + public string Name { get; set; } + + /// + /// The regex pattern. + /// + [Required] + public string Pattern { get; set; } + + /// + /// The regex message. + /// + public string Message { get; set; } + } +} diff --git a/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdatePatternDto.cs b/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdatePatternDto.cs new file mode 100644 index 000000000..89506dfcc --- /dev/null +++ b/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdatePatternDto.cs @@ -0,0 +1,32 @@ +// ========================================================================== +// AddPatternDto.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.ComponentModel.DataAnnotations; + +namespace Squidex.Areas.Api.Controllers.Apps.Models +{ + public class UpdatePatternDto + { + /// + /// The name of the suggestion. + /// + [Required] + public string Name { get; set; } + + /// + /// The regex pattern. + /// + [Required] + public string Pattern { get; set; } + + /// + /// The regex message. + /// + public string Message { get; set; } + } +} diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppDomainObjectTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppDomainObjectTests.cs index 65bc15461..d192ed65f 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppDomainObjectTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppDomainObjectTests.cs @@ -293,13 +293,13 @@ namespace Squidex.Domain.Apps.Entities.Apps { CreateApp(); - sut.AddPattern(CreateCommand(new AddPattern { Id = patternId, Name = "Any", Pattern = ".*", DefaultMessage = "Msg" })); + sut.AddPattern(CreateCommand(new AddPattern { Id = patternId, Name = "Any", Pattern = ".*", Message = "Msg" })); Assert.Single(sut.State.Patterns); sut.GetUncomittedEvents() .ShouldHaveSameEvents( - CreateEvent(new AppPatternAdded { Id = patternId, Name = "Any", Pattern = ".*", DefaultMessage = "Msg" }) + CreateEvent(new AppPatternAdded { Id = patternId, Name = "Any", Pattern = ".*", Message = "Msg" }) ); } @@ -343,13 +343,13 @@ namespace Squidex.Domain.Apps.Entities.Apps CreateApp(); CreatePattern(); - sut.UpdatePattern(CreateCommand(new UpdatePattern { Id = patternId, Name = "Any", Pattern = ".*", DefaultMessage = "Msg" })); + sut.UpdatePattern(CreateCommand(new UpdatePattern { Id = patternId, Name = "Any", Pattern = ".*", Message = "Msg" })); Assert.Single(sut.State.Patterns); sut.GetUncomittedEvents() .ShouldHaveSameEvents( - CreateEvent(new AppPatternUpdated { Id = patternId, Name = "Any", Pattern = ".*", DefaultMessage = "Msg" }) + CreateEvent(new AppPatternUpdated { Id = patternId, Name = "Any", Pattern = ".*", Message = "Msg" }) ); }