This commit is contained in:
Paul Schneider 2026-02-28 21:17:54 +00:00
commit 40e8e08690
3487 changed files with 39 additions and 21 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,75 @@
using System.Security.Claims;
using Microsoft.AspNetCore.Mvc;
namespace Yavsc.Controllers
{
using Microsoft.EntityFrameworkCore;
using Models;
using Models.Identity;
public class DevicesController : Controller
{
private readonly ApplicationDbContext _context;
public DevicesController(ApplicationDbContext context)
{
_context = context;
}
// GET: GCMDevices
public async Task<IActionResult> Index()
{
var uid = User.FindFirstValue(ClaimTypes.NameIdentifier);
var applicationDbContext = _context.DeviceDeclaration.Include(g => g.DeviceOwner).Where(d=>d.DeviceOwnerId == uid);
return View(await applicationDbContext.ToListAsync());
}
// GET: GCMDevices/Details/5
public async Task<IActionResult> Details(string id)
{
if (id == null)
{
return NotFound();
}
DeviceDeclaration googleCloudMobileDeclaration = await _context.DeviceDeclaration.SingleAsync(m => m.DeviceId == id);
if (googleCloudMobileDeclaration == null)
{
return NotFound();
}
return View(googleCloudMobileDeclaration);
}
// GET: GCMDevices/Delete/5
[ActionName("Delete")]
public async Task<IActionResult> Delete(string id)
{
if (id == null)
{
return NotFound();
}
DeviceDeclaration googleCloudMobileDeclaration = await _context.DeviceDeclaration.SingleAsync(m => m.DeviceId == id);
if (googleCloudMobileDeclaration == null)
{
return NotFound();
}
return View(googleCloudMobileDeclaration);
}
// POST: GCMDevices/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(string id)
{
DeviceDeclaration googleCloudMobileDeclaration = await _context.DeviceDeclaration.SingleAsync(m => m.DeviceId == id);
_context.DeviceDeclaration.Remove(googleCloudMobileDeclaration);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
}
}

View file

@ -0,0 +1,228 @@
/*
Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/
Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.
Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
Source code and license this software can be found
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*/
using System.Security.Claims;
using IdentityModel;
using IdentityServer8;
using IdentityServer8.Events;
using IdentityServer8.Services;
using IdentityServer8.Stores;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Yavsc;
using Yavsc.Extensions;
using Yavsc.Interfaces;
using Yavsc.Models;
namespace IdentityServerHost.Quickstart.UI;
[SecurityHeaders]
[AllowAnonymous]
public class ExternalController : Controller
{
private readonly IIdentityServerInteractionService _interaction;
private readonly IClientStore _clientStore;
private readonly ILogger<ExternalController> _logger;
private readonly IEventService _events;
private IExternalIdentityManager _users;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly RoleManager<IdentityRole> _roleManager;
private readonly ApplicationDbContext _dbContext;
public ExternalController(
IIdentityServerInteractionService interaction,
IClientStore clientStore,
IEventService events,
ILogger<ExternalController> logger,
IExternalIdentityManager externalIdentityProviderManager,
SignInManager<ApplicationUser> signInManager,
ApplicationDbContext dbContext,
RoleManager<IdentityRole> roleManager
)
{
// if the TestUserStore is not in DI, then we'll just use the global users collection
// this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)
_users = externalIdentityProviderManager;
_interaction = interaction;
_clientStore = clientStore;
_logger = logger;
_events = events;
_signInManager = signInManager;
_roleManager = roleManager;
_dbContext = dbContext;
}
/// <summary>
/// initiate roundtrip to external authentication provider
/// </summary>
[HttpGet]
public IActionResult Challenge(string scheme, string returnUrl)
{
if (string.IsNullOrEmpty(returnUrl)) returnUrl = "~/";
// validate returnUrl - either it is a valid OIDC URL or back to a local page
if (Url.IsLocalUrl(returnUrl) == false && _interaction.IsValidReturnUrl(returnUrl) == false)
{
// user might have clicked on a malicious link - should be logged
throw new Exception("invalid return URL");
}
// start challenge and roundtrip the return URL and scheme
var props = new AuthenticationProperties
{
RedirectUri = Url.Action(nameof(Callback)),
Items =
{
{ "returnUrl", returnUrl },
{ "scheme", scheme },
}
};
return Challenge(props, scheme);
}
/// <summary>
/// Post processing of external authentication
/// </summary>
[HttpGet]
public async Task<IActionResult> Callback()
{
// read external identity from the temporary cookie
var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
if (result?.Succeeded != true)
{
throw new Exception("External authentication error");
}
if (_logger.IsEnabled(LogLevel.Debug))
{
var externalClaims = result.Principal.Claims.Select(c => $"{c.Type}: {c.Value}");
_logger.LogDebug("External claims: {@claims}", externalClaims);
}
// lookup our user and external provider info
var (user, provider, providerUserId, claims) = await FindUserFromExternalProvider(result);
if (user == null)
{
// this might be where you might initiate a custom workflow for user registration
// in this sample we don't show how that would be done, as our sample implementation
// simply auto-provisions new external user
user = AutoProvisionUser(provider, providerUserId, claims);
}
// this allows us to collect any additional claims or properties
// for the specific protocols used and store them in the local auth cookie.
// this is typically used to store data needed for signout from those protocols.
var additionalLocalClaims = new List<Claim>();
var localSignInProps = new AuthenticationProperties();
ProcessLoginCallback(result, additionalLocalClaims, localSignInProps);
// issue authentication cookie for user
var isuser = new IdentityServerUser(user.Id)
{
DisplayName = user.UserName,
IdentityProvider = provider,
AdditionalClaims = additionalLocalClaims
};
await HttpContext.SignInAsync(isuser, localSignInProps);
//await HttpContext.SignInAsync(user, _roleManager, false, _dbContext);
// delete temporary cookie used during external authentication
await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
// retrieve return URL
var returnUrl = result.Properties.Items["returnUrl"] ?? "~/";
// check if external login is in the context of an OIDC request
var context = await _interaction.GetAuthorizationContextAsync(returnUrl);
await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.Id, user.UserName, true, context?.Client.ClientId));
if (context != null)
{
if (context.IsNativeClient())
{
// The client is native, so this change in how to
// return the response is for better UX for the end user.
return this.LoadingPage("Redirect", returnUrl);
}
}
return Redirect(returnUrl);
}
private async Task<(ApplicationUser user,
string provider,
string providerUserId,
IEnumerable<Claim> claims)>
FindUserFromExternalProvider(AuthenticateResult result)
{
var externalUser = result.Principal;
// try to determine the unique id of the external user (issued by the provider)
// the most common claim type for that are the sub claim and the NameIdentifier
// depending on the external provider, some other claim type might be used
var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ??
externalUser.FindFirst(ClaimTypes.NameIdentifier) ??
throw new Exception("Unknown userid");
// remove the user id claim so we don't include it as an extra claim if/when we provision the user
var claims = externalUser.Claims.ToList();
claims.Remove(userIdClaim);
var provider = result.Properties.Items["scheme"];
var providerUserId = userIdClaim.Value;
// find external user
ApplicationUser? user = await _users.FindByExternaleProviderAsync (provider, providerUserId);
return (user, provider, providerUserId, claims);
}
/// <summary>
/// Register a new user by external id
/// </summary>
/// <param name="provider"></param>
/// <param name="providerUserId"></param>
/// <param name="claims"></param>
/// <returns></returns>
private ApplicationUser AutoProvisionUser(string provider, string providerUserId, IEnumerable<Claim> claims)
{
var user = _users.AutoProvisionUser(provider, providerUserId, claims.ToList());
return user;
}
// if the external login is OIDC-based, there are certain things we need to preserve to make logout work
// this will be different for WS-Fed, SAML2p or other protocols
private void ProcessLoginCallback(AuthenticateResult externalResult, List<Claim> localClaims, AuthenticationProperties localSignInProps)
{
// if the external system sent a session id claim, copy it over
// so we can use it for single sign-out
var sid = externalResult.Principal.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId);
if (sid != null)
{
localClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value));
}
// if the external provider issued an id_token, we'll keep it for signout
var idToken = externalResult.Properties.GetTokenValue("id_token");
if (idToken != null)
{
localSignInProps.StoreTokens(new[] { new AuthenticationToken { Name = "id_token", Value = idToken } });
}
}
}

View file

@ -0,0 +1,22 @@
/*
Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/
Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.
Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
Source code and license this software can be found
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*/
using System.Security.Claims;
using Yavsc.Models;
namespace Yavsc.Interfaces;
public interface IExternalIdentityManager
{
ApplicationUser AutoProvisionUser(string provider, string providerUserId, List<Claim> claims);
Task<ApplicationUser?> FindByExternaleProviderAsync(string provider, string providerUserId);
}

View file

@ -0,0 +1,763 @@
using System.Security.Claims;
using System.IO;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Yavsc.Models.Workflow;
using Yavsc.Helpers;
using Yavsc.Models.Relationship;
using Yavsc.Models.Bank;
using Yavsc.ViewModels.Calendar;
using Yavsc.Models;
using Yavsc.Services;
using Yavsc.ViewModels.Manage;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Authorization;
using Yavsc.Server.Helpers;
namespace Yavsc.Controllers
{
[Authorize]
public class ManageController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IEmailSender _emailSender;
private readonly ILogger _logger;
private readonly SiteSettings _siteSettings;
private readonly ApplicationDbContext _dbContext;
private readonly GoogleAuthSettings _googleSettings;
private readonly PayPalSettings _payPalSettings;
private readonly IYavscMessageSender _GCMSender;
private readonly SIRENChecker _cchecker;
private readonly IStringLocalizer _SR;
private readonly CompanyInfoSettings _cinfoSettings;
readonly ICalendarManager _calendarManager;
public ManageController(
ApplicationDbContext context,
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IEmailSender emailSender,
IYavscMessageSender GCMSender,
IOptions<SiteSettings> siteSettings,
IOptions<GoogleAuthSettings> googleSettings,
IOptions<PayPalSettings> paypalSettings,
IOptions<CompanyInfoSettings> cinfoSettings,
IStringLocalizer<ManageController> SR,
ICalendarManager calendarManager,
ILoggerFactory loggerFactory)
{
_dbContext = context;
_userManager = userManager;
_signInManager = signInManager;
_emailSender = emailSender;
_GCMSender = GCMSender;
_siteSettings = siteSettings.Value;
_googleSettings = googleSettings.Value;
_payPalSettings = paypalSettings.Value;
_cinfoSettings = cinfoSettings.Value;
_cchecker = new SIRENChecker(cinfoSettings.Value);
_SR = SR;
_calendarManager = calendarManager;
_logger = loggerFactory.CreateLogger<ManageController>();
}
//
// GET: /Manage/Index
[HttpGet]
public async Task<IActionResult> Index(ManageMessageId? message = null)
{
ViewData["StatusMessage"] =
message == ManageMessageId.ChangePasswordSuccess ? _SR["Your password has been changed."]
: message == ManageMessageId.SetPasswordSuccess ? _SR["Your password has been set."]
: message == ManageMessageId.SetTwoFactorSuccess ? _SR["Your two-factor authentication provider has been set."]
: message == ManageMessageId.Error ? _SR["An error has occurred."]
: message == ManageMessageId.AddPhoneSuccess ? _SR["Your phone number was added."]
: message == ManageMessageId.RemovePhoneSuccess ? _SR["Your phone number was removed."]
: message == ManageMessageId.ChangeNameSuccess ? _SR["Your name was updated."]
: message == ManageMessageId.SetActivitySuccess ? _SR["Your activity was set."]
: message == ManageMessageId.AvatarUpdateSuccess ? _SR["Your avatar was updated."]
: message == ManageMessageId.IdentityUpdateSuccess ? _SR["Your identity was updated."]
: message == ManageMessageId.SetBankInfoSuccess ? _SR["Vos informations bancaires ont bien été enregistrées."]
: message == ManageMessageId.SetAddressSuccess ? _SR["Votre adresse a bien été enregistrée."]
: message == ManageMessageId.SetMonthlyEmailSuccess ? _SR["Vos préférences concernant la lettre mensuelle ont été sauvegardées."]
: message == ManageMessageId.SetFullNameSuccess ? _SR["Votre nom complet a été renseigné."]
: "";
var user = await GetCurrentUserAsync();
long pc = _dbContext.BlogSpot.Count(x => x.AuthorId == user.Id);
var model = new IndexViewModel
{
HasPassword = await _userManager.HasPasswordAsync(user),
PhoneNumber = await _userManager.GetPhoneNumberAsync(user),
TwoFactor = await _userManager.GetTwoFactorEnabledAsync(user),
Logins = await _userManager.GetLoginsAsync(user),
BrowserRemembered = await _signInManager.IsTwoFactorClientRememberedAsync(user),
UserName = user.UserName,
PostsCounter = pc,
Balance = user.AccountBalance,
ActiveCommandCount = _dbContext.RdvQueries.Count(x => (x.ClientId == user.Id) && (x.EventDate > DateTime.Now)),
HasDedicatedCalendar = !string.IsNullOrEmpty(user.DedicatedGoogleCalendar),
Roles = await _userManager.GetRolesAsync(user),
PostalAddress = user.PostalAddress?.Address,
FullName = user.FullName,
Avatar = user.Avatar,
BankInfo = user.BankInfo,
DiskUsage = user.DiskUsage,
DiskQuota = user.DiskQuota,
DedicatedCalendarId = user.DedicatedGoogleCalendar,
EMail = user.Email,
EmailConfirmed = await _userManager.IsEmailConfirmedAsync(user),
AllowMonthlyEmail = user.AllowMonthlyEmail,
Address = user.PostalAddress?.Address
};
model.HaveProfessionalSettings = _dbContext.Performers.Any(x => x.PerformerId == user.Id);
var usrActs = _dbContext.UserActivities.Include(a=>a.Does).Where(a=> a.UserId == user.Id).ToArray();
// TODO remember me who this magical a.Settings is built
var usrActToSet = usrActs.Where( a => ( a.Settings == null && a.Does.SettingsClassName != null )).ToArray();
model.HaveActivityToConfigure = usrActToSet .Count()>0;
model.Activity = _dbContext.UserActivities.Include(a=>a.Does).Where(u=>u.UserId == user.Id).ToList();
return View(model);
}
[HttpGet]
public async Task<IActionResult> ProfileEMailUsage ()
{
var user = await GetCurrentUserAsync();
return View("ProfileEMailUsage", new ProfileEMailUsageViewModel(user));
}
[HttpPost]
public async Task<IActionResult> ProfileEMailUsage (ProfileEMailUsageViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
// Generate the token and send it
var user = await GetCurrentUserAsync();
user.AllowMonthlyEmail = model.Allow;
await this._dbContext.SaveChangesAsync(User.GetUserId());
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetMonthlyEmailSuccess });
}
//
// POST: /Manage/RemoveLogin
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RemoveLogin(RemoveLoginViewModel account)
{
ManageMessageId? message = ManageMessageId.Error;
var user = await GetCurrentUserAsync();
if (user != null)
{
var result = await _userManager.RemoveLoginAsync(user, account.LoginProvider, account.ProviderKey);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
message = ManageMessageId.RemoveLoginSuccess;
}
}
return RedirectToAction(nameof(ManageLogins), new { Message = message });
}
//
// GET: /Manage/AddPhoneNumber
public IActionResult AddPhoneNumber()
{
return View();
}
//
// POST: /Manage/AddPhoneNumber
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddPhoneNumber(AddPhoneNumberViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
// Generate the token and send it
var user = await GetCurrentUserAsync();
var code = await _userManager.GenerateChangePhoneNumberTokenAsync(user, model.PhoneNumber);
// TODO ? await _smsSender.SendSmsAsync(_twilioSettings, model.PhoneNumber, "Your security code is: " + code);
return RedirectToAction(nameof(VerifyPhoneNumber), new { model.PhoneNumber });
}
//
// POST: /Manage/EnableTwoFactorAuthentication
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> EnableTwoFactorAuthentication()
{
var user = await GetCurrentUserAsync();
if (user != null)
{
await _userManager.SetTwoFactorEnabledAsync(user, true);
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation(1, "User enabled two-factor authentication.");
}
return RedirectToAction(nameof(Index), "Manage");
}
//
// POST: /Manage/DisableTwoFactorAuthentication
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DisableTwoFactorAuthentication()
{
var user = await GetCurrentUserAsync();
if (user != null)
{
await _userManager.SetTwoFactorEnabledAsync(user, false);
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation(2, "User disabled two-factor authentication.");
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.UnsetTwoFactorSuccess });
}
return RedirectToAction(nameof(Index), "Manage");
}
//
// GET: /Manage/VerifyPhoneNumber
[HttpGet]
public async Task<IActionResult> VerifyPhoneNumber(string phoneNumber)
{
var code = await _userManager.GenerateChangePhoneNumberTokenAsync(await GetCurrentUserAsync(), phoneNumber);
// Send an SMS to verify the phone number
return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber });
}
//
// POST: /Manage/VerifyPhoneNumber
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> VerifyPhoneNumber(VerifyPhoneNumberViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await GetCurrentUserAsync();
if (user != null)
{
var result = await _userManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.Code);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.AddPhoneSuccess });
}
}
// If we got this far, something failed, redisplay the form
ModelState.AddModelError(string.Empty, "Failed to verify phone number");
return View(model);
}
//
// GET: /Manage/RemovePhoneNumber
[HttpGet]
public async Task<IActionResult> RemovePhoneNumber()
{
var user = await GetCurrentUserAsync();
if (user != null)
{
var result = await _userManager.SetPhoneNumberAsync(user, null);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.RemovePhoneSuccess });
}
}
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
}
//
// GET: /Manage/ChangePassword
[HttpGet]
public IActionResult ChangePassword()
{
return View();
}
[HttpGet]
public async Task<IActionResult> SetGoogleCalendar(string returnUrl, string pageToken)
{
var uid = User.FindFirstValue(ClaimTypes.NameIdentifier);
var calendars = await _calendarManager.GetCalendarsAsync(pageToken);
return View(new SetGoogleCalendarViewModel {
ReturnUrl = returnUrl,
Calendars = calendars
});
}
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> SetGoogleCalendar(SetGoogleCalendarViewModel model)
{
var user = _dbContext.Users.FirstOrDefault(u => u.Id == User.GetUserId());
user.DedicatedGoogleCalendar = model.GoogleCalendarId;
await _dbContext.SaveChangesAsync(User.GetUserId());
if (string.IsNullOrEmpty(model.ReturnUrl))
return RedirectToAction("Index");
else return Redirect(model.ReturnUrl);
}
[HttpGet]
public async Task<IActionResult> AddBankInfo()
{
var uid = User.FindFirstValue(ClaimTypes.NameIdentifier);
var user = await _dbContext.Users.Include(u=>u.BankInfo).SingleAsync(u=>u.Id==uid);
return View(user.BankInfo);
}
[HttpPost]
public async Task<IActionResult> AddBankInfo (BankIdentity model)
{
if (ModelState.IsValid)
{
// TODO PostBankInfoRequirement & auth
var uid = User.FindFirstValue(ClaimTypes.NameIdentifier);
var user = _dbContext.Users.Include(u=>u.BankInfo)
.Single(u=>u.Id == uid);
if (user.BankInfo.Any(
bi => bi.Equals(model)
)) return BadRequest(new { message = "data already present" });
user.BankInfo.Add(model);
_dbContext.Update(user);
await _dbContext.SaveChangesAsync();
}
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetBankInfoSuccess });
}
[HttpGet]
public async Task<IActionResult> SetFullName()
{
var user = await _userManager.FindByIdAsync(User.GetUserId());
return View(new SetFullNameViewModel { FullName = user.FullName });
}
[HttpPost]
public async Task<IActionResult> SetFullName(SetFullNameViewModel model)
{
if (ModelState.IsValid)
{
var user = await _userManager.FindByIdAsync(User.GetUserId());
user.FullName = model.FullName;
await _userManager.UpdateAsync(user);
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetFullNameSuccess });
}
return View(model);
}
//
// POST: /Manage/ChangePassword
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ChangePassword(ChangePasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await GetCurrentUserAsync();
if (user != null)
{
var result = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation(3, "User changed their password successfully.");
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ChangePasswordSuccess });
}
AddErrors(result);
return View(model);
}
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
}
public IActionResult SetUserName()
{
return View(new SetUserNameViewModel() { UserName = User.Identity.Name });
}
[HttpPost]
public async Task<IActionResult> SetUserName(SetUserNameViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await GetCurrentUserAsync();
if (user != null)
{
var oldUserName = user.UserName;
var result = await this._userManager.SetUserNameAsync(user, model.UserName);
if (result.Succeeded)
{
// Renames the blog files
var userdirinfo = new DirectoryInfo(
Path.Combine(_siteSettings.Blog,
oldUserName));
var newdir = Path.Combine(_siteSettings.Blog,
model.UserName);
if (userdirinfo.Exists)
userdirinfo.MoveTo(newdir);
// Renames the Avatars files
foreach (string s in new string [] { ".png", ".s.png", ".xs.png" })
{
FileInfo fi = new FileInfo(
Path.Combine(_siteSettings.Avatars,
oldUserName+s));
if (fi.Exists)
fi.MoveTo(Path.Combine(_siteSettings.Avatars,
model.UserName+s));
}
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation(3, "User changed his user name successfully.");
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ChangeNameSuccess });
}
AddErrors(result);
return View(model);
}
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
}
//
// GET: /Manage/SetPassword
[HttpGet]
public IActionResult SetPassword()
{
return View();
}
//
// POST: /Manage/SetPassword
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> SetPassword(SetPasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await GetCurrentUserAsync();
if (user != null)
{
var result = await _userManager.AddPasswordAsync(user, model.NewPassword);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetPasswordSuccess });
}
AddErrors(result);
return View(model);
}
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
}
//GET: /Manage/ManageLogins
[HttpGet]
public async Task<IActionResult> ManageLogins(ManageMessageId? message = null)
{
ViewData["StatusMessage"] =
message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
: message == ManageMessageId.AddLoginSuccess ? "The external login was added."
: message == ManageMessageId.Error ? "An error has occurred."
: "";
var user = await GetCurrentUserAsync();
if (user == null)
{
return View("Error");
}
var userLogins = await _userManager.GetLoginsAsync(user);
ViewData["ShowRemoveButton"] = user.PasswordHash != null || userLogins.Count > 1;
return View(new ManageLoginsViewModel
{
CurrentLogins = userLogins
});
}
//
// POST: /Manage/LinkLogin
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult LinkLogin(string provider)
{
// Request a redirect to the external login provider to link a login for the current user
var redirectUrl = Url.Action("LinkLoginCallback", "Manage");
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, User.GetUserId());
return new ChallengeResult(provider, properties);
}
//
// GET: /Manage/LinkLoginCallback
[HttpGet]
public async Task<ActionResult> LinkLoginCallback()
{
var user = await GetCurrentUserAsync();
if (user == null)
{
return View("Error");
}
var info = await _signInManager.GetExternalLoginInfoAsync(User.GetUserId());
if (info == null)
{
return RedirectToAction(nameof(ManageLogins), new { Message = ManageMessageId.Error });
}
var result = await _userManager.AddLoginAsync(user, info);
var message = result.Succeeded ? ManageMessageId.AddLoginSuccess : ManageMessageId.Error;
return RedirectToAction(nameof(ManageLogins), new { Message = message });
}
[HttpGet]
public IActionResult SetAvatar()
{
return View();
}
[HttpGet]
public IActionResult SetActivity()
{
var user = GetCurrentUserAsync().Result;
var uid = user.Id;
var existing = _dbContext.Performers
.Include(p=>p.Performer)
.Include(x => x.OrganizationAddress)
.Include(p=>p.Activity)
.FirstOrDefault(x => x.PerformerId == uid);
ViewBag.GoogleSettings = _googleSettings;
if (existing!=null)
{
var currentProfile = _dbContext.Performers.Include(x => x.OrganizationAddress)
.First(x => x.PerformerId == uid);
ViewBag.Activities = _dbContext.ActivityItems(existing.Activity);
return View(currentProfile);
}
ViewBag.Activities = _dbContext.ActivityItems(new List<UserActivity>());
return View(new PerformerProfile
{
PerformerId = user.Id,
Performer = user,
OrganizationAddress = new Location()
});
}
[HttpPost]
public async Task<IActionResult> SetActivity(PerformerProfile model)
{
var user = GetCurrentUserAsync().Result;
var uid = user.Id;
try
{
if (ModelState.IsValid)
{
var exSiren = await _dbContext.ExceptionsSIREN.FirstOrDefaultAsync(
ex => ex.SIREN == model.SIREN
);
if (exSiren != null)
{
_logger.LogInformation("Exception SIREN:" + exSiren);
}
else
{
var taskCheck = await _cchecker.CheckAsync(model.SIREN);
if (!taskCheck.success)
{
ModelState.AddModelError(
"SIREN",
_SR["Invalid company number"] + " (" + taskCheck.errorCode + ")"
);
_logger.LogInformation($"Invalid company number: {model.SIREN}/{taskCheck.errorType}/{taskCheck.errorCode}/{taskCheck.errorMessage}" );
}
}
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
ModelState.AddModelError("SIREN", ex.Message);
}
if (ModelState.IsValid)
{
if (uid == model.PerformerId)
{
bool addrexists = _dbContext.Locations.Any(x => model.OrganizationAddress.Id == x.Id);
if (!addrexists)
{
_dbContext.Locations.Add(model.OrganizationAddress);
}
if (_dbContext.Performers.Any(p=>p.PerformerId == uid))
{
_dbContext.Update(model);
}
else _dbContext.Performers.Add(model);
_dbContext.SaveChanges(User.GetUserId());
// Give this user the Performer role
if (!User.IsInMsRole("Performer"))
await _userManager.AddToRoleAsync(user, "Performer");
var message = ManageMessageId.SetActivitySuccess;
return RedirectToAction(nameof(Index), new { Message = message });
}
else ModelState.AddModelError(string.Empty, $"Access denied ({uid} vs {model.PerformerId})");
}
ViewBag.Activities = _dbContext.ActivityItems(new List<UserActivity>());
ViewBag.GoogleSettings = _googleSettings;
model.Performer = _dbContext.Users.Single(u=>u.Id == model.PerformerId);
return View(model);
}
[HttpPost]
public async Task<IActionResult> UnsetActivity()
{
var user = GetCurrentUserAsync().Result;
var uid = user.Id;
bool existing = _dbContext.Performers.Any(x => x.PerformerId == uid);
if (existing)
{
_dbContext.Performers.Remove(
_dbContext.Performers.First(x => x.PerformerId == uid)
);
_dbContext.SaveChanges(User.GetUserId());
await _userManager.RemoveFromRoleAsync(user, "Performer");
}
var message = ManageMessageId.UnsetActivitySuccess;
return RedirectToAction(nameof(Index), new { Message = message });
}
[HttpGet, Route("/Manage/Credits")]
public IActionResult Credits()
{
return View();
}
public IActionResult Credit(string id)
{
if (id == "Cancel" || id == "Return")
{
return View ("Credit"+id);
}
return View();
}
#region Helpers
private void AddErrors(IdentityResult result)
{
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
public enum ManageMessageId
{
AddPhoneSuccess,
AddLoginSuccess,
ChangePasswordSuccess,
ChangeNameSuccess,
SetTwoFactorSuccess,
UnsetTwoFactorSuccess,
SetPasswordSuccess,
RemoveLoginSuccess,
RemovePhoneSuccess,
SetActivitySuccess,
UnsetActivitySuccess,
AvatarUpdateSuccess,
IdentityUpdateSuccess,
SetBankInfoSuccess,
SetAddressSuccess,
SetMonthlyEmailSuccess,
SetFullNameSuccess,
Error
}
private async Task<ApplicationUser> GetCurrentUserAsync()
{
return await _dbContext.Users.Include(u => u.PostalAddress)
.FirstOrDefaultAsync(u => u.Id == User.GetUserId());
}
#endregion
[HttpGet]
public async Task <IActionResult> SetAddress()
{
var uid = User.FindFirstValue(ClaimTypes.NameIdentifier);
var user = await _dbContext.Users.Include(u=>u.PostalAddress).SingleAsync(u=>u.Id==uid);
ViewBag.GoogleSettings = _googleSettings;
return View (user.PostalAddress ?? new Location());
}
[HttpPost]
public async Task <IActionResult> SetAddress(Location model)
{
if (ModelState.IsValid) {
var uid = User.FindFirstValue(ClaimTypes.NameIdentifier);
var user = _dbContext.Users.Include(u=>u.PostalAddress).Single(u=>u.Id==uid);
var existingLocation = _dbContext.Locations.FirstOrDefault( x=>x.Address == model.Address
&& x.Longitude == model.Longitude && x.Latitude == model.Latitude );
if (existingLocation!=null) {
user.PostalAddressId = existingLocation.Id;
} else _dbContext.Attach<Location>(model);
user.PostalAddress = model;
await _dbContext.SaveChangesAsync();
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetAddressSuccess });
}
ViewBag.GoogleSettings = _googleSettings;
return View(model);
}
public async Task<IActionResult> PaymentInfo (string id)
{
ViewData["id"] = id;
var info = await PayPalHelpers.GetCheckoutInfo(_dbContext,id);
return View(info);
}
public IActionResult PaymentError (string id, string error)
{
ViewData["error"] = error;
ViewData["id"] = id;
return View();
}
}
}

View file

@ -0,0 +1,127 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using Yavsc.Models;
namespace Yavsc.Controllers
{
[Authorize("AdministratorOnly")]
public class UsersController : Controller
{
private readonly ApplicationDbContext _context;
public UsersController(ApplicationDbContext context)
{
_context = context;
}
// GET: Users
public async Task<IActionResult> Index()
{
var applicationDbContext = _context.ApplicationUser.Include(a => a.PostalAddress);
return View(await applicationDbContext.ToListAsync());
}
// GET: Users/Details/5
public async Task<IActionResult> Details(string id)
{
if (id == null)
{
return NotFound();
}
ApplicationUser applicationUser = await _context.ApplicationUser.SingleAsync(m => m.Id == id);
if (applicationUser == null)
{
return NotFound();
}
return View(applicationUser);
}
// GET: Users/Create
public IActionResult Create()
{
ViewData["PostalAddressId"] = new SelectList(_context.Locations, "Id", "PostalAddress");
return View();
}
// POST: Users/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(ApplicationUser applicationUser)
{
if (ModelState.IsValid)
{
_context.ApplicationUser.Add(applicationUser);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
ViewData["PostalAddressId"] = new SelectList(_context.Locations, "Id", "PostalAddress", applicationUser.PostalAddressId);
return View(applicationUser);
}
// GET: Users/Edit/5
public async Task<IActionResult> Edit(string id)
{
if (id == null)
{
return NotFound();
}
ApplicationUser applicationUser = await _context.ApplicationUser.SingleAsync(m => m.Id == id);
if (applicationUser == null)
{
return NotFound();
}
ViewData["PostalAddressId"] = new SelectList(_context.Locations, "Id", "PostalAddress", applicationUser.PostalAddressId);
return View(applicationUser);
}
// POST: Users/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(ApplicationUser applicationUser)
{
if (ModelState.IsValid)
{
_context.Update(applicationUser);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
ViewData["PostalAddressId"] = new SelectList(_context.Locations, "Id", "PostalAddress", applicationUser.PostalAddressId);
return View(applicationUser);
}
// GET: Users/Delete/5
[ActionName("Delete")]
public async Task<IActionResult> Delete(string id)
{
if (id == null)
{
return NotFound();
}
ApplicationUser applicationUser = await _context.ApplicationUser.SingleAsync(m => m.Id == id);
if (applicationUser == null)
{
return NotFound();
}
return View(applicationUser);
}
// POST: Users/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(string id)
{
ApplicationUser applicationUser = await _context.ApplicationUser.SingleAsync(m => m.Id == id);
_context.ApplicationUser.Remove(applicationUser);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
}
}