diff --git a/app/models/concerns/limited_edit.rb b/app/models/concerns/limited_edit.rb new file mode 100644 index 000000000..8e91315bd --- /dev/null +++ b/app/models/concerns/limited_edit.rb @@ -0,0 +1,11 @@ +module LimitedEdit + extend ActiveSupport::Concern + + def edit_time_limit_expired? + if created_at && SiteSetting.post_edit_time_limit.to_i > 0 + created_at < SiteSetting.post_edit_time_limit.to_i.minutes.ago + else + false + end + end +end diff --git a/app/models/post.rb b/app/models/post.rb index d961188c2..b4bf023d5 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -14,6 +14,7 @@ class Post < ActiveRecord::Base include RateLimiter::OnCreateRecord include Trashable include HasCustomFields + include LimitedEdit # increase this number to force a system wide post rebake BAKED_VERSION = 1 @@ -524,14 +525,6 @@ class Post < ActiveRecord::Base end end - def edit_time_limit_expired? - if created_at && SiteSetting.post_edit_time_limit.to_i > 0 - created_at < SiteSetting.post_edit_time_limit.to_i.minutes.ago - else - false - end - end - private def parse_quote_into_arguments(quote) diff --git a/app/models/topic.rb b/app/models/topic.rb index 00e6cb0a4..4982259ba 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -11,6 +11,7 @@ class Topic < ActiveRecord::Base include RateLimiter::OnCreateRecord include HasCustomFields include Trashable + include LimitedEdit extend Forwardable def_delegator :featured_users, :user_ids, :featured_user_ids diff --git a/lib/guardian/topic_guardian.rb b/lib/guardian/topic_guardian.rb index a3ec5abb6..3efd1e388 100644 --- a/lib/guardian/topic_guardian.rb +++ b/lib/guardian/topic_guardian.rb @@ -30,7 +30,7 @@ module TopicGuardian return false if Discourse.static_doc_topic_ids.include?(topic.id) && !is_admin? return true if is_staff? || (!topic.private_message? && user.has_trust_level?(TrustLevel[3])) return false if topic.archived - is_my_own?(topic) + is_my_own?(topic) && !topic.edit_time_limit_expired? end # Recovery Method diff --git a/spec/components/guardian_spec.rb b/spec/components/guardian_spec.rb index e39f46b83..6cb9eaf3b 100644 --- a/spec/components/guardian_spec.rb +++ b/spec/components/guardian_spec.rb @@ -792,6 +792,30 @@ describe Guardian do expect(Guardian.new(trust_level_4).can_edit?(post)).to be_truthy end + it 'returns false when another user has too low trust level to edit wiki post' do + SiteSetting.stubs(:min_trust_to_edit_wiki_post).returns(2) + post.wiki = true + coding_horror.trust_level = 1 + + expect(Guardian.new(coding_horror).can_edit?(post)).to be_falsey + end + + it 'returns true when another user has adequate trust level to edit wiki post' do + SiteSetting.stubs(:min_trust_to_edit_wiki_post).returns(2) + post.wiki = true + coding_horror.trust_level = 2 + + expect(Guardian.new(coding_horror).can_edit?(post)).to be_truthy + end + + it 'returns true for post author even when he has too low trust level to edit wiki post' do + SiteSetting.stubs(:min_trust_to_edit_wiki_post).returns(2) + post.wiki = true + post.user.trust_level = 1 + + expect(Guardian.new(post.user).can_edit?(post)).to be_truthy + end + context 'post is older than post_edit_time_limit' do let(:old_post) { build(:post, topic: topic, user: topic.user, created_at: 6.minutes.ago) } before do @@ -818,30 +842,6 @@ describe Guardian do old_post.wiki = true expect(Guardian.new(coding_horror).can_edit?(old_post)).to be_truthy end - - it 'returns false when another user has too low trust level to edit wiki post' do - SiteSetting.stubs(:min_trust_to_edit_wiki_post).returns(2) - post.wiki = true - coding_horror.trust_level = 1 - - expect(Guardian.new(coding_horror).can_edit?(post)).to be_falsey - end - - it 'returns true when another user has adequate trust level to edit wiki post' do - SiteSetting.stubs(:min_trust_to_edit_wiki_post).returns(2) - post.wiki = true - coding_horror.trust_level = 2 - - expect(Guardian.new(coding_horror).can_edit?(post)).to be_truthy - end - - it 'returns true for post author even when he has too low trust level to edit wiki post' do - SiteSetting.stubs(:min_trust_to_edit_wiki_post).returns(2) - post.wiki = true - post.user.trust_level = 1 - - expect(Guardian.new(post.user).can_edit?(post)).to be_truthy - end end context "first post of a static page doc" do @@ -867,7 +867,6 @@ describe Guardian do expect(Guardian.new(topic.user).can_edit?(topic)).to eq(true) end - it 'returns false as a regular user' do expect(Guardian.new(coding_horror).can_edit?(topic)).to be_falsey end @@ -894,20 +893,44 @@ describe Guardian do end context 'archived' do + let(:archived_topic) { build(:topic, user: user, archived: true) } + it 'returns true as a moderator' do - expect(Guardian.new(moderator).can_edit?(build(:topic, user: user, archived: true))).to be_truthy + expect(Guardian.new(moderator).can_edit?(archived_topic)).to be_truthy end it 'returns true as an admin' do - expect(Guardian.new(admin).can_edit?(build(:topic, user: user, archived: true))).to be_truthy + expect(Guardian.new(admin).can_edit?(archived_topic)).to be_truthy end it 'returns true at trust level 3' do - expect(Guardian.new(trust_level_3).can_edit?(build(:topic, user: user, archived: true))).to be_truthy + expect(Guardian.new(trust_level_3).can_edit?(archived_topic)).to be_truthy end it 'returns false as a topic creator' do - expect(Guardian.new(user).can_edit?(build(:topic, user: user, archived: true))).to be_falsey + expect(Guardian.new(user).can_edit?(archived_topic)).to be_falsey + end + end + + context 'very old' do + let(:old_topic) { build(:topic, user: user, created_at: 6.minutes.ago) } + + before { SiteSetting.stubs(:post_edit_time_limit).returns(5) } + + it 'returns true as a moderator' do + expect(Guardian.new(moderator).can_edit?(old_topic)).to be_truthy + end + + it 'returns true as an admin' do + expect(Guardian.new(admin).can_edit?(old_topic)).to be_truthy + end + + it 'returns true at trust level 3' do + expect(Guardian.new(trust_level_3).can_edit?(old_topic)).to be_truthy + end + + it 'returns false as a topic creator' do + expect(Guardian.new(user).can_edit?(old_topic)).to be_falsey end end end