using System; using System.Collections.Generic; 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.Domain.Common; using gehGassi.Domain.Dogs; using gehGassi.External.Services; using gehGassi.Permissions; using gehGassi.Web.Auth; using gehGassi.Web.Auth.Attributes; using gehGassi.Web.Helper; using gehGassi.Web.Hubs; using gehGassi.Web.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Localization; using NetTopologySuite; using NetTopologySuite.Geometries; namespace gehGassi.Web.Controllers { /// /// Controller für die Verwaltung von App-Usern /// [Authorize] public class AppUserController : BaseController { private readonly IMapper _mapper; private readonly IStringLocalizer _localizer; private readonly IAppUserService _appUserService; private readonly ICountryService _countryService; private readonly IUserService _userService; private readonly IGeoLocationService _geoLocationService; private readonly IAppHubSender _appHubSender; private readonly IPushNotificationService _pushNotificationService; private readonly IWalkService _walkService; private readonly IPublicWalkResponseService _publicWalkResponseService; private readonly IFavouriteService _favouriteService; private readonly ISystemMessageService _systemMessageService; private readonly IDeviceService _deviceService; private readonly IRefreshTokenService _refreshTokenService; private readonly IRatingService _ratingService; private readonly IMessageService _messageService; private readonly IAppUserReportService _appUserReportService; private readonly IVoucherCampaignService _voucherCampaignService; /// /// Erstellt eine Instanz /// /// Instanz eines IMapper /// Instanz eines IStringLocalizer /// Instanz eines IDogOwnerService /// Instanz eines ICountryService /// Instanz eines IUserService /// Instanz eines IGeoLocationService /// Instanz eines IAppHubSender /// Instanz eines IPushNotificationService /// Instanz eines IWalkService /// Instanz eines IPublicWalkResponseService /// Instanz eines IFavouriteService /// Instanz eines ISystemMessageService /// Instanz eines IDeviceService /// Instanz eines IRefreshTokenService /// Instanz eines IRatingService /// Instanz eines IMessageService /// Instanz eines IAppUserReportService /// Instanz eines IVoucherCampaignService public AppUserController(IMapper mapper, IStringLocalizer localizer, IAppUserService appUserService, ICountryService countryService, IUserService userService, IGeoLocationService geoLocationService, IAppHubSender appHubSender, IPushNotificationService pushNotificationService, IWalkService walkService, IPublicWalkResponseService publicWalkResponseService, IFavouriteService favouriteService, ISystemMessageService systemMessageService, IDeviceService deviceService, IRefreshTokenService refreshTokenService, IRatingService ratingService, IMessageService messageService, IAppUserReportService appUserReportService, IVoucherCampaignService voucherCampaignService) { _mapper = mapper; _localizer = localizer; _appUserService = appUserService; _countryService = countryService; _userService = userService; _geoLocationService = geoLocationService; _appHubSender = appHubSender; _pushNotificationService = pushNotificationService; _walkService = walkService; _publicWalkResponseService = publicWalkResponseService; _favouriteService = favouriteService; _systemMessageService = systemMessageService; _deviceService = deviceService; _refreshTokenService = refreshTokenService; _ratingService = ratingService; _messageService = messageService; _appUserReportService = appUserReportService; _voucherCampaignService = voucherCampaignService; } /// /// Gibt einen View für die App-User-Verwaltung zurück /// /// View [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUsersRead)] 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.AppUsersRead)] [HttpPost] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult GetAppUsers([FromBody] DataManager dm) { if (dm != null) { var propList = new List { new() { Original = "email", Complex = "Contact.Email" }, new() { Original = "city", Complex = "Address.City" }, new() { Original = "zip", Complex = "Address.Zip" }, new() { Original = "countryCode", Complex = "Address.CountryCode" }, new() { Original = "state", Complex = "Address.State" } }; 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 == "type") whereFilterPredicate.value = (AppUserType)((int)((long)whereFilterPredicate.value)); if (whereFilterPredicate.Field == "sex") whereFilterPredicate.value = (Sex)((int)((long)whereFilterPredicate.value)); } } } } var resultList = _appUserService.Filter(dm?.SearchValue ?? "", false); //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.TypeText = itemVm.Type.GetDisplayName(AnnotationsLocalizer); itemVm.SexText = itemVm.Sex.GetDisplayName(AnnotationsLocalizer); itemVm.Photo = Tools.GetPhotoThumb(itemVm.Photo, 100); } //FilterPreview? if (!dm.RequiresCounts) return Json(resultListVm); return Json(new { result = resultListVm, count = countFiltered }); } /// /// Anlegen eines App-Users /// /// PartialView [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUsersCreate)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Create() { var model = new AppUserCrudVm() { Id = Guid.NewGuid().ToString("N"), Number = _appUserService.GetNextNumber() }; return PartialView("_Create", model); } /// /// Anlegen eines App-Users /// /// Model /// Json [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUsersCreate)] [ValidateAntiForgeryToken] [HttpPost] public async Task Create(AppUserCrudVm model) { var result = new ResponseVm { Success = false }; if (ModelState.IsValid) { var item = _appUserService.Create(); _mapper.Map(model, item); if(model.TermsAccepted) item.TermsAcceptedDate = DateTimeOffset.UtcNow; else item.TermsAcceptedDate = null; if (model.PrivacyAccepted) item.PrivacyAcceptedDate = DateTimeOffset.UtcNow; else item.PrivacyAcceptedDate = null; if (model.PaymentTermsAccepted) item.PaymentTermsAcceptedDate = DateTimeOffset.UtcNow; else item.PaymentTermsAcceptedDate = null; if (model.Verified) item.VerifiedDate = DateTimeOffset.UtcNow; else item.VerifiedDate = null; if (model.KycPassed) item.KycPassedDate = DateTimeOffset.UtcNow; else item.KycPassedDate = null; if (model.BirthDate.HasValue) item.BirthDate = new DateTimeOffset(model.BirthDate.Value.DateTime, TimeSpan.Zero); item.Created = DateTimeOffset.UtcNow; item.UpdatedAt = DateTimeOffset.UtcNow; var location = await _geoLocationService.GetLocationAsync(item.Address, SelectedLanguage); if (location.Success) { var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326); var geoLocation = geometryFactory.CreatePoint(new Coordinate(location.Longitude, location.Latitude)); item.Location = geoLocation; } _appUserService.Add(item); await _appUserService.CommitAsync(User.Identity.Name); if (item.Type != AppUserType.DogOwner) { await _appUserService.CreateWalkerProfileIfNotExistsAsync(item.Id); await _appUserService.CommitAsync(User.Identity.Name); } if (!string.IsNullOrWhiteSpace(model.Photo)) { //Nun das Bild umbenennen und dann kopieren. Ebenso Thumbnails erstellen var extension = Path.GetExtension(model.Photo); var fileName = Path.GetFileName(model.Photo); var filenameToUse = FileServiceHelper.GetAppUserPath(item.Id) + $"photo-{Guid.NewGuid():N}{extension}"; item.Photo = filenameToUse; await _appUserService.CommitAsync(User.Identity.Name); //Kopieren var tempFile = await FileService.GetAsync(FileServiceHelper.TempContainer, model.Photo); await FileService.StoreAsync(FileServiceHelper.DocumentContainer, filenameToUse, tempFile); //Thumbnails await GenerateThumbnail(FileServiceHelper.DocumentContainer, filenameToUse, 400); await GenerateThumbnail(FileServiceHelper.DocumentContainer, filenameToUse, 200); await GenerateThumbnail(FileServiceHelper.DocumentContainer, filenameToUse, 100); //Altes Löschen await FileService.DeleteAsync(FileServiceHelper.TempContainer, model.Photo); } result.Data = item.ToCamelCaseJson(); result.Success = true; result.Html = string.Empty; return Json(result); } ModelState.Remove("CountryName"); var country = _countryService.GetCountry(model.Address.CountryCode); model.CountryName = country != null ? country.Name : ""; ModelState.Remove("StateName"); var state = _countryService.GetState(model.Address.CountryCode, model.Address.State); model.StateName = state != null ? state.Name : ""; ModelState.Remove("NationalityName"); var nationality = _countryService.GetCountry(model.NationalityCode); model.NationalityName = nationality != null ? nationality.Name : ""; ModelState.Remove("MainResidenceName"); var mainResidence = _countryService.GetCountry(model.MainResidenceCode); model.MainResidenceName = mainResidence != null ? mainResidence.Name : ""; result.Html = await PartialView("_Create", model).ToStringAsync(ControllerContext); return Json(result); } /// /// Bearbeiten eines App-Users /// /// Id des AppUsers /// PartialView [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUsersEdit)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public async Task Edit(string id) { var item = await _appUserService.GetAsync(id); if (item != null) { var model = _mapper.Map(item); var country = _countryService.GetCountry(item.Address.CountryCode); model.CountryName = country != null ? country.Name : ""; var state = _countryService.GetState(item.Address.CountryCode, item.Address.State); model.StateName = state != null ? state.Name : ""; var nationality = _countryService.GetCountry(item.NationalityCode); model.NationalityName = nationality != null ? nationality.Name : ""; var mainResidence = _countryService.GetCountry(item.MainResidenceCode); model.MainResidenceName = mainResidence != null ? mainResidence.Name : ""; return PartialView("_Edit", model); } return PartialView("_Error"); } /// /// Bearbeiten eines App-Users /// /// Model /// Json [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUsersEdit)] [ValidateAntiForgeryToken] [HttpPost] public async Task Edit(AppUserCrudVm model) { var result = new ResponseVm { Success = false }; if (ModelState.IsValid) { var item = await _appUserService.GetAsync(model.Id); if (item is { Deleted: false }) { if (item.Version.SequenceEqual(model.Version)) { var oldPhoto = item.Photo; var addressHasChanges = item.Address.HasChanges(model.Address); var oldTermsAccepted = item.TermsAccepted; var oldPrivacyAccepted = item.PrivacyAccepted; var oldPaymentTermsAccepted = item.PaymentTermsAccepted; var oldVerified = item.Verified; var oldKycPassed = item.KycPassed; _mapper.Map(model, item); if (model.TermsAccepted != oldTermsAccepted && model.TermsAccepted) item.TermsAcceptedDate = DateTimeOffset.UtcNow; else if(!model.TermsAccepted) item.TermsAcceptedDate = null; if (model.PrivacyAccepted != oldPrivacyAccepted && model.PrivacyAccepted) item.PrivacyAcceptedDate = DateTimeOffset.UtcNow; else if(!model.PrivacyAccepted) item.PrivacyAcceptedDate = null; if (model.PaymentTermsAccepted != oldPaymentTermsAccepted && model.PaymentTermsAccepted) item.PaymentTermsAcceptedDate = DateTimeOffset.UtcNow; else if(!model.PaymentTermsAccepted) item.PaymentTermsAcceptedDate = null; if (model.Verified != oldVerified && model.Verified) item.VerifiedDate = DateTimeOffset.UtcNow; else if(!model.Verified) item.VerifiedDate = null; if (model.KycPassed != oldKycPassed && model.KycPassed) item.KycPassedDate = DateTimeOffset.UtcNow; else if(!model.KycPassed) item.KycPassedDate = null; if (model.BirthDate.HasValue) item.BirthDate = new DateTimeOffset(model.BirthDate.Value.DateTime, TimeSpan.Zero); item.UpdatedAt = DateTimeOffset.UtcNow; if (oldPhoto != item.Photo) { //Alte Daten löschen, neue Daten anlegen if (!string.IsNullOrWhiteSpace(oldPhoto)) { await FileService.DeleteAsync(FileServiceHelper.DocumentContainer, oldPhoto); await RemoveThumbnail(FileServiceHelper.DocumentContainer, oldPhoto, 400); await RemoveThumbnail(FileServiceHelper.DocumentContainer, oldPhoto, 200); await RemoveThumbnail(FileServiceHelper.DocumentContainer, oldPhoto, 100); } if (!string.IsNullOrWhiteSpace(item.Photo)) { //Neue Bilddaten verwenden.... var extension = Path.GetExtension(item.Photo); var fileName = Path.GetFileName(item.Photo); var filenameToUse = FileServiceHelper.GetAppUserPath(item.Id) + $"photo-{Guid.NewGuid():N}{extension}"; item.Photo = filenameToUse; //Kopieren var tempFile = await FileService.GetAsync(FileServiceHelper.TempContainer, model.Photo); await FileService.StoreAsync(FileServiceHelper.DocumentContainer, filenameToUse, tempFile); //Thumbnails await GenerateThumbnailByWidth(FileServiceHelper.DocumentContainer, filenameToUse, 400); await GenerateThumbnailByWidth(FileServiceHelper.DocumentContainer, filenameToUse, 200); await GenerateThumbnailByWidth(FileServiceHelper.DocumentContainer, filenameToUse, 100); //Altes Löschen await FileService.DeleteAsync(FileServiceHelper.TempContainer, model.Photo); } } if (addressHasChanges) { var location = await _geoLocationService.GetLocationAsync(item.Address, SelectedLanguage); if (location.Success) { var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326); var geoLocation = geometryFactory.CreatePoint(new Coordinate(location.Longitude, location.Latitude)); item.Location = geoLocation; } } await _appUserService.CommitAsync(User.Identity.Name); await _appHubSender.AppUserChangedAsync(item.Id); result.Data = item.ToCamelCaseJson(); result.Success = true; result.Html = string.Empty; return Json(new { result.Success, result.Html, result.Data }); } else { ModelState.AddModelError("", _localizer["Err_Entity_Changed"].Value); } } else { ModelState.AddModelError("", _localizer["Err_Entity_Deleted"].Value); } } ModelState.Remove("CountryName"); var country = _countryService.GetCountry(model.Address.CountryCode); model.CountryName = country != null ? country.Name : ""; ModelState.Remove("StateName"); var state = _countryService.GetState(model.Address.CountryCode, model.Address.State); model.StateName = state != null ? state.Name : ""; ModelState.Remove("NationalityName"); var nationality = _countryService.GetCountry(model.NationalityCode); model.NationalityName = nationality != null ? nationality.Name : ""; ModelState.Remove("MainResidenceName"); var mainResidence = _countryService.GetCountry(model.MainResidenceCode); model.MainResidenceName = mainResidence != null ? mainResidence.Name : ""; result.Html = await PartialView("_Edit", model).ToStringAsync(ControllerContext); return Json(result); } /// /// Löschen eines App-Users /// /// Liste Id der Entität /// Sollen die Daten physisch gelöscht werden? /// Json [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUsersDelete)] [HttpPost] public async Task Delete(List ids, bool forceDelete = false) { var batchErrorHeader = $"

{_localizer["Common_BatchDelete_Failed"].Value}

"; var batchResult = new BatchResponseVm(batchErrorHeader) { Success = true }; var ratingTargetsToUpdate = new List>(); foreach (var id in ids) { var item = await _appUserService.GetAsync(id); if (item != null) { //await _customerService.ResetTypeAsync(item.Id); //Spezial zurücksetzen wenn nötig var specialCount = 0; if (specialCount == 0) { batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = item.Id.ToString(), Name = item.Title, Success = true, NotFound = false, ErrorMessage = "" }); if (forceDelete) { var postingPath = FileServiceHelper.GetAppUserPath(item.Id); await FileService.ClearDirectoryAsync(FileServiceHelper.DocumentContainer, postingPath); await RemoveThumbnail(FileServiceHelper.DocumentContainer, item.Photo, 400); await RemoveThumbnail(FileServiceHelper.DocumentContainer, item.Photo, 200); await RemoveThumbnail(FileServiceHelper.DocumentContainer, item.Photo, 100); var applicationUser = await _userService.GetByAppUserAsync(item.Id); if (applicationUser != null) { //Refreshtokens löschen await _refreshTokenService.RemoveAllAsync(applicationUser.Id, applicationUser.UserName); //Benutzer löschen _userService.Remove(applicationUser); } //Walker-Profil löschen await _appUserService.RemoveWalkerProfileAsync(item.Id); //Blockierungen löschen await _appUserService.RemoveBlocksByBlockedUserAsync(item.Id); //Ratings löschen var ratingTargets = await _ratingService.DeleteAllForAppUserAsync(item.Id); foreach (var ratingTarget in ratingTargets) { if(ratingTargetsToUpdate.FirstOrDefault(c => c.Item1 == ratingTarget.Item1 && c.Item2 == ratingTarget.Item2) == null) ratingTargetsToUpdate.Add(ratingTarget); } System.Diagnostics.Debug.WriteLine($"Ratings: {ratingTargetsToUpdate.Count}"); //Favourites löschen var favouritesCount = await _favouriteService.DeleteAllForAppUserAsync(item.Id); System.Diagnostics.Debug.WriteLine($"Favourites: {favouritesCount}"); //SystemMessages löschen var systemMessageCount = await _systemMessageService.DeleteAllForAppUserAsync(item.Id); System.Diagnostics.Debug.WriteLine($"SystemMessages: {systemMessageCount}"); //Konversationen löschen var conversations = await _messageService.RemoveConversationByAppUserAsync(item.Id); //Devices vor löschen abmelden var devices = await _deviceService.GetAllAsync(item.Id); foreach (var device in devices) { #if RELEASE await _pushNotificationService.DeleteInstallationByIdAsync(device.InstallationId); #endif await _deviceService.DeleteAsync(item.Id, device.InstallationId, true); } System.Diagnostics.Debug.WriteLine($"Devices: {devices.Count}"); //AppReports löschen var appUserReportCount = await _appUserReportService.DeleteAllForAppUserAsync(item.Id); System.Diagnostics.Debug.WriteLine($"AppUserReports: {appUserReportCount}"); _appUserService.Remove(item); await _voucherCampaignService.RemoveVoucherUsageForAppUserAsync(item.Id); } else { item.Deleted = true; item.UpdatedAt = DateTimeOffset.UtcNow; var applicationUser = await _userService.GetByAppUserAsync(item.Id); if (applicationUser != null) { //Refreshtokens löschen await _refreshTokenService.RemoveAllAsync(applicationUser.Id, applicationUser.UserName); } //Zuordnung zum Benutzer zurücksetzen await _userService.ResetAppUserAsync(item.Id); //Ratings löschen var ratingTargets = await _ratingService.DeleteAllForAppUserAsync(item.Id); foreach (var ratingTarget in ratingTargets) { if (ratingTargetsToUpdate.FirstOrDefault(c => c.Item1 == ratingTarget.Item1 && c.Item2 == ratingTarget.Item2) == null) ratingTargetsToUpdate.Add(ratingTarget); } //Favourites löschen await _favouriteService.DeleteAllForAppUserAsync(item.Id); //SystemMessages löschen await _systemMessageService.DeleteAllForAppUserAsync(item.Id); //Konversationen löschen var conversations = await _messageService.RemoveConversationByAppUserAsync(item.Id); //Devices vor löschen abmelden var devices = await _deviceService.GetAllAsync(item.Id); foreach (var device in devices) { #if RELEASE await _pushNotificationService.DeleteInstallationByIdAsync(device.InstallationId); #endif await _deviceService.DeleteAsync(item.Id, device.InstallationId, true); } //AppReports löschen var appUserReportCount = await _appUserReportService.DeleteAllForAppUserAsync(item.Id); System.Diagnostics.Debug.WriteLine($"AppUserReports: {appUserReportCount}"); } } else { if (specialCount != 0) { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = item.Title, Success = false, NotFound = false, ErrorMessage = string.Format(_localizer["Common_BatchDelete_InUse"], $"{item.Title}", $"{specialCount}") + "
" }); } } } else { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = "", Success = false, NotFound = true, ErrorMessage = string.Format(_localizer["Common_BatchDelete_NotFound"], $"{id}") + "
" }); } } if (batchResult.BatchResponseList.Any(c => c.Success)) { await _appUserService.CommitAsync(User.Identity.Name); if (ratingTargetsToUpdate.Any()) { foreach (var ratingTargetToUpdate in ratingTargetsToUpdate) { await _ratingService.UpdateRatingStatisticsAsync(ratingTargetToUpdate.Item1, ratingTargetToUpdate.Item2); } await _ratingService.CommitAsync(User.Identity.Name); } } return Json(batchResult); } /// /// Sperren eines App-Users /// /// Id des AppUsers /// PartialView [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUsersEdit)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public async Task Lock(string id) { var item = await _appUserService.GetAsync(id); if (item != null) { var model = new AppUserLockVm() { Id = item.Id, LockedUntil = null, LockedReason = string.Empty }; return PartialView("_Lock", model); } return PartialView("_Error"); } /// /// Sperren eines App-Users /// /// Model /// Json [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUsersEdit)] [ValidateAntiForgeryToken] [HttpPost] public async Task Lock(AppUserLockVm model) { var result = new ResponseVm { Success = false }; if (ModelState.IsValid) { var item = await _appUserService.GetAsync(model.Id); if (item is { Deleted: false }) { item.Locked = true; item.LockedReason = model.LockedReason; item.LockedUntil = model.LockedUntil; item.LockedCount += 1; await _appUserService.CommitAsync(User.Identity.Name); //Senden einer Nachricht an die App dass ein Logout durchgeführt werden soll? if (!string.IsNullOrWhiteSpace(item.Id)) { //Logout-Aufforderung via SignalR await _appHubSender.LogoutAsync(item.Id); //Logout-Aufforderung via Push-Notification await _pushNotificationService.SendLogoutAsync(item.Id); } //Offene Walks stornieren var canceled = await _walkService.CancelWalksForLockedAsync(item.Id); //Offene Angebote auf öffentliche Anfragen stornieren var canceledResponses = await _publicWalkResponseService.CancelForLockedAsync(item.Id); result.Data = item.ToCamelCaseJson(); result.Success = true; result.Html = string.Empty; return Json(new { result.Success, result.Html, result.Data }); } else { ModelState.AddModelError("", _localizer["Err_Entity_Deleted"].Value); } } result.Html = await PartialView("_Lock", model).ToStringAsync(ControllerContext); return Json(result); } /// /// Entsperren eines App-Users /// /// Id des App-Users /// Json [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUsersEdit)] [HttpPost] public async Task Unlock(string id) { var result = new ResponseVm { Success = false }; var item = await _appUserService.GetAsync(id); if (item is { Locked: true }) { item.Locked = false; item.LockedUntil = null; item.LockedReason = string.Empty; await _appUserService.CommitAsync(User.Identity.Name); result.Success = true; return Json(result); } return Json(result); } #region Profil DogWalker /// /// Bearbeiten des DogWalker Profils eines App-Users /// /// Id des AppUsers /// PartialView [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUsersEdit)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public async Task EditProfile(string id) { var item = await _appUserService.GetAsync(id); if (item != null && item.Type != AppUserType.DogOwner) { var profile = await _appUserService.CreateWalkerProfileIfNotExistsAsync(id); await _appUserService.CommitAsync(User.Identity.Name); var model = _mapper.Map(profile); return PartialView("_EditProfile", model); } return PartialView("_Error"); } /// /// Bearbeiten des DogWalker Profils eines App-Users /// /// Model /// Json [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.AppUsersManage, Permission.AppUsersEdit)] [ValidateAntiForgeryToken] [HttpPost] public async Task EditProfile(DogWalkerProfileVm model) { var result = new ResponseVm { Success = false }; if (ModelState.IsValid) { var item = await _appUserService.GetWalkerProfileAsync(model.Id); if (item is { Deleted: false }) { if (item.Version.SequenceEqual(model.Version)) { _mapper.Map(model, item); item.UpdatedAt = DateTimeOffset.UtcNow; await _appUserService.CommitAsync(User.Identity.Name); await _appHubSender.AppUserChangedAsync(item.Id); result.Data = item.ToCamelCaseJson(); result.Success = true; result.Html = string.Empty; return Json(new { result.Success, result.Html, result.Data }); } else { ModelState.AddModelError("", _localizer["Err_Entity_Changed"].Value); } } else { ModelState.AddModelError("", _localizer["Err_Entity_Deleted"].Value); } } result.Html = await PartialView("_EditProfile", model).ToStringAsync(ControllerContext); return Json(result); } #endregion #region Helper /// /// Gibt eine Liste von App-Usern für LookUp zurück /// /// DataManager /// Soll "Keine(r)" integriert werden /// Liste [Authorize(Policy = Policies.PowerUserOnly)] public async Task Lookup([FromBody] DataManager dm, bool includeNone = false) { 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 = await _appUserService.SearchAsync(filter, false); var result = items.Select(item => new LookupItemVm() { Id = item.Id.ToString(), Name = $"{item.FirstName} {item.LastName} ({AnnotationsLocalizer["AppUserType_" + item.Type.ToString()]})" }).OrderBy(c => c.Name).ToList(); if (includeNone) result.Insert(0, new LookupItemVm() { Id = "", Name = _localizer["Common_None"].ToString() }); return Json(result); } #endregion } }