using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using AutoMapper; using gehGassi.Common.Data; using gehGassi.Core.Interfaces; using gehGassi.Core.Services; using gehGassi.Domain.Roles; using gehGassi.Domain.Users; using gehGassi.Permissions; using gehGassi.Web.Auth; using gehGassi.Web.Auth.Attributes; using gehGassi.Web.Helper; using gehGassi.Web.Models; using gehGassi.Web.Services; 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; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Options; using Newtonsoft.Json; namespace gehGassi.Web.Controllers { /// /// Controller für die Verwaltung der Benutzer /// [Authorize] public class UserController : BaseController { private readonly IUserService _userService; private readonly UserManager _userManager; private readonly RoleManager _roleManager; private readonly IFileService _fileService; private readonly IMapper _mapper; private readonly ITicketStore _ticketStore; private readonly IEmailSender _emailSender; private readonly IStringLocalizer _localizer; private readonly IStringLocalizerFactory _localizerFactory; private readonly IAuthorizationService _authorizationService; private readonly IOptions _authOptions; private readonly IRefreshTokenService _refreshTokenService; private readonly IAuditService _auditService; private readonly ICustomerService _customerService; private readonly IAppUserService _appUserService; /// /// Erstellt eine Instanz /// /// Instanz eines IUserService /// Instanz eines UserManager /// Instanz eines RoleManager /// Instanz eines IFileService /// Instanz eines IMapper /// Instanz eines ITicketStore /// Instanz eines IEmailSender /// Instanz eines IStringLocalizer /// Instanz einer IStringLocalizerFactory /// Instanz eines IAuthorizationService /// Instanz von IdentityOptions /// Instanz eines IRefreshTokenService /// Instanz eines IAuditService /// Instanz eines ICustomerService /// Instanz eines IDogOwnerService public UserController(IUserService userService, UserManager userManager, RoleManager roleManager, IFileService fileService, IMapper mapper, ITicketStore ticketStore, IEmailSender emailSender, IStringLocalizer localizer, IStringLocalizerFactory localizerFactory, IAuthorizationService authorizationService, IOptions authOptions, IRefreshTokenService refreshTokenService, IAuditService auditService, ICustomerService customerService, IAppUserService appUserService) { _userService = userService; _userManager = userManager; _roleManager = roleManager; _fileService = fileService; _mapper = mapper; _ticketStore = ticketStore; _emailSender = emailSender; _localizer = localizer; _localizerFactory = localizerFactory; _authorizationService = authorizationService; _authOptions = authOptions; _refreshTokenService = refreshTokenService; _auditService = auditService; _customerService = customerService; _appUserService = appUserService; } #region Admin /// /// Gibt einen View für die Benutzerverwaltung zurück /// /// View [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.UserManage, Permission.UserRead)] 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.UserManage, Permission.UserRead)] [HttpPost] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public async Task GetUsers([FromBody] DataManager dm) { if (dm != null) { var propList = new List(); dm.SetComplexProperties(propList); } var totalCount = await _userService.CountAsync(); var resultList = _userService.FilterWithNames(dm?.SearchValue ?? ""); //Sortierung resultList = dm.ApplySorting(resultList); //Filter resultList = dm.ApplyFiltering(resultList, out var countFiltered); //Paging resultList = dm.ApplyPaging(resultList); var resultListVm = new List(); foreach (var user in resultList.ToList()) { var applicationUser = await _userService.GetByUsernameAsync(user.UserName); var userVm = _mapper.Map(user); userVm.Locked = await _userManager.IsLockedOutAsync(applicationUser); userVm.Roles = string.Join(",", (await _userManager.GetRolesAsync(applicationUser))); userVm.Photo = Tools.GetPhotoThumb(user.Photo, 100); var online = await _ticketStore.RetrieveAsync(user.UserName); userVm.IsOnline = online != null; resultListVm.Add(userVm); } //FilterPreview? if (!dm.RequiresCounts) return Json(resultListVm); return Json(new { result = resultListVm, count = countFiltered }); } /// /// Anlegen eines Benutzers /// /// PartialView [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.UserManage, Permission.UserCreate)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Create() { var model = new ApplicationUserCreateVm { Id = Guid.NewGuid().ToString(), TimeZoneId = ApplicationUser.TimeZoneId, PreferredLanguage = SelectedLanguage, Roles = new List() }; foreach (var permission in Enum.GetValues(typeof(Permission))) { model.PermissionVms.Add(new PermissionVm() { Permission = (Permission)permission, Granted = false }); } var annotationslocalizer = _localizerFactory.Create("Annotations", "Localization"); ViewBag.Permissions = PermissionDisplay.GetPermissionsToDisplay(typeof(Permission), annotationslocalizer); ViewBag.Roles = _roleManager.Roles.ToList(); if(!User.IsInRole("Administrator")) ViewBag.Roles = _roleManager.Roles.Where(c => c.Name != "Administrator").ToList(); return PartialView("_Create", model); } /// /// Anlegen eines Benutzers /// /// Model /// Json [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.UserManage, Permission.UserCreate)] [ValidateAntiForgeryToken] [HttpPost] public async Task Create(ApplicationUserCreateVm model) { var result = new ResponseVm { Success = false }; if (ModelState.IsValid) { var user = _mapper.Map(model); user.FullName = $"{model.FirstName} {model.LastName}"; user.RegistrationDate = DateTimeOffset.UtcNow; user.Id = Guid.NewGuid().ToString(); user.Photo = string.Empty; user.Email = model.UserName; user.EmailConfirmed = !_authOptions.Value.MustConfirmEmail; user.Permissions = model.PermissionVms.Where(c => c.Granted).Select(c => c.Permission).PackPermissionsIntoString(); var createResult = await _userManager.CreateAsync(user, model.Password); if (createResult.Succeeded) { foreach (var role in model.Roles) { await _userManager.AddToRoleAsync(user, role); } result.Success = createResult.Succeeded; user = await _userService.GetAsync(user.Id); if (!string.IsNullOrWhiteSpace(model.Photo)) { //Neue Bilddaten verwenden.... var extension = Path.GetExtension(model.Photo); var fileName = Path.GetFileName(model.Photo); var filenameToUse = FileServiceHelper.GetProfilePath(user.Id) + $"photo-{Guid.NewGuid():N}{extension}"; user.Photo = filenameToUse; //Kopieren var tempFile = await _fileService.GetAsync(FileServiceHelper.TempContainer, model.Photo); await _fileService.StoreAsync(FileServiceHelper.DocumentContainer, filenameToUse, tempFile); //Thumbnails await GenerateThumbnail(FileServiceHelper.DocumentContainer, filenameToUse, 200); await GenerateThumbnail(FileServiceHelper.DocumentContainer, filenameToUse, 100); await _userService.CommitAsync(User.Identity.Name); result.Success = true; } if (result.Success) { if (_authOptions.Value.MustConfirmEmail) { var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme); await _emailSender.SendEmailConfirmationAsync(user.UserName, callbackUrl, _localizer, LicenseOptions); } var userInfo = _mapper.Map(user); result.Data = userInfo.ToCamelCaseJson(); result.Html = string.Empty; return Json(result); } } else { foreach (var identityError in createResult.Errors) { ModelState.AddModelError(string.Empty, identityError.Description); } } } var annotationslocalizer = _localizerFactory.Create("Annotations", "Localization"); ViewBag.Permissions = PermissionDisplay.GetPermissionsToDisplay(typeof(Permission), annotationslocalizer); ViewBag.Roles = _roleManager.Roles.ToList(); if (!User.IsInRole("Administrator")) ViewBag.Roles = _roleManager.Roles.Where(c => c.Name != "Administrator").ToList(); result.Html = await PartialView("_Create", model).ToStringAsync(ControllerContext); return Json(result); } /// /// Bearbeiten eines Benutzers /// /// Id des Benutzers /// PartialView [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.UserManage, Permission.UserEdit)] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public async Task Edit(string id) { var user = await _userService.GetAsync(id); if (user != null) { var model = _mapper.Map(user); var roles = new List(); model.Roles = (await _userManager.GetRolesAsync(user)).ToList(); foreach (var permission in Enum.GetValues(typeof(Permission))) { if (model.Permissions.ThisPermissionIsAllowed(permission.ToString())) model.PermissionVms.Add(new PermissionVm() { Permission = (Permission)permission, Granted = true }); else model.PermissionVms.Add(new PermissionVm() { Permission = (Permission)permission, Granted = false }); } var annotationslocalizer = _localizerFactory.Create("Annotations", "Localization"); ViewBag.Permissions = PermissionDisplay.GetPermissionsToDisplay(typeof(Permission), annotationslocalizer); var customer = await _customerService.GetAsync(user.CustomerId); model.CustomerName = customer != null ? customer.Name : ""; var appUser = await _appUserService.GetAsync(user.AppUserId); model.AppUserName = appUser != null ? $"{appUser.FirstName} {appUser.LastName}" : ""; //Zugriff auf Daten wegen DSGVO loggen await _auditService.LogAccessAsync(user.Id, user.AuditTable(), User.Identity.Name); ViewBag.Roles = _roleManager.Roles.ToList(); if (!User.IsInRole("Administrator")) ViewBag.Roles = _roleManager.Roles.Where(c => c.Name != "Administrator").ToList(); return PartialView("_Edit", model); } return PartialView("_Error"); } /// /// Bearbeiten eines Benutzers /// /// Model /// Json [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.UserManage, Permission.UserEdit)] [ValidateAntiForgeryToken] [HttpPost] public async Task Edit(ApplicationUserVm model) { var result = new ResponseVm { Success = false }; if (ModelState.IsValid) { var user = await _userService.GetAsync(model.Id); if (user != null) { var nameChanged = user.FirstName != model.FirstName || user.LastName != model.LastName; var oldRoles = (await _userManager.GetRolesAsync(user)).ToList(); var rolesChanged = oldRoles.SequenceEqual(oldRoles); var oldPhoto = user.Photo; _mapper.Map(model, user); user.FullName = $"{model.FirstName} {model.LastName}"; user.Permissions = model.PermissionVms.Where(c => c.Granted).Select(c => c.Permission).PackPermissionsIntoString(); if (user.UserName == User.Identity.Name && (await _authorizationService.AuthorizeAsync(User, Policies.AdministratorOnly)).Succeeded) { user.Permissions = user.Permissions.AddPermission(Permission.UserManage.ToString()); } if (oldPhoto != user.Photo) { //Alte Daten löschen, neue Daten anlegen if (!string.IsNullOrWhiteSpace(oldPhoto)) { await _fileService.DeleteAsync(FileServiceHelper.DocumentContainer, oldPhoto); await RemoveThumbnail(FileServiceHelper.DocumentContainer, oldPhoto, 200); await RemoveThumbnail(FileServiceHelper.DocumentContainer, oldPhoto, 100); } if (!string.IsNullOrWhiteSpace(user.Photo)) { //Neue Bilddaten verwenden.... var extension = Path.GetExtension(user.Photo); var fileName = Path.GetFileName(user.Photo); var filenameToUse = FileServiceHelper.GetProfilePath(user.Id) + $"photo-{Guid.NewGuid():N}{extension}"; user.Photo = filenameToUse; //Kopieren var tempFile = await _fileService.GetAsync(FileServiceHelper.TempContainer, model.Photo); await _fileService.StoreAsync(FileServiceHelper.DocumentContainer, filenameToUse, tempFile); //Thumbnails await GenerateThumbnail(FileServiceHelper.DocumentContainer, filenameToUse, 200); await GenerateThumbnail(FileServiceHelper.DocumentContainer, filenameToUse, 100); } } await _userService.CommitAsync(User.Identity.Name); if (rolesChanged) { var roleUser = await _userManager.FindByIdAsync(user.Id); await _userManager.RemoveFromRolesAsync(roleUser, oldRoles); await _userManager.AddToRolesAsync(roleUser, model.Roles); if (user.UserName == User.Identity.Name) { if ((await _authorizationService.AuthorizeAsync(User, Policies.AdministratorOnly)).Succeeded && !model.Roles.Contains("Administrator")) await _userManager.AddToRoleAsync(roleUser, "Administrator"); } } var ticket = await _ticketStore.RetrieveAsync(user.UserName); if (ticket != null) { var principal = ticket.Principal; var claimsIdentity = (ClaimsIdentity)principal.Identity; claimsIdentity.AddUpdateClaim(ClaimConstants.PackedPermissionClaimType, user.Permissions); #region customer var customerName = ""; var customerUniqueId = ""; if (user.CustomerId.HasValue) { var customer = await _customerService.GetAsync(user.CustomerId.Value); if (customer != null) { customerName = customer.Name; customerUniqueId = customer.UniqueId.ToString(); } } claimsIdentity.AddUpdateClaim(ClaimConstants.CustomerIdClaimType, user.CustomerId.ToString()); claimsIdentity.AddUpdateClaim(ClaimConstants.CustomerNameClaimType, customerName); claimsIdentity.AddUpdateClaim(ClaimConstants.CustomerUniqueIdClaimType, customerUniqueId); #endregion #region AppUser var appUserName = ""; if (!string.IsNullOrWhiteSpace(user.AppUserId)) { var appUser = await _appUserService.GetAsync(user.AppUserId); if (appUser != null) { appUserName = $"{appUser.FirstName} {appUser.LastName}"; } } claimsIdentity.AddUpdateClaim(ClaimConstants.AppUserIdClaimType, user.AppUserId); claimsIdentity.AddUpdateClaim(ClaimConstants.AppUserNameClaimType, appUserName); #endregion #region roles var rolesClaims = ticket.Principal.Claims.Where(c => c.Type == ClaimTypes.Role).ToList(); foreach (var rolesClaim in rolesClaims) { claimsIdentity.RemoveClaim(rolesClaim); } var roles = await _userManager.GetRolesAsync(user); foreach (var role in roles) { claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, role)); } #endregion var newTicket = new AuthenticationTicket(principal, ticket.Properties, IdentityConstants.ApplicationScheme); await _ticketStore.RenewAsync(user.UserName, newTicket); } result.Success = true; var userInfo = _mapper.Map(user); result.Data = userInfo.ToCamelCaseJson(); result.Html = string.Empty; return Json(new { result.Success, result.Html, result.Data }); } } var annotationslocalizer = _localizerFactory.Create("Annotations", "Localization"); ViewBag.Permissions = PermissionDisplay.GetPermissionsToDisplay(typeof(Permission), annotationslocalizer); ViewBag.Roles = _roleManager.Roles.ToList(); if (!User.IsInRole("Administrator")) ViewBag.Roles = _roleManager.Roles.Where(c => c.Name != "Administrator").ToList(); ModelState.Remove("CustomerName"); var customerToSet = await _customerService.GetAsync(model.CustomerId); model.CustomerName = customerToSet != null ? customerToSet.Name : ""; ModelState.Remove("AppUserName"); var appUserToSet = await _appUserService.GetAsync(model.AppUserId); model.AppUserName = appUserToSet != null ? $"{appUserToSet.FirstName} {appUserToSet.LastName}" : ""; result.Html = await PartialView("_Edit", model).ToStringAsync(ControllerContext); return Json(result); } /// /// Löschen eines Benutzers /// /// Liste Id der Entität /// Json [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.UserManage, Permission.UserDelete)] [HttpPost] public async Task Delete(List ids) { var batchErrorHeader = $"

{_localizer["Common_BatchDelete_Failed"].Value}

"; var batchResult = new BatchResponseVm(batchErrorHeader) { Success = true }; foreach (var id in ids) { var item = await _userService.GetAsync(id); if (item != null) { var projectCount = 0; var customerCount = 0; if (projectCount == 0 && customerCount == 0) { if (item.UserName != User.Identity.Name) { batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = item.Id.ToString(), Name = item.UserName, Success = true, NotFound = false, ErrorMessage = "" }); var postingPath = FileServiceHelper.GetProfilePath(item.Id); await _fileService.ClearDirectoryAsync(FileServiceHelper.DocumentContainer, postingPath); await RemoveThumbnail(FileServiceHelper.DocumentContainer, item.Photo, 200); await RemoveThumbnail(FileServiceHelper.DocumentContainer, item.Photo, 100); await _ticketStore.RemoveAsync(item.UserName); await _refreshTokenService.RemoveAllAsync(item.Id, User.Identity.Name); _userService.Remove(item); } else { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = item.UserName, Success = false, NotFound = false, ErrorMessage = string.Format(_localizer["Common_BatchDelete_Self"], $"{item.UserName}") + "
" }); } } else { if (projectCount != 0) { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = item.UserName, Success = false, NotFound = false, ErrorMessage = string.Format(_localizer["Common_BatchDelete_InUse_Proejcts"], $"{item.UserName}", $"{projectCount}") + "
" }); } if (customerCount != 0) { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = item.UserName, Success = false, NotFound = false, ErrorMessage = string.Format(_localizer["Common_BatchDelete_InUse_Customers"], $"{item.UserName}", $"{customerCount}") + "
" }); } } } 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 _userService.CommitAsync(User.Identity.Name); return Json(batchResult); } /// /// Sperren eines Benutzers /// /// Liste Id der Entität /// Json [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.UserManage)] [HttpPost] public async Task Lock(List ids) { var batchErrorHeader = $"

{_localizer["User_BatchLock_Failed"].Value}

"; var batchResult = new BatchResponseVm(batchErrorHeader) { Success = true }; foreach (var id in ids) { var item = await _userService.GetAsync(id); if (item != null) { if (item.UserName != User.Identity.Name) { batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = item.Id.ToString(), Name = item.UserName, Success = true, NotFound = false, ErrorMessage = "" }); item.LockoutEnd = DateTimeOffset.UtcNow.AddYears(5); await _ticketStore.RemoveAsync(item.UserName); } else { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = item.UserName, Success = false, NotFound = false, ErrorMessage = string.Format(_localizer["User_Batch_Lock"], $"{item.UserName}") + "
" }); } } else { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = "", Success = false, NotFound = true, ErrorMessage = string.Format(_localizer["Common_Batch_NotFound"], $"{id}") + "
" }); } } if (batchResult.BatchResponseList.Any(c => c.Success)) await _userService.CommitAsync(User.Identity.Name); return Json(batchResult); } /// /// Entsperren eines Benutzers /// /// Liste Id der Entität /// Json [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.UserManage)] [HttpPost] public async Task Unlock(List ids) { var batchErrorHeader = $"

{_localizer["User_BatchUnlock_Failed"].Value}

"; var batchResult = new BatchResponseVm(batchErrorHeader) { Success = true }; foreach (var id in ids) { var item = await _userService.GetAsync(id); if (item != null) { if (item.UserName != User.Identity.Name) { batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = item.Id.ToString(), Name = item.UserName, Success = true, NotFound = false, ErrorMessage = "" }); item.LockoutEnd = null; } else { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = item.UserName, Success = false, NotFound = false, ErrorMessage = string.Format(_localizer["User_Batch_Lock"], $"{item.UserName}") + "
" }); } } else { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = "", Success = false, NotFound = true, ErrorMessage = string.Format(_localizer["Common_Batch_NotFound"], $"{id}") + "
" }); } } if (batchResult.BatchResponseList.Any(c => c.Success)) await _userService.CommitAsync(User.Identity.Name); return Json(batchResult); } /// /// Neusetzen des Passworts eines Benutzers /// /// Liste Id der Entität /// Json [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.UserManage)] [HttpPost] public async Task ResetPassword(List ids) { var batchErrorHeader = $"

{_localizer["User_BatchResetPassword_Failed"].Value}

"; var batchResult = new BatchResponseVm(batchErrorHeader) { Success = true }; foreach (var id in ids) { var item = await _userService.GetAsync(id); if (item != null) { if (item.UserName != User.Identity.Name) { var token = await _userManager.GeneratePasswordResetTokenAsync(item); var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = item.Id, code = token }, protocol: Request.Scheme); await _emailSender.SendPasswordResetAsync(item.UserName, callbackUrl, _localizer, LicenseOptions); batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = item.Id.ToString(), Name = item.UserName, Success = true, NotFound = false, ErrorMessage = "", Data = callbackUrl}); } else { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = item.UserName, Success = false, NotFound = false, ErrorMessage = string.Format(_localizer["User_Batch_ResetPassword"], $"{item.UserName}") + "
" }); } } else { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = "", Success = false, NotFound = true, ErrorMessage = string.Format(_localizer["Common_Batch_NotFound"], $"{id}") + "
" }); } } return Json(batchResult); } /// /// Gibt zurück welche Permissions mit einer Rolle verknüpft sind /// /// Gesuchte Rolle /// Json - Liste Permissions [Authorize(Policy = Policies.PowerUserOnly)] public async Task GetPermissionsForRole(string role) { var permissions = new List(); if (!string.IsNullOrWhiteSpace(role)) { var roleItem = await _roleManager.FindByNameAsync(role); if (roleItem != null) { if (!string.IsNullOrWhiteSpace(roleItem.Permissions)) { permissions.AddRange(roleItem.Permissions.UnpackPermissionsFromString()); } } } var serializer = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, DateFormatHandling = DateFormatHandling.IsoDateFormat, Converters = new List() }; serializer.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter()); return Json(permissions, serializer); } /// /// Bestätigen der Email-Adresse eines Benutzers /// /// Id des Benutzers /// JSON [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.UserManage)] [HttpPost] public async Task ConfirmEmailAddress(string id) { var result = new ResponseVm { Success = false }; var item = await _userService.GetAsync(id); if (item != null && item.EmailConfirmed == false) { item.EmailConfirmed = true; await _userService.CommitAsync(User.Identity.Name); result.Success = true; } return Json(result); } /// /// Bestätigen der Email-Adresse an einen Benutzers senden /// /// Id des Benutzers /// JSON [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.UserManage)] [HttpPost] public async Task SendConfirmEmailAddress(string id) { var result = new ResponseVm { Success = false }; var item = await _userService.GetAsync(id); if (item != null && item.EmailConfirmed == false) { var code = await _userManager.GenerateEmailConfirmationTokenAsync(item); var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = item.Id, code = code }, protocol: HttpContext.Request.Scheme); await _emailSender.SendEmailConfirmationAsync(item.UserName, callbackUrl, _localizer, LicenseOptions); result.Success = true; } return Json(result); } /// /// Bestätigen der Email-Adresse an einen Benutzers senden /// /// Id des Benutzers /// JSON [Authorize(Policy = Policies.PowerUserOnly)] [HasPermission(Permission.UserManage)] [HttpPost] public async Task TwoFactorDisable(string id) { var result = new ResponseVm { Success = false }; var item = await _userManager.FindByIdAsync(id); if (item != null && item.TwoFactorEnabled) { var disable2faResult = await _userManager.SetTwoFactorEnabledAsync(item, false); if (disable2faResult.Succeeded) { result.Success = true; } } return Json(result); } #endregion #region Customer / Kunden /// /// Gibt einen View für die Benutzerverwaltung für Kunden zurück /// /// View [Authorize(Policy = Policies.CustomerOnly)] [HasPermission(Permission.UserManage, Permission.UserRead)] public IActionResult IndexCustomer() { var customerId = User.CustomerUniqueId(); return View(customerId); } /// /// Gibt eine Liste von Entitäten basierend auf Abfragekriterien zurück /// /// Abfragekriterien /// UniqueId des Kunden /// Liste von gefundenen Entitäten [Authorize(Policy = Policies.CustomerOnly)] [HasPermission(Permission.UserManage, Permission.UserRead)] [CustomerAuthorize("customerUniqueId")] [HttpPost] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public async Task GetUsersCustomer([FromBody] DataManager dm, Guid customerUniqueId) { if (dm != null) { var propList = new List(); dm.SetComplexProperties(propList); } long customerId = -1; var customer = await _customerService.GetByUniqueIdAsync(customerUniqueId); if (customer != null) customerId = customer.Id; var resultList = _userService.FilterWithNamesCustomer(dm?.SearchValue ?? "", customerId); //Sortierung resultList = dm.ApplySorting(resultList); //Filter resultList = dm.ApplyFiltering(resultList, out var countFiltered); //Paging resultList = dm.ApplyPaging(resultList); var resultListVm = new List(); int removeCount = 0; foreach (var user in resultList.ToList()) { var applicationUser = await _userService.GetByUsernameAsync(user.UserName); if (await _userManager.IsInRoleAsync(applicationUser, "Administrator") || await _userManager.IsInRoleAsync(applicationUser, "PowerUser")) { removeCount += 1; continue; } var userVm = _mapper.Map(user); userVm.Locked = await _userManager.IsLockedOutAsync(applicationUser); userVm.Photo = Tools.GetProfileImage(user.Photo); userVm.Roles = string.Join(",", (await _userManager.GetRolesAsync(applicationUser))); var online = await _ticketStore.RetrieveAsync(user.UserName); userVm.IsOnline = online != null; resultListVm.Add(userVm); } //FilterPreview? if (!dm.RequiresCounts) return Json(resultListVm); return Json(new { result = resultListVm, count = countFiltered - removeCount }); } /// /// Anlegen eines Benutzers für Kunden /// /// PartialView [Authorize(Policy = Policies.CustomerOnly)] [HasPermission(Permission.UserManage, Permission.UserCreate)] [CustomerAuthorize("customerUniqueId")] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult CreateCustomer(Guid customerUniqueId) { var model = new ApplicationUserCreateVm { Id = Guid.NewGuid().ToString(), TimeZoneId = ApplicationUser.TimeZoneId, PreferredLanguage = SelectedLanguage, Roles = new List(), CustomerId = User.CustomerId().Value }; foreach (var permission in PermissionHelper.GetForRole("Customer")) { model.PermissionVms.Add(new PermissionVm() { Permission = (Permission)permission, Granted = false }); } var annotationslocalizer = _localizerFactory.Create("Annotations", "Localization"); ViewBag.Permissions = PermissionDisplay.GetPermissionsToDisplay(typeof(Permission), "Customer", annotationslocalizer); ViewBag.Roles = _roleManager.Roles.Where(c => c.Name != "Administrator" && c.Name != "PowerUser" && c.Name != "DogOwner" && c.Name != "DogWalker").ToList(); return PartialView("_CreateCustomer", model); } /// /// Anlegen eines Benutzers für Kunden /// /// Model /// Json [Authorize(Policy = Policies.CustomerOnly)] [HasPermission(Permission.UserManage, Permission.UserCreate)] [CustomerAuthorize("CustomerId")] [ValidateAntiForgeryToken] [HttpPost] public async Task CreateCustomer(ApplicationUserCreateVm model) { var result = new ResponseVm { Success = false }; if (ModelState.IsValid) { var user = _mapper.Map(model); user.CustomerId = User.CustomerId(); user.FullName = $"{model.FirstName} {model.LastName}"; user.RegistrationDate = DateTimeOffset.UtcNow; user.Id = Guid.NewGuid().ToString(); user.Photo = string.Empty; user.Email = model.UserName; user.EmailConfirmed = !_authOptions.Value.MustConfirmEmail; user.Permissions = model.PermissionVms.Where(c => c.Granted).Select(c => c.Permission).PackPermissionsIntoString(); var createResult = await _userManager.CreateAsync(user, model.Password); if (createResult.Succeeded) { foreach (var role in model.Roles) { await _userManager.AddToRoleAsync(user, role); } result.Success = createResult.Succeeded; user = await _userService.GetAsync(user.Id); if (!string.IsNullOrWhiteSpace(model.Photo)) { //Neue Bilddaten verwenden.... var extension = Path.GetExtension(model.Photo); var fileName = Path.GetFileName(model.Photo); var filenameToUse = FileServiceHelper.GetProfilePath(user.Id) + $"photo-{Guid.NewGuid():N}{extension}"; user.Photo = filenameToUse; //Kopieren var tempFile = await _fileService.GetAsync(FileServiceHelper.TempContainer, model.Photo); await _fileService.StoreAsync(FileServiceHelper.DocumentContainer, filenameToUse, tempFile); //Thumbnails await GenerateThumbnail(FileServiceHelper.DocumentContainer, filenameToUse, 200); await GenerateThumbnail(FileServiceHelper.DocumentContainer, filenameToUse, 100); await _userService.CommitAsync(User.Identity.Name); result.Success = true; } if (result.Success) { if (_authOptions.Value.MustConfirmEmail) { var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme); await _emailSender.SendEmailConfirmationAsync(user.UserName, callbackUrl, _localizer, LicenseOptions); } var userInfo = _mapper.Map(user); result.Data = userInfo.ToCamelCaseJson(); result.Html = string.Empty; return Json(result); } } else { foreach (var identityError in createResult.Errors) { ModelState.AddModelError(string.Empty, identityError.Description); } } } var annotationslocalizer = _localizerFactory.Create("Annotations", "Localization"); ViewBag.Permissions = PermissionDisplay.GetPermissionsToDisplay(typeof(Permission), "Customer", annotationslocalizer); ViewBag.Roles = _roleManager.Roles.Where(c => c.Name != "Administrator" && c.Name != "PowerUser" && c.Name != "DogOwner" && c.Name != "DogWalker").ToList(); result.Html = await PartialView("_CreateCustomer", model).ToStringAsync(ControllerContext); return Json(result); } /// /// Bearbeiten eines Benutzers für Kunden /// /// Id des Benutzers /// UniqueId des Kunden /// PartialView [Authorize(Policy = Policies.CustomerOnly)] [HasPermission(Permission.UserManage, Permission.UserEdit)] [CustomerAuthorize("customerUniqueId")] [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public async Task EditCustomer(string id, Guid customerUniqueId) { var user = await _userService.GetAsync(id); if (user != null && user.CustomerId == User.CustomerId()) { var model = _mapper.Map(user); var roles = new List(); model.Roles = (await _userManager.GetRolesAsync(user)).ToList(); foreach (var permission in PermissionHelper.GetForRole("Customer")) { if (model.Permissions.ThisPermissionIsAllowed(permission.ToString())) model.PermissionVms.Add(new PermissionVm() { Permission = (Permission)permission, Granted = true }); else model.PermissionVms.Add(new PermissionVm() { Permission = (Permission)permission, Granted = false }); } var annotationslocalizer = _localizerFactory.Create("Annotations", "Localization"); ViewBag.Permissions = PermissionDisplay.GetPermissionsToDisplay(typeof(Permission), "Customer", annotationslocalizer); ViewBag.Roles = _roleManager.Roles.Where(c => c.Name != "Administrator" && c.Name != "PowerUser" && c.Name != "DogOwner" && c.Name != "DogWalker").ToList(); //Zugriff auf Daten wegen DSGVO loggen await _auditService.LogAccessAsync(user.Id, user.AuditTable(), User.Identity.Name); return PartialView("_EditCustomer", model); } return PartialView("_Error"); } /// /// Bearbeiten eines Benutzers für Kunden /// /// Model /// Json [Authorize(Policy = Policies.CustomerOnly)] [HasPermission(Permission.UserManage, Permission.UserEdit)] [CustomerAuthorize("CustomerId")] [ValidateAntiForgeryToken] [HttpPost] public async Task EditCustomer(ApplicationUserVm model) { var result = new ResponseVm { Success = false }; if (ModelState.IsValid) { var user = await _userService.GetAsync(model.Id); if (user != null && user.CustomerId == User.CustomerId()) { var nameChanged = user.FirstName != model.FirstName || user.LastName != model.LastName; var oldRoles = (await _userManager.GetRolesAsync(user)).ToList(); var rolesChanged = oldRoles.SequenceEqual(oldRoles); var oldPhoto = user.Photo; _mapper.Map(model, user); user.FullName = $"{model.FirstName} {model.LastName}"; user.Permissions = model.PermissionVms.Where(c => c.Granted).Select(c => c.Permission).PackPermissionsIntoString(); if (oldPhoto != user.Photo) { //Alte Daten löschen, neue Daten anlegen if (!string.IsNullOrWhiteSpace(oldPhoto)) { await _fileService.DeleteAsync(FileServiceHelper.DocumentContainer, oldPhoto); await RemoveThumbnail(FileServiceHelper.DocumentContainer, oldPhoto, 200); await RemoveThumbnail(FileServiceHelper.DocumentContainer, oldPhoto, 100); } if (!string.IsNullOrWhiteSpace(user.Photo)) { //Neue Bilddaten verwenden.... var extension = Path.GetExtension(user.Photo); var fileName = Path.GetFileName(user.Photo); var filenameToUse = FileServiceHelper.GetProfilePath(user.Id) + $"photo-{Guid.NewGuid():N}{extension}"; user.Photo = filenameToUse; //Kopieren var tempFile = await _fileService.GetAsync(FileServiceHelper.TempContainer, model.Photo); await _fileService.StoreAsync(FileServiceHelper.DocumentContainer, filenameToUse, tempFile); //Thumbnails await GenerateThumbnail(FileServiceHelper.DocumentContainer, filenameToUse, 200); await GenerateThumbnail(FileServiceHelper.DocumentContainer, filenameToUse, 100); } } await _userService.CommitAsync(User.Identity.Name); if (rolesChanged) { var roleUser = await _userManager.FindByIdAsync(user.Id); await _userManager.RemoveFromRolesAsync(roleUser, oldRoles); await _userManager.AddToRolesAsync(roleUser, model.Roles); } var ticket = await _ticketStore.RetrieveAsync(user.UserName); if (ticket != null) { var principal = ticket.Principal; var claimsIdentity = (ClaimsIdentity)principal.Identity; claimsIdentity.AddUpdateClaim(ClaimConstants.PackedPermissionClaimType, user.Permissions); #region customer var customerName = ""; var customerUniqueId = ""; if (user.CustomerId.HasValue) { var customer = await _customerService.GetAsync(user.CustomerId.Value); if (customer != null) { customerName = customer.Name; customerUniqueId = customer.UniqueId.ToString(); } } claimsIdentity.AddUpdateClaim(ClaimConstants.CustomerIdClaimType, user.CustomerId.ToString()); claimsIdentity.AddUpdateClaim(ClaimConstants.CustomerNameClaimType, customerName); claimsIdentity.AddUpdateClaim(ClaimConstants.CustomerUniqueIdClaimType, customerUniqueId); #endregion #region AppUser var appUserName = ""; if (!string.IsNullOrWhiteSpace(user.AppUserId)) { var appUser = await _appUserService.GetAsync(user.AppUserId); if (appUser != null) { appUserName = $"{appUser.FirstName} {appUser.LastName}"; } } claimsIdentity.AddUpdateClaim(ClaimConstants.AppUserIdClaimType, user.AppUserId); claimsIdentity.AddUpdateClaim(ClaimConstants.AppUserNameClaimType, appUserName); #endregion #region roles var rolesClaims = ticket.Principal.Claims.Where(c => c.Type == ClaimTypes.Role).ToList(); foreach (var rolesClaim in rolesClaims) { claimsIdentity.RemoveClaim(rolesClaim); } var roles = await _userManager.GetRolesAsync(user); foreach (var role in roles) { claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, role)); } #endregion var newTicket = new AuthenticationTicket(principal, ticket.Properties, IdentityConstants.ApplicationScheme); await _ticketStore.RenewAsync(user.UserName, newTicket); } result.Success = true; var userInfo = _mapper.Map(user); result.Data = userInfo.ToCamelCaseJson(); result.Html = string.Empty; return Json(new { result.Success, result.Html, result.Data }); } } var annotationslocalizer = _localizerFactory.Create("Annotations", "Localization"); ViewBag.Permissions = PermissionDisplay.GetPermissionsToDisplay(typeof(Permission), "Customer", annotationslocalizer); ViewBag.Roles = _roleManager.Roles.Where(c => c.Name != "Administrator" && c.Name != "PowerUser" && c.Name != "DogOwner" && c.Name != "DogWalker").ToList(); result.Html = await PartialView("_EditCustomer", model).ToStringAsync(ControllerContext); return Json(result); } /// /// Löschen eines Benutzers für Kunden /// /// Liste Id der Entität /// UniqueId des Kunden /// Json [Authorize(Policy = Policies.CustomerOnly)] [HasPermission(Permission.UserManage, Permission.UserDelete)] [CustomerAuthorize("customerUniqueId")] [HttpPost] public async Task DeleteCustomer(List ids, [FromQuery] Guid customerUniqueId) { var batchErrorHeader = $"

{_localizer["Common_BatchDelete_Failed"].Value}

"; var batchResult = new BatchResponseVm(batchErrorHeader) { Success = true }; foreach (var id in ids) { var item = await _userService.GetAsync(id); if (item != null) { var projectCount = 0; var customerCount = 0; if (projectCount == 0 && customerCount == 0) { if (item.UserName != User.Identity.Name) { batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = item.Id.ToString(), Name = item.UserName, Success = true, NotFound = false, ErrorMessage = "" }); var postingPath = FileServiceHelper.GetProfilePath(item.Id); await _fileService.ClearDirectoryAsync(FileServiceHelper.DocumentContainer, postingPath); await RemoveThumbnail(FileServiceHelper.DocumentContainer, item.Photo, 200); await RemoveThumbnail(FileServiceHelper.DocumentContainer, item.Photo, 100); await _ticketStore.RemoveAsync(item.UserName); await _refreshTokenService.RemoveAllAsync(item.Id, User.Identity.Name); _userService.Remove(item); } else { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = item.UserName, Success = false, NotFound = false, ErrorMessage = string.Format(_localizer["Common_BatchDelete_Self"], $"{item.UserName}") + "
" }); } } else { if (projectCount != 0) { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = item.UserName, Success = false, NotFound = false, ErrorMessage = string.Format(_localizer["Common_BatchDelete_InUse_Proejcts"], $"{item.UserName}", $"{projectCount}") + "
" }); } if (customerCount != 0) { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = item.UserName, Success = false, NotFound = false, ErrorMessage = string.Format(_localizer["Common_BatchDelete_InUse_Customers"], $"{item.UserName}", $"{customerCount}") + "
" }); } } } 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 _userService.CommitAsync(User.Identity.Name); return Json(batchResult); } /// /// Sperren eines Benutzers für Kunden /// /// Liste Id der Entität /// UniqueId des Kunden /// Json [Authorize(Policy = Policies.CustomerOnly)] [HasPermission(Permission.UserManage)] [HttpPost] public async Task LockCustomer(List ids, [FromQuery] Guid customerUniqueId) { var batchErrorHeader = $"

{_localizer["User_BatchLock_Failed"].Value}

"; var batchResult = new BatchResponseVm(batchErrorHeader) { Success = true }; foreach (var id in ids) { var item = await _userService.GetAsync(id); if (item != null) { if (item.UserName != User.Identity.Name) { batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = item.Id.ToString(), Name = item.UserName, Success = true, NotFound = false, ErrorMessage = "" }); item.LockoutEnd = DateTimeOffset.UtcNow.AddYears(5); await _ticketStore.RemoveAsync(item.UserName); } else { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = item.UserName, Success = false, NotFound = false, ErrorMessage = string.Format(_localizer["User_Batch_Lock"], $"{item.UserName}") + "
" }); } } else { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = "", Success = false, NotFound = true, ErrorMessage = string.Format(_localizer["Common_Batch_NotFound"], $"{id}") + "
" }); } } if (batchResult.BatchResponseList.Any(c => c.Success)) await _userService.CommitAsync(User.Identity.Name); return Json(batchResult); } /// /// Entsperren eines Benutzers für Kunden /// /// Liste Id der Entität /// UniqueId des Kunden /// Json [Authorize(Policy = Policies.CustomerOnly)] [HasPermission(Permission.UserManage)] [HttpPost] public async Task UnlockCustomer(List ids, [FromQuery] Guid customerUniqueId) { var batchErrorHeader = $"

{_localizer["User_BatchUnlock_Failed"].Value}

"; var batchResult = new BatchResponseVm(batchErrorHeader) { Success = true }; foreach (var id in ids) { var item = await _userService.GetAsync(id); if (item != null) { if (item.UserName != User.Identity.Name) { batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = item.Id.ToString(), Name = item.UserName, Success = true, NotFound = false, ErrorMessage = "" }); item.LockoutEnd = null; } else { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = item.UserName, Success = false, NotFound = false, ErrorMessage = string.Format(_localizer["User_Batch_Lock"], $"{item.UserName}") + "
" }); } } else { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = "", Success = false, NotFound = true, ErrorMessage = string.Format(_localizer["Common_Batch_NotFound"], $"{id}") + "
" }); } } if (batchResult.BatchResponseList.Any(c => c.Success)) await _userService.CommitAsync(User.Identity.Name); return Json(batchResult); } /// /// Neusetzen des Passworts eines Benutzers für Kunden /// /// Liste Id der Entität /// UniqueId des Kunden /// Json [Authorize(Policy = Policies.CustomerOnly)] [HasPermission(Permission.UserManage)] [HttpPost] public async Task ResetPasswordCustomer(List ids, [FromQuery] Guid customerUniqueId) { var batchErrorHeader = $"

{_localizer["User_BatchResetPassword_Failed"].Value}

"; var batchResult = new BatchResponseVm(batchErrorHeader) { Success = true }; foreach (var id in ids) { var item = await _userService.GetAsync(id); if (item != null) { if (item.UserName != User.Identity.Name) { batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = item.Id.ToString(), Name = item.UserName, Success = true, NotFound = false, ErrorMessage = "" }); var token = await _userManager.GeneratePasswordResetTokenAsync(item); var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = item.Id, code = token }, protocol: Request.Scheme); await _emailSender.SendPasswordResetAsync(item.UserName, callbackUrl, _localizer, LicenseOptions); } else { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = item.UserName, Success = false, NotFound = false, ErrorMessage = string.Format(_localizer["User_Batch_ResetPassword"], $"{item.UserName}") + "
" }); } } else { batchResult.Success = false; batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = "", Success = false, NotFound = true, ErrorMessage = string.Format(_localizer["Common_Batch_NotFound"], $"{id}") + "
" }); } } return Json(batchResult); } /// /// Gibt zurück welche Permissions mit einer Rolle verknüpft sind für Kunden /// /// Gesuchte Rolle /// Json - Liste Permissions [Authorize(Policy = Policies.CustomerOnly)] public async Task GetPermissionsForRoleCustomer(string role) { var permissions = new List(); if (!string.IsNullOrWhiteSpace(role)) { var roleItem = await _roleManager.FindByNameAsync(role); if (roleItem != null) { if (!string.IsNullOrWhiteSpace(roleItem.Permissions)) { permissions.AddRange(roleItem.Permissions.UnpackPermissionsFromString()); } } } var serializer = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, DateFormatHandling = DateFormatHandling.IsoDateFormat, Converters = new List() }; serializer.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter()); return Json(permissions, serializer); } /// /// Bestätigen der Email-Adresse eines Benutzers für Kunden /// /// Id des Benutzers /// UniqueId des Kunden /// JSON [Authorize(Policy = Policies.CustomerOnly)] [HasPermission(Permission.UserManage)] [HttpPost] public async Task ConfirmEmailAddressCustomer(string id, [FromQuery] Guid customerUniqueId) { var result = new ResponseVm { Success = false }; var item = await _userService.GetAsync(id); if (item != null && item.EmailConfirmed == false) { item.EmailConfirmed = true; await _userService.CommitAsync(User.Identity.Name); result.Success = true; } return Json(result); } /// /// Bestätigen der Email-Adresse an einen Benutzers senden für Kunden /// /// Id des Benutzers /// UniqueId des Kunden /// JSON [Authorize(Policy = Policies.CustomerOnly)] [HasPermission(Permission.UserManage)] [HttpPost] public async Task SendConfirmEmailAddressCustomer(string id, [FromQuery] Guid customerUniqueId) { var result = new ResponseVm { Success = false }; var item = await _userService.GetAsync(id); if (item != null && item.EmailConfirmed == false) { var code = await _userManager.GenerateEmailConfirmationTokenAsync(item); var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = item.Id, code = code }, protocol: HttpContext.Request.Scheme); await _emailSender.SendEmailConfirmationAsync(item.UserName, callbackUrl, _localizer, LicenseOptions); result.Success = true; } return Json(result); } /// /// Bestätigen der Email-Adresse an einen Benutzers senden für Kunden /// /// Id des Benutzers /// UniqueId des Kunden /// JSON [Authorize(Policy = Policies.CustomerOnly)] [HasPermission(Permission.UserManage)] [HttpPost] public async Task TwoFactorDisableCustomer(string id, [FromQuery] Guid customerUniqueId) { var result = new ResponseVm { Success = false }; var item = await _userManager.FindByIdAsync(id); if (item != null && item.TwoFactorEnabled) { var disable2faResult = await _userManager.SetTwoFactorEnabledAsync(item, false); if (disable2faResult.Succeeded) { result.Success = true; } } return Json(result); } #endregion #region Upload /// /// Hochladen eines Files. Speichert ins temporäre Verzeichnis /// /// Bild-Datei /// Json true wenn erfolgreich, false sons [Authorize(Policy = Policies.CustomerOnly)] [HttpPost] public async Task UploadTempFile(IFormFile file, [FromQuery] string uid) { if (file.Length > 0) { try { var userInfo = await UserService.GetByUsernameAsync(ApplicationUser.UserName); var path = Path.GetFileName(file.FileName); var extension = Path.GetExtension(path); var fileName = FileServiceHelper.GetProfilePath(userInfo.Id) + 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 = "" }); } /// /// Löschem eines Files im temporäre Verzeichnis /// /// Dateinamr Bild-Datei /// Json true wenn erfolgreich, false sons [Authorize(Policy = Policies.CustomerOnly)] [HttpPost] public async Task 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 Helper /// /// Überprüft ob die Domain einer Email-Adresse existiert und ob der Benutzername frei ist /// /// true wenn möglich, false sonst [HttpPost] public async Task IsUsernameAvailable(string userName, string id) { return Json(await _userService.IsUsernameAvailableAsync(userName, id)); } #endregion } }