users: let mods see email addresses on user profiles.

* Let Mods and Admins see the email addresses of users below their level.
* Let users see their own email address on their profile.
* Let users verify or edit their email address from their profile.

This is to make catching sockpuppets easier, and to make it easier for
users to fix their email.
This commit is contained in:
evazion
2020-12-13 19:50:25 -06:00
parent 9f09c495e4
commit 67eefadd7f
7 changed files with 96 additions and 6 deletions

View File

@@ -201,6 +201,9 @@
--user-member-color: var(--link-color); --user-member-color: var(--link-color);
--user-banned-color: black; --user-banned-color: black;
--user-verified-email-color: #0A0;
--user-unverified-email-color: #F80;
--news-updates-background: #EEE; --news-updates-background: #EEE;
--news-updates-border: 2px solid #666; --news-updates-border: 2px solid #666;
@@ -291,6 +294,9 @@ body[data-current-user-theme="dark"] {
--user-moderator-color: var(--green-1); --user-moderator-color: var(--green-1);
--user-admin-color: var(--red-1); --user-admin-color: var(--red-1);
--user-verified-email-color: var(--green-1);
--user-unverified-email-color: var(--yellow-1);
/* misc specific colors */ /* misc specific colors */
--autocomplete-selected-background-color: var(--grey-3); --autocomplete-selected-background-color: var(--grey-3);
--autocomplete-border: 1px solid var(--grey-4); --autocomplete-border: 1px solid var(--grey-4);

View File

@@ -30,6 +30,14 @@ div#c-users {
p { p {
margin-bottom: 0.5em; margin-bottom: 0.5em;
} }
.user-verified-email-icon {
color: var(--user-verified-email-color);
}
.user-unverified-email-icon {
color: var(--user-unverified-email-color);
}
} }
} }

View File

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

View File

@@ -0,0 +1,21 @@
class NilClassPolicy < ApplicationPolicy
def index?
false
end
def show?
false
end
def create?
false
end
def update?
false
end
def destroy?
false
end
end

View File

@@ -6,12 +6,12 @@
<% if @user.is_restricted? %> <% if @user.is_restricted? %>
<p>Your account is restricted because you signed up from a VPN or proxy. <p>Your account is restricted because you signed up from a VPN or proxy.
You can still use the site, but you won't be able to leave comments, edit You can still use the site, but you must verify your email address to be
tags, or upload posts until you verify your account.</p> able to leave comments, edit tags, or upload posts.</p>
<% end %> <% end %>
<p>Click below to send an email to <strong><%= @email_address.address %></strong> <p>Your email address is unverified. Click below to send an email to
to verify your account.</p> <strong><%= @email_address.address %></strong> to verify your email address.</p>
<%= edit_form_for(@user, method: :post, url: send_confirmation_user_email_path(@user)) do |f| %> <%= edit_form_for(@user, method: :post, url: send_confirmation_user_email_path(@user)) do |f| %>
<%= f.submit "Send confirmation email" %> <%= f.submit "Send confirmation email" %>

View File

@@ -10,6 +10,7 @@
<th>Join Date</th> <th>Join Date</th>
<td><%= presenter.join_date %></td> <td><%= presenter.join_date %></td>
</tr> </tr>
<% if policy(IpAddress).show? %> <% if policy(IpAddress).show? %>
<tr> <tr>
<th>Last IP</th> <th>Last IP</th>
@@ -27,6 +28,33 @@
</tr> </tr>
<% end %> <% end %>
<% if policy(user.email_address).show? %>
<tr class="user-email-address">
<th>Email Address</th>
<td>
<% if user.email_address.present? %>
<%= user.email_address.address %>
<% if user == CurrentUser.user %>
(<%= link_to "edit", edit_user_email_path(user) %>)
<% end %>
<% if user.email_address.is_verified? %>
<i class="fas fa-check-circle user-verified-email-icon" title="Verified email"></i>
<% elsif user == CurrentUser.user %>
<%= link_to verify_user_email_path(user) do %>
<i class="fas fa-exclamation-triangle user-unverified-email-icon" title="Unverified email. Click here to verify your email."></i>
<% end %>
<% else %>
<i class="fas fa-exclamation-triangle user-email-unverified" title="Unverified email."></i>
<% end %>
<% else %>
<em>none</em>
<% end %>
</td>
</tr>
<% end %>
<tr> <tr>
<th>Inviter</th> <th>Inviter</th>
<% if user.inviter %> <% if user.inviter %>

View File

@@ -114,7 +114,7 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
context "show action" do context "show action" do
setup do setup do
# flesh out profile to get more test coverage of user presenter. # flesh out profile to get more test coverage of user presenter.
@user = create(:banned_user, can_approve_posts: true, created_at: 2.weeks.ago) @user = create(:user, can_approve_posts: true, created_at: 2.weeks.ago)
as(@user) do as(@user) do
create(:saved_search, user: @user) create(:saved_search, user: @user)
create(:post, uploader: @user, tag_string: "fav:#{@user.name}") create(:post, uploader: @user, tag_string: "fav:#{@user.name}")
@@ -152,6 +152,33 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
assert_equal(false, xml["user"]["enable_safe_mode"]) assert_equal(false, xml["user"]["enable_safe_mode"])
end end
context "for a user with an email address" do
setup do
create(:email_address, user: @user)
end
should "show the email address to the user themselves" do
get_auth user_path(@user), @user
assert_response :success
assert_select ".user-email-address", count: 1
end
should "show the email address to mods" do
get_auth user_path(@user), create(:moderator_user)
assert_response :success
assert_select ".user-email-address", count: 1
end
should "not show the email address to other users" do
get_auth user_path(@user), create(:user)
assert_response :success
assert_select ".user-email-address", count: 0
end
end
context "for a tooltip" do context "for a tooltip" do
setup do setup do
@banned = create(:banned_user) @banned = create(:banned_user)