Class: User

Inherits:
ApplicationRecord show all
Includes:
CustomFields
Defined in:
app/models/user.rb

Overview

specific user rights through memberships (see Group)

Instance Attribute Summary collapse

Attributes included from CustomFields

#custom_fields

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#create_ordergroupObject

Returns the value of attribute create_ordergroup.



21
22
23
# File 'app/models/user.rb', line 21

def create_ordergroup
  @create_ordergroup
end

#passwordObject

Returns the value of attribute password.



21
22
23
# File 'app/models/user.rb', line 21

def password
  @password
end

#send_welcome_mailObject

Returns the value of attribute send_welcome_mail.



21
22
23
# File 'app/models/user.rb', line 21

def send_welcome_mail
  @send_welcome_mail
end

#settings_attributesObject

Returns the value of attribute settings_attributes.



21
22
23
# File 'app/models/user.rb', line 21

def settings_attributes
  @settings_attributes
end

Class Method Details

.authenticate(login, password) ⇒ Object



232
233
234
235
236
237
# File 'app/models/user.rb', line 232

def self.authenticate(, password)
  user = find_by_nick() || find_by_email()
  return unless user && password && user.has_password(password)

  user
end

.custom_fieldsObject



239
240
241
242
243
244
# File 'app/models/user.rb', line 239

def self.custom_fields
  fields = FoodsoftConfig[:custom_fields] && FoodsoftConfig[:custom_fields][:user]
  return [] unless fields

  fields.map(&:deep_symbolize_keys)
end

.natural_orderObject

sorted by display name



96
97
98
99
100
101
102
103
# File 'app/models/user.rb', line 96

def self.natural_order
  # would be sensible to match ApplicationController#show_user
  if FoodsoftConfig[:use_nick]
    order('nick')
  else
    order('first_name', 'last_name')
  end
end

.natural_search(q) ⇒ Object

search by (nick)name



106
107
108
109
110
111
112
113
114
115
116
# File 'app/models/user.rb', line 106

def self.natural_search(q)
  q = q.strip
  users = User.arel_table
  # full string as nickname
  match_nick = users[:nick].matches("%#{q}%")
  # or each word matches either first or last name
  match_name = q.split.map do |a|
    users[:first_name].matches("%#{a}%").or users[:last_name].matches("%#{a}%")
  end.reduce(:and)
  User.where(match_nick.or(match_name))
end

.sort_by_param(param) ⇒ Object



263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'app/models/user.rb', line 263

def self.sort_by_param(param)
  param ||= 'name'

  sort_param_map = {
    'nick' => 'nick',
    'nick_reverse' => 'nick DESC',
    'name' => 'first_name, last_name',
    'name_reverse' => 'first_name DESC, last_name DESC',
    'email' => 'users.email',
    'email_reverse' => 'users.email DESC',
    'phone' => 'phone',
    'phone_reverse' => 'phone DESC',
    'last_activity' => 'last_activity',
    'last_activity_reverse' => 'last_activity DESC',
    'ordergroup' => "IFNULL(groups.type, '') <> 'Ordergroup', groups.name",
    'ordergroup_reverse' => "IFNULL(groups.type, '') <> 'Ordergroup', groups.name DESC"
  }

  # Never pass user input data to Arel.sql() because of SQL Injection vulnerabilities.
  # This case here is okay, as param is mapped to the actual order string.
  eager_load(:groups).order(Arel.sql(sort_param_map[param])) # eager_load is like left_join but without duplicates
end

Instance Method Details

#deleted?Boolean

Returns:

  • (Boolean)


220
221
222
# File 'app/models/user.rb', line 220

def deleted?
  deleted_at.present?
end

#displayObject

XXX this is view-related; need to move out things like token_attributes

then this can be removed


248
249
250
251
252
253
254
255
# File 'app/models/user.rb', line 248

def display
  # would be sensible to match ApplicationHelper#show_user
  if FoodsoftConfig[:use_nick]
    nick.nil? ? I18n.t('helpers.application.nick_fallback') : nick
  else
    name
  end
end

#has_password(password) ⇒ Object

Returns true if the password argument matches the user’s password.



140
141
142
# File 'app/models/user.rb', line 140

def has_password(password)
  Digest::SHA1.hexdigest(password + password_salt) == password_hash
end

#localeObject



118
119
120
# File 'app/models/user.rb', line 118

def locale
  settings.profile['language']
end

#mark_as_deletedObject



224
225
226
# File 'app/models/user.rb', line 224

def mark_as_deleted
  update_column :deleted_at, Time.now
end

#member_of?(group) ⇒ Boolean

returns true if user is a member of a given group

Returns:

  • (Boolean)


211
212
213
# File 'app/models/user.rb', line 211

def member_of?(group)
  group.users.exists?(id)
end

#member_of_groupsObject

Returns an array with the users groups (but without the Ordergroups -> because tpye=>“”)



216
217
218
# File 'app/models/user.rb', line 216

def member_of_groups
  groups.where(type: '')
end

#nameObject



122
123
124
# File 'app/models/user.rb', line 122

def name
  [first_name, last_name].join(' ')
end

#new_random_password(size = 6) ⇒ Object

Returns a random password.



145
146
147
148
149
150
151
152
153
154
155
# File 'app/models/user.rb', line 145

def new_random_password(size = 6)
  c = %w[b c d f g h j k l m n p qu r s t v w x z ch cr fr nd ng nk nt ph pr rd sh sl sp st th tr]
  v = %w[a e i o u y]
  f = true
  r = ''
  (size * 2).times do
    r << (f ? c[rand * c.size] : v[rand * v.size])
    f = !f
  end
  r
end

#ordergroupObject

has_one :ordergroup, :through => :memberships, :source => :group, :class_name => “Ordergroup”



10
11
12
# File 'app/models/user.rb', line 10

def ordergroup
  Ordergroup.joins(:memberships).where(memberships: { user_id: id }).first
end

#ordergroup_nameObject



206
207
208
# File 'app/models/user.rb', line 206

def ordergroup_name
  ordergroup ? ordergroup.name : I18n.t('model.user.no_ordergroup')
end

#receive_email?Boolean

Returns:

  • (Boolean)


126
127
128
# File 'app/models/user.rb', line 126

def receive_email?
  settings.messages['send_as_email'] && email.present?
end

#request_password_reset!Boolean

Generates password reset token and sends email

Returns:

  • (Boolean)

    Whether it succeeded or not



159
160
161
162
163
164
165
166
167
168
169
# File 'app/models/user.rb', line 159

def request_password_reset!
  self.reset_password_token = new_random_password(16)
  self.reset_password_expires = Time.now.advance(days: 2)
  if save!
    Mailer.reset_password(self).deliver_now
    logger.debug("Sent password reset email to #{email}.")
    true
  else
    false
  end
end

#restoreObject



228
229
230
# File 'app/models/user.rb', line 228

def restore
  update_column :deleted_at, nil
end

#role_admin?Boolean

Checks the admin role

Returns:

  • (Boolean)


172
173
174
# File 'app/models/user.rb', line 172

def role_admin?
  groups.detect { |group| group.role_admin? }
end

#role_article_meta?Boolean

Checks the article_meta role

Returns:

  • (Boolean)


187
188
189
# File 'app/models/user.rb', line 187

def 
  FoodsoftConfig[:default_role_article_meta] || groups.detect { |group| group. }
end

#role_finance?Boolean

Checks the finance role

Returns:

  • (Boolean)


177
178
179
# File 'app/models/user.rb', line 177

def role_finance?
  FoodsoftConfig[:default_role_finance] || groups.detect { |group| group.role_finance? }
end

#role_invoices?Boolean

Checks the invoices role

Returns:

  • (Boolean)


182
183
184
# File 'app/models/user.rb', line 182

def role_invoices?
  FoodsoftConfig[:default_role_invoices] || groups.detect { |group| group.role_invoices? }
end

#role_orders?Boolean

Checks the orders role

Returns:

  • (Boolean)


202
203
204
# File 'app/models/user.rb', line 202

def role_orders?
  FoodsoftConfig[:default_role_orders] || groups.detect { |group| group.role_orders? }
end

#role_pickups?Boolean

Checks the invoices role

Returns:

  • (Boolean)


197
198
199
# File 'app/models/user.rb', line 197

def role_pickups?
  FoodsoftConfig[:default_role_pickups] || groups.detect { |group| group.role_pickups? }
end

#role_suppliers?Boolean

Checks the suppliers role

Returns:

  • (Boolean)


192
193
194
# File 'app/models/user.rb', line 192

def role_suppliers?
  FoodsoftConfig[:default_role_suppliers] || groups.detect { |group| group.role_suppliers? }
end

#send_welcome_mail?Boolean

Returns:

  • (Boolean)


91
92
93
# File 'app/models/user.rb', line 91

def send_welcome_mail?
  ActiveModel::Type::Boolean.new.cast(send_welcome_mail)
end

#set_passwordObject

Sets the user’s password. It will be stored encrypted along with a random salt.



131
132
133
134
135
136
137
# File 'app/models/user.rb', line 131

def set_password
  return if password.blank?

  salt = [Array.new(6) { rand(256).chr }.join].pack('m').chomp
  self.password_hash = Digest::SHA1.hexdigest(password + salt)
  self.password_salt = salt
end

#token_attributesObject



257
258
259
260
261
# File 'app/models/user.rb', line 257

def token_attributes
  # would be sensible to match ApplicationController#show_user
  #   this should not be part of the model anyway
  { id: id, name: "#{display} (#{ordergroup.try(:name)})" }
end