Ejemplo n.º 1
0
        public async Task <IActionResult> OAuth(string code = null, string state = null)
        {
            var now = DateTime.UtcNow;

            if (string.IsNullOrWhiteSpace(code))
            {
                return(BadRequest());
            }

            if (string.IsNullOrWhiteSpace(state))
            {
                return(BadRequest());
            }

            var trysKey = $"oauthtrys={Request.HttpContext.Connection.RemoteIpAddress}";
            var trys    = (int?)memoryCache.Get(trysKey);

            if (trys.HasValue)
            {
                memoryCache.Set(trysKey, trys.Value + 1, now.AddMinutes(1));
                if (trys.Value > 5)
                {
                    return(StatusCode(420, $"Too Many Requests. Try again after {now.AddSeconds(70).ToString("o")}"));
                }
            }
            else
            {
                memoryCache.Set(trysKey, 1, TimeSpan.FromMinutes(1));
            }

            var storedState = Request.Cookies["state"];

            if (storedState != state)
            {
                return(BadRequest());
            }
            Response.Cookies.Append("state", "", new CookieOptions
            {
                HttpOnly    = true,
                Expires     = DateTimeOffset.Now.AddDays(-100),
                IsEssential = true
            });

            var accessTokenResponse = await discordHttp.GetAccessToken(code);

            if (!accessTokenResponse.Scopes.Contains("identify") ||
                !accessTokenResponse.Scopes.Contains("guilds"))
            {
                return(BadRequest());
            }

            var userReponse = await discordHttp.GetCurrentUser(accessTokenResponse.AccessToken);

            if (!ulong.TryParse(userReponse.Id, out var userId))
            {
                return(BadRequest());
            }

            var unixTime  = now.AddSeconds(accessTokenResponse.ExpiresIn).ToUnixTime();
            var authEntry = new AuthEntry
            {
                AccessToken  = accessTokenResponse.AccessToken,
                Expires      = unixTime,
                RefreshToken = accessTokenResponse.RefreshToken,
                Scope        = accessTokenResponse.Scope,
                UserId       = userId,
                Avatar       = userReponse.Avatar
            };
            var newAuthEntry = await authRepo.CreateAuthEntry(authEntry);

            var cookieOptions = new CookieOptions
            {
                Expires     = DateTimeOffset.FromUnixTimeSeconds(unixTime),
                HttpOnly    = true,
                IsEssential = true,
            };

            Response.Cookies.Append("key", newAuthEntry.Key, cookieOptions);
            memoryCache.Set($"key={newAuthEntry.Key}", authEntry, TimeSpan.FromMinutes(1));
            return(RedirectToAction("Index", "Home"));
        }