1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
class User < ApplicationRecord
has_secure_password
has_many :sessions, dependent: :destroy
has_many :images, dependent: :destroy
normalizes :email_address, with: ->(e) { e.strip.downcase }
validates :email_address, presence: true, uniqueness: true
validates :name, presence: true
# Session security settings
attribute :require_two_factor, :boolean, default: false
attribute :session_timeout_minutes, :integer, default: 60
attribute :notify_on_new_login, :boolean, default: true
attribute :max_sessions, :integer, default: 5
# 确保 roles 字段始终是数组
# attribute :roles, :json, default: -> { [] }
serialize :roles, coder: JSON, yaml: true
# 定义可用的角色
AVAILABLE_ROLES = %w[admin editor viewer]
# 添加角色
def add_role(role)
return unless AVAILABLE_ROLES.include?(role.to_s)
current_roles = (roles || []).map(&:to_s)
current_roles << role.to_s unless current_roles.include?(role.to_s)
update(roles: current_roles)
end
# 移除角色
def remove_role(role)
current_roles = (roles || []).map(&:to_s)
current_roles.delete(role.to_s)
update(roles: current_roles)
end
# 检查是否有指定角色
def has_role?(role)
Rails.logger.info("roles#{roles.class}")
(roles || []).map(&:to_s).include?(role.to_s)
end
# 向后兼容的 admin? 方法
def admin?
has_role?("admin")
end
def security_settings
{
require_two_factor: require_two_factor,
session_timeout_minutes: session_timeout_minutes,
notify_on_new_login: notify_on_new_login,
max_sessions: max_sessions
}
end
def enforce_max_sessions
return unless max_sessions > 0
# Get all sessions except the current one, ordered by last activity
other_sessions = sessions.where.not(id: Current.session&.id).order(updated_at: :desc)
# If we have more sessions than allowed, destroy the oldest ones
if other_sessions.count >= max_sessions
sessions_to_remove = other_sessions.offset(max_sessions - 1)
sessions_to_remove.destroy_all
end
end
def notify_on_new_login?
notify_on_new_login
end
end