public static async Task InitializeJournalDownloadersAsync(PerformContext context)
        {
            context.WriteLine("Looking for journals do download!");

            using (var scope = Startup.ServiceProvider.CreateScope())
            {
                MSSQLDB db = scope.ServiceProvider.GetRequiredService<MSSQLDB>();
                IConfiguration configuration = scope.ServiceProvider.GetRequiredService<IConfiguration>();

                var usersToDownloadJournalsFor = await db.ExecuteListAsync<Shared.Models.User.Profile>(
    @"SELECT *
FROM user_profile
WHERE DATEDIFF(MINUTE, GETUTCDATE(), CAST(JSON_VALUE(user_settings, '$.TokenExpiration') as DATETIMEOFFSET)) > 10
AND last_notification_mail IS NULL
AND skip_download = 0
AND deleted = 0"
                );

                if (usersToDownloadJournalsFor.Count > 0)
                {
                    await SSEActivitySender.SendGlobalActivityAsync("Fetching journals from Elite", $"Downloading journals for {usersToDownloadJournalsFor.Count} users");
                }

                foreach (var user in usersToDownloadJournalsFor)
                {
                    if (RedisJobLock.IsLocked($"JournalDownloader.DownloadJournal.{user.UserIdentifier}")) continue;
                    BackgroundJob.Schedule(() => JournalDownloader.DownloadJournalAsync(user.UserIdentifier, null), TimeSpan.Zero);
                }
            }

            context.WriteLine("All done!");
        }
예제 #2
0
        public async Task <IActionResult> Authenticate()
        {
            var code  = Request.Query["code"];
            var state = Request.Query["state"];

            if (!_memoryCache.TryGetValue("frontierLogin-" + HttpContext.Connection.RemoteIpAddress.ToString(), out string storedState))
            {
                return(BadRequest("Could not find login token, try again"));
            }

            if (state != storedState)
            {
                return(Unauthorized("Invalid state, please relogin"));
            }

            var redirectUrl = string.Format("{0}://{1}{2}", Request.Scheme, Request.Host, Url.Content("~/api/journal/authenticate"));

            using var c = new HttpClient();

            var formData = new Dictionary <string, string>();

            formData.Add("grant_type", "authorization_code");
            formData.Add("code", code);
            formData.Add("client_id", _configuration["EliteDangerous:ClientId"]);
            formData.Add("client_secret", _configuration["EliteDangerous:ClientSecret"]);
            formData.Add("state", state);
            formData.Add("redirect_uri", redirectUrl);

            var result = await c.PostAsync("https://auth.frontierstore.net/token", new FormUrlEncodedContent(formData));

            var tokenInfo = JsonSerializer.Deserialize <OAuth2Response>(await result.Content.ReadAsStringAsync());

            if (result.IsSuccessStatusCode)
            {
                c.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", tokenInfo.AccessToken);

                result = await c.GetAsync("https://auth.frontierstore.net/me");

                var profile = JsonSerializer.Deserialize <FrontierProfile>(await result.Content.ReadAsStringAsync());

                var settings = new Settings
                {
                    AuthToken       = tokenInfo.AccessToken,
                    TokenExpiration = DateTimeOffset.UtcNow.AddSeconds(tokenInfo.ExpiresIn),
                    RefreshToken    = tokenInfo.RefreshToken,
                    FrontierProfile = profile
                };

                // Move this so a service later
                var matchingUser = (await _db.ExecuteListAsync <Profile>(@"
SELECT *
FROM user_profile
WHERE JSON_VALUE(user_settings, '$.FrontierProfile.customer_id') = @customerId",
                                                                         new SqlParameter("customerId", profile.CustomerId))
                                    ).FirstOrDefault();

                if (matchingUser != null)
                {
                    // Update user with new token info
                    await _db.ExecuteNonQueryAsync("UPDATE user_profile SET user_settings = @settings, last_notification_mail = NULL, skip_download = 0 WHERE user_identifier = @userIdentifier",
                                                   new SqlParameter("settings", JsonSerializer.Serialize(settings)),
                                                   new SqlParameter("userIdentifier", matchingUser.UserIdentifier)
                                                   );

                    matchingUser.UserSettings = settings;
                }
                else
                {
                    // Create new user
                    matchingUser = await _db.ExecuteSingleRowAsync <Profile>("INSERT INTO user_profile (user_settings) OUTPUT INSERTED.* VALUES (@settings)",
                                                                             new SqlParameter("settings", JsonSerializer.Serialize(settings))
                                                                             );

                    var userCount = await _db.ExecuteScalarAsync <long>("SELECT COUNT_BIG(user_identifier) FROM user_profile WHERE deleted = 0");

                    await SSEActivitySender.SendGlobalActivityAsync("A new user has registered!", $"We now have {userCount:N0} users registered!");

                    await SSEActivitySender.SendStatsActivityAsync(_db);

                    BackgroundJob.Enqueue(() => JournalDownloader.DownloadJournalAsync(matchingUser.UserIdentifier, null));
                }

                var claims = new List <Claim>()
                {
                    new Claim(ClaimTypes.Name, matchingUser.UserIdentifier.ToString())
                };

                var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);

                var authProperties = new AuthenticationProperties
                {
                    AllowRefresh = true,
                    IsPersistent = false,
                    IssuedUtc    = DateTimeOffset.UtcNow
                };

                await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);

                return(LocalRedirect("~/Index"));
            }
            else
            {
                return(new JsonResult(await result.Content.ReadAsStringAsync()));
            }
        }