using gehGassi.Core.Interfaces;
using gehGassi.Core.Services;
using gehGassi.Domain.Users;
using gehGassi.Web.Helper;
using gehGassi.Web.Models;
using gehGassi.Web.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Threading.Tasks;
using gehGassi.Web.Hubs;
namespace gehGassi.Web.Controllers
{
///
/// Controller für Funktionen die via App nicht verfügbar sind, aber für App-Benutzer wichtig sind
///
[Authorize]
public class AppController : BaseController
{
private readonly ILogger _logger;
private readonly IStringLocalizer _localizer;
private readonly IEmailSender _emailSender;
private readonly IUserService _userService;
private readonly IOptions _emailSenderOptions;
private readonly UserManager _userManager;
private readonly DataProtectorTokenProvider _tokenProvider;
private readonly IRefreshTokenService _refreshTokenService;
private readonly IPushNotificationService _pushNotificationService;
private readonly IAppUserService _appUserService;
private readonly IAppHubSender _appHubSender;
///
/// Erstellt eine Instanz
///
/// Instanz eines ILogger
/// Instanz eines IStringLocalizer
/// Instanz eines IEmailSender
/// Instanz eines IUserService
/// Instanz von EmailSenderOptions
/// Instanz eines UserManager
/// Instanz eines DataProtectorTokenProvider
/// Instanz eines IRefreshTokenService
/// Instanz eines IPushNotificationService
/// Instanz eines IAppUserService
/// Instanz eines IAppHubSender
public AppController(ILogger logger, IStringLocalizer localizer, IEmailSender emailSender, IUserService userService, IOptions emailSenderOptions,
UserManager userManager, DataProtectorTokenProvider tokenProvider, IRefreshTokenService refreshTokenService, IPushNotificationService pushNotificationService, IAppUserService appUserService,
IAppHubSender appHubSender)
{
_logger = logger;
_localizer = localizer;
_emailSender = emailSender;
_userService = userService;
_emailSenderOptions = emailSenderOptions;
_userManager = userManager;
_tokenProvider = tokenProvider;
_refreshTokenService = refreshTokenService;
_pushNotificationService = pushNotificationService;
_appUserService = appUserService;
_appHubSender = appHubSender;
}
///
/// Zeigt eine View für das Löschen eines Accounts an
///
/// View
[HttpGet]
[AllowAnonymous]
public IActionResult DeleteAccount()
{
return View();
}
///
/// Handling für Account löschen
///
/// Benutzereingaben
/// Redirect oder View
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task DeleteAccount(DeleteAccountVm model)
{
if (ModelState.IsValid)
{
try
{
var user = await _userManager.FindByNameAsync(model.Email);
if (user != null && !user.LockoutEnd.HasValue)
{
var token = await _tokenProvider.GenerateAsync("deleteAccount", _userManager, user);
var callbackUrl = Url.DeleteAccountCallbackLinkApp(user.Id, token, Request.Scheme);
await _emailSender.SendDeleteAccountAsync(model.Email, callbackUrl, _localizer);
}
}
catch { }
return RedirectToAction(nameof(DeleteAccountConfirmation));
}
// If we got this far, something failed, redisplay form
return View(model);
}
///
/// Zeigt eine Bestätungun an, dass eine Email zum Löschen des Accounts versendet wurde
/// Wird in jedem Fall angezeigt, auch wenn die Email nicht versendet werden konnte
///
/// View
[HttpGet]
[AllowAnonymous]
public IActionResult DeleteAccountConfirmation()
{
return View();
}
///
/// Handler wenn ein Account Löschen Link angeklickt wurde
///
/// Id des Benutzers
/// Token-Code
/// View
[HttpGet]
[AllowAnonymous]
public async Task DoDeleteAccount(string userId, string code)
{
if (!string.IsNullOrWhiteSpace(userId))
{
if (!string.IsNullOrWhiteSpace(code))
{
var user = await _userManager.FindByIdAsync(userId);
if (user != null)
{
var isCodeValid = await _tokenProvider.ValidateAsync("deleteAccount", code, _userManager, user);
if (isCodeValid)
{
//Sperren des Benutzers
user.LockoutEnd = DateTimeOffset.UtcNow.AddYears(5);
await _userManager.UpdateAsync(user);
//Löschen aller Refresh-tokens des Benutzers da eine Abmeldung erfolgt ist
await _refreshTokenService.RemoveAllAsync(user.Id, user.UserName);
await _refreshTokenService.CommitAsync(user.UserName);
var appUser = await _appUserService.GetAsync(user.AppUserId);
if (appUser != null)
{
appUser.Locked = true;
appUser.LockedReason = "Delete account requested";
await _appUserService.CommitAsync(user.UserName);
}
//Nun Email an gehgassi senden, dass der Benutzer gelöscht werden soll
await _emailSender.SendDeleteAccountEmailAsync(user.Email, user.FirstName, user.LastName, _localizer, _emailSenderOptions);
//Senden einer Nachricht an die App dass ein Logout durchgeführt werden soll?
if (!string.IsNullOrWhiteSpace(user.AppUserId))
{
//Logout-Aufforderung via SignalR
await _appHubSender.LogoutAsync(user.AppUserId);
//Logout-Aufforderung via Push-Notification
await _pushNotificationService.SendLogoutAsync(user.AppUserId);
}
return View();
}
}
}
}
return View("DoDeleteAccountFailed");
}
}
}