public async Task <IHttpActionResult> PostNewCampaign([FromBody] Campaign_CreateBM model) { if (db.Campaigns.Where(c => c.Title == model.Title).Count() > 0) { return(Conflict()); } var thisUserId = int.Parse(User.Identity.GetUserId()); if (db.Campaigns.Where(c => c.CreatedById == thisUserId && (c.Status == CampaignStatus.PreliminaryRegistered || c.Status == CampaignStatus.CompletelyRegistered || c.Status == CampaignStatus.Waiting)).Count() >= 2) { CustomHttpExceptions.CustomHttpException(HttpStatusCode.Conflict, "The user cannot create a campaign because they already have maximum two 'Not-Accepted' campaigns"); } var todayUtc = DateTime.UtcNow.Date; if ( db.Campaigns.Where(c => c.CreatedById == thisUserId && c.CreatedDateUtc >= todayUtc).Count() >= ApplicationDbContext.GlobalSettings.SecurityDoSMaxCampaignsPerUserPerDay ) { CustomHttpExceptions.CustomHttpException(HttpStatusCode.Conflict, "The user must wait up to one day to create a new campaign"); } if (!ModelState.IsValid) { return(BadRequest(ModelState)); } //NOTE: We use Ganss sanitizer for HTML (perhaps only Story) and our own MySanitizer for the rest model.Title = Helpers.MySanitizer.StrictSanitize(model.Title); model.Tagline = Helpers.MySanitizer.StrictSanitize(model.Tagline); var campaign = new Campaign { Status = CampaignStatus.PreliminaryRegistered, CreatedById = thisUserId, TargetFund = model.TargetFund, Title = model.Title, Tagline = model.Tagline }; AddOrUpdateSlug(ref campaign); db.Campaigns.Add(campaign); await db.SaveChangesAsync(); // return CreatedAtRoute("DefaultApi", new { id = campaign.Id }, campaign); return(Created <Campaign>("DefaultApi", campaign)); }
private void AddTags(string[] tags, Campaign campaign) { var lengthyTags = tags.Where(t => t.Length > 20); if (lengthyTags.Count() > 0) { CustomHttpExceptions.CustomBadRequest("Some tags are lengthy:" + string.Join(",", lengthyTags)); } //Sanitize tags tags = tags.Select(t => Helpers.MySanitizer.StrictSanitize(t)).ToArray(); /*NOTE:AddRange is a no-op if the entity is already in the context in the Added state, but the tags added * previously are in Unchanged state so we have to add only new entities*/ var oldTags = campaign.TagMaps.ToList(); var newTags = tags.Select(t => new CampaignTag { Name = t }).ToList(); //Remove only old tags that are not in new tags foreach (var t in oldTags) { if (!tags.Contains(t.CampaignTagName)) { db.CampaignTagMaps.Remove(t); } } //add only new tags that are not in old tags var oldTagNames = oldTags.Select(ot => ot.CampaignTagName).ToArray(); foreach (var nt in newTags) { if (!TagExist(nt)) { db.CampaignTags.Add(nt); } if (!oldTagNames.Contains(nt.Name)) { db.CampaignTagMaps.Add(new CampaignTagMap { CampaignTagName = nt.Name, CampaignId = campaign.Id }); } } }
public bool CheckandUpdateWaitingStatus(Campaign campaign, string status) { if (string.Equals(status, CampaignStatus.Waiting.ToString(), StringComparison.OrdinalIgnoreCase)) { /* * NOTE: This is not neccessary and in some cases against RESTful implementation * although not practical from client-side point of view there are no problems with changing * some campaign props and request a waiting status at the same request! * //counts non-null values of model * var nonNullCount = typeof(UpdateCampaignVM).GetProperties() * .Where(p => p.GetValue(model) != null) * .Count(); * if (nonNullCount > 1) { * CustomBadRequest(string.Format( * "Model can not have Status value and other values at the same time: {0} non-null values in model" * ,nonNullCount)); * } */ ModelState.Clear(); var validationProps = typeof(Campaign_WaitingValidationModel).GetProperties().Select(p => p.Name).ToList(); //Check Null or Empty values of campaign var nullOrWhiteSpaceProps = typeof(Campaign).GetProperties() .Where(p => validationProps.Contains(p.Name)) .Where(p => string.IsNullOrWhiteSpace((p.GetValue(campaign) ?? "").ToString())) .Select(p => p.Name); if (nullOrWhiteSpaceProps.Count() > 0) { CustomHttpExceptions.CustomBadRequest("The following properties of campaign have Null or Empty values:" + string.Join(",", nullOrWhiteSpaceProps.ToArray())); } return(true); } return(false); }
public async Task <IHttpActionResult> PostCampaign(string id_or_slug, Campaign_UpdateBM model, bool soft_delete = false) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } var campaign = GetCampaignByIdOrSlug(id_or_slug); //Only the one who created the campaign can edit it //TODO: What about admins? var userId = User.Identity.GetUserId(); var user = db.Users.Find(int.Parse(userId)); if (campaign.CreatedById.ToString() != userId) { CustomHttpExceptions.CustomHttpException(HttpStatusCode.Unauthorized, string.Format( "Unauthorized: The user (Id = {0}) who has requested the update is not the creator of the campaign!", userId) ); } /*TODO: think about these conditions and code business logic accordingly: * 1) The user decides to cancel campaign in 'Waiting' status * 2) The user decides to interrupt 'Waiting' status and do some changes * 3) The user decides to remove an 'Approved' or 'Waiting' campaign */ if (campaign.Status.HasFlag(CampaignStatus.ReadOnly)) { CustomHttpExceptions.CustomHttpException(HttpStatusCode.Forbidden, "Campaign can not be modified because of its current status"); } if (soft_delete) { campaign.RemovedFlagUtc = DateTime.UtcNow; db.Entry(campaign).State = EntityState.Modified; await db.SaveChangesAsync(); return(StatusCode(HttpStatusCode.NoContent)); } UpdateCampaignByUpdateCampaignVM(ref campaign, model); AddOrUpdateSlug(ref campaign); //Checks whether there is a base64 thumbnail if (model.Base64Thumbnail != null) { var uploaderResponse = await Helpers.UploadHelper.UploadBase64ImageAsync(db, userId, model.Base64Thumbnail, FileServerTokenType.CampaignImageUpload); if (uploaderResponse.StatusCode == HttpStatusCode.OK || uploaderResponse.StatusCode == HttpStatusCode.Created) { model.ThumbnailPath = uploaderResponse.FilePath; model.ThumbnailServerId = uploaderResponse.FileServerId; campaign.ThumbnailFileServerId = model.ThumbnailServerId; campaign.ThumbnailFilePath = model.ThumbnailPath; Console.WriteLine("Thumbnail Uploaded. Thumbnail Path:" + campaign.ThumbnailFilePath); } else { Console.WriteLine("Thumbnail Upload Error Code:" + uploaderResponse.StatusCode); Console.WriteLine(uploaderResponse.Message); } } if (model.CityId != null) { if (campaign.Location != null) { var location = campaign.Location; location.CityId = (int)model.CityId; db.Entry(location).State = EntityState.Modified; } else { campaign.Location = new Location { CityId = (int)model.CityId }; } } var waitingStatus = CheckandUpdateWaitingStatus(campaign, model.Status); if (waitingStatus) { campaign.Status = CampaignStatus.Waiting | CampaignStatus.ReadOnly; if (campaign.Account == null) { campaign.Account = new Account { AccountName = "cmp_" + campaign.Id.ToString(), AccountType = AccountType.CampaignAccount }; } } if (model.Tags != null) { AddTags(model.Tags, campaign); } db.Entry(campaign).State = EntityState.Modified; await db.SaveChangesAsync(); return(StatusCode(HttpStatusCode.NoContent)); }