410 lines
16 KiB
C#

using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using gehGassi.Common.Data;
using gehGassi.Core.Interfaces;
using gehGassi.Core.Services;
using gehGassi.Permissions;
using gehGassi.Web.Auth;
using gehGassi.Web.Auth.Attributes;
using gehGassi.Web.Helper;
using gehGassi.Web.Models;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
namespace gehGassi.Web.Controllers
{
/// <summary>
/// Controller der allgemeine Funktionen zur Verfügung stellt
/// </summary>
[Authorize]
public class CommonController : BaseController
{
private readonly IMapper _mapper;
private readonly IVatValidationService _vatValidationService;
private readonly IUserService _userService;
private readonly ITicketStore _ticketStore;
private readonly IAuditService _auditService;
private readonly ILanguageService _languageService;
private readonly IPlaceHolderService _placeHolderService;
private readonly ICustomerService _customerService;
private readonly IAppUserService _appUserService;
private readonly IFileService _fileService;
private readonly IGeoLocationService _geoLocationService;
/// <summary>
/// Erstellt eine Instanz
/// </summary>
/// <param name="mapper">Isntanz eines IMapper</param>
/// <param name="vatValidationService">Instanz eines IVatValidationService</param>
/// <param name="userService">Instanz eines IUserService</param>
/// <param name="ticketStore">Instanz eines ITicketStore</param>
/// <param name="auditService">Instanz eines IAuditService</param>
/// <param name="languageService">Instanz eines ILanguageService</param>
/// <param name="placeHolderService">Instanz eines IPlaceHolderService</param>
/// <param name="customerService">Instanz eines ICustomerService</param>
/// <param name="appUserService">Instanz eines IDogOwnerService</param>
/// <param name="fileService">Instanz eines IFileService</param>
/// <param name="geoLocationService">Instanz eines IGeoLocationService</param>
public CommonController(IMapper mapper, IVatValidationService vatValidationService, IUserService userService, ITicketStore ticketStore,
IAuditService auditService, ILanguageService languageService, IPlaceHolderService placeHolderService, ICustomerService customerService, IAppUserService appUserService,
IFileService fileService, IGeoLocationService geoLocationService)
{
_mapper = mapper;
_vatValidationService = vatValidationService;
_userService = userService;
_ticketStore = ticketStore;
_auditService = auditService;
_languageService = languageService;
_placeHolderService = placeHolderService;
_customerService = customerService;
_appUserService = appUserService;
_fileService = fileService;
_geoLocationService = geoLocationService;
}
/// <summary>
/// Überprüft ob der Name für einen Typen noch verfügbar ist
/// </summary>
/// <returns>true wenn möglich, false sonst</returns>
[HttpPost]
public async Task<IActionResult> IsVatValid(string vat, AddressVm address)
{
if (string.IsNullOrWhiteSpace(address.CountryCode))
return Json(false);
vat = vat.Trim();
return Json(await _vatValidationService.IsValidAsync(vat, address.CountryCode.ToUpper()));
}
/// <summary>
/// Setzt den Anzeige-Status des Sidebars für den aktuellen Benutzer
/// </summary>
/// <param name="show">true wenn anzeigen, false sonst</param>
/// <returns>true</returns>
[HttpPost]
public async Task<IActionResult> SetSidebarShow(bool show)
{
if (User.Identity != null && User.Identity.IsAuthenticated)
{
var user = await _userService.GetByUsernameAsync(User.Identity.Name);
if (user != null)
{
var settings = user.Settings;
settings.SidebarShow = show;
user.Settings = settings;
await _userService.CommitAsync(User.Identity.Name);
}
}
return Json(true);
}
/// <summary>
/// Setzt den Anzeige-Status des Sidebars für den aktuellen Benutzer
/// </summary>
/// <param name="minimized">true wenn minimiert, false sonst</param>
/// <returns>true</returns>
[HttpPost]
public async Task<IActionResult> SetSidebarMinimized(bool minimized)
{
if (User.Identity != null && User.Identity.IsAuthenticated)
{
var user = await _userService.GetByUsernameAsync(User.Identity.Name);
if (user != null)
{
var settings = user.Settings;
settings.SidebarMinimized = minimized;
user.Settings = settings;
await _userService.CommitAsync(User.Identity.Name);
}
}
return Json(true);
}
/// <summary>
/// Gibt eine Ansicht für die Auswahl eines Mandanten und eines Kunden für Administratoren zurück
/// </summary>
/// <returns>PartialView</returns>
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.ImpersionateAdmin)]
public IActionResult ImpersionateAdmin()
{
var model = new ImpersionateAdminVm()
{
CustomerId = User.CustomerId(),
CustomerName = User.CustomerName(),
AppUserId = User.AppUserId(),
AppUserName = User.AppUserName()
};
return PartialView("_ImpersionateAdmin", model);
}
/// <summary>
/// Gibt eine Ansicht für die Auswahl eines Mandanten und eines Kunden für Administratoren zurück
/// </summary>
/// <returns>PartialView</returns>
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.ImpersionateAdmin)]
[ValidateAntiForgeryToken]
[HttpPost]
public async Task<IActionResult> ImpersionateAdmin(ImpersionateAdminVm model)
{
var result = new ResponseVm { Success = false };
if (ModelState.IsValid)
{
var ticket = await _ticketStore.RetrieveAsync(User.Identity.Name);
if (ticket != null)
{
var settings = ApplicationUser.Settings;
settings.SelectedCustomerId = null;
settings.SelectedAppUserId = null;
User.AddUpdateClaim(ClaimConstants.SelectedCustomerIdClaimType, "");
User.AddUpdateClaim(ClaimConstants.SelectedCustomerUniqueIdClaimType, "");
User.AddUpdateClaim(ClaimConstants.SelectedCustomerNameClaimType, "");
User.AddUpdateClaim(ClaimConstants.SelectedAppUserIdClaimType, "");
User.AddUpdateClaim(ClaimConstants.SelectedAppUserNameClaimType, "");
if (model.CustomerId != null)
{
var customer = await _customerService.GetAsync(model.CustomerId.Value);
if (customer != null)
{
settings.SelectedCustomerId = customer.Id;
User.AddUpdateClaim(ClaimConstants.SelectedCustomerIdClaimType, customer.Id.ToString());
User.AddUpdateClaim(ClaimConstants.SelectedCustomerUniqueIdClaimType, customer.UniqueId.ToString());
User.AddUpdateClaim(ClaimConstants.SelectedCustomerNameClaimType, customer.Name);
}
}
if (!string.IsNullOrWhiteSpace(model.AppUserId))
{
var appUser = await _appUserService.GetAsync(model.AppUserId);
if (appUser != null)
{
settings.SelectedAppUserId = appUser.Id;
User.AddUpdateClaim(ClaimConstants.SelectedAppUserIdClaimType, appUser.Id);
User.AddUpdateClaim(ClaimConstants.SelectedAppUserNameClaimType, $"{appUser.FirstName} {appUser.LastName}");
}
}
ApplicationUser.Settings = settings;
await UserService.CommitAsync(ApplicationUser.UserName);
var newTicket = new AuthenticationTicket(User, ticket.Properties, IdentityConstants.ApplicationScheme);
await _ticketStore.RenewAsync(User.Identity.Name, newTicket);
result.Data = $"{{\"customerId\":\"{model.CustomerId}\"}}";
}
result.Success = true;
result.Html = string.Empty;
return Json(result);
}
result.Html = await PartialView("_ImpersionateAdmin", model).ToStringAsync(ControllerContext);
return Json(result);
}
/// <summary>
/// Gibt eine Ansicht von Audit-Einträgen für ein Objekt zurück
/// </summary>
/// <param name="key">Key des Objektes</param>
/// <param name="table">Zuhehörige Tabelle</param>
/// <returns>PartialView</returns>
[Authorize(Policy = Policies.CustomerOnly)]
public async Task<IActionResult> AuditInfo(string key, string table)
{
var list = await _auditService.GetListAsync(key, table);
var resultListVm = list.ToList().Select(item => _mapper.Map<AuditInfoVm>(item)).OrderByDescending(c => c.DateTime).ToList();
return PartialView("_AuditInfo", resultListVm);
}
/// <summary>
/// Gibt eine Ansicht von Audit-Einträgen für ein Objekt zurück - Erweitert,
/// ohne Header, ohne Buttons
/// </summary>
/// <param name="key">Key des Objektes</param>
/// <param name="table">Zuhehörige Tabelle</param>
/// <returns>PartialView</returns>
[Authorize(Policy = Policies.CustomerOnly)]
public async Task<IActionResult> AuditInfoEx(string key, string table)
{
var list = await _auditService.GetListWithNamesAsync(key, table);
var resultListVm = list.ToList().Select(item => _mapper.Map<AuditInfoWithNamesVm>(item)).OrderByDescending(c => c.DateTime).ToList();
return PartialView("_AuditInfoEx", resultListVm);
}
/// <summary>
/// Gibt eine Liste von Sprachen für LookUp zurück
/// </summary>
/// <param name="dm">DataManager</param>
/// <returns>Liste</returns>
[Authorize(Policy = Policies.CustomerOnly)]
public IActionResult LookupLanguages([FromBody] DataManager dm)
{
var filter = string.Empty;
if (dm.Where?.FirstOrDefault() != null)
{
filter = dm.Where.First().value.ToString();
if (filter.IndexOf('(') > 0)
{
filter = filter.Substring(0, (filter.IndexOf('(') - 1));
filter = filter.TrimEnd();
}
}
var items = _languageService.Search(filter);
var result = items.Select(item => new LookupItemVm() { Id = item.Iso2, Name = $"{item.Name}" }).OrderBy(c => c.Name).ToList();
return Json(result);
}
/// <summary>
/// Gibt eine Liste von Sprachen zurück
/// </summary>
/// <returns>Liste</returns>
[Authorize(Policy = Policies.CustomerOnly)]
public IActionResult GetLanguages()
{
var items = _languageService.GetAll();
var resultListVm = items.ToList().Select(item => _mapper.Map<LanguageVm>(item)).ToList();
return Json(resultListVm);
}
#region Placeholder
/// <summary>
/// Gibt alle Platzhalter als Kategorien und Platzhalterlisten zurück
/// </summary>
/// <param name="lang">Sprache ISO2</param>
/// <returns></returns>
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public ActionResult GetPlaceholders(string lang)
{
var placeholders = _placeHolderService.GetCategories(lang);
return Json(placeholders);
}
#endregion
#region Upload
/// <summary>
/// Hochladen eines Files. Speichert ins temporäre Verzeichnis
/// </summary>
/// <param name="file">Bild-Datei</param>
/// <returns>Json true wenn erfolgreich, false sons</returns>
[Authorize(Policy = Policies.CustomerOnly)]
[HttpPost]
public async Task<IActionResult> UploadTempFile(IFormFile file)
{
if (file.Length > 0)
{
try
{
var path = Path.GetFileName(file.FileName);
var extension = Path.GetExtension(path);
var fileName = FileServiceHelper.GetUploadTempPath() + Path.GetFileName($"{Guid.NewGuid().ToString()}{extension}");
fileName = FileServiceHelper.SanitizeFileName(fileName);
await _fileService.StoreAsync(FileServiceHelper.TempContainer, fileName, file.OpenReadStream());
return Json(new { filename = fileName });
}
catch
{
return Json(new { filename = "" });
}
}
return Json(new { filename = "" });
}
/// <summary>
/// Löschem eines Files im temporäre Verzeichnis
/// </summary>
/// <param name="fileName">Dateinamr Bild-Datei</param>
/// <returns>Json true wenn erfolgreich, false sons</returns>
[Authorize(Policy = Policies.CustomerOnly)]
[HttpPost]
public async Task<IActionResult> RemoveTempFile(string fileName)
{
if (!string.IsNullOrWhiteSpace(fileName))
{
try
{
await _fileService.DeleteAsync(FileServiceHelper.TempContainer, fileName);
return Json(true);
}
catch
{
return Json(false);
}
}
return Json(false);
}
#endregion
#region Map
/// <summary>
/// Anzeigen einer Karte mittels Leaflet
/// </summary>
/// <returns>PartialView</returns>
public IActionResult ShowMap()
{
return PartialView("_ShowMap");
}
/// <summary>
/// Anzeigen einer Karte mittels Leaflet
/// </summary>
/// <returns>PartialView</returns>
[HttpPost]
public IActionResult ShowMapPreset(MapVm model)
{
if (ModelState.IsValid)
{
return PartialView("_ShowMapPreset", model);
}
return PartialView("_Error");
}
/// <summary>
/// Versucht für eine Adresse Längen- und Breitengrad zurückzugeben
/// </summary>
/// <param name="model">Adress-Info</param>
/// <returns>JSON</returns>
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[HttpPost]
public async Task<IActionResult> LookupGeoCode(string model)
{
var result = new ResponseVm()
{
Success = false,
Html = string.Empty
};
var geoResult = await _geoLocationService.GetLocationAsync(model, SelectedLanguage);
result.Success = geoResult.Success;
result.ErrorMessage = geoResult.ErrorMessage;
result.Data = geoResult.ToCamelCaseJson();
return Json(result);
}
#endregion
}
}