public override async Task IsActiveAsync(IsActiveContext context) { context.IsActive = false; if (long.TryParse(context.Subject.GetSubjectId(), out var id)) { var guildMember = await _discordClientProvider.GetMemberAsync(id); if (guildMember is not null) { context.IsActive = _discordClientProvider.HasMemberRole(guildMember); } } }
public async Task <IActionResult> Callback(string?returnUrl = null, string?remoteError = null) { IdentityResult?identityResult; returnUrl ??= Url.Content("~/"); if (remoteError != null) { return(LocalRedirect("~/loginerror/" + LoginErrorReason.FromDiscord + "/" + remoteError)); } var info = await _signInManager.GetExternalLoginInfoAsync(); if (info == null || !long.TryParse(info.ProviderKey, out var discordId)) { _logger.LogError($"Error getting external login info. Provider key returned was {info?.ProviderKey ?? "(null)"}"); return(LocalRedirect("~/loginerror/" + LoginErrorReason.FromLoginProvider)); } DiscordMember?guildMember; try { guildMember = await _discordClientProvider.GetMemberAsync(discordId); if (guildMember is null) { return(LocalRedirect("~/loginerror/" + LoginErrorReason.NotInGuild)); } } catch (Exception ex) { _logger.LogError(ex, "A problem occurred while trying to get guild member information."); return(LocalRedirect("~/loginerror/" + LoginErrorReason.FromLoginProvider)); } if (!_discordClientProvider.HasMemberRole(guildMember)) { return(LocalRedirect("~/loginerror/" + LoginErrorReason.NotAMember)); } // Sign in the user with this external login provider if the user already has a login. //var signInResult = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: true, bypassTwoFactor: true); var user = await _signInManager.UserManager.FindByIdAsync(info.ProviderKey); if (user is not null) { if (await _signInManager.UserManager.IsLockedOutAsync(user)) { return(LocalRedirect("~/loginerror/" + LoginErrorReason.LockedOut)); } await _signInManager.SignInAsync(user, isPersistent : true, authenticationMethod : info.LoginProvider); _logger.LogInformation("{Name} logged in with {LoginProvider} provider.", info.Principal.Identity?.Name, info.LoginProvider); return(LocalRedirect(returnUrl)); } else { user = new AppUser { Id = long.Parse(info.ProviderKey), UserName = guildMember.DisplayName }; identityResult = await _signInManager.UserManager.CreateAsync(user); if (identityResult.Succeeded) { identityResult = await _signInManager.UserManager.AddLoginAsync(user, info); if (identityResult.Succeeded) { _logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider); await _signInManager.SignInAsync(user, isPersistent : true, authenticationMethod : info.LoginProvider); return(LocalRedirect(returnUrl)); } } _logger.LogError("User creation failed: {Result}", identityResult); return(LocalRedirect("~/loginerror/" + LoginErrorReason.FromAccountCreation)); } }