Skip to content

Commit 808ea07

Browse files
authored
Merge pull request #1578 from codidact/art/new-user-comments
New user comments
2 parents 544903f + e4ee008 commit 808ea07

File tree

5 files changed

+88
-28
lines changed

5 files changed

+88
-28
lines changed

app/controllers/comments_controller.rb

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,12 @@ def create_thread
3232

3333
pings = check_for_pings @comment_thread, body
3434

35-
return if comment_rate_limited
35+
rate_limited, limit_message = helpers.comment_rate_limited?(current_user, @post)
36+
if rate_limited
37+
flash[:danger] = limit_message
38+
redirect_to helpers.generic_share_link(@post)
39+
return
40+
end
3641

3742
success = ActiveRecord::Base.transaction do
3843
@comment_thread.save!
@@ -76,7 +81,12 @@ def create
7681
@comment = Comment.new(post: @post, content: body, user: current_user,
7782
comment_thread: @comment_thread, has_reference: false)
7883

79-
return if comment_rate_limited
84+
rate_limited, limit_message = helpers.comment_rate_limited?(current_user, @post)
85+
if rate_limited
86+
flash[:danger] = limit_message
87+
redirect_to helpers.generic_share_link(@post)
88+
return
89+
end
8090

8191
if @comment.save
8292
apply_pings pings
@@ -324,29 +334,4 @@ def apply_pings(pings)
324334
helpers.comment_link(@comment))
325335
end
326336
end
327-
328-
def comment_rate_limited
329-
recent_comments = Comment.where(created_at: 24.hours.ago..DateTime.now, user: current_user).where \
330-
.not(post: Post.includes(:parent).where(parents_posts: { user_id: current_user.id })) \
331-
.where.not(post: Post.where(user_id: current_user.id)).count
332-
max_comments_per_day = SiteSetting[current_user.privilege?('unrestricted') ? 'RL_Comments' : 'RL_NewUserComments']
333-
334-
if (!@post.user_id == current_user.id || @post&.parent&.user_id == current_user.id) \
335-
&& recent_comments >= max_comments_per_day
336-
comment_limit_msg = "You have used your daily comment limit of #{recent_comments} comments. " \
337-
'Come back tomorrow to continue commenting. Comments on own posts and on answers ' \
338-
'to own posts are exempt.'
339-
340-
if recent_comments.zero? && !current_user.privilege?('unrestricted')
341-
comment_limit_msg = 'New users can only comment on their own posts and on answers to them.'
342-
end
343-
344-
AuditLog.rate_limit_log(event_type: 'comment', related: @comment, user: current_user,
345-
comment: "limit: #{max_comments_per_day}\n\comment:\n#{@comment.attributes_print}")
346-
347-
render json: { status: 'failed', message: comment_limit_msg }, status: :forbidden
348-
return true
349-
end
350-
false
351-
end
352337
end

app/helpers/comments_helper.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,44 @@ def get_pingable(thread)
7676

7777
ActiveRecord::Base.connection.execute(query).to_a.flatten
7878
end
79+
80+
##
81+
# Is the specified user comment rate limited for the specified post?
82+
# @param [User] user The user to check.
83+
# @param [Post] post The post on which the user proposes to comment.
84+
# @param [Boolean] create_audit_log Whether to create an AuditLog if the user is rate limited.
85+
# @return [Array(Boolean, String)] 2-tuple: boolean indicating if the user is rate-limited, and a string containing
86+
# a rate limit message if the user is rate-limited.
87+
def comment_rate_limited?(user, post, create_audit_log: true)
88+
# Comments created by the current user in the last 24 hours, excluding comments on own posts and responses to them.
89+
recent_comments = Comment.where(created_at: 24.hours.ago..DateTime.now, user: user).where \
90+
.not(post: Post.includes(:parent).where(parents_posts: { user_id: user.id })) \
91+
.where.not(post: Post.where(user_id: user.id)).count
92+
max_comments_per_day = SiteSetting[user.privilege?('unrestricted') ? 'RL_Comments' : 'RL_NewUserComments']
93+
94+
if post.user_id != user.id && post.parent&.user_id != user.id
95+
if !user.privilege?('unrestricted')
96+
message = 'As a new user, you can only comment on your own posts and on answers to them.'
97+
if create_audit_log
98+
AuditLog.rate_limit_log(event_type: 'comment', related: post, user: user,
99+
comment: "limit: #{max_comments_per_day}")
100+
end
101+
[true, message]
102+
elsif recent_comments >= max_comments_per_day
103+
message = "You have used your daily comment limit of #{recent_comments} comments. Come back tomorrow to " \
104+
'continue commenting. Comments on your own posts and on answers to own posts are exempt.'
105+
if create_audit_log
106+
AuditLog.rate_limit_log(event_type: 'comment', related: post, user: user,
107+
comment: "limit: #{max_comments_per_day}")
108+
end
109+
[true, message]
110+
else
111+
[false, nil]
112+
end
113+
else
114+
[false, nil]
115+
end
116+
end
79117
end
80118

81119
class CommentScrubber < Rails::Html::PermitScrubber

test/fixtures/posts.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,27 @@ question_two:
4040
upvote_count: 0
4141
downvote_count: 0
4242

43+
new_user_question:
44+
post_type: question
45+
title: Q1 - This is test question number one
46+
body: This is the body of test question one. Note that we did not include any markdown or HTML in here.
47+
body_markdown: This is the body of test question one. Note that we did not include any markdown or HTML in here.
48+
tags_cache:
49+
- discussion
50+
- support
51+
- bug
52+
tags:
53+
- discussion
54+
- support
55+
- bug
56+
score: 0.5
57+
user: basic_user
58+
community: sample
59+
category: main
60+
license: cc_by_sa
61+
upvote_count: 0
62+
downvote_count: 0
63+
4364
bad_answers:
4465
post_type: question
4566
title: Q3B - This question has bad answers

test/fixtures/user_abilities.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,8 @@ d_ep:
5252

5353
d_et:
5454
community_user: sample_deleter
55-
ability: edit_tags
55+
ability: edit_tags
56+
57+
b_eo:
58+
community_user: sample_basic_user
59+
ability: everyone

test/helpers/comments_helper_test.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,16 @@ class CommentsHelperTest < ActionView::TestCase
4848
assert_equal expect, render_comment_helpers(+input, users(:standard_user))
4949
end
5050
end
51+
52+
test 'comment_rate_limited prevents new users commenting on others posts' do
53+
rate_limited, limit_message = comment_rate_limited? users(:basic_user), posts(:question_one)
54+
assert_equal true, rate_limited
55+
assert_equal 'As a new user, you can only comment on your own posts and on answers to them.', limit_message
56+
end
57+
58+
test 'comment_rate_limited allows new user to comment on own post' do
59+
rate_limited, limit_message = comment_rate_limited? users(:basic_user), posts(:new_user_question)
60+
assert_equal false, rate_limited
61+
assert_equal nil, limit_message
62+
end
5163
end

0 commit comments

Comments
 (0)