/// <summary> /// Public method to generate the Sites XML representation /// </summary> /// <param name="siteOptionListXml">an XMLNode representing its site options. Can be null</param> /// <param name="site">The site</param> /// <param name="element"> The element to add the xml to</param> /// <param name="fullDetails">False means just a few key bits of information, True is all details</param> /// <returns>The node representing the site data</returns> public XmlNode GenerateXml(XmlNode siteOptionListXml, ISite site, XmlElement element, bool fullDetails) { //RootElement.RemoveAll(); XmlNode siteXML; siteXML = AddElementTag(element, "SITE"); AddAttribute(siteXML, "ID", site.SiteID.ToString()); AddTextTag(siteXML, "NAME", site.SiteName); AddTextTag(siteXML, "URLNAME", site.SiteName); AddTextTag(siteXML, "SHORTNAME", site.ShortName); AddTextTag(siteXML, "DESCRIPTION", site.Description); if (fullDetails) { AddTextTag(siteXML, "SSOSERVICE", site.SSOService); AddTextTag(siteXML, "IDENTITYSIGNIN", site.UseIdentitySignInSystem ? "1" : "0"); AddTextTag(siteXML, "IDENTITYPOLICY", site.IdentityPolicy); AddTextTag(siteXML, "MINAGE", site.MinAge); AddTextTag(siteXML, "MAXAGE", site.MaxAge); AddTextTag(siteXML, "MODERATIONSTATUS", ((int)site.ModerationStatus).ToString()); AddIntElement(siteXML, "CLASSID", site.ModClassID); // Now add the open closing times to the xml Dictionary<string, XmlNode> dailySchedules = new Dictionary<string, XmlNode>(); XmlNode openCloseTimes = AddElementTag(siteXML, "OPENCLOSETIMES"); foreach (OpenCloseTime openCloseTime in site.OpenCloseTimes) { // Check to see if we hve already got a node for this day of the week XmlNode dayOfWeek = null; if (dailySchedules.ContainsKey(openCloseTime.DayOfWeek.ToString())) { // Just get the node dayOfWeek = dailySchedules[openCloseTime.DayOfWeek.ToString()]; } else { // We need to create it, and then add it to the list dayOfWeek = AddElementTag(openCloseTimes, "OPENCLOSETIME"); AddAttribute(dayOfWeek, "DAYOFWEEK", openCloseTime.DayOfWeek.ToString()); dailySchedules.Add(openCloseTime.DayOfWeek.ToString(), dayOfWeek); } // Now check to see if it's an open or closing time XmlNode newTime = null; if (openCloseTime.Closed == 0) { // Create an open time newTime = AddElementTag(dayOfWeek, "OPENTIME"); } else { // Create a closing time newTime = AddElementTag(dayOfWeek, "CLOSETIME"); } // Now add the times to the new time AddTextTag(newTime, "HOUR", openCloseTime.Hour.ToString()); AddTextTag(newTime, "MINUTE", openCloseTime.Minute.ToString()); } XmlNode siteXMLClosed = AddElementTag(siteXML, "SITECLOSED"); if (site.IsEmergencyClosed) { AddAttribute(siteXMLClosed, "EMERGENCYCLOSED", "1"); } else { AddAttribute(siteXMLClosed, "EMERGENCYCLOSED", "0"); } bool IsScheduledClosedNow = site.IsSiteScheduledClosed(DateTime.Now); if (IsScheduledClosedNow) { AddAttribute(siteXMLClosed, "SCHEDULEDCLOSED", "1"); } else { AddAttribute(siteXMLClosed, "SCHEDULEDCLOSED", "0"); } if (site.IsEmergencyClosed || IsScheduledClosedNow) { siteXMLClosed.InnerText = "1"; } else { siteXMLClosed.InnerText = "0"; } if (siteOptionListXml != null) { siteXML.AppendChild(ImportNode(siteOptionListXml)); } } return siteXML; }
/// <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 new post after checking relevant items... /// </summary> /// <param name="cacheManager"></param> /// <param name="readerCreator"></param> /// <param name="site"></param> /// <param name="viewingUser"></param> /// <param name="siteList"></param> /// <param name="forumId"></param> /// <param name="ThreadId"></param> /// <param name="_iPAddress"></param> /// <param name="bbcUidCookie"></param> public void PostToForum(ICacheManager cacheManager, IDnaDataReaderCreator readerCreator, ISite site, IUser viewingUser, ISiteList siteList, string _iPAddress, Guid bbcUidCookie, int forumId) { if (viewingUser.UserId == 0) { throw ApiException.GetError(ErrorType.NotAuthorized); } ForumSource forumSource = ForumSource.CreateForumSource(cacheManager, readerCreator, null, forumId, ThreadId, site.SiteID, false, false, false); if (forumSource == null) { throw ApiException.GetError(ErrorType.ForumUnknown); } bool isNotable = viewingUser.IsNotable; ForumHelper helper = new ForumHelper(readerCreator); bool ignoreModeration = viewingUser.IsEditor || viewingUser.IsSuperUser; // Check 4) check ThreadId exists and user has permission to write if (!ignoreModeration) { if (ThreadId != 0) { bool canReadThread = false; bool canWriteThread = false; helper.GetThreadPermissions(viewingUser.UserId, ThreadId, ref canReadThread, ref canWriteThread); if (!canReadThread) { throw ApiException.GetError(ErrorType.NotAuthorized); } if (!canWriteThread) { throw ApiException.GetError(ErrorType.ForumReadOnly); } } else { bool canReadForum = false; bool canWriteForum = false; helper.GetForumPermissions(viewingUser.UserId, forumId, ref canReadForum, ref canWriteForum); if (!canReadForum) { throw ApiException.GetError(ErrorType.NotAuthorized); } if (!canWriteForum) { throw ApiException.GetError(ErrorType.ForumReadOnly); } } } if (viewingUser.IsBanned) { throw ApiException.GetError(ErrorType.UserIsBanned); } if (!ignoreModeration && (site.IsEmergencyClosed || site.IsSiteScheduledClosed(DateTime.Now))) { throw ApiException.GetError(ErrorType.SiteIsClosed); } if (String.IsNullOrEmpty(Text)) { throw ApiException.GetError(ErrorType.EmptyText); } try { int maxCharCount = siteList.GetSiteOptionValueInt(site.SiteID, "CommentForum", "MaxCommentCharacterLength"); string tmpText = StringUtils.StripFormattingFromText(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(Text); if (minCharCount != 0 && tmpText.Length < minCharCount) { throw ApiException.GetError(ErrorType.MinCharLimitNotReached); } } catch (SiteOptionNotFoundException) { } //Only check xml parsing for richtext plain text we want what is there so smileys etc work //if (this.Style == PostStyle.Style.richtext) //{ // string errormessage = string.Empty; // // Check to make sure that the comment is made of valid XML // if (!HtmlUtils.ParseToValidGuideML(Text, ref errormessage)) // { // throw ApiException.GetError(ErrorType.XmlFailedParse); // } //} bool forceModeration; string matchingProfanity= string.Empty; string profanityxml = string.Empty; string postString = Subject + " " + Text; List<Term> terms = null; if (InReplyTo > 0) {//only check text if not first post postString = Text; } CheckForProfanities(site, postString, out forceModeration, out matchingProfanity, out terms, forumId); if (false == string.IsNullOrEmpty(matchingProfanity)) { matchingProfanity = "Filtered terms: " + matchingProfanity; // Adding an extra bit of information for clarity } if (terms != null && terms.Count > 0) { profanityxml = new Term().GetProfanityXML(terms); } //check posting frequency if (!viewingUser.IsEditor && !viewingUser.IsSuperUser && !viewingUser.IsNotable) { SecondsToWait = CheckPostFrequency(readerCreator, viewingUser.UserId, site.SiteID); if (SecondsToWait != 0) { var error = ApiException.GetError(ErrorType.PostFrequencyTimePeriodNotExpired); ApiException newError = new ApiException( error.Message + " You must wait " + SecondsToWait.ToString() + " more seconds before posting.", error.type); throw newError; } } bool forcePreModeration = false; // PreModerate first post in discussion if site premoderatenewdiscussions option set. if ((InReplyTo == 0) && siteList.GetSiteOptionValueBool(site.SiteID, "Moderation", "PreModerateNewDiscussions")) { if (!ignoreModeration && !isNotable) { forcePreModeration = true; } } if (forumSource.Type == ForumSourceType.Journal && ThreadId == 0) { CreateJournalPost(readerCreator, site.SiteID, viewingUser.UserId, viewingUser.UserName, forumId, false, _iPAddress, bbcUidCookie, forceModeration); } else { CreateForumPost(readerCreator, viewingUser.UserId, forumId, ignoreModeration, isNotable, _iPAddress, bbcUidCookie, false, false, forcePreModeration, forceModeration, matchingProfanity, profanityxml); } }
/// <summary> /// applies the site specific items /// </summary> /// <param name="forum"></param> /// <param name="site"></param> /// <returns></returns> private static CommentForum ApplySiteVariables(CommentForum forum, ISite site) { forum.isClosed = forum.isClosed || site.IsEmergencyClosed || site.IsSiteScheduledClosed(DateTime.Now) || (DateTime.Now > forum.CloseDate); return forum; }
/// <summary> /// applies the site specific items /// </summary> /// <param name="comments"></param> /// <returns></returns> private RatingForum ApplySiteVariables(RatingForum forum, ISite site) { forum.isClosed = site.IsEmergencyClosed || site.IsSiteScheduledClosed(DateTime.Now) || (forum.CloseDate != null && DateTime.Now > forum.CloseDate); return forum; }