Skip to content

Commit

Permalink
AO3-6709 Allow certain admins to access inboxes (#4880)
Browse files Browse the repository at this point in the history
* AO3-6709 Certain admins can view the user's inbox page

* AO3-6709 prevent admins from deleting comments or marking them as read

* AO3-6709 Show inbox link on user dashboard only for superadmin and policy and abuse admins

* AO3-6709 redirect to homepage with error if js format is requested

* AO3-6709 fix rubocop issues

* AO3-6709 use i18n standard for sidebar on user dashboard

* AO3-6709 use i18n standard for admin only access denied error messages

* AO3-6709 fix linting issues

* AO3-6709 fix issues with renaming variable

* AO3-6709 Use single inbox_comment_policy for controlling access to inbox page for admins

---------

Co-authored-by: Brian Austin <brianjaustin@gmail.com>
  • Loading branch information
nish-shai-scacap and brianjaustin authored Nov 28, 2024
1 parent 6b187f7 commit 634e7fe
Show file tree
Hide file tree
Showing 7 changed files with 261 additions and 95 deletions.
8 changes: 6 additions & 2 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -269,13 +269,17 @@ def access_denied(options ={})
def admin_only_access_denied
respond_to do |format|
format.html do
flash[:error] = ts("Sorry, only an authorized admin can access the page you were trying to reach.")
flash[:error] = t("admin.access.page_access_denied")
redirect_to root_path
end
format.json do
errors = [ts("Sorry, only an authorized admin can do that.")]
errors = [t("admin.access.action_access_denied")]
render json: { errors: errors }, status: :forbidden
end
format.js do
flash[:error] = t("admin.access.page_access_denied")
render js: "window.location.href = '#{root_path}';"
end
end
end

Expand Down
4 changes: 3 additions & 1 deletion app/controllers/inbox_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class InboxController < ApplicationController
include BlockHelper

before_action :load_user
before_action :check_ownership
before_action :check_ownership_or_admin

before_action :load_commentable, only: :reply
before_action :check_blocked, only: :reply
Expand All @@ -13,6 +13,7 @@ def load_user
end

def show
authorize InboxComment if logged_in_as_admin?
@inbox_total = @user.inbox_comments.with_bad_comments_removed.count
@unread = @user.inbox_comments.with_bad_comments_removed.count_unread
@filters = filter_params[:filters] || {}
Expand All @@ -30,6 +31,7 @@ def reply
end

def update
authorize InboxComment if logged_in_as_admin?
begin
@inbox_comments = InboxComment.find(params[:inbox_comments])
if params[:read]
Expand Down
7 changes: 7 additions & 0 deletions app/policies/inbox_comment_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class InboxCommentPolicy < ApplicationPolicy
VIEW_INBOX_ROLES = %w[superadmin policy_and_abuse].freeze

def show?
user_has_roles?(VIEW_INBOX_ROLES)
end
end
48 changes: 25 additions & 23 deletions app/views/users/_sidebar.html.erb
Original file line number Diff line number Diff line change
@@ -1,62 +1,64 @@
<div id="dashboard" class="region <%= @user == current_user ? "own" : "" %>" role="navigation region">
<h4 class="landmark heading"><%= ts("Choices")%></h4>
<h4 class="landmark heading"><%= t(".landmark.choices") %></h4>
<ul class="navigation actions">
<li><%= span_if_current ts("Dashboard"), @user %></li>
<li><%= span_if_current ts("Profile"), user_profile_path(@user) %></li>
<li><%= span_if_current t(".choices.dashboard"), @user %></li>
<li><%= span_if_current t(".choices.profile"), user_profile_path(@user) %></li>
<% if @user.pseuds.size > 1 %>
<li class="pseud" aria-haspopup="true">
<a href="#" title="<%= ts("Pseud Switcher") %>"><%= ts("Pseuds") %></a>
<a href="#" title="<%= t(".choices.pseud_switcher") %>"><%= t(".choices.pseuds") %></a>
<ul class="expandable secondary">
<%= pseud_selector(pseuds_for_sidebar(@user, @pseud)) %>
<li><%= span_if_current ts("All Pseuds (%{pseud_number})", :pseud_number => @user.pseuds.count), user_pseuds_path(@user) %></li>
<li><%= span_if_current t(".choices.all_pseuds", pseud_number: @user.pseuds.count), user_pseuds_path(@user) %></li>
</ul>
</li>
<% end %>
<% if @user == current_user %>
<li><%= span_if_current ts("Preferences"), user_preferences_path(@user) %></li>
<li><%= span_if_current ts("Skins"), user_skins_path(@user) %></li>
<li><%= span_if_current t(".choices.preferences"), user_preferences_path(@user) %></li>
<li><%= span_if_current t(".choices.skins"), user_skins_path(@user) %></li>
<% end %>
</ul>


<h4 class="landmark heading"><%= ts("Pitch")%></h4>
<h4 class="landmark heading"><%= t(".landmark.pitch") %></h4>
<ul class="navigation actions">
<li><%= works_link(@user, @pseud) %></li>
<% if @user == current_user || logged_in_as_admin? %>
<li><%= span_if_current ts("Drafts") + " (#{@user.unposted_works.size})", drafts_user_works_path(@user) %></li>
<li><%= span_if_current t(".pitch.drafts", drafts_number: @user.unposted_works.size), drafts_user_works_path(@user) %></li>
<% end %>
<li><%= series_link(@user, @pseud) %></li>

<% unless @user == User.orphan_account %>
<li><%= bookmarks_link(@user, @pseud) %></li>
<% end %>

<li><%= span_if_current ts("Collections (%{coll_number})", :coll_number => @user.maintained_collections.count), user_collections_path(@user) %></li>
<li><%= span_if_current t(".pitch.collections", coll_number: @user.maintained_collections.count), user_collections_path(@user) %></li>
</ul>

<% if @user == current_user %>
<h4 class="landmark heading"><%= ts("Catch")%></h4>
<% if @user == current_user || policy(:inbox_comment).show? %>
<h4 class="landmark heading"><%= t(".landmark.catch") %></h4>
<ul class="navigation actions">
<li><%= span_if_current ts("Inbox (%{inbox_number})", :inbox_number => @user.unread_inbox_comments_count.to_s), user_inbox_path(@user) %></li>
<li><%= span_if_current ts("Statistics"), user_stats_path(@user) %></li>
<% if @user.preference.try(:history_enabled?) %>
<li><%= span_if_current ts("History"), user_readings_path(@user) %></li>
<li><%= span_if_current t(".catch.inbox", inbox_number: @user.unread_inbox_comments_count.to_s), user_inbox_path(@user) %></li>
<% if @user == current_user %>
<li><%= span_if_current t(".catch.statistics"), user_stats_path(@user) %></li>
<% if @user.preference.try(:history_enabled?) %>
<li><%= span_if_current t(".catch.history"), user_readings_path(@user) %></li>
<% end %>
<li><%= span_if_current t(".catch.subscriptions"), user_subscriptions_path(@user) %></li>
<% end %>
<li><%= span_if_current ts("Subscriptions"), user_subscriptions_path(@user) %></li>
</ul>
<% end %>

<h4 class="landmark heading"><%= ts("Switch")%></h4>
<h4 class="landmark heading"><%= t(".landmark.switch") %></h4>
<ul class="navigation actions">
<% if @user == current_user %>
<% if @user.preference.allow_cocreator %>
<li><%= span_if_current ts("Co-Creator Requests (%{count})", count: Creatorship.unapproved.for_user(@user).count), user_creatorships_path(@user) %></li>
<li><%= span_if_current t(".switch.co_creator_requests", count: Creatorship.unapproved.for_user(@user).count), user_creatorships_path(@user) %></li>
<% end %>
<li><%= span_if_current ts("Sign-ups (%{signup_number})", :signup_number =>@user.challenge_signups.count), user_signups_path(@user) %></li>
<li><%= span_if_current ts("Assignments (%{assignment_number})", :assignment_number => (@user.offer_assignments.undefaulted.count + @user.pinch_hit_assignments.undefaulted.count)), user_assignments_path(@user) %></li>
<li><%= span_if_current ts("Claims (%{claim_number})", :claim_number => (@user.request_claims.unposted.count)), user_claims_path(@user) %></li>
<li><%= span_if_current ts("Related Works (%{related_works_number})", :related_works_number => (@user.related_works.posted.count + @user.parent_work_relationships.count)), user_related_works_path(@user) %></li>
<li><%= span_if_current t(".switch.sign_ups", signup_number: @user.challenge_signups.count), user_signups_path(@user) %></li>
<li><%= span_if_current t(".switch.assignments", assignment_number: (@user.offer_assignments.undefaulted.count + @user.pinch_hit_assignments.undefaulted.count)), user_assignments_path(@user) %></li>
<li><%= span_if_current t(".switch.claims", claim_number: @user.request_claims.unposted.count), user_claims_path(@user) %></li>
<li><%= span_if_current t(".switch.related_works", related_works_number: (@user.related_works.posted.count + @user.parent_work_relationships.count)), user_related_works_path(@user) %></li>
<% end %>
<li><%= gifts_link(@user) %></li>
</ul>
Expand Down
3 changes: 3 additions & 0 deletions config/locales/controllers/en.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
---
en:
admin:
access:
action_access_denied: Sorry, only an authorized admin can do that.
page_access_denied: Sorry, only an authorized admin can access the page you were trying to reach.
admin_invitations:
find:
user_not_found: No results were found. Try another search.
Expand Down
28 changes: 28 additions & 0 deletions config/locales/views/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1791,6 +1791,34 @@ en:
privacy_policy: Privacy Policy
tos: Terms of Service
welcome_html: Hi! It looks like you've just logged in to AO3 for the first time. For help getting started on AO3, check out some %{new_user_tips_link} or browse through %{our_faqs_link}.
sidebar:
catch:
history: History
inbox: Inbox (%{inbox_number})
statistics: Statistics
subscriptions: Subscriptions
choices:
all_pseuds: All Pseuds (%{pseud_number})
dashboard: Dashboard
preferences: Preferences
profile: Profile
pseud_switcher: Pseud Switcher
pseuds: Pseuds
skins: Skins
landmark:
catch: Catch
choices: Choices
pitch: Pitch
switch: Switch
pitch:
collections: Collections (%{coll_number})
drafts: Drafts (%{drafts_number})
switch:
assignments: Assignments (%{assignment_number})
claims: Claims (%{claim_number})
co_creator_requests: Co-Creator Requests (%{count})
related_works: Related Works (%{related_works_number})
sign_ups: Sign-ups (%{signup_number})
works:
adult:
caution: This work could have adult content. If you continue, you have agreed that you are willing to see such content.
Expand Down
Loading

0 comments on commit 634e7fe

Please sign in to comment.