class User < ApplicationRecord
require "digest"
- require "xml/libxml"
+ include AASM
has_many :traces, -> { where(:visible => true) }
has_many :diary_entries, -> { order(:created_at => :desc) }
scope :active, -> { where(:status => %w[active confirmed]) }
scope :identifiable, -> { where(:data_public => true) }
- has_one_attached :avatar
+ has_one_attached :avatar, :service => Settings.avatar_storage
validates :display_name, :presence => true, :length => 3..255,
:exclusion => %w[new terms save confirm confirm-email go_public reset-password forgot-password suspended]
user
end
+ aasm :column => :status, :no_direct_assignment => true do
+ state :pending, :initial => true
+ state :active
+ state :confirmed
+ state :suspended
+ state :deleted
+
+ # A normal account is active
+ event :activate do
+ transitions :from => :pending, :to => :active
+ end
+
+ # Used in test suite, not something that we would normally need to do.
+ if Rails.env.test?
+ event :deactivate do
+ transitions :from => :active, :to => :pending
+ end
+ end
+
+ # To confirm an account is used to override the spam scoring
+ event :confirm do
+ transitions :from => [:pending, :active, :suspended], :to => :confirmed
+ end
+
+ # To unconfirm an account is to make it subject to future spam scoring again
+ event :unconfirm do
+ transitions :from => :confirmed, :to => :active
+ end
+
+ # Accounts can be automatically suspended by spam_check
+ event :suspend do
+ transitions :from => [:pending, :active], :to => :suspended
+ end
+
+ # Unsuspending an account moves it back to active without overriding the spam scoring
+ event :unsuspend do
+ transitions :from => :suspended, :to => :active
+ end
+
+ # Mark the account as deleted but keep all data intact
+ event :hide do
+ transitions :from => [:pending, :active, :confirmed, :suspended], :to => :deleted
+ end
+
+ event :unhide do
+ transitions :from => [:deleted], :to => :active
+ end
+
+ # Mark the account as deleted and remove personal data
+ event :soft_destroy do
+ before do
+ remove_personal_data
+ end
+
+ transitions :from => [:pending, :active, :confirmed, :suspended], :to => :deleted
+ end
+ end
+
def description
RichText.new(self[:description_format], self[:description])
end
end
##
- # delete a user - leave the account but purge most personal data
- def delete
+ # remove personal data - leave the account but purge most personal data
+ def remove_personal_data
avatar.purge_later
self.display_name = "user_#{id}"
self.new_email = nil
self.auth_provider = nil
self.auth_uid = nil
- self.status = "deleted"
save
end
##
# perform a spam check on a user
def spam_check
- update(:status => "suspended") if status == "active" && spam_score > Settings.spam_threshold
+ suspend! if may_suspend? && spam_score > Settings.spam_threshold
end
##