public static async Task <HttpResponseMessage> UpdatePixel([HttpTrigger(AuthorizationLevel.Anonymous, "post", "options", Route = null)] HttpRequestMessage req, ILogger log, ExecutionContext context) { if (req.Method == HttpMethod.Options) { var res = req.CreateResponse(); ApplyCORSRules(req, res); return(res); } string userId; string idp; DateTime time = DateTime.UtcNow; // Validate the user is authenticated try { // "x-ms-client-principal-id" is the flag that this is a valid token userId = req.Headers.FirstOrDefault(h => string.Equals(h.Key, "x-ms-client-principal-id", StringComparison.OrdinalIgnoreCase)).Value?.FirstOrDefault() ?? throw new InvalidOperationException("Principal id header was missing"); idp = req.Headers.FirstOrDefault(h => string.Equals(h.Key, "x-ms-client-principal-idp", StringComparison.OrdinalIgnoreCase)).Value?.FirstOrDefault() ?? throw new InvalidOperationException("Identity provider header was missing"); } catch (Exception err) { log.LogError(err); log.LogInformation($"Headers {HeadersToString(req.Headers)}"); var res = req.CreateErrorResponse(HttpStatusCode.Unauthorized, $"Could not authenticate user. Reference {context.InvocationId} for details."); ApplyCORSRules(req, res); return(res); } // Grab pixels from request Pixel[] pixels; try { pixels = await req.Content.ReadAsAsync <Pixel[]>(); } catch (Exception err) { log.LogError(err); var res = req.CreateErrorResponse(HttpStatusCode.BadRequest, $"Could not create pixel object from body content. Refer to {context.InvocationId} for details."); ApplyCORSRules(req, res); return(res); } // Block bad users // User throttling // Admin should be the only one allowed to insert more than 1 pixel // Admin should be hte only one allowed to insert more often than 30 seconds try { UserService us = UserService.GetDefaultSingleton(); User user = await us.GetOrCreateUser(userId); if (user.IsBlocked == true) { // log for telemetry and then silently return their results. log.LogInformation($"User {userId} is blocked."); var fakeRes = req.CreateResponse(HttpStatusCode.Created, new { timestamp = time }); ApplyCORSRules(req, fakeRes); return(fakeRes); } user.IsAdmin = (idp == "aad"); // All users logged in through AAD are admins, everyone else is not if (pixels.Length > 1 && !user.IsAdmin) { var res = req.CreateErrorResponse(HttpStatusCode.BadRequest, $"User can only insert 1 pixel at a time. Refer to {context.InvocationId} for details."); ApplyCORSRules(req, res); return(res); } if (!user.IsAdmin && user.LastInsert > time.AddSeconds(-1 * GetThrottleRate())) { var res = req.CreateErrorResponse((HttpStatusCode)429, $"Too many pixel inserts. Refer to {context.InvocationId} for details."); ApplyCORSRules(req, res); return(res); } user.LastInsert = time; await us.UpsertUser(user); } catch (Exception err) { log.LogError(err); var res = req.CreateErrorResponse(HttpStatusCode.BadRequest, $"Issue validating user. Refer to {context.InvocationId} for details."); ApplyCORSRules(req, res); return(res); } // Insert pixels into Cosmos DB try { PixelService ps = PixelService.Singleton(); await ps.InsertBatch(pixels, userId, time); } catch (Exception err) { log.LogError(err); var res = req.CreateErrorResponse(HttpStatusCode.InternalServerError, $"Could not insert pixels. Refer to {context.InvocationId} for details."); ApplyCORSRules(req, res); return(res); } var response = req.CreateResponse(HttpStatusCode.Created, new { timestamp = time }); ApplyCORSRules(req, response); return(response); }
static async Task Main(string[] args) { var logPath = @"E:\proj\my\ImageGallery\log\pexel"; var pixel_dbPath = @"E:\proj\my\ImageGallery\pixel.db"; //var im_dbPath = @"E:\proj\my\ImageGallery\im.db"; var im_dbPath = @"E:\proj\my\ImageGallery\test.im.db"; //var jsonDbPath= @"E:\proj\my\ImageGallery\db.json"; var jsonDbPath = @"E:\proj\my\ImageGallery\test.db.json"; var userAgentsPath = @"E:\proj\github\ichensky\ImageGallery\data\useragents.txt"; var pixelMigrationsPath = @"E:\proj\github\ichensky\ImageGallery\src\db\pixel.txt"; var imMigrationsPath = @"E:\proj\github\ichensky\ImageGallery\src\db\im.txt"; var pathToGoogleKeys = @"E:\proj\github\ichensky\ImageGallery\keys\google"; var msVisionKeysPath = @"E:\proj\github\ichensky\ImageGallery\keys\msvisionkeys.txt"; LogManager.Configuration = LoggerService.DefaultConfiguration(logPath); var logger = LogManager.GetLogger(Services.Logger.log.ToString()); var userAgents = await File.ReadAllLinesAsync(userAgentsPath); var userAgentsService = new UserAgentService(logger, userAgents); var stopwatchService = new StopwatchService(logger); var attemptService = new AttemptService(logger); var httpClientSerive = new HttpClientService(logger, stopwatchService, userAgentsService); var usersParser = new UsersParser(logger, httpClientSerive, attemptService); var imagesParser = new ImagesParser(logger, httpClientSerive, attemptService); var imageMetaParser = new ImageMetaParser(logger, httpClientSerive, attemptService); var fileLoader = new FileLoader(logger, httpClientSerive, attemptService); var googleService = new GoogleService(logger, pathToGoogleKeys); var msvisionService = new MSVisionService(logger, msVisionKeysPath); var pixel_builder = new DbContextOptionsBuilder().UseSqlite($"Data Source={pixel_dbPath}"); var imBuilder = new DbContextOptionsBuilder().UseSqlite($"Data Source={im_dbPath}"); //await googleService.Clean(); //var migrationService = new MigrationsService(pixel_builder.Options); //logger.Info("Applying migrations to database."); //await migrationService.MigrateAsync(migrationsPath); var pixelService = new PixelService(logger, pixel_builder.Options, usersParser, imagesParser, imageMetaParser, fileLoader, googleService, msvisionService); //await pixelService.UpdateUsers(5514); //await pixelService.UpdateUsersImages(16124); //await pixelService.UpdateImagesMeta(388970); //await pixelService.PixelImagesToGoogle(); //await pixelService.CleanGoogleImages(); //-- //-- //await pixelService.LoadMSVisionMeta(); //-- //-- //var jsonDb = await pixelService.GenJsonDb(); //File.WriteAllText(jsonDbPath, jsonDb); //-- //-- if (File.Exists(im_dbPath)) { var err = "Deleting database file ..."; logger.Warn(err); File.Delete(im_dbPath); } var migrationService = new MigrationsService(imBuilder.Options); logger.Info("Applying migrations to database."); await migrationService.MigrateAsync(imMigrationsPath); //var im_connection = new Microsoft.Data.Sqlite.SqliteConnection($"DataSource={im_dbPath}"); //im_connection.Open(); //var connectionInMemory = new Microsoft.Data.Sqlite.SqliteConnection("DataSource=:memory:"); //connectionInMemory.Open(); //var builderInMemory = new DbContextOptionsBuilder().UseSqlite(connectionInMemory); //im_connection.BackupDatabase(connectionInMemory); var pixelToImageGalleryService = new PixelToImageGalleryService( logger, pixel_builder.Options, imBuilder.Options); //builderInMemory.Options); //-- //var jsonDb = await pixelToImageGalleryService.GenJsonDb(); //File.WriteAllText(jsonDbPath, jsonDb); //-- var json = File.ReadAllText(jsonDbPath); await pixelToImageGalleryService.GenDb(json); //connectionInMemory.BackupDatabase(im_connection); Console.WriteLine("Hello World!"); }