using System; using AutoMapper; using gehGassi.Core.Interfaces; using gehGassi.Permissions; using gehGassi.Web.Auth.Attributes; using gehGassi.Web.Auth; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Localization; using gehGassi.Common.Data; using gehGassi.Core.Services; using gehGassi.Domain.Common; using System.Collections.Generic; using System.Linq; using gehGassi.Web.Helper; using gehGassi.Web.Models; using System.Threading.Tasks; using gehGassi.External.Services; using gehGassi.Domain.Dogs; using System.Text.Json; using gehGassi.Domain.Walks; namespace gehGassi.Web.Controllers { /// /// Controller für die Verwaltung von Meldungen von Verstößen gegen die Nutzungsbedingungen /// [Authorize] public class AppUserReportController : BaseController { private readonly IMapper _mapper; private readonly IStringLocalizer _localizer; private readonly IAppUserReportService _appUserReportService; private readonly IAppUserService _appUserService; private readonly IPublicWalkRequestService _publicWalkRequestService; private readonly IDogService _dogService; private readonly IWalkService _walkService; private readonly IRatingService _ratingService; private readonly IPublicWalkResponseService _publicWalkResponseService; /// /// Erstellt eine Instanz /// /// Instanz eines IMapper /// Instanz eines IStringLocalizer /// Instanz eines IAppUserReportService /// Instanz eines IAppUserService /// Instanz eines IPublicWalkRequestService /// Instanz eines IDogService /// Instanz eines IWalkService /// Instanz eines IRatingService /// Instanz eines IPublicWalkResponseService public AppUserReportController(IMapper mapper, IStringLocalizer localizer, IAppUserReportService appUserReportService, IAppUserService appUserService, IPublicWalkRequestService publicWalkRequestService, IDogService dogService, IWalkService walkService, IRatingService ratingService, IPublicWalkResponseService publicWalkResponseService) { _mapper = mapper; _localizer = localizer; _appUserReportService = appUserReportService; _appUserService = appUserService; _publicWalkRequestService = publicWalkRequestService; _dogService = dogService; _walkService = walkService; _ratingService = ratingService; _publicWalkResponseService = publicWalkResponseService; } /// /// Gibt einen View für die Verwaltung von Meldungen zurück /// /// View [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUserReports)] public IActionResult Index() { return View(); } /// /// Gibt eine Liste von Entitäten basierend auf Abfragekriterien zurück /// /// Abfragekriterien /// Liste von gefundenen Entitäten [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUserReports)] [HttpPost] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult GetReports([FromBody] DataManager dm) { if (dm != null) { var propList = new List(); dm.SetComplexProperties(propList); if (dm.Where != null) { foreach (var whereFilter in dm.Where) { if (whereFilter.predicates == null) continue; foreach (var whereFilterPredicate in whereFilter.predicates) { if (whereFilterPredicate.Field == "status") whereFilterPredicate.value = (AppUserReportStatus)((int)((long)whereFilterPredicate.value)); if (whereFilterPredicate.Field == "section") whereFilterPredicate.value = (AppUserReportSection)((int)((long)whereFilterPredicate.value)); if (whereFilterPredicate.Field == "type") whereFilterPredicate.value = (AppUserReportType)((int)((long)whereFilterPredicate.value)); if (whereFilterPredicate.Field == "blockType") whereFilterPredicate.value = (AppUserReportBlockType)((int)((long)whereFilterPredicate.value)); } } } } var resultList = _appUserReportService.FilterWithNames(dm?.SearchValue ?? ""); //Sortierung resultList = dm.ApplySorting(resultList); //Filter resultList = dm.ApplyFiltering(resultList, out var countFiltered); //Paging resultList = dm.ApplyPaging(resultList); var resultListVm = resultList.ToList().Select(item => _mapper.Map(item)).ToList(); foreach (var itemVm in resultListVm) { itemVm.ReportingAppUserTypeText = itemVm.ReportingAppUserType.GetDisplayName(AnnotationsLocalizer); itemVm.ReportedAppUserTypeText = itemVm.ReportedAppUserType.GetDisplayName(AnnotationsLocalizer); itemVm.StatusText = itemVm.Status.GetDisplayName(AnnotationsLocalizer); itemVm.SectionText = itemVm.Section.GetDisplayName(AnnotationsLocalizer); itemVm.TypeText = itemVm.Type.GetDisplayName(AnnotationsLocalizer); itemVm.BlockTypeText = itemVm.BlockType.GetDisplayName(AnnotationsLocalizer); } //FilterPreview? if (!dm.RequiresCounts) return Json(resultListVm); return Json(new { result = resultListVm, count = countFiltered }); } /// /// Details einer Meldung /// /// Id der Meldung /// PartialView [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUserReports)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public async Task Details(long id) { var item = await _appUserReportService.GetAsync(id); if (item != null) { var reportingUser = await _appUserService.GetAsync(item.ReportingAppUserId); var reportedUser = await _appUserService.GetAsync(item.ReportedAppUserId); var reportingCount = await _appUserReportService.CountReportingAsync(item.ReportingAppUserId); var reportedCount = await _appUserReportService.CountReportedAsync(item.ReportedAppUserId); var model = new AppUserReportDetailVm { Report = _mapper.Map(item), ReportingUser = _mapper.Map(reportingUser), ReportingCount = reportingCount, ReportedUser = _mapper.Map(reportedUser), ReportedCount = reportedCount }; return PartialView("_Details", model); } return PartialView("_Error"); } /// /// Aktualisieren des Status einer Meldung /// /// model /// JSON [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUserReports)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] [HttpPost] public async Task UpdateStatus(AppUserReportUpdateStatusVm model) { var result = new ResponseVm() { Success = false, Html = string.Empty }; if (ModelState.IsValid) { var item = await _appUserReportService.GetAsync(model.Id); if (item != null) { item.Status = (AppUserReportStatus)model.Status; item.InternalComment = model.InternalComment; item.UpdatedBy = User.Identity.Name; item.Updated = DateTimeOffset.UtcNow; await _appUserReportService.CommitAsync(User.Identity.Name); result.Success = true; } } return Json(result); } /// /// Gibt eine View mit dem beanstandeten Inhalt zurück /// Dies hängt vom Report, der Section und den beiden Section-Id´s ab /// /// Id der Medlung /// PartialView [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUserReports)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] [HttpGet] public async Task ShowContent(long id) { var result = new AppUserReportResponseVm { Success = false }; var item = await _appUserReportService.GetAsync(id); if (item != null) { if (item.Section == AppUserReportSection.HomeDogOwner || item.Section == AppUserReportSection.WalkersSearch || item.Section == AppUserReportSection.ProfileWalker) { return await ShowAppUser(item.ReportedAppUserId); } else if (item.Section == AppUserReportSection.HomeWalker || item.Section == AppUserReportSection.JobsSearch || item.Section == AppUserReportSection.OpenRequestWalker) { return await ShowOpenRequest(item.SectionId); } else if (item.Section == AppUserReportSection.ProfileDog) { return await ShowDogProfile(item.SectionId); } else if (item.Section == AppUserReportSection.ProfileDogOwner) { return await ShowDogOwnerProfile(item.SectionId); } else if (item.Section == AppUserReportSection.WalkDetailsWalker) { return await ShowWalkWalker(item.SectionId); } else if (item.Section == AppUserReportSection.WalkDetailDogOwner) { return await ShowWalkDogOwner(item.SectionId); } else if (item.Section == AppUserReportSection.RatingsMy || item.Section == AppUserReportSection.RatingsDog || item.Section == AppUserReportSection.RatingsDogOwner || item.Section == AppUserReportSection.RatingsWalker) { return await ShowRating(item.SectionId); } else if (item.Section == AppUserReportSection.OpenRequestResponse) { return await ShowOpenRequestResponse(item.ReportingAppUserId, item.SectionId); } else if (item.Section == AppUserReportSection.Messages) { return await ShowMessage(item.ReportedAppUserId, item.Message); } else if (item.Section == AppUserReportSection.Conversations) { if (string.IsNullOrWhiteSpace(item.Message)) item.Message = "Keine Zusarzinformationen vorhanden."; return await ShowMessage(item.ReportedAppUserId, item.Message); } } return Json(result); } #region Handler für die Inhaltstypen für die Anzeige /// /// Anzeige eines App-Users ohne Möglichkeit der Bearbeitung /// /// Id des App-Users /// JSON [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUserReports)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] [HttpGet] public async Task ShowAppUser(string appUserId) { var result = new AppUserReportResponseVm { Success = false, Module = "AppUserReportShowAppUserModule" }; var item = await _appUserService.GetAsync(appUserId); if (item != null) { var model = _mapper.Map(item); if (item.Type != AppUserType.DogOwner) { var profile = await _appUserService.GetWalkerProfileAsync(appUserId); ViewBag.Profile = _mapper.Map(profile); } result.Data = item.ToCamelCaseJson(); result.Success = true; result.Html = await PartialView("_ShowAppUser", model).ToStringAsync(ControllerContext); return Json(result); } return Json(result); } /// /// Anzeige einer öffentlichen Anfrage ohne Möglichkeit der Bearbeitung /// /// Id der öffentlichen Anfrage /// JSON [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUserReports)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] [HttpGet] public async Task ShowOpenRequest(string openRequestId) { var result = new AppUserReportResponseVm { Success = false, Module = "AppUserReportShowOpenRequestModule" }; var item = await _publicWalkRequestService.GetWithNamesAsync(openRequestId); if (item != null) { item.Dogs = new List(); if (!string.IsNullOrWhiteSpace(item.DogsJson)) { var dogsList = JsonSerializer.Deserialize>(item.DogsJson, new JsonSerializerOptions(JsonSerializerDefaults.Web)); foreach (var dogItem in dogsList) { var dog = await _dogService.GetWithNamesAsync(dogItem.Id, SelectedLanguage, LocalizationOptions.Value.DefaultCulture, true); if (dog != null) { item.Dogs.Add(new DogMinInfo() { Id = dog.Id, Index = dog.Index, Version = dog.Version, UpdatedAt = dog.UpdatedAt, Deleted = dog.Deleted, DogRaceId = dog.DogRaceId, DogRaceName = dog.DogRaceName, Name = dog.Name, Photo = !string.IsNullOrWhiteSpace(dog.Photo) ? $"/file/documents/thumbnails/{200}/{dog.Photo}" : string.Empty, Sex = dog.Sex, Size = dog.Size, BirthDate = dog.BirthDate, AverageRating = dog.RatingStatistics_AverageRating }); } } } var model = _mapper.Map(item); result.Data = item.ToCamelCaseJson(); result.Success = true; result.Html = await PartialView("_ShowOpenRequest", model).ToStringAsync(ControllerContext); return Json(result); } return Json(result); } /// /// Anzeige eines Hundeprofils ohne Möglichkeit der Bearbeitung /// /// Id des Hundes /// JSON [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUserReports)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] [HttpGet] public async Task ShowDogProfile(string dogId) { var result = new AppUserReportResponseVm { Success = false, Module = "AppUserReportShowDogProfileModule" }; var item = await _dogService.GetAsync(dogId); if (item != null) { var model = _mapper.Map(item); result.Data = item.ToCamelCaseJson(); result.Success = true; result.Html = await PartialView("_ShowDogProfile", model).ToStringAsync(ControllerContext); return Json(result); } return Json(result); } /// /// Anzeige eines Hundebesitzer-Profils ohne Möglichkeit der Bearbeitung /// /// Id des App-Users /// JSON [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUserReports)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] [HttpGet] public async Task ShowDogOwnerProfile(string appUserId) { var result = new AppUserReportResponseVm { Success = false, Module = "AppUserReportShowDogOwnerProfileModule" }; var item = await _appUserService.GetAsync(appUserId); if (item != null) { var model = _mapper.Map(item); var dogs = await _dogService.GetDogsAsync(appUserId, null); var dogList = _mapper.Map>(dogs); ViewBag.Dogs = dogList; result.Data = item.ToCamelCaseJson(); result.Success = true; result.Html = await PartialView("_ShowDogOwnerProfile", model).ToStringAsync(ControllerContext); return Json(result); } return Json(result); } /// /// Anzeige eines Walks für Walker ohne Möglichkeit der Bearbeitung /// /// Id des Walks /// JSON [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUserReports)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] [HttpGet] public async Task ShowWalkWalker(string walkId) { var result = new AppUserReportResponseVm { Success = false, Module = "AppUserReportShowWalkWalkerModule" }; var item = await _walkService.GetWalkWithNamesAsync(walkId); if (item != null) { item.Dogs = new List(); if (!string.IsNullOrWhiteSpace(item.DogsJson)) { var dogsList = JsonSerializer.Deserialize>(item.DogsJson, new JsonSerializerOptions(JsonSerializerDefaults.Web)); foreach (var dogItem in dogsList) { var dog = await _dogService.GetWithNamesAsync(dogItem.Id, SelectedLanguage, LocalizationOptions.Value.DefaultCulture, true); if (dog != null) { item.Dogs.Add(new DogMinInfo() { Id = dog.Id, Index = dog.Index, Version = dog.Version, UpdatedAt = dog.UpdatedAt, Deleted = dog.Deleted, DogRaceId = dog.DogRaceId, DogRaceName = dog.DogRaceName, Name = dog.Name, Photo = !string.IsNullOrWhiteSpace(dog.Photo) ? $"/file/documents/thumbnails/{200}/{dog.Photo}" : string.Empty, Sex = dog.Sex, Size = dog.Size, BirthDate = dog.BirthDate, AverageRating = dog.RatingStatistics_AverageRating }); } } } var model = _mapper.Map(item); result.Data = item.ToCamelCaseJson(); result.Success = true; result.Html = await PartialView("_ShowWalkWalker", model).ToStringAsync(ControllerContext); return Json(result); } return Json(result); } /// /// Anzeige eines Walks für Hundebesitzer ohne Möglichkeit der Bearbeitung /// /// Id des Walks /// JSON [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUserReports)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] [HttpGet] public async Task ShowWalkDogOwner(string walkId) { var result = new AppUserReportResponseVm { Success = false, Module = "AppUserReportShowWalkDogOwnerModule" }; var item = await _walkService.GetWalkWithNamesAsync(walkId); if (item != null) { var model = _mapper.Map(item); result.Data = item.ToCamelCaseJson(); result.Success = true; result.Html = await PartialView("_ShowWalkDogOwner", model).ToStringAsync(ControllerContext); return Json(result); } return Json(result); } /// /// Anzeige eines Ratings /// /// Id des Ratings /// JSON [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUserReports)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] [HttpGet] public async Task ShowRating(string ratingId) { var result = new AppUserReportResponseVm { Success = false, Module = "AppUserReportShowRatingModule" }; var item = await _ratingService.GetWithNamesAsync(ratingId); if (item != null) { var model = _mapper.Map(item); result.Data = item.ToCamelCaseJson(); result.Success = true; result.Html = await PartialView("_ShowRating", model).ToStringAsync(ControllerContext); return Json(result); } return Json(result); } /// /// Anzeige einer Antwort auf eine öffentliche Anfrage /// /// Id des App-Users der die Antwort erhalten hat /// Id der Antwort /// JSON [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUserReports)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] [HttpGet] public async Task ShowOpenRequestResponse(string appUserId, string reponseId) { var result = new AppUserReportResponseVm { Success = false, Module = "AppUserReportShowOpenRequestResponseModule" }; var item = await _publicWalkResponseService.GetWithNamesAsync(appUserId, reponseId); if (item != null) { var model = _mapper.Map(item); var profile = await _appUserService.GetWalkerProfileAsync(item.DogWalkerId); ViewBag.Profile = _mapper.Map(profile); result.Data = item.ToCamelCaseJson(); result.Success = true; result.Html = await PartialView("_ShowOpenRequestResponse", model).ToStringAsync(ControllerContext); return Json(result); } return Json(result); } /// /// Anzeige eine Chat-Nachricht ohne Möglichkeit der Bearbeitung /// /// Id des App-Users /// Nachricht die angezeigt werden soll /// JSON [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUserReports)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] [HttpGet] public async Task ShowMessage(string appUserId, string message) { var result = new AppUserReportResponseVm { Success = false, Module = "AppUserReportShowMessageModule" }; var item = await _appUserService.GetAsync(appUserId); if (item != null) { var model = _mapper.Map(item); ViewBag.Message = message; result.Data = item.ToCamelCaseJson(); result.Success = true; result.Html = await PartialView("_ShowMessage", model).ToStringAsync(ControllerContext); return Json(result); } return Json(result); } #endregion #region Bearbeitungsfunktionen /// /// Aktualisieren des Textes eines Ratings /// /// Model /// Json [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUserReports)] [HttpPost] public async Task UpdateRating(RatingUpdateInfoVm model) { var result = new ResponseVm { Success = false }; if (ModelState.IsValid) { var rating = await _ratingService.GetAsync(model.Id); if (rating != null) { rating.Info = model.Info; rating.UpdatedAt = DateTimeOffset.UtcNow; await _ratingService.CommitAsync(User.Identity.Name); result.Success = true; result.Data = rating.ToCamelCaseJson(); } } return Json(result); } /// /// Rating auf gelöscht setzen und Berechnungen neu starten /// /// Id des Ratings /// Json [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUserReports)] [HttpPost] public async Task DeleteRating(string ratingId) { var result = new ResponseVm { Success = false }; var rating = await _ratingService.GetAsync(ratingId); if (rating != null) { rating.Deleted = true; rating.UpdatedAt = DateTimeOffset.UtcNow; await _ratingService.CommitAsync(User.Identity.Name); await _ratingService.UpdateRatingStatisticsAsync(rating.TargetId, rating.TargetType); await _ratingService.CommitAsync(User.Identity.Name); result.Success = true; result.Data = rating.ToCamelCaseJson(); } return Json(result); } #endregion } }