Class: Incline::User
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Incline::User
- Defined in:
- app/models/incline/user.rb
Overview
This class represents an application user.
Constant Summary collapse
- ANONYMOUS_EMAIL =
'[email protected]'
Instance Attribute Summary collapse
-
#activation_token ⇒ Object
Returns the value of attribute activation_token.
-
#recaptcha ⇒ Object
Returns the value of attribute recaptcha.
-
#remember_token ⇒ Object
Returns the value of attribute remember_token.
-
#reset_token ⇒ Object
Returns the value of attribute reset_token.
Class Method Summary collapse
-
.anonymous ⇒ Object
Gets a generic anonymous user.
-
.digest(string) ⇒ Object
Returns a hash digest of the given string.
-
.ensure_admin_exists! ⇒ Object
Generates the necessary system administrator account.
-
.new_token ⇒ Object
Generates a new random token in (url safe) base64.
-
.send_disabled_reset_email(email, client_ip = '0.0.0.0') ⇒ Object
Sends a disabled account message when a user requests a password reset.
-
.send_inactive_reset_email(email, client_ip = '0.0.0.0') ⇒ Object
Sends a non-activated account message when a user requests a password reset.
-
.send_missing_reset_email(email, client_ip = '0.0.0.0') ⇒ Object
Sends a missing account message when a user requests a password reset.
Instance Method Summary collapse
-
#activate ⇒ Object
Marks the user as activated and removes the activation digest from the user model.
-
#anonymous? ⇒ Boolean
Is this the anonymous user?.
-
#authenticated?(attribute, token) ⇒ Boolean
Determines if the supplied token digests to the stored digest in the user model.
-
#create_reset_digest ⇒ Object
Creates a reset token and stores the digest to the user model.
-
#disable(other_user, reason) ⇒ Object
Disables the user.
-
#effective_groups(refresh = false) ⇒ Object
Gets the effective group membership of this user.
-
#enable ⇒ Object
Enables the user and removes any previous disable information.
-
#enabled ⇒ Object
Gets all of the currently enabled users.
-
#failed_login_streak ⇒ Object
Gets the failed logins for a user since the last successful login.
-
#forget ⇒ Object
Removes the remember digest from the user model.
-
#formatted_email ⇒ Object
Gets the email formatted with the name.
-
#group_ids ⇒ Object
Gets the IDs for the groups that the user explicitly belongs to.
-
#group_ids=(values) ⇒ Object
Sets the IDs for the groups that the user explicitly belongs to.
-
#has_any_group?(*group_list) ⇒ Boolean
Does this user have the equivalent of one or more of these groups?.
-
#known ⇒ Object
Gets all known users.
-
#last_failed_login ⇒ Object
Gets the last failed login for this user.
-
#last_successful_login ⇒ Object
Gets the last successful login for this user.
-
#partial_email ⇒ Object
Gets the email address in a partially obfuscated fashion.
-
#password_reset_expired? ⇒ Boolean
Was the password reset requested more than 2 hours ago?.
-
#refresh_comments ⇒ Object
Generates some brief comments about the user account and stores them in the comments attribute.
-
#remember ⇒ Object
Generates a remember token and saves the digest to the user model.
-
#send_activation_email(client_ip = '0.0.0.0') ⇒ Object
Sends the activation email to the user.
-
#send_password_reset_email(client_ip = '0.0.0.0') ⇒ Object
Sends the password reset email to the user.
-
#sorted ⇒ Object
Sorts the users by name.
-
#to_s ⇒ Object
Gets the formatted email for this user.
Instance Attribute Details
#activation_token ⇒ Object
Returns the value of attribute activation_token.
27 28 29 |
# File 'app/models/incline/user.rb', line 27 def activation_token @activation_token end |
#recaptcha ⇒ Object
Returns the value of attribute recaptcha.
24 25 26 |
# File 'app/models/incline/user.rb', line 24 def recaptcha @recaptcha end |
#remember_token ⇒ Object
Returns the value of attribute remember_token.
26 27 28 |
# File 'app/models/incline/user.rb', line 26 def remember_token @remember_token end |
#reset_token ⇒ Object
Returns the value of attribute reset_token.
28 29 30 |
# File 'app/models/incline/user.rb', line 28 def reset_token @reset_token end |
Class Method Details
.anonymous ⇒ Object
Gets a generic anonymous user.
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 |
# File 'app/models/incline/user.rb', line 375 def self.anonymous @anonymous = nil if Rails.env.test? # always start fresh in test environment. @anonymous ||= Incline::Recaptcha::pause_for do pwd = new_token User .where(email: ANONYMOUS_EMAIL) .first_or_create!( email: ANONYMOUS_EMAIL, name: 'Anonymous', enabled: false, activated: true, activated_at: Time.now, password: pwd, password_confirmation: pwd, recaptcha: 'na' ) end end |
.digest(string) ⇒ Object
Returns a hash digest of the given string.
297 298 299 300 |
# File 'app/models/incline/user.rb', line 297 def self.digest(string) cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost BCrypt::Password.create(string, cost: cost) end |
.ensure_admin_exists! ⇒ Object
Generates the necessary system administrator account.
When the database is initially seeded, the only user is the system administrator.
The absolute default is **[email protected]** with a password of Password1. These values will be used if they are not overridden for the current environment.
You can override this by setting the default_admin
property in “config/secrets.yml”.
# config/secrets.yml
development:
default_admin:
email: [email protected]
password: Password1
Regardless of whether you use the absolute defaults or create your own, you will want to change the password on first login.
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 |
# File 'app/models/incline/user.rb', line 327 def self.ensure_admin_exists! unless where(system_admin: true, enabled: true).count > 0 msg = "Creating/reactivating default administrator...\n" if Rails.application.running? Rails.logger.info msg else print msg end def_adm = (Rails.application.secrets[:default_admin] || {}).symbolize_keys def_adm_email = def_adm[:email] || '[email protected]' def_adm_pass = def_adm[:password] || 'Password1' user = Incline::Recaptcha::pause_for do User .where( email: def_adm_email ) .first_or_create!( name: 'Default Administrator', email: def_adm_email, password: def_adm_pass, password_confirmation: def_adm_pass, enabled: true, system_admin: true, activated: true, activated_at: Time.now, recaptcha: 'na' ) end unless user.activated? && user.enabled? && user.system_admin? user.password = def_adm_pass user.password_confirmation = def_adm_pass user.enabled = true user.system_admin = true user.activated = true user.activated_at = Time.now user.save! end end end |
.new_token ⇒ Object
Generates a new random token in (url safe) base64.
304 305 306 |
# File 'app/models/incline/user.rb', line 304 def self.new_token SecureRandom.urlsafe_base64(32) end |
.send_disabled_reset_email(email, client_ip = '0.0.0.0') ⇒ Object
Sends a disabled account message when a user requests a password reset.
285 286 287 |
# File 'app/models/incline/user.rb', line 285 def self.send_disabled_reset_email(email, client_ip = '0.0.0.0') Incline::UserMailer::invalid_password_reset(email: email, message: 'The account attached to this email address has been disabled.', client_ip: client_ip).deliver_now end |
.send_inactive_reset_email(email, client_ip = '0.0.0.0') ⇒ Object
Sends a non-activated account message when a user requests a password reset.
291 292 293 |
# File 'app/models/incline/user.rb', line 291 def self.send_inactive_reset_email(email, client_ip = '0.0.0.0') Incline::UserMailer::invalid_password_reset(email: email, message: 'The account attached to this email has not yet been activated.', client_ip: client_ip).deliver_now end |
.send_missing_reset_email(email, client_ip = '0.0.0.0') ⇒ Object
Sends a missing account message when a user requests a password reset.
279 280 281 |
# File 'app/models/incline/user.rb', line 279 def self.send_missing_reset_email(email, client_ip = '0.0.0.0') Incline::UserMailer::invalid_password_reset(email: email, client_ip: client_ip).deliver_now end |
Instance Method Details
#activate ⇒ Object
Marks the user as activated and removes the activation digest from the user model.
201 202 203 204 205 206 207 |
# File 'app/models/incline/user.rb', line 201 def activate update_columns( activated: true, activated_at: Time.now, activation_digest: nil ) && refresh_comments end |
#anonymous? ⇒ Boolean
Is this the anonymous user?
233 234 235 |
# File 'app/models/incline/user.rb', line 233 def anonymous? email == ANONYMOUS_EMAIL end |
#authenticated?(attribute, token) ⇒ Boolean
Determines if the supplied token digests to the stored digest in the user model.
164 165 166 167 168 169 |
# File 'app/models/incline/user.rb', line 164 def authenticated?(attribute, token) return false unless respond_to?("#{attribute}_digest") digest = send("#{attribute}_digest") return false if digest.blank? BCrypt::Password.new(digest).is_password?(token) end |
#create_reset_digest ⇒ Object
Creates a reset token and stores the digest to the user model.
217 218 219 220 221 222 223 |
# File 'app/models/incline/user.rb', line 217 def create_reset_digest self.reset_token = Incline::User::new_token update_columns( reset_digest: Incline::User::digest(reset_token), reset_sent_at: Time.now ) end |
#disable(other_user, reason) ⇒ Object
Disables the user.
The other_user
is required, cannot be the current user, and must be a system administrator. The reason
is technically optional, but should be provided.
176 177 178 179 180 181 182 183 184 185 186 |
# File 'app/models/incline/user.rb', line 176 def disable(other_user, reason) return false unless other_user&.system_admin? return false if other_user == self update_columns( disabled_by: other_user.email, disabled_at: Time.now, disabled_reason: reason, enabled: false ) && refresh_comments end |
#effective_groups(refresh = false) ⇒ Object
Gets the effective group membership of this user.
124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'app/models/incline/user.rb', line 124 def effective_groups(refresh = false) @effective_groups = nil if refresh @effective_groups ||= if system_admin? AccessGroup.all.map{ |g| g.to_s.upcase } else groups .collect{ |g| g.effective_groups } .flatten end .map{ |g| g.to_s.upcase } .uniq .sort end |
#enable ⇒ Object
Enables the user and removes any previous disable information.
190 191 192 193 194 195 196 197 |
# File 'app/models/incline/user.rb', line 190 def enable update_columns( disabled_by: nil, disabled_at: nil, disabled_reason: nil, enabled: true ) && refresh_comments end |
#enabled ⇒ Object
Gets all of the currently enabled users.
78 |
# File 'app/models/incline/user.rb', line 78 scope :enabled, ->{ where(enabled: true, activated: true) } |
#failed_login_streak ⇒ Object
Gets the failed logins for a user since the last successful login.
251 252 253 254 255 256 257 258 259 260 |
# File 'app/models/incline/user.rb', line 251 def failed_login_streak @failed_login_streak ||= begin results = login_histories.where.not(successful: true) if last_successful_login results = results.where('created_at > ?', last_successful_login.created_at) end results.order(created_at: :desc) end end |
#forget ⇒ Object
Removes the remember digest from the user model.
158 159 160 |
# File 'app/models/incline/user.rb', line 158 def forget update_attribute(:remember_digest, nil) end |
#formatted_email ⇒ Object
Gets the email formatted with the name.
103 104 105 |
# File 'app/models/incline/user.rb', line 103 def formatted_email "#{name} <#{email}>" end |
#group_ids ⇒ Object
Gets the IDs for the groups that the user explicitly belongs to.
109 110 111 |
# File 'app/models/incline/user.rb', line 109 def group_ids groups.map{|g| g.id} end |
#group_ids=(values) ⇒ Object
Sets the IDs for the groups that the user explicitly belongs to.
115 116 117 118 119 120 |
# File 'app/models/incline/user.rb', line 115 def group_ids=(values) values ||= [] values = [ values ] unless values.is_a?(::Array) values = values.reject{|v| v.blank?}.map{|v| v.to_i} self.groups = Incline::AccessGroup.where(id: values).to_a end |
#has_any_group?(*group_list) ⇒ Boolean
Does this user have the equivalent of one or more of these groups?
140 141 142 143 144 145 146 147 |
# File 'app/models/incline/user.rb', line 140 def has_any_group?(*group_list) return :system_admin if system_admin? return false if anonymous? r = group_list.select{|g| effective_groups.include?(g.upcase)} r.blank? ? false : r end |
#known ⇒ Object
Gets all known users.
74 |
# File 'app/models/incline/user.rb', line 74 scope :known, ->{ where.not(email: ANONYMOUS_EMAIL) } |
#last_failed_login ⇒ Object
Gets the last failed login for this user.
245 246 247 |
# File 'app/models/incline/user.rb', line 245 def last_failed_login @last_failed_login ||= login_histories.where.not(successful: true).order(created_at: :desc).first end |
#last_successful_login ⇒ Object
Gets the last successful login for this user.
239 240 241 |
# File 'app/models/incline/user.rb', line 239 def last_successful_login @last_successful_login ||= login_histories.where(successful: true).order(created_at: :desc).first end |
#partial_email ⇒ Object
Gets the email address in a partially obfuscated fashion.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'app/models/incline/user.rb', line 86 def partial_email @partial_email ||= begin uid,_,domain = email.partition('@') if uid.length < 4 uid = '*' * uid.length elsif uid.length < 8 uid = uid[0..2] + ('*' * (uid.length - 3)) else uid = uid[0..2] + ('*' * (uid.length - 6)) + uid[-3..-1] end "#{uid}@#{domain}" end end |
#password_reset_expired? ⇒ Boolean
Was the password reset requested more than 2 hours ago?
227 228 229 |
# File 'app/models/incline/user.rb', line 227 def password_reset_expired? reset_sent_at.nil? || reset_sent_at < 2.hours.ago end |
#refresh_comments ⇒ Object
Generates some brief comments about the user account and stores them in the comments attribute.
This gets updated automatically on every login attempt.
266 267 268 269 |
# File 'app/models/incline/user.rb', line 266 def refresh_comments update_columns :comments => generate_comments comments end |
#remember ⇒ Object
Generates a remember token and saves the digest to the user model.
151 152 153 154 |
# File 'app/models/incline/user.rb', line 151 def remember self.remember_token = Incline::User::new_token update_attribute(:remember_digest, Incline::User::digest(self.remember_token)) end |
#send_activation_email(client_ip = '0.0.0.0') ⇒ Object
Sends the activation email to the user.
211 212 213 |
# File 'app/models/incline/user.rb', line 211 def send_activation_email(client_ip = '0.0.0.0') Incline::UserMailer.account_activation(user: self, client_ip: client_ip).deliver_now end |
#send_password_reset_email(client_ip = '0.0.0.0') ⇒ Object
Sends the password reset email to the user.
273 274 275 |
# File 'app/models/incline/user.rb', line 273 def send_password_reset_email(client_ip = '0.0.0.0') Incline::UserMailer.password_reset(user: self, client_ip: client_ip).deliver_now end |
#sorted ⇒ Object
Sorts the users by name.
82 |
# File 'app/models/incline/user.rb', line 82 scope :sorted, ->{ order(name: :asc) } |
#to_s ⇒ Object
Gets the formatted email for this user.
397 398 399 |
# File 'app/models/incline/user.rb', line 397 def to_s formatted_email end |