Skip to content

Commit

Permalink
AO3-5860 Prevent leaving comments or kudos when logged in as admin (#…
Browse files Browse the repository at this point in the history
…4378)

* Ask admins to log out before commenting

https://otwarchive.atlassian.net/browse/AO3-5860

* Ask admins to log out before leaving kudos

https://otwarchive.atlassian.net/browse/AO3-5860

* Clean up now irrelevant code

* Update reminder text

https://otwarchive.atlassian.net/browse/AO3-5860?focusedCommentId=356267

* Controller tests instead of integration tests

* Hide kudos/comments button as admin

https://otwarchive.atlassian.net/browse/AO3-5860?focusedCommentId=356272

* Restrict commenting on works only?

* Attempt at disabling all admin comments

* Revert "Attempt at disabling all admin comments"

This reverts commit 33b89e0.

* Fix test to not restrict admin comments on tags

* ? spacing

IDE?

* Hound

* Hide whole form, not solely button

* Prevent admin from commenting on anything

* Update old test for new behavior

* Check message and redirection at once

* Add test for no reply comment

* Remove empty if

Not exactly sure why I wrote it in the first place honestly...

* Now useless admin only form

* Lost EOF newline

* Actually hide Reply link

* Check not admin on all "add comment" routes

* Consistent location for check

* Updated test for new behavior

* Unneeded change

* More precise message

* Better test description

* Missing test

* Normalize i18n files

Unrelated to the rest of the PR
Just caught by a different hound

* Forgot to update similar tests indeed

* Handle :js format

* Revert "Handle :js format"

This reverts commit 5ddfb2e.

* Make sure admin cannot create kudos through AJAX

* Oops

* Doing two things as once...

To make sure each takes forever due to silly mistakes

* Actual non silly merge conflict

* Intended behavior?

* Update ts( to t(

In for a penny

* If you start doing something...

You might as well do it right

* Test update

* Acceptable HTML
  • Loading branch information
ceithir authored May 17, 2024
1 parent 3e683fc commit 2889787
Show file tree
Hide file tree
Showing 13 changed files with 150 additions and 77 deletions.
1 change: 1 addition & 0 deletions app/controllers/comments_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class CommentsController < ApplicationController
before_action :check_permission_to_moderate, only: [:approve, :reject]
before_action :check_permission_to_modify_frozen_status, only: [:freeze, :unfreeze]
before_action :check_permission_to_modify_hidden_status, only: [:hide, :unhide]
before_action :admin_logout_required, only: [:new, :create, :add_comment_reply]

include BlockHelper

Expand Down
1 change: 1 addition & 0 deletions app/controllers/kudos_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class KudosController < ApplicationController
skip_before_action :store_location
before_action :admin_logout_required, only: [:create]

def index
@work = Work.find(params[:work_id])
Expand Down
1 change: 1 addition & 0 deletions app/helpers/comments_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ def can_reply_to_comment?(comment)
return false if comment_parent_hidden?(comment)
return false if blocked_by_comment?(comment)
return false if blocked_by?(comment.ultimate_parent)
return false if logged_in_as_admin?

return true unless guest?

Expand Down
83 changes: 36 additions & 47 deletions app/views/comments/_comment_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<div class="post comment" id="comment_form_for_<%= commentable.id %>">
<%= form_for value_for_comment_form(commentable, comment), remote: !comment.new_record?, authenticity_token: true, html: { id: "comment_for_#{commentable.id}" } do |f| %>
<fieldset>
<legend><%= ts("Post Comment") %></legend>
<legend><%= t(".legend") %></legend>

<% # here come the hacks (hidden fields to transmit various info to the create action) %>
<%# here come the hacks (hidden fields to transmit various info to the create action) %>
<% if commentable.is_a?(Tag) %>
<%= hidden_field_tag :tag_id, commentable.name %>
<% end %>
Expand All @@ -28,88 +28,77 @@

<% if comments_are_moderated(commentable) && !current_user_is_work_creator(commentable) %>
<p class="notice">
<%= ts("This work's creator has chosen to moderate comments on the work. Your comment will not appear until it has been approved by the creator.") %>
<%= t(".moderation_forewarning") %>
</p>
<% end %>

<% if logged_in? %>
<% if current_user_is_anonymous_creator(commentable) %>
<p class="notice">
<%= ts("While this work is anonymous, comments you post will also be listed anonymously.") %>
<%= t(".anonymous_forewarning") %>
</p>
<% end %>

<% if current_user.pseuds.count > 1 %>
<h4 class="heading"><%= ts("Comment as") %> <%= f.collection_select :pseud_id, current_user.pseuds, :id, :name, {:selected => (comment.pseud ? comment.pseud.id.to_s : current_user.default_pseud.id.to_s)}, :id => "comment_pseud_id_for_#{commentable.id}", :title => ts("Choose Name") %>
<h4 class="heading"><%= t(".comment_as") %> <%= f.collection_select :pseud_id, current_user.pseuds, :id, :name, { selected: (comment.pseud ? comment.pseud.id.to_s : current_user.default_pseud.id.to_s) }, id: "comment_pseud_id_for_#{commentable.id}", title: t(".choose_name_field_title") %>
<% if controller.controller_name == "inbox" %>
<% if commentable.by_anonymous_creator? %>
<span><%= ts("to") %> <%= "Anonymous Creator" %> <%= ts("on") %> <%= commentable_description_link(commentable) %></span>
<% else %>
<span><%= ts("to") %> <%= get_commenter_pseud_or_name(commentable) %> <%= ts("on") %> <%= commentable_description_link(commentable) %></span>
<% end %>
<span><%= t(".inbox_reference_html",
commentable_creator: commentable.by_anonymous_creator? ? t(".anonymous_creator") : get_commenter_pseud_or_name(commentable),
commentable_link: commentable_description_link(commentable)) %></span>
<% end %>
(<%= allowed_html_instructions %>)
</h4>
<% else %>
<h4 class="heading"><%= ts("Comment as") %> <span class="byline"><%= current_user.default_pseud.name %></span>
<%= f.hidden_field :pseud_id, :value => "#{current_user.default_pseud.id}", :id => "comment_pseud_id_for_#{commentable.id}" %>
<h4 class="heading"><%= t(".comment_as") %> <span class="byline"><%= current_user.default_pseud.name %></span>
<%= f.hidden_field :pseud_id, value: current_user.default_pseud.id.to_s, id: "comment_pseud_id_for_#{commentable.id}" %>
<% if controller.controller_name == "inbox" %>
<% if commentable.by_anonymous_creator? %>
<span><%= ts("to") %> <%= "Anonymous Creator" %> <%= ts("on") %> <%= commentable_description_link(commentable) %></span>
<% else %>
<span><%= ts("to") %> <%= get_commenter_pseud_or_name(commentable) %> <%= ts("on") %> <%= commentable_description_link(commentable) %></span>
<% end %>
<span><%= t(".inbox_reference_html",
commentable_creator: commentable.by_anonymous_creator? ? t(".anonymous_creator") : get_commenter_pseud_or_name(commentable),
commentable_link: commentable_description_link(commentable)) %></span>
<% end %>
</h4>
<p class="footnote">(<%= allowed_html_instructions %>)</p>
<% end %>

<% elsif logged_in_as_admin? %>
<h4 class="heading"><%= ts("Comment as") %> <span class="byline"><%= current_admin.login %></span>
<%= f.hidden_field :name, :value => "#{current_admin.login}", :id => "comment_name_for_#{commentable.id}" %>
<%= f.hidden_field :email, :value => "#{current_admin.email}", :id => "comment_email_for_#{commentable.id}" %>
</h4>
<p class="footnote">(<%= allowed_html_instructions %>)</p>
<% else %>
<dl>
<dt class="landmark"><%= ts("Note") %>:</dt>
<dd class="instructions comment_form"><%=ts("All fields are required. Your email address will not be published.") %></dd>
<dt><%= f.label "name_for_#{commentable.id}", ts("Guest name: ") %></dt>
<dt class="landmark"><%= t(".landmark.note") %>:</dt>
<dd class="instructions comment_form"><%= t(".guest_instructions") %></dd>
<dt><%= f.label "name_for_#{commentable.id}", t(".guest_name") %></dt>
<dd>
<%= f.text_field :name, :id => "comment_name_for_#{commentable.id}" %>
<%= live_validation_for_field("comment_name_for_#{commentable.id}", :failureMessage => ts('Please enter your name.')) %>
<%= f.text_field :name, id: "comment_name_for_#{commentable.id}" %>
<%= live_validation_for_field("comment_name_for_#{commentable.id}", failureMessage: t(".guest_name_failure")) %>
</dd>
<dt><%= f.label "email_for_#{commentable.id}", ts("Guest email: ") %></dt>
<dt><%= f.label "email_for_#{commentable.id}", t(".guest_email") %></dt>
<dd>
<%= f.text_field :email, :id => "comment_email_for_#{commentable.id}" %>
<%= live_validation_for_field("comment_email_for_#{commentable.id}", :failureMessage => ts('Please enter your email address.')) %>
<%= f.text_field :email, id: "comment_email_for_#{commentable.id}" %>
<%= live_validation_for_field("comment_email_for_#{commentable.id}", failureMessage: t(".guest_email_failure")) %>
</dd>
</dl>
<p class="footnote">(<%= allowed_html_instructions %>)</p>
<% end %>

<p>
<% content_id = "comment_content_for_#{commentable.id}" %>
<label for="<%= content_id %>" class="landmark"><%= ts("Comment") %></label>
<%= f.text_area :comment_content, :id => content_id, :class => "comment_form observe_textlength", :title => ts("Enter Comment") %>
<label for="<%= content_id %>" class="landmark"><%= t(".landmark.comment") %></label>
<%= f.text_area :comment_content, id: content_id, class: "comment_form observe_textlength", title: t(".comment_field_title") %>
<input type="hidden" id="controller_name_for_<%= commentable.id %>" name="controller_name" value="<%= @controller_name ||= controller.controller_name %>" />
</p>
<%= generate_countdown_html("comment_content_for_#{commentable.id}", ArchiveConfig.COMMENT_MAX) %>
<%= live_validation_for_field("comment_content_for_#{commentable.id}",
:failureMessage => ts('Brevity is the soul of wit, but we need your comment to have text in it.'),
:maximum_length => ArchiveConfig.COMMENT_MAX,
:tooLongMessage => ts("must be less than %{count} characters long.", :count => ArchiveConfig.COMMENT_MAX)) %>
<%= live_validation_for_field "comment_content_for_#{commentable.id}",
failureMessage: t(".comment_too_short"),
maximum_length: ArchiveConfig.COMMENT_MAX,
tooLongMessage: t(".comment_too_long", count: ArchiveConfig.COMMENT_MAX) %>
<p class="submit actions">
<%= f.submit button_name, :id => "comment_submit_for_#{commentable.id}", data: {disable_with: ts("Please wait...")} %>
<% if controller.controller_name == 'inbox' %>
<a name="comment_cancel" id="comment_cancel"><%= ts("Cancel") %></a>
<% elsif comment.persisted? %>
<%= cancel_edit_comment_link(comment) %>
<% elsif commentable.is_a?(Comment) || commentable.is_a?(CommentDecorator) %>
<%= cancel_comment_reply_link(commentable) %>
<% end %>
</p>
<%= f.submit button_name, id: "comment_submit_for_#{commentable.id}", data: { disable_with: t(".processing_message") } %>
<% if controller.controller_name == 'inbox' %>
<a name="comment_cancel" id="comment_cancel"><%= t(".cancel_action") %></a>
<% elsif comment.persisted? %>
<%= cancel_edit_comment_link(comment) %>
<% elsif commentable.is_a?(Comment) || commentable.is_a?(CommentDecorator) %>
<%= cancel_comment_reply_link(commentable) %>
<% end %>
</p>
</fieldset>
<% end %>
</div>
Expand Down
6 changes: 5 additions & 1 deletion app/views/comments/_commentable.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<li><%= link_to ts('Back to AO3 News Index'), admin_posts_path %></li>
<% end %>

<% if @work && !is_author_of?(@work) && !blocked_by?(@work) %>
<% if @work && !is_author_of?(@work) && !blocked_by?(@work) && !logged_in_as_admin? %>
<li>
<%= form_for(:kudo, url: kudos_path, html: { method: 'post', id: 'new_kudo' }) do |kudo_form| %>
<%= kudo_form.hidden_field :commentable_id, :value => @work.id %>
Expand Down Expand Up @@ -113,6 +113,10 @@
<p class="notice">
<%= t(".blocked") %>
</p>
<% elsif logged_in_as_admin? %>
<p class="notice">
<%= t(".logged_as_admin") %>
</p>
<% else %>
<div id="add_comment_placeholder" title="top level comment">
<div id="add_comment">
Expand Down
24 changes: 23 additions & 1 deletion config/locales/views/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ en:
admins:
index:
confidentiality_reminder: You are now logged in as an admin. That means you will probably encounter information that is personal or confidential (e.g. usernames, email and IP addresses, creator names on anonymous works, etc). Please do not use this information in ways unrelated to your OTW role. If you have questions about what you can or cannot do with information you see here, contact your committee chair(s).
log_out_reminder: Please remember to log out before resuming your normal site activity and leaving comments and kudos!
log_out_reminder: Please remember to log out before resuming your normal site activity!
page_title: Hi, %{login}!
responsibility: With great power comes great responsibility.
roles:
Expand Down Expand Up @@ -414,13 +414,35 @@ en:
unreviewed_by_collection: Works and bookmarks listed here have been added to a collection but need approval from a collection moderator before they are listed in the collection.
page_heading: Items by %{username} in Collections
comments:
comment_form:
anonymous_creator: Anonymous Creator
anonymous_forewarning: While this work is anonymous, comments you post will also be listed anonymously.
cancel_action: Cancel
choose_name_field_title: Choose Name
comment_as: Comment as
comment_field_title: Enter Comment
comment_too_long: must be less than %{count} characters long.
comment_too_short: Brevity is the soul of wit, but we need your comment to have text in it.
guest_email: Guest email
guest_email_failure: Please enter your email address.
guest_instructions: All fields are required. Your email address will not be published.
guest_name: Guest name
guest_name_failure: Please enter your name.
inbox_reference_html: to %{commentable_creator} on %{commentable_link}
landmark:
comment: Comment
note: Note
legend: Post Comment
moderation_forewarning: This work's creator has chosen to moderate comments on the work. Your comment will not appear until it has been approved by the creator.
processing_message: Please wait...
commentable:
actions:
comment: Comment
add_to_collections_link: Add to Collections
blocked: Sorry, you have been blocked by one or more of this work's creators.
guest_comments_disabled: Sorry, the Archive doesn't allow guests to comment right now.
invite_to_collections_link: Invite To Collections
logged_as_admin: Please log out of your admin account to comment.
permissions:
admin_post:
alt_action: You can however %{support_link} with any feedback or questions.
Expand Down
5 changes: 0 additions & 5 deletions features/admins/admin_settings.feature
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,6 @@ Feature: Admin Settings Page
Scenario: Tag comments are not affected when guest comments are turned off
Given guest comments are off
And a fandom exists with name: "Stargate SG-1", canonical: true
When I am logged in as a super admin
And I view the tag "Stargate SG-1" with comments
Then I should not see "Sorry, the Archive doesn't allow guests to comment right now."
When I post the comment "Important policy decision" on the tag "Stargate SG-1"
Then I should see "Comment created!"
When I am logged in as a tag wrangler
And I view the tag "Stargate SG-1" with comments
Then I should not see "Sorry, the Archive doesn't allow guests to comment right now."
Expand Down
27 changes: 27 additions & 0 deletions features/comments_and_kudos/add_comment.feature
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,30 @@ Scenario: Users with different time zone preferences should see the time in thei
And I view the work "Generic Work" with comments
Then I should see "AEST" within ".posted.datetime"
And I should see "AEST" within ".edited.datetime"

Scenario: Cannot comment (no form) while logged as admin

Given the work "Generic Work"
And I am logged in as an admin
And I view the work "Generic Work"
Then I should see "Generic Work"
And I should not see "Post Comment"
And I should not see a "Comment" button
And I should see "Please log out of your admin account to comment."

Scenario: Cannot reply to comments (no button) while logged as admin

Given the work "Generic Work"
When I am logged in as "commenter"
And I view the work "Generic Work"
And I post a comment "Woohoo"
When I am logged in as an admin
And I view the work "Generic Work"
And I follow "Comments (1)"
Then I should see "Woohoo"
And I should not see "Reply"
When I am logged out
And I view the work "Generic Work"
And I follow "Comments (1)"
Then I should see "Woohoo"
And I should see "Reply"
6 changes: 6 additions & 0 deletions features/comments_and_kudos/kudos.feature
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,9 @@ Feature: Kudos
And the kudos cache has expired
And I view the work "Interesting beans"
Then I should not see "newusername1 left kudos on this work!"

Scenario: Cannot leave kudos (no button) while logged as admin
Given I am logged in as an admin
And I view the work "Awesome Story"
Then I should see "Awesome Story"
And I should not see a "Kudos ♥" button
2 changes: 1 addition & 1 deletion features/importing/work_import.feature
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ Feature: Import Works
When I am logged out
And I go to the "Detected Title" work page
And I follow "Yes, Continue"
Then I should see "Guest name:"
Then I should see "Guest name"

Scenario: Imported works can have comments disabled to guests
When I start importing "http://import-site-with-tags" with a mock website
Expand Down
15 changes: 4 additions & 11 deletions features/tags_and_wrangling/tag_comment.feature
Original file line number Diff line number Diff line change
Expand Up @@ -43,24 +43,17 @@ I'd like to comment on a tag'
Scenario: Multiple comments on a tag increment correctly

Given the following activated tag wranglers exist
| login |
| dizmo |
| login |
| dizmo |
| someone_else |
And a fandom exists with name: "Stargate Atlantis", canonical: true
When I am logged in as "dizmo"
When I post the comment "Yep, we should have a Stargate franchise metatag." on the tag "Stargate Atlantis"
When I am logged in as an admin
When I am logged in as "someone_else"
When I post the comment "Important policy decision" on the tag "Stargate Atlantis"
When I view the tag "Stargate Atlantis"
Then I should see "2 comments"

Scenario: admin can also comment on tags, issue 1428

Given a fandom exists with name: "Stargate Atlantis", canonical: true
When I am logged in as an admin
When I post the comment "Important policy decision" on the tag "Stargate Atlantis" via web
When I view the tag "Stargate Atlantis"
Then I should see "1 comment"

Scenario: Issue 2185: email notifications for tag commenting; TO DO: replies to comments

Given the following activated tag wranglers exist
Expand Down
36 changes: 25 additions & 11 deletions spec/controllers/comments_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,15 @@
it_redirects_to_with_error(work_path(work), "Sorry, this work doesn't allow comments.")
end
end

context "when logged in as an admin" do
before { fake_login_admin(create(:admin)) }

it "redirects to root with notice prompting log out" do
get :add_comment_reply, params: { comment_id: comment.id }
it_redirects_to_with_notice(root_path, "Please log out of your admin account first!")
end
end
end

shared_examples "guest cannot reply to a user with guest replies disabled" do
Expand Down Expand Up @@ -308,10 +317,9 @@
context "when logged in as an admin" do
before { fake_login_admin(create(:admin)) }

it "renders the :new template" do
it "redirects to root with notice prompting log out" do
get :new, params: { tag_id: fandom.name }
expect(response).to render_template("new")
expect(assigns(:name)).to eq("Fandom")
it_redirects_to_with_notice(root_path, "Please log out of your admin account first!")
end
end

Expand Down Expand Up @@ -543,16 +551,11 @@
context "when logged in as an admin" do
before { fake_login_admin(create(:admin)) }

it "posts the comment and shows it in context" do
it "redirects to root with notice prompting log out" do
post :create, params: { tag_id: fandom.name, comment: anon_comment_attributes }
it_redirects_to_with_notice(root_path, "Please log out of your admin account first!")
comment = Comment.last
expect(comment.commentable).to eq fandom
expect(comment.name).to eq anon_comment_attributes[:name]
expect(comment.email).to eq anon_comment_attributes[:email]
expect(comment.comment_content).to include anon_comment_attributes[:comment_content]
path = comments_path(tag_id: fandom.to_param,
anchor: "comment_#{comment.id}")
expect(response).to redirect_to path
expect(comment).to eq nil
end
end

Expand Down Expand Up @@ -636,6 +639,17 @@
expect(cookies[:flash_is_set]).to eq(1)
end
end

context "when logged in as an admin" do
let(:work) { create(:work) }

before { fake_login_admin(create(:admin)) }

it "redirects to root with notice prompting log out" do
post :create, params: { work_id: work.id, comment: anon_comment_attributes }
it_redirects_to_with_notice(root_path, "Please log out of your admin account first!")
end
end
end

context "when the commentable is an admin post" do
Expand Down
Loading

0 comments on commit 2889787

Please sign in to comment.