using KTUSAPS.Auth; using KTUSAPS.Data.Model; using KTUSAPS.Extensions; using KTUSAPS.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace KTUSAPS.Controllers { [Route("api/[controller]")] [ApiController] public class IssuesController : ControllerBase { private readonly Data.SAPSDataContext dataContext; private readonly IAuthorizationService _authorizationService; public IssuesController(Data.SAPSDataContext dataContext, IAuthorizationService authorizationService) { this.dataContext = dataContext; _authorizationService = authorizationService; } [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] [Authorize] public async Task>> GetIssues([FromQuery] RequestScope requestScope = RequestScope.All) { if (requestScope == RequestScope.All) { var authorizationResult = await _authorizationService.AuthorizeAsync(User, "admin"); if (!authorizationResult.Succeeded) return Forbid(); return await dataContext.Issues.ToListAsync(); } else if (requestScope == RequestScope.My) return await dataContext.Issues.Where(i => i.UserID == User.GetUserId()).ToListAsync(); throw new NotImplementedException(); } [HttpPost] [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [Authorize] public async Task> CreateIssueAsync([FromBody] Issue issueToCreate) { if (issueToCreate == null) return BadRequest("No data provided for object to be created."); if (issueToCreate.Id != default) return BadRequest("Id has been set on create request, please do not do that, set id to 0 or ommit it."); if (issueToCreate.IssueTypeId == default) return BadRequest("No typeId has been specified"); if (issueToCreate.Problem != null && issueToCreate.Feedback != null && issueToCreate.IssueType != null) return BadRequest("Do not privide navigation property values."); if (issueToCreate.UserID != default || issueToCreate.Email != default) return BadRequest("Do not provide indentity values."); issueToCreate.UserID = User.GetUserId(); issueToCreate.Email = User.GetEmail(); var createdValue = await dataContext.AddAsync(issueToCreate); await dataContext.SaveChangesAsync(); return CreatedAtAction(nameof(GetIssue), new { Id = createdValue.Entity.Id }, createdValue.Entity); } [HttpGet("{id}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize] public async Task> GetIssue(int id) { var issue = dataContext.Issues.AsQueryable().Where(i => i.Id == id).FirstOrDefault(); if(issue == default) return NotFound(); var authorizationResult = await _authorizationService.AuthorizeAsync(User, issue, new MyIssueRequirement()); if(authorizationResult.Succeeded) return Ok(issue); return Forbid(); } [HttpPatch("{id}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize("admin")] public async Task> UpdateIssueAsync(int id, [FromBody] Issue issue) { var databaseIssue = dataContext.Issues.AsQueryable().Where(i => i.Id == id).FirstOrDefault(); if (databaseIssue == default) return NotFound(); var eIssue = dataContext.Attach(databaseIssue); eIssue.MovePropertyDataWhiteList(issue, new string[] { nameof(databaseIssue.Description), nameof(databaseIssue.IssueTypeId), nameof(databaseIssue.Publishable) }); await dataContext.SaveChangesAsync(); return Ok(eIssue.Entity); } [HttpDelete("{id}")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize("admin")] public async Task DeleteIssueAsync(int id) { var issue = dataContext.Issues.AsQueryable().Where(i => i.Id == id).FirstOrDefault(); if (issue == default) return NotFound(); dataContext.Issues.Remove(issue); await dataContext.SaveChangesAsync(); return NoContent(); } } }