emails: add /emails index page.

Add emails index page at https://danbooru.donmai.us/emails. Mods can use
this page to view and search emails belonging to users below mod level.
This commit is contained in:
evazion
2020-12-13 21:02:12 -06:00
parent 67eefadd7f
commit 2e633f84f6
7 changed files with 90 additions and 1 deletions

View File

@@ -1,8 +1,19 @@
class EmailsController < ApplicationController
respond_to :html, :xml, :json
def index
@email_addresses = authorize EmailAddress.visible(CurrentUser.user).paginated_search(params, count_pages: true)
@email_addresses = @email_addresses.includes(:user)
respond_with(@email_addresses)
end
def show
@email_address = authorize EmailAddress.find_by_user_id!(params[:user_id])
if params[:user_id]
@email_address = authorize EmailAddress.find_by_user_id!(params[:user_id])
else
@email_address = authorize EmailAddress.find(params[:id])
end
respond_with(@email_address)
end

View File

@@ -10,6 +10,14 @@ class EmailAddress < ApplicationRecord
validate :validate_deliverable, on: :deliverable
after_save :update_user
def self.visible(user)
if user.is_moderator?
where(user: User.where("level < ?", user.level)).or(where(user: user))
else
none
end
end
def address=(value)
self.normalized_address = EmailValidator.normalize(value) || address
super
@@ -29,6 +37,15 @@ class EmailAddress < ApplicationRecord
user.update!(is_verified: is_verified? && nondisposable?)
end
def self.search(params)
q = super
q = q.search_attributes(params, :user, :address, :normalized_address, :is_verified, :is_deliverable)
q = q.apply_default_order(params)
q
end
concerning :VerificationMethods do
def verifier
@verifier ||= Danbooru::MessageVerifier.new(:email_verification_key)

View File

@@ -1,4 +1,8 @@
class EmailAddressPolicy < ApplicationPolicy
def index?
user.is_moderator?
end
def show?
record.user_id == user.id || (user.is_moderator? && record.user.level < user.level)
end

View File

@@ -0,0 +1,32 @@
<div id="c-emails">
<div id="a-index">
<%= search_form_for(emails_path) do |f| %>
<%= f.simple_fields_for :user do |fa| %>
<%= fa.input :name, label: "User Name", input_html: { value: params.dig(:search, :user, :name), "data-autocomplete": "user" } %>
<% end %>
<%= f.input :address_ilike, label: "Address", input_html: { value: params[:search][:address] }, hint: "Use * for wildcard" %>
<%= f.input :is_verified, label: "Verified?", collection: %w[Yes No], selected: params[:search][:is_verified] %>
<%= f.submit "Search" %>
<% end %>
<%= table_for @email_addresses, class: "striped autofit" do |t| %>
<% t.column :user do |email| %>
<%= link_to_user email.user %>
<% end %>
<% t.column :address %>
<% t.column :is_verified, name: "Verified?" do |email| %>
<% if email.is_verified? %>
<%= link_to "Yes", emails_path(search: { is_verified: true }) %>
<% else %>
<%= link_to "No", emails_path(search: { is_verified: false }) %>
<% end %>
<% end %>
<% t.column :updated_at, name: "Updated" do |email| %>
<%= time_ago_in_words_tagged(email.updated_at) %>
<% end %>
<% end %>
<%= numbered_paginator(@email_addresses) %>
</div>
</div>

View File

@@ -154,6 +154,10 @@
<li><%= link_to("Moderation Reports", moderation_reports_path) %></li>
<% end %>
<% if policy(EmailAddress).index? %>
<li><%= link_to("Email Addresses", emails_path) %></li>
<% end %>
<% if policy(IpAddress).index? %>
<li><%= link_to("IP Addresses", ip_addresses_path) %></li>
<% end %>

View File

@@ -103,6 +103,7 @@ Rails.application.routes.draw do
end
resource :dtext_preview, :only => [:create]
resources :dtext_links, only: [:index]
resources :emails, only: [:index, :show]
resources :favorites, :only => [:index, :create, :destroy]
resources :favorite_groups do
member do

View File

@@ -10,6 +10,26 @@ class EmailsControllerTest < ActionDispatch::IntegrationTest
@restricted_user = create(:user, requires_verification: true, is_verified: false)
end
context "#index" do
should "not let regular users see emails belonging to other users" do
get_auth emails_path, @user
assert_response 403
end
should "let mods see emails belonging to themselves and all users below mod level" do
@mod1 = create(:moderator_user, email_address: build(:email_address))
@mod2 = create(:moderator_user, email_address: build(:email_address))
get_auth emails_path, @mod1
assert_response :success
assert_select "#email-address-#{@user.email_address.id}", count: 1
assert_select "#email-address-#{@other_user.email_address.id}", count: 1
assert_select "#email-address-#{@mod1.email_address.id}", count: 1
assert_select "#email-address-#{@mod2.email_address.id}", count: 0
end
end
context "#show" do
should "render" do
get_auth user_email_path(@user), @user, as: :json