// validation public static PostValidateDTO ValidatePost(PostSubmitDTO postDTO) { PostValidateDTO validatedPost = new PostValidateDTO() { post = postDTO }; if (validatedPost.post == null) { validatedPost.invalid_reason = "No post submitted."; return(validatedPost); } if (validatedPost.post.title == null) { validatedPost.invalid_reason = "No title given."; return(validatedPost); } if (validatedPost.post.body == null && validatedPost.post.url == null) { validatedPost.invalid_reason = "No body or URL."; return(validatedPost); } if (validatedPost.post.tags?.Count > 12) { validatedPost.invalid_reason = "Too many tags (max 12)"; return(validatedPost); } // check valid URL if (!string.IsNullOrEmpty(validatedPost.post.url) && !Tools.ValidateUri(validatedPost.post.url)) { validatedPost.invalid_reason = "Invalid URL"; } // if has URL validatedPost.post.type = string.IsNullOrEmpty(validatedPost.post.url) ? "post" : "url"; validatedPost.post.body = validatedPost.post.type == "post" ? validatedPost.post.body : ""; // check for provided summary if (!string.IsNullOrEmpty(validatedPost.post.summary)) { validatedPost.post.summary = validatedPost.post.summary.Length > 140 ? validatedPost.post.summary.Substring(0, 140) : validatedPost.post.summary; } validatedPost.post.title = validatedPost.post.title.Length > 80 ? validatedPost.post.title.Substring(0, 80) : validatedPost.post.title; validatedPost.post.body = validatedPost.post.body.Length > 10000 ? validatedPost.post.body.Substring(0, 10000) : validatedPost.post.body; validatedPost.post.summary = string.IsNullOrEmpty(validatedPost.post.summary) ? Tools.GenerateSummary(validatedPost.post.body) : validatedPost.post.summary; validatedPost.post.tags = Tools.ValidateTags(validatedPost.post.tags); return(validatedPost); }
// table storage stuff public static async Task <Post> InsertPost(PostSubmitDTO postDTO) { long now = Tools.ConvertToEpoch(DateTime.UtcNow); long countdown = Tools.GetCountdownFromDateTime(now); string id = countdown.ToString() + Guid.NewGuid().ToString(); Post post = new Post(id, postDTO.track_id) { body = postDTO.body, url = postDTO.url, summary = postDTO.summary, date_created = now, track_name = postDTO.track_name, tags = string.Join(",", postDTO.tags), title = postDTO.title, type = postDTO.type, has_image = false }; // TODO: process image if (Tools.ValidateUri(postDTO.image_url)) { post.has_image = await ProcessImage(id, postDTO.image_url); } var result = await TableStorageRepository.InsertPost(post); if (result == null) { return(null); } // shit hack to remove body for queue processing post.body = null; // add to queues for further processing TableStorageRepository.AddMessageToQueue("process-new-post-increment-track-tags", JsonConvert.SerializeObject(post)); TableStorageRepository.AddMessageToQueue("process-new-post-add-to-cosmos", JsonConvert.SerializeObject(post)); // check rate limit Random rnd = new Random(); if (rnd.Next(1, 8) == 3) { TableStorageRepository.AddMessageToQueue("process-new-post-check-rate-limit", post.PartitionKey); } return(post); }
public static async Task <IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "track/{trackId}/post")] HttpRequest req, string trackId, TraceWriter log) { try { KeySecret keySecret = AuthRepository.DecodeKeyAndSecret(req.Headers["X-Track-Key"]); if (keySecret == null) { return(new UnauthorizedResult()); } // validate authKey if (!AuthRepository.ValidateSHA256(trackId + keySecret.Key, keySecret.Secret)) { return(new UnauthorizedResult()); } // get post from req body string requestBody = new StreamReader(req.Body).ReadToEnd(); PostSubmitDTO post = JsonConvert.DeserializeObject <PostSubmitDTO>(requestBody); // validate post PostValidateDTO validatedPost = PostRepository.ValidatePost(post); if (validatedPost.invalid_reason != null) { return(new BadRequestObjectResult(validatedPost.invalid_reason)); } // get track TrackAuth track = await TrackRepository.GetTrack(trackId); if (track == null || track.track_key != keySecret.Key) { return(new UnauthorizedResult()); } // check rate limit if (track.rate_limit_exceeded) { return(new ForbidResult()); } // create the post validatedPost.post.track_id = trackId; validatedPost.post.track_name = track.name; Post newPost = await PostRepository.InsertPost(validatedPost.post); // if didn't create return bad response if (newPost == null) { return(new BadRequestResult()); } // convert to post DTO return(new OkObjectResult(new PostQueryDTO() { date_created = newPost.date_created, id = newPost.RowKey, summary = newPost.summary, tags = newPost.tags.Split(',').ToList(), title = newPost.title, track_id = newPost.PartitionKey, track_name = newPost.track_name, type = newPost.type, url = newPost.url })); } catch (Exception e) { log.Info(e.Message); return(new UnauthorizedResult()); } }