Exemple #1
0
        public async Task <IActionResult> OnGetAsync(string code)
        {
            if (code == null)
            {
                return(Page());
            }

            // We have now been redirected from the discord authorization.

            await _signInManager.SignOutAsync();

            var    client       = _clientFactory.CreateClient();
            string clientID     = _configuration[Constants.ClientIDKey];
            string clientSecret = _configuration[Constants.ClientSecretKey];

            var    tokenRequest = new HttpRequestMessage(HttpMethod.Post, "https://discordapp.com/api/oauth2/token");
            string parameters   = $"client_id={clientID}&client_secret={clientSecret}&grant_type=authorization_code&code={code}&redirect_uri={RedirectUrl}";

            tokenRequest.Content = new StringContent(parameters, Encoding.UTF8, "application/x-www-form-urlencoded");

            var tokenResult = await client.SendAsync(tokenRequest);

            if (!tokenResult.IsSuccessStatusCode)
            {
                ModelState.AddModelError(string.Empty, "Discord authorization failed.");
                return(Page());
            }

            var content = await tokenResult.Content.ReadAsAsync <JObject>();

            string access_token = content.Value <string>("access_token");

            var userRequest = new HttpRequestMessage(HttpMethod.Get, "https://discordapp.com/api/users/@me");

            userRequest.Headers.Add("Authorization", "Bearer " + access_token);

            var userResult = await client.SendAsync(userRequest);

            if (!userResult.IsSuccessStatusCode)
            {
                ModelState.AddModelError(string.Empty, "Discord authorization failed.");
                return(Page());
            }

            var userContent = await userResult.Content.ReadAsAsync <JObject>();

            var userId = userContent.Value <string>("id");

            var user = await _userManager.FindByIdAsync(userId);

            if (user == null)
            {
                // If the user doesn't have an account make one, but only if they have the admin role in the Redmew guild.
                var isAdmin = await _discordBot.IsAdminRoleAsync(userId);

                if (!isAdmin)
                {
                    ModelState.AddModelError(string.Empty, "Discord authorization failed - not an admin member of the Redmew guild.");
                    return(Page());
                }

                user = new ApplicationUser()
                {
                    Id       = userId,
                    UserName = userContent.Value <string>("username")
                };
                var result = await _userManager.CreateAsync(user);

                if (!result.Succeeded)
                {
                    foreach (var error in result.Errors)
                    {
                        ModelState.AddModelError(string.Empty, error.Description);
                    }

                    return(Page());
                }

                result = await _userManager.AddToRoleAsync(user, Constants.AdminRole);

                if (!result.Succeeded)
                {
                    foreach (var error in result.Errors)
                    {
                        ModelState.AddModelError(string.Empty, error.Description);
                    }

                    return(Page());
                }
            }
            else if (!await AllowedToSingIn(user))
            {
                return(Page());
            }

            await _signInManager.SignInAsync(user, isPersistent : false);

            _logger.LogInformation($"User {user.UserName} signed in using discord.");

            string returnUrl = HttpContext.Session.GetString("returnUrl") ?? "Servers";

            return(Redirect(returnUrl));
        }