Class: User

Inherits:
Sequel::Model
  • Object
show all
Includes:
BCrypt
Defined in:
app/models/user.rb

Constant Summary collapse

MIN_PASSWORD_LENGTH =

Password strength rules

8
PASSWORD_RULES =
[
  [/[A-Z]/, "must contain at least one uppercase letter"],
  [/[0-9]/, "must contain at least one number"],
]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.authenticate(username, password) ⇒ Object



79
80
81
82
83
# File 'app/models/user.rb', line 79

def self.authenticate(username, password)
  user = self.find(username: username)
  return user if user && user.password == password
  nil
end

.countObject

Override count for Mongo support



19
20
21
22
23
24
25
# File 'app/models/user.rb', line 19

def self.count
  if mongo?
    MONGO_CLIENT[:users].count_documents
  else
    super
  end
end

.find(params) ⇒ Object

Override find for Mongo support



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'app/models/user.rb', line 28

def self.find(params)
  if mongo?
    # Map :id to :_id and handle ObjectId conversion
    if params[:id]
      id_val = params.delete(:id)
      params[:_id] = BSON::ObjectId.from_string(id_val) rescue id_val
    end
    doc = MONGO_CLIENT[:users].find(params).first
    return nil unless doc
    user = User.new
    # Set virtual ID from Mongo _id
    user.values[:id] = doc[:_id].to_s if doc[:_id]
    user.set(
      username: doc[:username],
      password_hash: doc[:password_hash],
      avatar_url: doc[:avatar_url]
    )
    user
  else
    super
  end
end

.mongo?Boolean

Helper to check if we are in Mongo mode

Returns:

  • (Boolean)


14
15
16
# File 'app/models/user.rb', line 14

def self.mongo?
  defined?(MONGO_CLIENT) && MONGO_CLIENT
end

Instance Method Details

#passwordObject



67
68
69
# File 'app/models/user.rb', line 67

def password
  @password ||= Password.new(password_hash)
end

#password=(new_password) ⇒ Object

Raises:

  • (ArgumentError)


71
72
73
74
75
76
77
# File 'app/models/user.rb', line 71

def password=(new_password)
  errors = validate_password_strength(new_password)
  raise ArgumentError, "Weak password: #{errors.join(', ')}" if errors.any?

  @password = Password.create(new_password)
  self.password_hash = @password
end

#saveObject

Override save for Mongo support



52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'app/models/user.rb', line 52

def save
  if self.class.mongo?
    data = {
      username: self.username,
      password_hash: self.password_hash,
      avatar_url: self.avatar_url,
      updated_at: Time.now
    }
    MONGO_CLIENT[:users].update_one({ username: self.username }, { "$set" => data }, { upsert: true })
    self
  else
    super
  end
end