// ========================================================================== // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex UG (haftungsbeschränkt) // All rights reserved. Licensed under the MIT license. // ========================================================================== using System; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using NSwag.Annotations; using Squidex.Areas.Api.Controllers.Schemas.Models; using Squidex.Domain.Apps.Entities; using Squidex.Domain.Apps.Entities.Schemas; using Squidex.Domain.Apps.Entities.Schemas.Commands; using Squidex.Infrastructure.Commands; using Squidex.Pipeline; namespace Squidex.Areas.Api.Controllers.Schemas { /// /// Manages and retrieves information about schemas. /// [ApiAuthorize] [ApiExceptionFilter] [AppApi] [SwaggerTag(nameof(Schemas))] public sealed class SchemasController : ApiController { private readonly IAppProvider appProvider; public SchemasController(ICommandBus commandBus, IAppProvider appProvider) : base(commandBus) { this.appProvider = appProvider; } /// /// Get schemas. /// /// The name of the app to get the schemas for. /// /// 200 => Schemas returned. /// 404 => App not found. /// [MustBeAppEditor] [HttpGet] [Route("apps/{app}/schemas/")] [ProducesResponseType(typeof(SchemaDto[]), 200)] [ApiCosts(0)] public async Task GetSchemas(string app) { var schemas = await appProvider.GetSchemasAsync(AppId); var response = schemas.Select(SchemaDto.FromSchema).ToList(); return Ok(response); } /// /// Get a schema by name. /// /// The name of the app. /// The name of the schema to retrieve. /// /// 200 => Schema found. /// 404 => Schema or app not found. /// [MustBeAppEditor] [HttpGet] [Route("apps/{app}/schemas/{name}/")] [ProducesResponseType(typeof(SchemaDetailsDto[]), 200)] [ApiCosts(0)] public async Task GetSchema(string app, string name) { ISchemaEntity entity; if (Guid.TryParse(name, out var id)) { entity = await appProvider.GetSchemaAsync(AppId, id); } else { entity = await appProvider.GetSchemaAsync(AppId, name); } if (entity == null || entity.IsDeleted) { return NotFound(); } var response = SchemaDetailsDto.FromSchema(entity); Response.Headers["ETag"] = entity.Version.ToString(); return Ok(response); } /// /// Create a new schema. /// /// The name of the app. /// The schema object that needs to be added to the app. /// /// 201 => Schema created. /// 400 => Schema name or properties are not valid. /// 409 => Schema name already in use. /// [MustBeAppDeveloper] [HttpPost] [Route("apps/{app}/schemas/")] [ProducesResponseType(typeof(EntityCreatedDto), 201)] [ProducesResponseType(typeof(ErrorDto), 400)] [ProducesResponseType(typeof(ErrorDto), 409)] [ApiCosts(1)] public async Task PostSchema(string app, [FromBody] CreateSchemaDto request) { var command = request.ToCommand(); var context = await CommandBus.PublishAsync(command); var result = context.Result>(); var response = new EntityCreatedDto { Id = command.SchemaId.ToString(), Version = result.Version }; return CreatedAtAction(nameof(GetSchema), new { name = request.Name }, response); } /// /// Update a schema. /// /// The name of the app. /// The name of the schema. /// The schema object that needs to updated. /// /// 204 => Schema has been updated. /// 400 => Schema properties are not valid. /// 404 => Schema or app not found. /// [MustBeAppDeveloper] [HttpPut] [Route("apps/{app}/schemas/{name}/")] [ApiCosts(1)] public async Task PutSchema(string app, string name, [FromBody] UpdateSchemaDto request) { await CommandBus.PublishAsync(request.ToCommand()); return NoContent(); } /// /// Update a schema category. /// /// The name of the app. /// The name of the schema. /// The schema object that needs to updated. /// /// 204 => Schema has been updated. /// 400 => Schema properties are not valid. /// 404 => Schema or app not found. /// [MustBeAppDeveloper] [HttpPut] [Route("apps/{app}/schemas/{name}/category")] [ApiCosts(1)] public async Task PutCategory(string app, string name, [FromBody] ChangeCategoryDto request) { await CommandBus.PublishAsync(request.ToCommand()); return NoContent(); } /// /// Update the scripts of a schema. /// /// The name of the app. /// The name of the schema. /// The schema scripts object that needs to updated. /// /// 204 => Schema has been updated. /// 400 => Schema properties are not valid. /// 404 => Schema or app not found. /// [MustBeAppDeveloper] [HttpPut] [Route("apps/{app}/schemas/{name}/scripts/")] [ApiCosts(1)] public async Task PutSchemaScripts(string app, string name, [FromBody] ConfigureScriptsDto request) { await CommandBus.PublishAsync(request.ToCommand()); return NoContent(); } /// /// Publish a schema. /// /// The name of the app. /// The name of the schema to publish. /// /// 204 => Schema has been published. /// 400 => Schema is already published. /// 404 => Schema or app not found. /// [MustBeAppDeveloper] [HttpPut] [Route("apps/{app}/schemas/{name}/publish/")] [ProducesResponseType(typeof(ErrorDto), 400)] [ApiCosts(1)] public async Task PublishSchema(string app, string name) { await CommandBus.PublishAsync(new PublishSchema()); return NoContent(); } /// /// Unpublish a schema. /// /// The name of the app. /// The name of the schema to unpublish. /// /// 204 => Schema has been unpublished. /// 400 => Schema is not published. /// 404 => Schema or app not found. /// [MustBeAppDeveloper] [HttpPut] [Route("apps/{app}/schemas/{name}/unpublish/")] [ProducesResponseType(typeof(ErrorDto), 400)] [ApiCosts(1)] public async Task UnpublishSchema(string app, string name) { await CommandBus.PublishAsync(new UnpublishSchema()); return NoContent(); } /// /// Delete a schema. /// /// The name of the app. /// The name of the schema to delete. /// /// 204 => Schema has been deleted. /// 404 => Schema or app not found. /// [MustBeAppDeveloper] [HttpDelete] [Route("apps/{app}/schemas/{name}/")] [ApiCosts(1)] public async Task DeleteSchema(string app, string name) { await CommandBus.PublishAsync(new DeleteSchema()); return NoContent(); } } }