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



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

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

  user
end

.custom_fieldsObject



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

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



89
90
91
92
93
94
95
96
# File 'app/models/user.rb', line 89

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



99
100
101
102
103
104
105
106
107
108
109
# File 'app/models/user.rb', line 99

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



256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'app/models/user.rb', line 256

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)


213
214
215
# File 'app/models/user.rb', line 213

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


241
242
243
244
245
246
247
248
# File 'app/models/user.rb', line 241

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.



133
134
135
# File 'app/models/user.rb', line 133

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

#localeObject



111
112
113
# File 'app/models/user.rb', line 111

def locale
  settings.profile['language']
end

#mark_as_deletedObject



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

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)


204
205
206
# File 'app/models/user.rb', line 204

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=>“”)



209
210
211
# File 'app/models/user.rb', line 209

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

#nameObject



115
116
117
# File 'app/models/user.rb', line 115

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

#new_random_password(size = 6) ⇒ Object

Returns a random password.



138
139
140
141
142
143
144
145
146
147
148
# File 'app/models/user.rb', line 138

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



199
200
201
# File 'app/models/user.rb', line 199

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

#receive_email?Boolean

Returns:

  • (Boolean)


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

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



152
153
154
155
156
157
158
159
160
161
162
# File 'app/models/user.rb', line 152

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



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

def restore
  update_column :deleted_at, nil
end

#role_admin?Boolean

Checks the admin role

Returns:

  • (Boolean)


165
166
167
# File 'app/models/user.rb', line 165

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

#role_article_meta?Boolean

Checks the article_meta role

Returns:

  • (Boolean)


180
181
182
# File 'app/models/user.rb', line 180

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

#role_finance?Boolean

Checks the finance role

Returns:

  • (Boolean)


170
171
172
# File 'app/models/user.rb', line 170

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

#role_invoices?Boolean

Checks the invoices role

Returns:

  • (Boolean)


175
176
177
# File 'app/models/user.rb', line 175

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

#role_orders?Boolean

Checks the orders role

Returns:

  • (Boolean)


195
196
197
# File 'app/models/user.rb', line 195

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

#role_pickups?Boolean

Checks the invoices role

Returns:

  • (Boolean)


190
191
192
# File 'app/models/user.rb', line 190

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

#role_suppliers?Boolean

Checks the suppliers role

Returns:

  • (Boolean)


185
186
187
# File 'app/models/user.rb', line 185

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

#send_welcome_mail?Boolean

Returns:

  • (Boolean)


84
85
86
# File 'app/models/user.rb', line 84

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.



124
125
126
127
128
129
130
# File 'app/models/user.rb', line 124

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



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

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