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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
|
require 'digest/sha2'
class User < ActiveRecord::Base
after_create :create_a_default_phone_book, :if => :'is_native != false'
# Sync other nodes when this is a cluster.
#
after_create :create_on_other_gs_nodes
after_destroy :destroy_on_other_gs_nodes
after_update :update_on_other_gs_nodes
attr_accessible :user_name, :email, :password, :password_confirmation,
:first_name, :middle_name, :last_name, :male,
:image, :current_tenant_id, :language_id,
:new_pin, :new_pin_confirmation, :send_voicemail_as_email_attachment,
:importer_checksum, :gs_node_id
attr_accessor :new_pin, :new_pin_confirmation
before_validation {
# If the PIN and PIN confirmation are left blank in the GUI
# then the user/admin does not want to change the PIN.
if self.new_pin.blank? && self.new_pin_confirmation.blank?
self.new_pin = nil
self.new_pin_confirmation = nil
end
}
validates_length_of [:new_pin, :new_pin_confirmation],
:minimum => (GsParameter.get('MINIMUM_PIN_LENGTH').nil? ? 4 : GsParameter.get('MINIMUM_PIN_LENGTH')),
:maximum => (GsParameter.get('MAXIMUM_PIN_LENGTH').nil? ? 10 : GsParameter.get('MAXIMUM_PIN_LENGTH')),
:allow_blank => true, :allow_nil => true
validates_format_of [:new_pin, :new_pin_confirmation],
:with => /^[0-9]+$/,
:allow_blank => true, :allow_nil => true,
:message => "must be numeric."
validates_confirmation_of :new_pin, :if => :'pin_changed?'
before_save :hash_new_pin, :if => :'pin_changed?'
has_secure_password
validates_presence_of :password, :password_confirmation, :on => :create, :if => :'password_digest.blank?'
validates_presence_of :email
validates_presence_of :last_name
validates_presence_of :first_name
validates_presence_of :user_name
validates_uniqueness_of :user_name, :case_sensitive => false
validates_uniqueness_of :email, :allow_nil => true, :case_sensitive => false
validates_length_of :user_name, :within => 0..50
validates_presence_of :uuid
validates_uniqueness_of :uuid
# Associations:
#
has_many :tenant_memberships, :dependent => :destroy
has_many :tenants, :through => :tenant_memberships
has_many :user_group_memberships, :dependent => :destroy, :uniq => true
has_many :user_groups, :through => :user_group_memberships
has_many :phone_books, :as => :phone_bookable, :dependent => :destroy
has_many :phone_book_entries, :through => :phone_books
has_many :phones, :as => :phoneable
has_many :sip_accounts, :as => :sip_accountable, :dependent => :destroy
has_many :phone_numbers, :through => :sip_accounts
has_many :conferences, :as => :conferenceable, :dependent => :destroy
has_many :fax_accounts, :as => :fax_accountable, :dependent => :destroy
has_many :system_messages, :dependent => :destroy
has_many :auto_destroy_access_authorization_phone_numbers, :class_name => 'PhoneNumber', :foreign_key => 'access_authorization_user_id', :dependent => :destroy
belongs_to :current_tenant, :class_name => 'Tenant'
validates_presence_of :current_tenant, :if => Proc.new{ |user| user.current_tenant_id }
belongs_to :language
validates_presence_of :language_id
validates_presence_of :language
validate :current_tenant_is_included_in_tenants, :if => Proc.new{ |user| user.current_tenant_id }
belongs_to :gs_node
# Avatar like photo
mount_uploader :image, ImageUploader
before_save :format_email_and_user_name
before_destroy :destroy_or_logout_phones
after_save :become_a_member_of_default_user_groups
def destroy
clean_whitelist_entries
super
end
def pin_changed?
! @new_pin.blank?
end
def sip_domain
if self.current_tenant
return self.current_tenant.sip_domain
end
return nil
end
def to_s
max_first_name_length = 10
max_last_name_length = 20
if self.first_name.blank?
self.last_name.strip
else
"#{self.first_name.strip} #{self.last_name.strip}"
end
end
def self.find_user_by_phone_number( number, tenant )
tenant = Tenant.where( :id => tenant.id ).first
if tenant
if tenant.sip_domain
user = tenant.sip_domain.sip_accounts.
joins(:phone_numbers).
where(:phone_numbers => { :number => number }).
first.
try(:sip_accountable)
if user.class.name == 'User'
return user
end
end
end
return nil
end
def authenticate_by_pin?( entered_pin )
self.pin_hash == Digest::SHA2.hexdigest( "#{self.pin_salt}#{entered_pin}" )
end
private
def hash_new_pin
if @new_pin \
&& @new_pin_confirmation \
&& @new_pin_confirmation == @new_pin
self.pin_salt = SecureRandom.base64(8)
self.pin_hash = Digest::SHA2.hexdigest(self.pin_salt + @new_pin)
end
end
def format_email_and_user_name
self.email = self.email.downcase.strip if !self.email.blank?
self.user_name = self.user_name.downcase.strip if !self.user_name.blank?
end
# Create a personal phone book for this user:
def create_a_default_phone_book
private_phone_book = self.phone_books.find_or_create_by_name_and_description(
I18n.t('phone_books.private_phone_book.name', :resource => self.to_s),
I18n.t('phone_books.private_phone_book.description')
)
end
# Check if a current_tenant_id is possible tenant_membership wise.
def current_tenant_is_included_in_tenants
if !self.tenants.include?(Tenant.find(self.current_tenant_id))
errors.add(:current_tenant_id, "is not possible (no TenantMembership)")
end
end
# Make sure that there are no whitelist entries with phone_numbers of
# a just destroyed user.
#
def clean_whitelist_entries
phone_numbers = PhoneNumber.where( :phone_numberable_type => 'Whitelist').
where( :number => self.phone_numbers.map{ |x| x.number } )
phone_numbers.each do |phone_number|
if phone_number.phone_numberable.whitelistable.class == Callthrough
whitelist = Whitelist.find(phone_number.phone_numberable)
phone_number.destroy
if whitelist.phone_numbers.count == 0
# Very lickly that this Whitelist doesn't make sense any more.
#
whitelist.destroy
end
end
end
end
# Make sure that a tenant phone goes back to the tenant and doesn't
# get deleted with this user.
#
def destroy_or_logout_phones
self.phones.each do |phone|
if phone.sip_accounts.where(:sip_accountable_type => 'Tenant').count > 0
phone.user_logout
else
phone.destroy
end
phone.resync
end
end
# Normaly a new user should become a member of default user groups.
#
def become_a_member_of_default_user_groups
UserGroup.where(:id => GsParameter.get('DEFAULT_USER_GROUPS_IDS')).each do |user_group|
user_group.user_group_memberships.create(:user_id => self.id)
end
end
end
|