using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; using Microsoft.EntityFrameworkCore; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using Sockeye.Models; using Sockeye.Api.ControllerHelpers; using Sockeye.Biz; namespace Sockeye.Api.Controllers { [ApiController] [ApiVersion("8.0")] [Route("api/v{version:apiVersion}/memo")] [Produces("application/json")] [Authorize] public class MemoController : ControllerBase { private readonly AyContext ct; private readonly ILogger log; private readonly ApiServerState serverState; /// /// ctor /// /// /// /// public MemoController(AyContext dbcontext, ILogger logger, ApiServerState apiServerState) { ct = dbcontext; log = logger; serverState = apiServerState; } /// /// Create Memo /// /// /// From route path /// [HttpPost] public async Task PostMemo([FromBody] SendMemo newObject, ApiVersion apiVersion) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); MemoBiz biz = MemoBiz.GetBiz(ct, HttpContext); if (!Authorized.HasCreateRole(HttpContext.Items, biz.BizType)) return StatusCode(403, new ApiNotAuthorizedResponse()); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); var RouteUserId = UserIdFromContext.Id(HttpContext.Items); //v8 migrate hacky workaround to allow specifying toid //-7 to id means it's migrating from v7 so treat as a single object if (newObject.Users.Count == 1 && newObject.Users[0] == -7 && RouteUserId == 1) { Memo newMemo = new Memo(); Sockeye.Util.CopyObject.Copy(newObject.Memo, newMemo); // newMemo.ToId = newObject.Memo.ToId; // newMemo.FromId = newObject.Memo.FromId; Memo o = await biz.CreateAsync(newMemo); if (o == null) return BadRequest(new ApiErrorResponse(biz.Errors)); return Ok(ApiOkResponse.Response(new { Id = o.Id }));//v8 migrate needs to id number to fixup the log post migrate } else { foreach (long lUserId in newObject.Users) { Memo newMemo = new Memo(); Sockeye.Util.CopyObject.Copy(newObject.Memo, newMemo); newMemo.ToId = lUserId; newMemo.FromId = RouteUserId; Memo o = await biz.CreateAsync(newMemo); if (o == null) return BadRequest(new ApiErrorResponse(biz.Errors)); } //return nothing but ok return Accepted(); } } public class SendMemo { public SendMemo() { Users = new List(); } [Required] public Memo Memo { get; set; } [Required] public List Users { get; set; } } //------------ //NO DUPLICATING MEMOS // /// // /// Duplicate Memo // /// (Wiki and Attachments are not duplicated) // /// // /// Source object id // /// From route path // /// Memo // [HttpPost("duplicate/{id}")] // public async Task DuplicateMemo([FromRoute] long id, ApiVersion apiVersion) // { // if (!serverState.IsOpen) // return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); // MemoBiz biz = MemoBiz.GetBiz(ct, HttpContext); // if (!Authorized.HasCreateRole(HttpContext.Items, biz.BizType)) // return StatusCode(403, new ApiNotAuthorizedResponse()); // if (!ModelState.IsValid) // return BadRequest(new ApiErrorResponse(ModelState)); // Memo o = await biz.DuplicateAsync(id); // if (o == null) // return BadRequest(new ApiErrorResponse(biz.Errors)); // else // return CreatedAtAction(nameof(MemoController.GetMemo), new { id = o.Id, version = apiVersion.ToString() }, new ApiCreatedResponse(o)); // } /// /// Get Memo /// /// /// Memo [HttpGet("{id}")] public async Task GetMemo([FromRoute] long id) { //NOTE: In this case always getting own memo only //also it's always just for read only purposes so it should include from user name if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); MemoBiz biz = MemoBiz.GetBiz(ct, HttpContext); if (!Authorized.HasReadFullRole(HttpContext.Items, biz.BizType)) return StatusCode(403, new ApiNotAuthorizedResponse()); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); var o = await biz.GetAsync(id); if (o == null) return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); var fromUser = await ct.User.AsNoTracking().SingleOrDefaultAsync(z => z.Id == o.FromId); var from = "??"; if (fromUser != null) from = fromUser.Name; var ret = new { Id = o.Id, Name = o.Name, Notes = o.Notes, Wiki = o.Wiki, CustomFields = o.CustomFields, Tags = o.Tags, Viewed = o.Viewed, Replied = o.Replied, FromId = o.FromId, ToId = o.ToId, Sent = o.Sent, FromName = from }; return Ok(ApiOkResponse.Response(ret)); } //NO UPDATING MEMOS // /// // /// Update Memo // /// // /// // /// // [HttpPut] // public async Task PutMemo([FromBody] Memo updatedObject) // { // if (!serverState.IsOpen) // return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); // if (!ModelState.IsValid) // return BadRequest(new ApiErrorResponse(ModelState)); // MemoBiz biz = MemoBiz.GetBiz(ct, HttpContext); // if (!Authorized.HasModifyRole(HttpContext.Items, biz.BizType)) // return StatusCode(403, new ApiNotAuthorizedResponse()); // var o = await biz.PutAsync(updatedObject); // if (o == null) // { // if (biz.Errors.Exists(z => z.Code == ApiErrorCode.CONCURRENCY_CONFLICT)) // return StatusCode(409, new ApiErrorResponse(biz.Errors)); // else // return BadRequest(new ApiErrorResponse(biz.Errors)); // } // return Ok(ApiOkResponse.Response(new { Concurrency = o.Concurrency }));; // } /// /// Delete Memo /// /// /// NoContent [HttpDelete("{id}")] public async Task DeleteMemo([FromRoute] long id) { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); MemoBiz biz = MemoBiz.GetBiz(ct, HttpContext); if (!Authorized.HasDeleteRole(HttpContext.Items, biz.BizType)) return StatusCode(403, new ApiNotAuthorizedResponse()); if (!await biz.DeleteAsync(id)) return BadRequest(new ApiErrorResponse(biz.Errors)); return NoContent(); } //------------ }//eoc }//eons