From 4f6b208e8dd854c773ee996a2c0db346fef6b3d6 Mon Sep 17 00:00:00 2001 From: Neil Lalonde Date: Wed, 15 Jan 2014 11:34:17 -0500 Subject: [PATCH] Posts by trust level 3 users do not have nofollow on their external links. --- app/models/post.rb | 11 ++++++++++- app/models/user.rb | 3 ++- lib/pretty_text.rb | 2 +- spec/components/pretty_text_spec.rb | 4 ++++ spec/models/post_spec.rb | 16 ++++++++++++++++ spec/models/user_spec.rb | 29 ++++++++++++++++++++++++----- 6 files changed, 57 insertions(+), 8 deletions(-) diff --git a/app/models/post.rb b/app/models/post.rb index e8d336980c3..68d6f0b9b0c 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -133,7 +133,16 @@ class Post < ActiveRecord::Base return raw if cook_method == Post.cook_methods[:raw_html] # Default is to cook posts - Plugin::Filter.apply(:after_post_cook, self, post_analyzer.cook(*args)) + cooked = if !self.user || !self.user.has_trust_level?(:leader) + post_analyzer.cook(*args) + else + # At trust level 3, we don't apply nofollow to links + cloned = args.dup + cloned[1] ||= {} + cloned[1][:omit_nofollow] = true + post_analyzer.cook(*cloned) + end + Plugin::Filter.apply( :after_post_cook, self, cooked ) end # Sometimes the post is being edited by someone else, for example, a mod. diff --git a/app/models/user.rb b/app/models/user.rb index 84cbe5386f6..7f7780d051d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -408,6 +408,7 @@ class User < ActiveRecord::Base def change_trust_level!(level) raise "Invalid trust level #{level}" unless TrustLevel.valid_level?(level) self.trust_level = TrustLevel.levels[level] + self.bio_raw_will_change! # So it can get re-cooked based on the new trust level transaction do self.save! Group.user_trust_level_change!(self.id, self.trust_level) @@ -526,7 +527,7 @@ class User < ActiveRecord::Base def cook if bio_raw.present? - self.bio_cooked = PrettyText.cook(bio_raw) if bio_raw_changed? + self.bio_cooked = PrettyText.cook(bio_raw, omit_nofollow: self.has_trust_level?(:leader)) if bio_raw_changed? else self.bio_cooked = nil end diff --git a/lib/pretty_text.rb b/lib/pretty_text.rb index 5dfde4fddc4..54c3e16027f 100644 --- a/lib/pretty_text.rb +++ b/lib/pretty_text.rb @@ -167,7 +167,7 @@ module PrettyText # we have a minor inconsistency cloned[:topicId] = opts[:topic_id] sanitized = markdown(text.dup, cloned) - sanitized = add_rel_nofollow_to_user_content(sanitized) if SiteSetting.add_rel_nofollow_to_user_content + sanitized = add_rel_nofollow_to_user_content(sanitized) if !cloned[:omit_nofollow] && SiteSetting.add_rel_nofollow_to_user_content sanitized end diff --git a/spec/components/pretty_text_spec.rb b/spec/components/pretty_text_spec.rb index ef5c1a6600d..34a35ef9ea2 100644 --- a/spec/components/pretty_text_spec.rb +++ b/spec/components/pretty_text_spec.rb @@ -74,6 +74,10 @@ describe PrettyText do it "should not inject nofollow for bar.foo.com" do (PrettyText.cook("cnn") !~ /nofollow/).should be_true end + + it "should not inject nofollow if omit_nofollow option is given" do + (PrettyText.cook('cnn', omit_nofollow: true) !~ /nofollow/).should be_true + end end describe "Excerpt" do diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb index 1f143588518..c6f926b62dd 100644 --- a/spec/models/post_spec.rb +++ b/spec/models/post_spec.rb @@ -771,4 +771,20 @@ describe Post do end end + describe "cooking" do + let(:post) { Fabricate.build(:post, post_args.merge(raw: "please read my blog http://blog.example.com")) } + + it "should add nofollow to links in the post for trust levels below 3" do + post.user.trust_level = 2 + post.save + post.cooked.should =~ /nofollow/ + end + + it "should not add nofollow for trust level 3 and higher" do + post.user.trust_level = 3 + post.save + (post.cooked =~ /nofollow/).should be_false + end + end + end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 5195e6bf51d..0d2f4274cd9 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -762,21 +762,40 @@ describe User do context "with a user that has a link in their bio" do let(:user) { Fabricate.build(:user, bio_raw: "im sissy and i love http://ponycorns.com") } - before do - # Let's cook that bio up good + it "includes the link as nofollow if the user is not new" do user.send(:cook) - end - - it "includes the link if the user is not new" do expect(user.bio_excerpt).to eq("im sissy and i love http://ponycorns.com") expect(user.bio_processed).to eq("

im sissy and i love http://ponycorns.com

") end it "removes the link if the user is new" do user.trust_level = TrustLevel.levels[:newuser] + user.send(:cook) expect(user.bio_excerpt).to eq("im sissy and i love http://ponycorns.com") expect(user.bio_processed).to eq("

im sissy and i love http://ponycorns.com

") end + + it "includes the link without nofollow if the user is trust level 3 or higher" do + user.trust_level = TrustLevel.levels[:leader] + user.send(:cook) + expect(user.bio_excerpt).to eq("im sissy and i love http://ponycorns.com") + expect(user.bio_processed).to eq("

im sissy and i love http://ponycorns.com

") + end + + it "removes nofollow from links in bio when trust level is increased" do + user.save + user.change_trust_level!(:leader) + expect(user.bio_excerpt).to eq("im sissy and i love http://ponycorns.com") + expect(user.bio_processed).to eq("

im sissy and i love http://ponycorns.com

") + end + + it "adds nofollow to links in bio when trust level is decreased" do + user.trust_level = TrustLevel.levels[:leader] + user.save + user.change_trust_level!(:regular) + expect(user.bio_excerpt).to eq("im sissy and i love http://ponycorns.com") + expect(user.bio_processed).to eq("

im sissy and i love http://ponycorns.com

") + end end end