Fix email verification being a user level

Having a distinct level for user verification proved to be rather
problematic for code flow and introduced an extra level below
blocked. Since it makes the account unusable until activated
it made sense to use an extra field and stop messing with user
levels explicitly.

This should also make tests a lot easier to deal with because it
doesn't require any changing of the user level.
This commit is contained in:
Kira 2019-09-23 16:16:28 -07:00
parent 9ed7e2227e
commit f5bf733c86
8 changed files with 32 additions and 9 deletions

View File

@ -9,6 +9,8 @@ module Admin
def update
@user = User.find(params[:id])
@user.update!(user_params)
@user.mark_verified! if params[:user][:verified] == 'true'
@user.mark_unverified! if params[:user][:verified] == 'false'
@user.promote_to!(params[:user][:level], params[:user])
redirect_to edit_admin_user_path(@user), :notice => "User updated"
end

View File

@ -30,7 +30,7 @@ class EmailsController < ApplicationController
raise User::PrivilegeError.new('Account cannot be activated because the email is not allowed.') if EmailBlacklist.is_banned?(user.email)
raise User::PrivilegeError.new('Account already activated.') if user.is_verified?
user.update_attribute(:level, User::Levels::MEMBER)
user.mark_verified!
redirect_to home_users_path, notice: "Account activated"
end

View File

@ -54,6 +54,7 @@ class UsersController < ApplicationController
raise User::PrivilegeError.new("Already signed in") unless CurrentUser.is_anonymous?
raise User::PrivilegeError.new("Signups are disabled") unless Danbooru.config.enable_signups?
@user = User.new(user_params(:create))
@user.email_verification_key = '1' if Danbooru.config.enable_email_verification?
if !Danbooru.config.enable_recaptcha? || verify_recaptcha(model: @user)
@user.save
if @user.errors.empty?

View File

@ -70,7 +70,7 @@ class User < ApplicationRecord
validates :email, format: { with: /\A.+@[^ ,;@]+\.[^ ,;@]+\z/, on: :create }
validates :email, format: { with: /\A.+@[^ ,;@]+\.[^ ,;@]+\z/, on: :update, if: ->(rec) { rec.email_changed? } }
else
validates :email, uniqueness: { case_sensitive: false, on: :create, if: ->(rec) { not rec.email.empty?} }
validates :email, uniqueness: { case_sensitive: false, on: :create, if: ->(rec) { rec.email.present?} }
end
validate :validate_email_address_allowed, on: [:create, :update], if: ->(rec) { (rec.new_record? && rec.email.present?) || (rec.email.present? && rec.email_changed?) }
@ -310,15 +310,15 @@ class User < ApplicationRecord
# Changed from e6 to match new Danbooru semantics.
define_method("is_#{normalized_name}?") do
self.level >= value && self.id.present?
is_verified? && self.level >= value && self.id.present?
end
define_method("is_#{normalized_name}_or_higher?") do
self.level >= value && self.id.present?
is_verified? && self.level >= value && self.id.present?
end
define_method("is_#{normalized_name}_or_lower?") do
self.level <= value && self.id.present?
!is_verified? || (self.level <= value && self.id.present?)
end
end
@ -349,7 +349,15 @@ class User < ApplicationRecord
module EmailMethods
def is_verified?
level > Levels::UNACTIVATED
id.present? && email_verification_key.nil?
end
def mark_unverified!
update_attribute(:email_verification_key, '1')
end
def mark_verified!
update_attribute(:email_verification_key, nil)
end
def normalize_email

View File

@ -10,6 +10,11 @@
<%= text_field "user", "email", size: "50" %>
</div>
<div class="input">
<label class="block" for="user_verified">Email Verified</label>
<%= select_tag("user[verified]", options_for_select([["Yes", true], ["No", false]], @user.is_verified?)) %>
</div>
<div class="input">
<label class="block" for="user_about">About</label>
<%= text_area "user", "profile_about", size: "50x8", class: "dtext-full" %>

View File

@ -1,2 +1,2 @@
<p>Your new account in e621 is current unactivated and you still need to confirm your email before you can fully use the account.</p>
<p>Your new account in e621 is currently unactivated and you still need to confirm your email before you can fully use the account.</p>
<p>To finish things up, you only need to click <%= link_to "here.", activate_user_email_url(sig: email_sig(@user, :activate, 48.hours)) %></p>

View File

@ -98,7 +98,6 @@ module Danbooru
def levels
{
"Anonymous" => 0,
"Unactivated" => 1,
"Blocked" => 10,
"Member" => 20,
"Privileged" => 30,
@ -112,7 +111,6 @@ module Danbooru
# Set the default level, permissions, and other settings for new users here.
def customize_new_user(user)
user.level = User::Levels::UNACTIVATED unless user.will_save_change_to_level?
user.comment_threshold = -10 unless user.will_save_change_to_comment_threshold?
user.blacklisted_tags = 'gore
scat

View File

@ -18,11 +18,20 @@ puts "== Seeding database with sample content ==\n"
admin = User.find_or_create_by!(name: "admin") do |user|
user.created_at = 2.weeks.ago
user.password = "e621test"
user.password_hash = ""
user.email = "admin@e621.net"
user.can_upload_free = true
user.level = User::Levels::ADMIN
end
User.find_or_create_by!(name: Danbooru.config.system_user) do |user|
user.password_hash = ""
user.password = "ae3n4oie2n3oi4en23oie4noienaorshtaioresnt"
user.email = "system@e621.net"
user.can_upload_free = true
user.level = User::Levels::ADMIN
end
unless Rails.env.test?
CurrentUser.user = admin
CurrentUser.ip_addr = "127.0.0.1"