You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Ombi/src/Ombi/Controllers/V1/IssuesController.cs

345 lines
13 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Ombi.Attributes;
using Ombi.Core;
using Ombi.Core.Notifications;
using Ombi.Helpers;
using Ombi.Models;
using Ombi.Notifications.Models;
using Ombi.Store.Entities;
using Ombi.Store.Entities.Requests;
using Ombi.Store.Repository;
namespace Ombi.Controllers.V1
{
[ApiV1]
[Authorize]
[Produces("application/json")]
[ApiController]
public class IssuesController : ControllerBase
{
public IssuesController(IRepository<IssueCategory> categories, IRepository<Issues> issues, IRepository<IssueComments> comments,
UserManager<OmbiUser> userManager, INotificationHelper notify)
{
_categories = categories;
_issues = issues;
_issueComments = comments;
_userManager = userManager;
_notification = notify;
}
private readonly IRepository<IssueCategory> _categories;
private readonly IRepository<Issues> _issues;
private readonly IRepository<IssueComments> _issueComments;
private readonly UserManager<OmbiUser> _userManager;
private readonly INotificationHelper _notification;
/// <summary>
/// Get's all categories
/// </summary>
/// <returns></returns>
[HttpGet("categories")]
public async Task<IEnumerable<IssueCategory>> Categories()
{
return await _categories.GetAll().ToListAsync();
}
/// <summary>
/// Creates a new category
/// </summary>
/// <param name="cat"></param>
/// <returns></returns>
[PowerUser]
[HttpPost("categories")]
public async Task<bool> CreateCategory([FromBody]IssueCategory cat)
{
var result = await _categories.Add(cat);
if (result.Id > 0)
{
return true;
}
return false;
}
/// <summary>
/// Deletes a Category
/// </summary>
/// <param name="catId"></param>
/// <returns></returns>
[PowerUser]
[HttpDelete("categories/{catId}")]
public async Task<bool> DeleteCategory([FromRoute]int catId)
{
var cat = await _categories.GetAll().FirstOrDefaultAsync(x => x.Id == catId);
await _categories.Delete(cat);
return true;
}
/// <summary>
/// Returns all the issues
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<IEnumerable<Issues>> GetIssues()
{
return await _issues.GetAll().Include(x => x.IssueCategory).ToListAsync();
}
/// <summary>
/// Returns all the issues
/// </summary>
/// <returns></returns>
[HttpGet("{take}/{skip}/{status}")]
public async Task<IEnumerable<Issues>> GetIssues(int take, int skip, IssueStatus status)
{
return await _issues
.GetAll()
.Where(x => x.Status == status)
.Include(x => x.IssueCategory)
.Include(x => x.UserReported)
.Skip(skip)
.Take(take)
.ToListAsync();
}
/// <summary>
/// Returns all the issues count
/// </summary>
/// <returns></returns>
[HttpGet("count")]
public async Task<IssueCountModel> GetIssueCount()
{
return new IssueCountModel
{
Pending = await _issues.GetAll().Where(x => x.Status == IssueStatus.Pending).CountAsync(),
InProgress = await _issues.GetAll().Where(x => x.Status == IssueStatus.InProgress).CountAsync(),
Resolved = await _issues.GetAll().Where(x => x.Status == IssueStatus.Resolved).CountAsync()
};
}
/// <summary>
/// Create Movie Issue
/// </summary>
[HttpPost]
public async Task<int> CreateIssue([FromBody]Issues i)
{
i.IssueCategory = null;
i.CreatedDate = DateTime.UtcNow;
var username = User.Identity.Name.ToUpper();
var reportedUser = await _userManager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username);
i.UserReportedId = reportedUser.Id;
await _issues.Add(i);
var category = await _categories.GetAll().FirstOrDefaultAsync(x => i.IssueCategoryId == x.Id);
if (category != null)
{
i.IssueCategory = category;
}
var notificationModel = new NotificationOptions
{
RequestId = i.RequestId ?? 0,
DateTime = DateTime.UtcNow,
NotificationType = NotificationType.Issue,
RequestType = i.RequestType,
Recipient = string.Empty,
AdditionalInformation = $"{i.Subject} | {i.Description}",
UserId = i.UserReportedId,
};
AddIssueNotificationSubstitutes(notificationModel, i, reportedUser.UserName, reportedUser.UserAlias);
await _notification.Notify(notificationModel);
return i.Id;
}
/// <summary>
/// Returns the issue by Id
/// </summary>
[HttpGet("{id}")]
public async Task<Issues> GetIssue([FromRoute] int id)
{
return await _issues.GetAll().Where(x => x.Id == id)
.Include(x => x.IssueCategory)
.Include(x => x.UserReported)
.FirstOrDefaultAsync();
}
[HttpGet("request/{id}")]
public async Task<IActionResult> GetIssueByRequestId([FromRoute] int id)
{
return new OkObjectResult(await _issues.GetAll().Where(x => x.RequestId == id)
.Include(x => x.IssueCategory)
.Include(x => x.UserReported).ToListAsync());
}
[HttpGet("provider/{id}")]
public async Task<IActionResult> GetIssueByProviderId([FromRoute] string id)
{
return new OkObjectResult(await _issues.GetAll().Where(x => x.ProviderId == id)
.Include(x => x.IssueCategory)
.Include(x => x.UserReported).ToListAsync());
}
/// <summary>
/// Get's all the issue comments by id
/// </summary>
[HttpGet("{id}/comments")]
public async Task<IEnumerable<IssueCommentChatViewModel>> GetComments([FromRoute]int id)
{
var comment = await _issueComments.GetAll().Where(x => x.IssuesId == id).Include(x => x.User).ToListAsync();
var vm = new List<IssueCommentChatViewModel>();
foreach (var c in comment)
{
var roles = await _userManager.GetRolesAsync(c.User);
vm.Add(new IssueCommentChatViewModel
{
Id = c.Id,
Comment = c.Comment,
Date = c.Date,
Username = c.User.UserAlias,
AdminComment = roles.Contains(OmbiRoles.PowerUser) || roles.Contains(OmbiRoles.Admin) || c.User.IsSystemUser
});
}
return vm;
}
/// <summary>
/// Adds a comment on an issue
/// </summary>
[HttpPost("comments")]
public async Task<IssueComments> AddComment([FromBody] NewIssueCommentViewModel comment)
{
var user = await _userManager.Users.Where(x => User.Identity.Name == x.UserName)
.FirstOrDefaultAsync();
var issue = await _issues.GetAll().Include(x => x.UserReported).Include(x => x.IssueCategory).FirstOrDefaultAsync(x => x.Id == comment.IssueId);
if (issue == null)
{
return null;
}
var newComment = new IssueComments
{
Comment = comment.Comment,
Date = DateTime.UtcNow,
UserId = user.Id,
IssuesId = comment.IssueId,
};
var notificationModel = new NotificationOptions
{
RequestId = issue.RequestId ?? 0,
DateTime = DateTime.Now,
NotificationType = NotificationType.IssueComment,
RequestType = issue.RequestType,
UserId = user.Id
};
var isAdmin = await _userManager.IsInRoleAsync(user, OmbiRoles.Admin) || user.IsSystemUser;
AddIssueNotificationSubstitutes(notificationModel, issue, user.UserName, user.UserAlias);
notificationModel.Substitutes.Add(NotificationSubstitues.NewIssueComment, comment.Comment);
notificationModel.Substitutes.Add(NotificationSubstitues.IssueId, comment.IssueId.ToString());
notificationModel.Substitutes.Add(NotificationSubstitues.AdminComment, isAdmin.ToString());
if (isAdmin)
{
// Send to user
notificationModel.Recipient = issue.UserReported.Email;
}
else
{
notificationModel.Recipient = user.Email;
}
await _notification.Notify(notificationModel);
return await _issueComments.Add(newComment);
}
/// <summary>
/// Deletes a comment on a issue
/// </summary>
[HttpDelete("comments/{id}")]
[PowerUser]
public async Task<bool> DeleteComment(int id)
{
var comment = await _issueComments.GetAll().FirstOrDefaultAsync(x => x.Id == id);
await _issueComments.Delete(comment);
return true;
}
[HttpDelete("{id}")]
[PowerUser]
public async Task<bool> DeleteIssue(int id)
{
var issue = await _issues.GetAll().Include(x => x.Comments).FirstOrDefaultAsync(x => x.Id == id);
await _issues.Delete(issue);
return true;
}
[HttpPost("status")]
public async Task<bool> UpdateStatus([FromBody] IssueStateViewModel model)
{
var username = User.Identity.Name.ToUpper();
var user = await _userManager.Users.Where(x => username == x.NormalizedUserName)
.FirstOrDefaultAsync();
var issue = await _issues.GetAll().Include(x => x.UserReported).Include(x => x.IssueCategory).FirstOrDefaultAsync(x => x.Id == model.IssueId);
if (issue == null)
{
return false;
}
issue.Status = model.Status;
if (model.Status == IssueStatus.Resolved)
{
issue.ResovledDate = DateTime.UtcNow;
}
await _issues.SaveChangesAsync();
if (issue.Status == IssueStatus.Resolved)
{
var notificationModel = new NotificationOptions
{
RequestId = 0,
DateTime = DateTime.Now,
NotificationType = NotificationType.IssueResolved,
RequestType = issue.RequestType,
Recipient = !string.IsNullOrEmpty(issue.UserReported?.Email)
? issue.UserReported.Email
: string.Empty,
AdditionalInformation = $"{issue.Subject} | {issue.Description}",
UserId = issue.UserReported.Id, // This is a resolved notification, so needs to go to the user who raised it
};
AddIssueNotificationSubstitutes(notificationModel, issue, issue.UserReported?.UserName ?? string.Empty, issue.UserReported.UserAlias);
await _notification.Notify(notificationModel);
}
return true;
}
private static void AddIssueNotificationSubstitutes(NotificationOptions notificationModel, Issues issue, string issueReportedUsername, string alias)
{
notificationModel.Substitutes.Add(NotificationSubstitues.Title, issue.Title);
notificationModel.Substitutes.Add(NotificationSubstitues.IssueDescription, issue.Description);
notificationModel.Substitutes.Add(NotificationSubstitues.IssueCategory, issue.IssueCategory?.Value);
notificationModel.Substitutes.Add(NotificationSubstitues.IssueStatus, issue.Status.ToString());
notificationModel.Substitutes.Add(NotificationSubstitues.IssueSubject, issue.Subject);
notificationModel.Substitutes.Add(NotificationSubstitues.IssueUser, issueReportedUsername);
notificationModel.Substitutes.Add(NotificationSubstitues.IssueUserAlias, alias);
notificationModel.Substitutes.Add(NotificationSubstitues.RequestType, notificationModel.RequestType.ToString());
notificationModel.Substitutes.Add(NotificationSubstitues.PosterPath, issue.PosterPath);
}
}
}