public int CreateCommentRating(Forum commentForum, ISite site, int entryId, int userId, short value, Guid userHash) { if (userId == 0 && userHash == Guid.Empty) { throw ApiException.GetError(ErrorType.MissingUserAttributes); } if (entryId <= 0) { throw ApiException.GetError(ErrorType.InvalidEntryId); } var updatedValue = 0; //create unique comment hash //add comment to db try { using (IDnaDataReader reader = CreateReader("commentratingcreate")) { reader.AddParameter("postid", entryId); reader.AddParameter("forumid", commentForum.ForumID); reader.AddParameter("siteid", site.SiteID); reader.AddParameter("userid", userId); reader.AddParameter("userhash", userHash); reader.AddParameter("value", value); reader.Execute(); if (reader.HasRows && reader.Read()) { updatedValue = reader.GetInt32NullAsZero("value"); } } } catch (Exception ex) { throw new ApiException(ex.Message, ex.InnerException); } //return new comment complete with id etc return updatedValue; }
/// <summary> /// Completes all checks on the data before creating it /// </summary> /// <param name="commentForum"></param> /// <param name="comment"></param> /// <param name="site"></param> /// <param name="ignoreModeration"></param> /// <param name="forceModeration"></param> public void ValidateComment(Forum commentForum, CommentInfo comment, ISite site, out bool ignoreModeration, out bool forceModeration, out string notes, out List<Term> terms) { if (CallingUser == null || CallingUser.UserID == 0) { throw ApiException.GetError(ErrorType.MissingUserCredentials); } //check if the posting is secure try { int requireSecurePost = SiteList.GetSiteOptionValueInt(site.SiteID, "CommentForum", "EnforceSecurePosting"); if (!CallingUser.IsSecureRequest && requireSecurePost == 1) { throw ApiException.GetError(ErrorType.NotSecure); } } catch (SiteOptionNotFoundException e) { DnaDiagnostics.WriteExceptionToLog(e); } ignoreModeration = CallingUser.IsUserA(UserTypes.Editor) || CallingUser.IsUserA(UserTypes.SuperUser); if (CallingUser.IsUserA(UserTypes.BannedUser)) { throw ApiException.GetError(ErrorType.UserIsBanned); } //check if site is open if (!ignoreModeration && (site.IsEmergencyClosed || site.IsSiteScheduledClosed(DateTime.Now))) { throw ApiException.GetError(ErrorType.SiteIsClosed); } // reject comments that do not have any text if (String.IsNullOrEmpty(comment.text)) { throw ApiException.GetError(ErrorType.EmptyText); } try { //check for option - if not set then it throws exception int maxCharCount = SiteList.GetSiteOptionValueInt(site.SiteID, "CommentForum", "MaxCommentCharacterLength"); string tmpText = StringUtils.StripFormattingFromText(comment.text); if (maxCharCount != 0 && tmpText.Length > maxCharCount) { throw ApiException.GetError(ErrorType.ExceededTextLimit); } } catch (SiteOptionNotFoundException) { } try { //check for option - if not set then it throws exception int minCharCount = SiteList.GetSiteOptionValueInt(site.SiteID, "CommentForum", "MinCommentCharacterLength"); string tmpText = StringUtils.StripFormattingFromText(comment.text); if (minCharCount != 0 && tmpText.Length < minCharCount) { throw ApiException.GetError(ErrorType.MinCharLimitNotReached); } } catch (SiteOptionNotFoundException) { } //strip out invalid chars comment.text = StringUtils.StripInvalidXmlChars(comment.text); // Check to see if we're doing richtext and check if its valid xml if (comment.PostStyle == PostStyle.Style.unknown) { //default to plain text... comment.PostStyle = PostStyle.Style.richtext; } if (comment.PostStyle == PostStyle.Style.richtext) { string errormessage = string.Empty; // Check to make sure that the comment is made of valid XML if (!HtmlUtils.ParseToValidGuideML(comment.text, ref errormessage)) { DnaDiagnostics.WriteWarningToLog("Comment box post failed xml parse.", errormessage); throw ApiException.GetError(ErrorType.XmlFailedParse); } } if (commentForum.isContactForm) { //We don't want to do any terms filtering on contact forms. ignoreModeration = true; forceModeration = false; notes = string.Empty; terms = null; } else { //run against profanity filter notes = string.Empty; CheckForProfanities(site, comment.text, out forceModeration, out notes, out terms, commentForum.ForumID); forceModeration = forceModeration || (commentForum.ModerationServiceGroup > ModerationStatus.ForumStatus.Reactive); //force moderation if anything greater than reactive } }
/// <summary> /// Creates a comment for the given comment forum id /// </summary> /// <param name="commentForum"></param> /// <param name="comment">The comment to add</param> /// <returns>The created comment object</returns> public CommentInfo CreateComment(Forum commentForum, CommentInfo comment) { ISite site = SiteList.GetSite(commentForum.SiteName); bool ignoreModeration; bool forceModeration; var notes = string.Empty; string profanityxml = string.Empty; List<Term> terms = null; ValidateComment(commentForum, comment, site, out ignoreModeration, out forceModeration, out notes, out terms); if (terms != null && terms.Count > 0) { profanityxml = new Term().GetProfanityXML(terms); } //create unique comment hash Guid guid = DnaHasher.GenerateCommentHashValue(comment.text, commentForum.Id, CallingUser.UserID); //add comment to db try { using (IDnaDataReader reader = CreateReader("commentcreate")) { reader.AddParameter("commentforumid", commentForum.Id); reader.AddParameter("userid", CallingUser.UserID); if (commentForum.isContactForm) { reader.AddParameter("content", CONTACT_POST_TEXT); } else { reader.AddParameter("content", comment.text); } reader.AddParameter("hash", guid); reader.AddParameter("forcemoderation", forceModeration); //reader.AddParameter("forcepremoderation", (commentForum.ModerationServiceGroup == ModerationStatus.ForumStatus.PreMod?1:0)); reader.AddParameter("ignoremoderation", ignoreModeration); reader.AddParameter("isnotable", CallingUser.IsUserA(UserTypes.Notable)); reader.AddParameter("applyprocesspremodexpirytime", comment.ApplyProcessPremodExpiryTime); if (CallingUser.UserID != commentForum.NotSignedInUserId) {//dont include as this is data protection reader.AddParameter("ipaddress", IpAddress); reader.AddParameter("bbcuid", BbcUid); } if (CallingUser.UserID == commentForum.NotSignedInUserId && comment.User != null && !String.IsNullOrEmpty(comment.User.DisplayName)) {//add display name for not signed in comment reader.AddParameter("nickname", comment.User.DisplayName); } reader.AddIntReturnValue(); reader.AddParameter("poststyle", (int) comment.PostStyle); if (!String.IsNullOrEmpty(notes)) { reader.AddParameter("modnotes", notes); } if (false == string.IsNullOrEmpty(profanityxml)) { reader.AddParameter("profanityxml", profanityxml); } reader.Execute(); if (reader.HasRows && reader.Read()) { //all good - create comment comment.PreModPostingsModId = reader.GetInt32NullAsZero("PreModPostingModId"); comment.IsPreModerated = (reader.GetInt32NullAsZero("IsPreModerated") == 1); comment.hidden = (comment.IsPreModerated ? CommentStatus.Hidden.Hidden_AwaitingPreModeration : CommentStatus.Hidden.NotHidden); comment.text = CommentInfo.FormatComment(comment.text, comment.PostStyle, comment.hidden, CallingUser.IsUserA(UserTypes.Editor)); var displayName = CallingUser.UserName; if (CallingUser.UserID == commentForum.NotSignedInUserId && comment.User != null && !String.IsNullOrEmpty(comment.User.DisplayName)) {//add display name for not signed in comment displayName = comment.User.DisplayName; } comment.User = UserReadByCallingUser(site); comment.User.DisplayName = displayName; comment.Created = new DateTimeHelper(DateTime.Now); if (reader.GetInt32NullAsZero("postid") != 0) { // no id as it is may be pre moderated comment.ID = reader.GetInt32NullAsZero("postid"); var replacement = new Dictionary<string, string>(); replacement.Add("sitename", site.SiteName); replacement.Add("postid", comment.ID.ToString()); comment.ComplaintUri = UriDiscoverability.GetUriWithReplacments(BasePath, SiteList.GetSiteOptionValueString(site.SiteID, "General", "ComplaintUrl") , replacement); replacement = new Dictionary<string, string>(); replacement.Add("commentforumid", commentForum.Id); replacement.Add("sitename", site.SiteName); UriDiscoverability.UriType uriType = UriDiscoverability.UriType.CommentForumById; if (commentForum.isContactForm) { uriType = UriDiscoverability.UriType.ContactFormById; // We now need to store the comment in the encrypted thread entries table. using (IDnaDataReader contactDataReader = CreateReader("addencryptedcontactdetails")) { contactDataReader.AddParameter("postid", comment.ID); contactDataReader.AddParameter("text", comment.text); contactDataReader.Execute(); } } comment.ForumUri = UriDiscoverability.GetUriWithReplacments(BasePath, uriType, replacement); } else { comment.ID = 0; } } else { int returnValue; reader.TryGetIntReturnValue(out returnValue); ParseCreateCommentSpError(returnValue); } } } catch (ApiException) { throw; } catch (Exception ex) { throw new ApiException(ex.Message, ex.InnerException); } //return new comment complete with id etc return comment; }
/// <summary> /// Creates a comment for the given comment forum id /// </summary> /// <param name="commentForum"></param> /// <param name="comment">The comment to add</param> /// <returns>The created comment object</returns> public int CreateCommentRating(Forum commentForum, ISite site, int entryId, int userId, short value) { if (userId == 0 && (BbcUid == Guid.Empty || string.IsNullOrEmpty(IpAddress))) { throw ApiException.GetError(ErrorType.MissingUserAttributes); } Guid userHash = Guid.Empty; if (userId == 0) { userHash = DnaHasher.GenerateHash(BbcUid + "|" + IpAddress); } return CreateCommentRating(commentForum, site, entryId, userId, value, userHash); }
/// <summary> /// Creates a new comment forum for a specificed site. If the commentforum id already exists, then nothing will be created /// </summary> /// <param name="commentForum">The comment forum object</param> /// <param name="site"></param> /// <returns>The comment forum (either new or existing) which matches to the </returns> public CommentForum CreateCommentForum(Forum commentForum, ISite site) { if (site == null) { throw ApiException.GetError(ErrorType.UnknownSite); } var tmpCommentForum = GetCommentForumByUid(commentForum.Id, site); if (tmpCommentForum == null) { CreateForum(commentForum, site); //return comment forum data tmpCommentForum = GetCommentForumByUid(commentForum.Id, site); } return tmpCommentForum; }
/// <summary> /// performs update as well as creation /// </summary> /// <param name="commentForum"></param> /// <param name="site"></param> /// <returns></returns> public CommentForum CreateAndUpdateCommentForum(Forum commentForum, ISite site, bool? isClosed) { if (site == null) { throw ApiException.GetError(ErrorType.UnknownSite); } var tmpCommentForum = GetCommentForumByUid(commentForum.Id, site); if (tmpCommentForum == null) { CreateForum(commentForum, site); } else { UpdateForum(commentForum, site, isClosed); } //return comment forum data tmpCommentForum = GetCommentForumByUid(commentForum.Id, site); return tmpCommentForum; }
/// <summary> /// Creates a Reply comment to the given comment thread id /// </summary> /// <param name="commentForum">The forum containing the comment to post the reply to</param> /// <param name="threadId">The thread to post to</param> /// <param name="comment">The comment to add</param> /// <returns>The created comment object</returns> public CommentInfo CommentReplyCreate(Forum commentForum, int threadId, CommentInfo comment) { var site = SiteList.GetSite(commentForum.SiteName); bool ignoreModeration; bool forceModeration; var notes = string.Empty; string profanityxml = string.Empty; List<Term> terms = null; ValidateComment(commentForum, comment, site, out ignoreModeration, out forceModeration, out notes, out terms); if (terms != null && terms.Count > 0) { profanityxml = new Term().GetProfanityXML(terms); } //create unique comment hash var guid = DnaHasher.GenerateCommentHashValue(comment.text, commentForum.Id, CallingUser.UserID); //add comment to db try { using (IDnaDataReader reader = CreateReader("commentreplycreate")) { reader.AddParameter("commentforumid", commentForum.Id); reader.AddParameter("threadid", threadId); reader.AddParameter("userid", CallingUser.UserID); reader.AddParameter("content", comment.text); reader.AddParameter("hash", guid); reader.AddParameter("forcemoderation", forceModeration); //reader.AddParameter("forcepremoderation", (commentForum.ModerationServiceGroup == ModerationStatus.ForumStatus.PreMod?1:0)); reader.AddParameter("ignoremoderation", ignoreModeration); reader.AddParameter("isnotable", CallingUser.IsUserA(UserTypes.Notable)); reader.AddParameter("ipaddress", IpAddress); reader.AddParameter("bbcuid", BbcUid); reader.AddIntReturnValue(); reader.AddParameter("poststyle", (int) comment.PostStyle); if (!String.IsNullOrEmpty(notes)) { reader.AddParameter("modnotes", notes); } if (false == string.IsNullOrEmpty(profanityxml)) { reader.AddParameter("profanityxml", profanityxml); } reader.Execute(); if (reader.HasRows && reader.Read()) { //all good - create comment comment.PreModPostingsModId = reader.GetInt32NullAsZero("PreModPostingModId"); comment.IsPreModerated = (reader.GetInt32NullAsZero("IsPreModerated") == 1); comment.hidden = (comment.IsPreModerated ? CommentStatus.Hidden.Hidden_AwaitingPreModeration : CommentStatus.Hidden.NotHidden); comment.User = UserReadByCallingUser(site); comment.Created = new DateTimeHelper(DateTime.Now); //count = reader.GetInt32NullAsZero("ThreadPostCount"); if (reader.GetInt32NullAsZero("postid") != 0) { // no id as it is may be pre moderated comment.ID = reader.GetInt32NullAsZero("postid"); var replacement = new Dictionary<string, string>(); replacement.Add("sitename", site.SiteName); replacement.Add("postid", comment.ID.ToString()); comment.ComplaintUri = UriDiscoverability.GetUriWithReplacments(BasePath, SiteList.GetSiteOptionValueString(site.SiteID, "General", "ComplaintUrl") , replacement); replacement = new Dictionary<string, string>(); replacement.Add("commentforumid", commentForum.Id); replacement.Add("sitename", site.SiteName); comment.ForumUri = UriDiscoverability.GetUriWithReplacments(BasePath, UriDiscoverability.UriType. CommentForumById, replacement); comment.text = CommentInfo.FormatComment(comment.text, comment.PostStyle, comment.hidden, comment.User.Editor); } else { comment.ID = 0; } } else { int returnValue; reader.TryGetIntReturnValue(out returnValue); ParseCreateCommentSpError(returnValue); } } } catch (ApiException) { throw; } catch (Exception ex) { throw new ApiException(ex.Message, ex.InnerException); } //return new comment complete with id etc return comment; }
/// <summary> /// Creates a new comment forum for a specificed site. If the commentforum id already exists, then nothing will be created /// </summary> /// <param name="commentForum">The comment forum object</param> /// <param name="site"></param> /// <returns>The comment forum (either new or existing) which matches to the </returns> public void UpdateForum(Forum commentForum, ISite site, bool? isClosed) { //validate data if (string.IsNullOrEmpty(commentForum.Id) || commentForum.Id.Length > 255) { throw ApiException.GetError(ErrorType.InvalidForumUid); } if (string.IsNullOrEmpty(commentForum.ParentUri) || (commentForum.ParentUri.IndexOf("bbc.co.uk") < 0 && commentForum.ParentUri.IndexOf("bbc.com") < 0)) { throw ApiException.GetError(ErrorType.InvalidForumParentUri); } if (string.IsNullOrEmpty(commentForum.Title)) { throw ApiException.GetError(ErrorType.InvalidForumTitle); } if (site == null) { throw ApiException.GetError(ErrorType.UnknownSite); } using (IDnaDataReader reader = CreateReader("commentforumupdate")) { try { reader.AddParameter("uid", commentForum.Id); reader.AddParameter("url", commentForum.ParentUri); reader.AddParameter("title", commentForum.Title); reader.AddParameter("sitename", site.SiteName); reader.AddParameter("moderationstatus", (int)commentForum.ModerationServiceGroup); if (commentForum.CloseDate != DateTime.MinValue) { reader.AddParameter("closeDate", commentForum.CloseDate); } if (isClosed.HasValue) { reader.AddParameter("canwrite", !isClosed); } reader.Execute(); } catch (Exception ex) { throw new ApiException(ex.Message, ex.InnerException); //DnaApiWebProtocalException.ThrowDnaApiWebProtocalException(System.Net.HttpStatusCode.InternalServerError, ex.Message, ex); } } }
/// <summary> /// Creates a new comment forum for a specificed site. if the commentforum id already exists, then nothing will be created /// </summary> /// <param name="commentForum">The comment forum object</param> /// <param name="site"></param> /// <returns>The comment forum (either new or existing) which matches to the </returns> public void CreateForum(Forum commentForum, ISite site) { //validate data if (string.IsNullOrEmpty(commentForum.Id) || commentForum.Id.Length > 255) { throw ApiException.GetError(ErrorType.InvalidForumUid); } if (string.IsNullOrEmpty(commentForum.ParentUri) || (commentForum.ParentUri.IndexOf("bbc.co.uk") < 0 && commentForum.ParentUri.IndexOf("bbc.com") < 0)) { throw ApiException.GetError(ErrorType.InvalidForumParentUri); } if (string.IsNullOrEmpty(commentForum.Title)) { throw ApiException.GetError(ErrorType.InvalidForumTitle); } if (site == null) { throw ApiException.GetError(ErrorType.UnknownSite); } //get the inital moderation status... var moderationStatus = (int)commentForum.ModerationServiceGroup; //get forum duration in days int duration = 0; if (commentForum.CloseDate != DateTime.MinValue) { duration = (commentForum.CloseDate.Subtract(DateTime.Today)).Days; //the plus one takes to midnight } using (IDnaDataReader reader = CreateReader("commentforumcreate")) { try { reader.AddParameter("uid", commentForum.Id); reader.AddParameter("url", commentForum.ParentUri); reader.AddParameter("title", commentForum.Title); reader.AddParameter("sitename", site.SiteName); if (moderationStatus != 0) { reader.AddParameter("moderationstatus", moderationStatus); } if (duration > 0) { reader.AddParameter("duration", duration); } reader.Execute(); if (reader.Read()) { commentForum.ForumID = reader.GetInt32NullAsZero("forumid"); } } catch (Exception ex) { throw new ApiException(ex.Message, ex.InnerException); //DnaApiWebProtocalException.ThrowDnaApiWebProtocalException(System.Net.HttpStatusCode.InternalServerError, ex.Message, ex); } } //set up not signed in commenting if (commentForum.allowNotSignedInCommenting) { if (SiteList.GetSiteOptionValueBool(site.SiteID, "CommentForum", "AllowNotSignedInCommenting")) { var user = new Dna.Users.User(DnaDataReaderCreator, DnaDiagnostics, CacheManager); user.CreateAnonymousUserForForum(site.SiteID, commentForum.ForumID, ""); } } }
/// <summary> /// gets the calling user or uses the notsignedin forum user /// </summary> /// <param name="site"></param> /// <param name="forum"></param> /// <returns></returns> protected CallingUser GetCallingUserOrNotSignedInUser(ISite site, Forum forum) { CallingUser callingUser = null; bool userSignedIn = false; if (site != null) { if (String.IsNullOrEmpty(site.IdentityPolicy)) { callingUser = new CallingUser(SignInSystem.SSO, readerCreator, dnaDiagnostic, cacheManager, debugDnaUserId, siteList); userSignedIn = callingUser.IsUserSignedIn(QueryStringHelper.GetCookieValueAsString("SSO2-UID", ""), site.SSOService, site.SiteID, "", _iPAddress, bbcUidCookie); } else { callingUser = new CallingUser(SignInSystem.Identity, readerCreator, dnaDiagnostic, cacheManager, debugDnaUserId, siteList); userSignedIn = callingUser.IsUserSignedInSecure(QueryStringHelper.GetCookieValueAsString("IDENTITY", ""), QueryStringHelper.GetCookieValueAsString("IDENTITY-HTTPS", ""), site.IdentityPolicy, site.SiteID, _iPAddress, bbcUidCookie); } // Check to see if we've got a user who's signed in, but not logged in. This usualy means they haven't agreed T&Cs if (callingUser.GetSigninStatus == CallingUser.SigninStatus.SignedInNotLoggedIn) { throw new DnaWebProtocolException(new ApiException(site.IdentityPolicy, ErrorType.FailedTermsAndConditions)); } } if ((callingUser == null || !userSignedIn) && (forum.allowNotSignedInCommenting && forum.NotSignedInUserId != 0)) { userSignedIn = callingUser.CreateUserFromDnaUserID(forum.NotSignedInUserId, site.SiteID); } if (callingUser == null || !userSignedIn) { throw new DnaWebProtocolException(ApiException.GetError(ErrorType.MissingUserCredentials)); } return callingUser; }
public void GivenIHaveAnCommentInTheReferalQueue() { //To get to this stage we need:- //1. Create a comment forum (make it pre-mod) //2. Add at least 2 posts //3. Refer the first post // a) for a post to be referred it should be in the mod queue (so - make the comment forum pre-mod //Let's not make a web request if possible - we'll need the databse though //SnapshotInitialisation.RestoreFromSnapshot(); //TODO: SnapshotInitialisation should not depend on IIS at all. //Whatever info is required should be injected. //TODO: get this from config string connectionString = @"database=smallGuide; server=.\MSSQL2008R2; user id=sa; password=Thanatos99; pooling=false"; DataReaderCreator = new DnaDataReaderCreator(connectionString, Diagnostics.Object); SiteList = new SiteList(DataReaderCreator, Diagnostics.Object, CacheManager.Object, RipleyServerAddresses, DotNetServerAddresses); var comments = new BBC.Dna.Api.Comments(Diagnostics.Object, DataReaderCreator, CacheManager.Object, SiteList); Forum = new Forum(); Forum.Id = "distress-message-fun-and-games"; Forum.ParentUri = "http://www.bbc.co.uk/dna/h2g2"; Forum.Title = "distress-message-fun-and-games"; Forum.ModerationServiceGroup = ModerationStatus.ForumStatus.PostMod; Site.Setup(x => x.SiteID).Returns(1); Site.Setup(x => x.SiteName).Returns("h2g2"); //see if this comment forum already exists var commentForum = comments.GetCommentForumByUid(Forum.Id, Site.Object, true); if (commentForum == null) { commentForum = comments.CreateCommentForum(Forum, Site.Object); } //save the forumid for later in the test CommentForumId = commentForum.ForumID; //if we have less than 2 comments we need to get up to 2 int commentCount = commentForum.commentList.TotalCount; while (commentCount < 2) { //Ok this is what I want to do but... //commentForum.Post(new Comment(...)); //TODO: can we add this method through a good refactor var commentInfo = new CommentInfo(); commentInfo.text = "Simple comment text " + commentCount.ToString(); var callingUser = new Mock<ICallingUser>(); callingUser.Setup(x => x.UserID).Returns(TestUserAccounts.GetNormalUserAccount.UserID); callingUser.Setup(x => x.IsSecureRequest).Returns(true); comments.CallingUser = callingUser.Object; var info = comments.CreateComment(commentForum, commentInfo); commentCount++; } }