You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
3.1 KiB

require_relative '../../lib/edu/units'
class User < ApplicationRecord
# 邮箱验证
VALID_EMAIL_REGEX = /\A[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+\z/i
# 手机号验证
VALID_PHONE_REGEX = /\A1\d{10}\z/
# 身份证验证
VALID_NUMBER_REGEX = /(\A[1-9]\d{5}(18|19|20|(3\d))\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^([A-Z]\d{6,10}(\(\w{1}\))?)\z)/
SESSION_ACTION = '_educoder_session'
validates :email, format: { with: VALID_EMAIL_REGEX }
validates :password, length: { minimum: 5, maximum: 50 }
validates_uniqueness_of :email, :if => Proc.new { |user| user.email_changed? && user.email.present? }, case_sensitive: false
before_save :update_hashed_password
scope :active, lambda { where(status: USER_STATUS::STATUS_ACTIVE) }
module USER_STATUS
STATUS_INVALID = 0
STATUS_ACTIVE = 1
STATUS_LOCKED = 2
end
def logged?
true
end
module USER_TYPE
ANONYMOUS = "Anonymous"
USER = "User"
end
def self.anonymous
User.find_by(user_type:USER_TYPE::ANONYMOUS)
end
def self.current=(user)
RequestStore.store[:current_user] = user
end
def self.current
RequestStore.store[:current_user]
end
def self.try_to_session_id(key)
user = Token.find_active_user(User::SESSION_ACTION, key)
user.update(last_login_on: Time.now) if user
user
end
def self.try_to_autologin(key)
user = Token.find_active_user('autologin', key)
user.update(last_login_on: Time.now) if user
user
end
def delete_session_token(value)
Token.where(:user_id => id, :action => 'session', :value => value).delete_all
end
def delete_autologin_token(value)
Token.where(:user_id => id, :action => 'autologin', :value => value).delete_all
end
# 修改用户状态
def activate
self.status = STATUS_ACTIVE
end
def lock
self.status = USER_STATUS::STATUS_LOCKED
end
# 用户账号状态
def active?
status == USER_STATUS::STATUS_ACTIVE
end
def invalid?
status == USER_STATUS::STATUS_INVALID
end
def locked?
status == USER_STATUS::STATUS_LOCKED
end
def self.try_to_login(login)
login = login.to_s.strip
# Make sure no one can sign in with an empty login or password
return nil if login.empty?
if (login =~ VALID_EMAIL_REGEX)
user = find_by_email(login)
elsif (login =~ VALID_PHONE_REGEX)
user = find_by_phone(login)
else
user = find_by_login(login)
end
user
rescue => text
raise text
end
# 密码加密
def self.password(clear_password)
Digest::SHA1.hexdigest(clear_password || "")
end
# 检查密码
def check_password?(clear_password)
# Preventing Timing Attack
ActiveSupport::SecurityUtils.secure_compare(
User.password("#{salt}#{User.password clear_password}"),
password
)
end
def self.generate_salt
Edu::Utils.random_hex(16)
end
# 密码加密
def salt_password(clear_password)
self.salt = User.generate_salt
self.password = User.password("#{salt}#{User.password clear_password}")
end
def update_hashed_password
if password
salt_password(password)
end
end
end