Class: User
- Inherits:
-
BarkestCore::DbTable
- Object
- ActiveRecord::Base
- BarkestCore::DbTable
- User
- Includes:
- BarkestCore::EmailTester, BarkestCore::NamedModel
- Defined in:
- app/models/user.rb
Overview
The user class defines the individual users in the application.
Each user can login with their email address, if the domain portion of their email address happens to match an LdapSource, then that LdapSource will be used to authenticate them, otherwise the password_digest
stored in the database will be used to authenticate them.
Constant Summary collapse
- ANONYMOUS_EMAIL =
'[email protected]'
- UNIQUE_STRING_FIELD =
:email
Constants included from BarkestCore::EmailTester
BarkestCore::EmailTester::VALID_EMAIL_REGEX
Instance Attribute Summary collapse
-
#activation_token ⇒ Object
Gets the temporary token used to activate this user.
-
#remember_token ⇒ Object
Gets the temporary token used to remember this user.
-
#reset_token ⇒ Object
Gets the temporary token used to reset this user’s password.
Class Method Summary collapse
-
.anonymous ⇒ Object
Gets a generic anonymous user.
-
.digest(string) ⇒ Object
Returns a hash digest of the given string.
-
.enabled ⇒ Object
Gets all of the currently enabled users.
-
.ensure_admin_exists! ⇒ Object
Generates the necessary system administrator account.
-
.known ⇒ Object
Gets all known users.
-
.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_ldap_reset_email(email, client_ip = '0.0.0.0') ⇒ Object
Sends a message informing the user we cannot change LDAP passwords.
-
.send_missing_reset_email(email, client_ip = '0.0.0.0') ⇒ Object
Sends a missing account message when a user requests a password reset.
-
.sorted ⇒ Object
Sorts the users by name.
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.
-
#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.
-
#has_any_group?(*group_list) ⇒ Boolean
Does this user have the equivalent of one or more of these groups?.
-
#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?.
-
#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.
- #settings(reload = false) ⇒ Object
-
#system_admin? ⇒ Boolean
Is the user a system administrator?.
Methods included from BarkestCore::EmailTester
Methods included from BarkestCore::NamedModel
Instance Attribute Details
#activation_token ⇒ Object
Gets the temporary token used to activate this user.
34 35 36 |
# File 'app/models/user.rb', line 34 def activation_token @activation_token end |
#remember_token ⇒ Object
Gets the temporary token used to remember this user.
30 31 32 |
# File 'app/models/user.rb', line 30 def remember_token @remember_token end |
#reset_token ⇒ Object
Gets the temporary token used to reset this user’s password.
38 39 40 |
# File 'app/models/user.rb', line 38 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 |
# File 'app/models/user.rb', line 375 def self.anonymous @anonymous = nil if Rails.env.test? @anonymous ||= begin pwd = new_token where(email: ANONYMOUS_EMAIL) .first_or_create( email: ANONYMOUS_EMAIL, name: 'Anonymous', enabled: false, activated: true, activated_at: Time.zone.now, password: pwd, password_confirmation: pwd ) end end |
.digest(string) ⇒ Object
Returns a hash digest of the given string.
297 298 299 300 |
# File 'app/models/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 |
.enabled ⇒ Object
Gets all of the currently enabled users.
316 317 318 |
# File 'app/models/user.rb', line 316 def self.enabled where(enabled: true, activated: true) 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 system administrator is **[email protected]** and the password is initially Password1. You should change this immediately once the app is running. You will most likely want to create a completely new admin account and disable the **[email protected]** account.
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/user.rb', line 333 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_email = '[email protected]' def_adm_pass = 'Password1' user = 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.zone.now ) unless 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.zone.now user.save! end end end |
.known ⇒ Object
Gets all known users.
310 311 312 |
# File 'app/models/user.rb', line 310 def self.known where.not(email: ANONYMOUS_EMAIL) end |
.new_token ⇒ Object
Generates a new random token in (url safe) base64.
304 305 306 |
# File 'app/models/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.
279 280 281 |
# File 'app/models/user.rb', line 279 def self.send_disabled_reset_email(email, client_ip = '0.0.0.0') BarkestCore::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.
285 286 287 |
# File 'app/models/user.rb', line 285 def self.send_inactive_reset_email(email, client_ip = '0.0.0.0') BarkestCore::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_ldap_reset_email(email, client_ip = '0.0.0.0') ⇒ Object
Sends a message informing the user we cannot change LDAP passwords.
291 292 293 |
# File 'app/models/user.rb', line 291 def self.send_ldap_reset_email(email, client_ip = '0.0.0.0') BarkestCore::UserMailer::invalid_password_reset(email: email, message: 'The account attached to this email is an LDAP account. This application cannot change passwords on an LDAP account.', 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.
273 274 275 |
# File 'app/models/user.rb', line 273 def self.send_missing_reset_email(email, client_ip = '0.0.0.0') BarkestCore::UserMailer::invalid_password_reset(email: email, client_ip: client_ip).deliver_now end |
.sorted ⇒ Object
Sorts the users by name.
322 323 324 |
# File 'app/models/user.rb', line 322 def self.sorted order(name: :asc) end |
Instance Method Details
#activate ⇒ Object
Marks the user as activated and removes the activation digest from the user model.
166 167 168 169 170 171 172 |
# File 'app/models/user.rb', line 166 def activate update_columns( activated: true, activated_at: Time.zone.now, activation_digest: nil ) end |
#anonymous? ⇒ Boolean
Is this the anonymous user?
198 199 200 |
# File 'app/models/user.rb', line 198 def anonymous? email == ANONYMOUS_EMAIL end |
#authenticated?(attribute, token) ⇒ Boolean
Determines if the supplied token digests to the stored digest in the user model.
128 129 130 131 132 133 |
# File 'app/models/user.rb', line 128 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.
182 183 184 185 186 187 188 |
# File 'app/models/user.rb', line 182 def create_reset_digest self.reset_token = User.new_token update_columns( reset_digest: User.digest(reset_token), reset_sent_at: Time.zone.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.
140 141 142 143 144 145 146 147 148 149 150 |
# File 'app/models/user.rb', line 140 def disable(other_user, reason) return false unless other_user && other_user.system_admin? return false if other_user == self update_columns( disabled_by_id: other_user.id, disabled_at: Time.zone.now, disabled_reason: reason, enabled: false ) end |
#effective_groups(refresh = false) ⇒ Object
Gets the effective group membership of this user.
86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'app/models/user.rb', line 86 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 .inject([]){ |memo,item| memo << item unless memo.include?(item); memo } end .map{ |g| g.to_s.upcase } .sort end |
#enable ⇒ Object
Enables the user and removes any previous disable information.
154 155 156 157 158 159 160 161 |
# File 'app/models/user.rb', line 154 def enable update_columns( disabled_by_id: nil, disabled_at: nil, disabled_reason: nil, enabled: true ) end |
#failed_login_streak ⇒ Object
Gets the failed logins for a user since the last successful login.
216 217 218 219 220 221 222 223 224 225 |
# File 'app/models/user.rb', line 216 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.
122 123 124 |
# File 'app/models/user.rb', line 122 def forget update_attribute(:remember_digest, nil) end |
#has_any_group?(*group_list) ⇒ Boolean
Does this user have the equivalent of one or more of these groups?
102 103 104 105 106 107 108 109 110 111 |
# File 'app/models/user.rb', line 102 def has_any_group?(*group_list) return true if system_admin? group_list.each do |group| group = group.to_s.upcase return true if effective_groups.include?(group) end false end |
#last_failed_login ⇒ Object
Gets the last failed login for this user.
210 211 212 |
# File 'app/models/user.rb', line 210 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.
204 205 206 |
# File 'app/models/user.rb', line 204 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.
66 67 68 69 70 71 72 73 74 75 76 |
# File 'app/models/user.rb', line 66 def partial_email 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 |
#password_reset_expired? ⇒ Boolean
Was the password reset requested more than 2 hours ago?
192 193 194 |
# File 'app/models/user.rb', line 192 def password_reset_expired? reset_sent_at.nil? || reset_sent_at < 2.hours.ago end |
#remember ⇒ Object
Generates a remember token and saves the digest to the user model.
115 116 117 118 |
# File 'app/models/user.rb', line 115 def remember self.remember_token = User.new_token update_attribute(:remember_digest, User.digest(self.remember_token)) end |
#send_activation_email(client_ip = '0.0.0.0') ⇒ Object
Sends the activation email to the user.
176 177 178 |
# File 'app/models/user.rb', line 176 def send_activation_email(client_ip = '0.0.0.0') BarkestCore::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.
267 268 269 |
# File 'app/models/user.rb', line 267 def send_password_reset_email(client_ip = '0.0.0.0') BarkestCore::UserMailer.password_reset(user: self, client_ip: client_ip).deliver_now end |
#settings(reload = false) ⇒ Object
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'app/models/user.rb', line 227 def settings(reload = false) @settings = nil if reload @settings ||= begin h = SystemConfig.get("user_#{id}") || {} h.instance_variable_set :@user_id, id def h.save SystemConfig.set "user_#{@user_id}", self end def h.method_missing(m,*a,&b) x = (/^([A-Z][A-Z0-9_]*)(=)?$/i).match(m.to_s) if x key = x[1].to_sym if x[2] == '=' val = a ? a.first : nil self[key] = val return val else return self[key] end end super m, *a, &b end def h.[](key) super key.to_sym end def h.[]=(key, value) super key.to_sym, value end h end end |
#system_admin? ⇒ Boolean
Is the user a system administrator?
80 81 82 |
# File 'app/models/user.rb', line 80 def system_admin? enabled && system_admin end |