Retrospring/app/models/user.rb

201 lines
6.4 KiB
Ruby
Raw Normal View History

2022-06-26 02:00:09 -07:00
# frozen_string_literal: true
2020-04-18 15:59:18 -07:00
class User < ApplicationRecord
2021-12-31 13:19:21 -08:00
include User::Relationship
include User::Relationship::Follow
2022-04-18 12:24:15 -07:00
include User::Relationship::Block
include User::AnswerMethods
include User::BanMethods
include User::InboxMethods
include User::QuestionMethods
include User::ReactionMethods
include User::RelationshipMethods
include User::TimelineMethods
2020-10-18 01:39:46 -07:00
include ActiveModel::OneTimePassword
2014-08-01 03:07:16 -07:00
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
2015-01-01 09:17:34 -08:00
devise :database_authenticatable, :async, :registerable,
2014-08-01 06:27:08 -07:00
:recoverable, :rememberable, :trackable,
:validatable, :confirmable, :authentication_keys => [:login]
2014-11-30 10:43:22 -08:00
2020-10-18 01:39:46 -07:00
has_one_time_password
enum otp_module: { disabled: 0, enabled: 1 }, _prefix: true
2020-10-18 01:39:46 -07:00
attr_accessor :otp_attempt, :otp_validation
rolify
2014-08-01 06:27:08 -07:00
# attr_accessor :login
2014-11-30 10:43:22 -08:00
has_many :questions, dependent: :destroy_async
has_many :answers, dependent: :destroy_async
has_many :comments, dependent: :destroy_async
has_many :inboxes, dependent: :destroy_async
has_many :smiles, class_name: "Appendable::Reaction", dependent: :destroy_async
has_many :services, dependent: :destroy_async
has_many :notifications, foreign_key: :recipient_id, dependent: :destroy_async
has_many :reports, dependent: :destroy_async
has_many :moderation_comments, dependent: :destroy_async
has_many :moderation_votes, dependent: :destroy_async
has_many :lists, dependent: :destroy_async
has_many :list_memberships, class_name: "ListMember", dependent: :destroy_async
has_many :mute_rules, dependent: :destroy_async
has_many :anonymous_blocks, dependent: :destroy_async
2014-11-30 05:43:35 -08:00
has_many :subscriptions, dependent: :destroy_async
has_many :totp_recovery_codes, dependent: :destroy_async
2015-04-20 18:12:11 -07:00
has_one :profile, dependent: :destroy
has_one :theme, dependent: :destroy
has_many :bans, class_name: "UserBan", dependent: :destroy_async
has_many :banned_users, class_name: 'UserBan',
foreign_key: 'banned_by_id',
dependent: :nullify
2014-08-01 06:27:08 -07:00
SCREEN_NAME_REGEX = /\A[a-zA-Z0-9_]{1,16}\z/
WEBSITE_REGEX = /https?:\/\/([A-Za-z.\-]+)\/?(?:.*)/i
2014-11-30 10:43:22 -08:00
before_validation do
screen_name.strip!
end
validates :email, fake_email: true, typoed_email: true
validates :screen_name, presence: true, format: { with: SCREEN_NAME_REGEX }, uniqueness: { case_sensitive: false }, screen_name: true
2020-05-01 15:43:46 -07:00
mount_uploader :profile_picture, ProfilePictureUploader, mount_on: :profile_picture_file_name
2020-05-17 11:58:27 -07:00
process_in_background :profile_picture
2020-05-01 15:43:46 -07:00
mount_uploader :profile_header, ProfileHeaderUploader, mount_on: :profile_header_file_name
2020-05-17 11:58:27 -07:00
process_in_background :profile_header
2014-12-29 01:18:12 -08:00
2020-05-02 09:45:11 -07:00
# when a user has been deleted, all reports relating to the user become invalid
2015-04-29 17:04:43 -07:00
before_destroy do
2015-04-29 17:22:24 -07:00
rep = Report.where(target_id: self.id, type: 'Reports::User')
2015-04-29 17:04:43 -07:00
rep.each do |r|
unless r.nil?
r.deleted = true
r.save
end
end
end
after_create do
Profile.create(user_id: id) if Profile.where(user_id: id).count.zero?
end
2014-08-01 06:27:08 -07:00
def login=(login)
@login = login
end
def login
@login || self.screen_name || self.email
end
2014-11-30 10:43:22 -08:00
2014-08-01 06:27:08 -07:00
def self.find_first_by_auth_conditions(warden_conditions)
2015-04-21 15:33:55 -07:00
conditions = warden_conditions.dup
2014-08-01 06:27:08 -07:00
if login = conditions.delete(:login)
where(conditions).where(["lower(screen_name) = :value OR lower(email) = :value", { :value => login.downcase }]).first
else
where(conditions).first
end
end
# @param list [List]
# @return [Boolean] true if +self+ is a member of +list+
def member_of?(list)
list_memberships.pluck(:list_id).include? list.id
2015-01-13 22:07:40 -08:00
end
# answers a question
# @param question [Question] the question to answer
# @param content [String] the answer content
def answer(question, content)
2022-06-12 04:46:48 -07:00
# rubocop:disable Style/RedundantSelf
raise Errors::AnsweringOtherBlockedSelf if question.user&.blocking?(self)
2022-06-11 14:14:01 -07:00
raise Errors::AnsweringSelfBlockedOther if self.blocking?(question.user)
2022-06-12 04:46:48 -07:00
# rubocop:enable Style/RedundantSelf
2022-06-11 14:14:01 -07:00
Answer.create!(content: content,
user: self,
question: question)
end
2015-01-03 09:40:56 -08:00
# has the user answered +question+ yet?
# @param question [Question]
def answered?(question)
2015-01-13 22:50:27 -08:00
question.answers.pluck(:user_id).include? self.id
2015-01-03 09:40:56 -08:00
end
2014-12-05 05:11:08 -08:00
def comment(answer, content)
2022-06-12 04:46:48 -07:00
# rubocop:disable Style/RedundantSelf
raise Errors::CommentingSelfBlockedOther if self.blocking?(answer.user)
raise Errors::CommentingOtherBlockedSelf if answer.user.blocking?(self)
2022-06-12 04:46:48 -07:00
# rubocop:enable Style/RedundantSelf
2014-12-28 12:58:11 -08:00
Comment.create!(user: self, answer: answer, content: content)
2014-12-05 05:11:08 -08:00
end
2014-12-28 10:32:08 -08:00
# @return [Boolean] is the user a moderator?
def mod?
has_role?(:moderator) || has_role?(:administrator)
2014-12-28 10:32:08 -08:00
end
# region stuff used for reporting/moderation
2015-04-21 19:59:10 -07:00
def report(object, reason = nil)
2015-04-29 17:22:24 -07:00
existing = Report.find_by(type: "Reports::#{object.class}", target_id: object.id, user_id: self.id, deleted: false)
2015-04-21 19:59:10 -07:00
if existing.nil?
Report.create(type: "Reports::#{object.class}", target_id: object.id, user_id: self.id, reason: reason)
elsif not reason.nil? and reason.length > 0
if existing.reason.nil?
existing.update(reason: reason)
else
existing.update(reason: [existing.reason || "", reason].join("\n"))
end
else
existing
end
2014-12-28 10:32:08 -08:00
end
2014-12-28 14:26:16 -08:00
# @param upvote [Boolean]
def report_vote(report, upvote = false)
return unless mod?
ModerationVote.create!(user: self, report: report, upvote: upvote)
end
def report_unvote(report)
return unless mod?
ModerationVote.find_by(user: self, report: report).destroy
end
def report_voted?(report)
return false unless mod?
report.moderation_votes.each { |s| return true if s.user_id == self.id }
false
end
# @param upvote [Boolean]
def report_x_voted?(report, upvote)
return false unless mod?
report.moderation_votes.where(upvote: upvote).each { |s| return true if s.user_id == self.id }
false
end
2014-12-28 15:50:14 -08:00
def report_comment(report, content)
ModerationComment.create!(user: self, report: report, content: content)
end
# endregion
2014-12-29 05:51:52 -08:00
2016-01-05 11:54:13 -08:00
def can_export?
2016-01-05 12:50:21 -08:00
unless self.export_created_at.nil?
return (Time.now > self.export_created_at.in(1.week)) && !self.export_processing
end
!self.export_processing
2016-01-05 11:54:13 -08:00
end
# %w[admin moderator].each do |m|
# define_method(m) { raise "not allowed: #{m}" }
# define_method(m+??) { raise "not allowed: #{m}?"}
# define_method(m+?=) { |*a| raise "not allowed: #{m}="}
# end
2014-08-01 03:07:16 -07:00
end