-
Notifications
You must be signed in to change notification settings - Fork 14.9k
Expand file tree
/
Copy pathuser.rb
More file actions
144 lines (124 loc) · 4.59 KB
/
user.rb
File metadata and controls
144 lines (124 loc) · 4.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
require 'securerandom'
module Msf::DBManager::User
MIN_TOKEN_LENGTH = 20
# Returns a list of all users in the database
def users(opts)
::ApplicationRecord.connection_pool.with_connection {
opts = opts.clone() # protect the original caller's opts
search_term = opts.delete(:search_term)
if search_term && !search_term.empty?
column_search_conditions = Msf::Util::DBManager.create_all_column_search_conditions(Mdm::User, search_term)
Mdm::User.where(opts).where(column_search_conditions)
else
Mdm::User.where(opts)
end
}
end
#
# Report a user's attributes.
#
# The opts parameter MUST contain:
# +:username+:: -- the username
# +:password+:: -- the users's cleartext password
#
# The opts parameter can contain:
# +:fullname+:: -- the users's fullname
# +:email+:: -- the users's email
# +:phone+:: -- the users's phone
# +:email+:: -- the users's email
# +:company+:: -- the users's company
# +:prefs+:: -- [Hash] the users's preferences
# +:admin+:: -- [Boolean] True if the user is an admin; otherwise, false.
#
# @return [Mdm::User] The reported Mdm::User object.
def report_user(opts)
return unless active
raise ArgumentError.new("Missing required option :username") if opts[:username].nil?
raise ArgumentError.new("Missing required option :password") if opts[:password].nil?
::ApplicationRecord.connection_pool.with_connection {
conditions = {username: opts[:username]}
user = Mdm::User.where(conditions).first_or_initialize
opts.each do |k,v|
if user.attribute_names.include?(k.to_s)
user[k] = v
elsif !v.blank?
dlog("Unknown attribute for ::Mdm::User: #{k}")
end
end
user.crypted_password = BCrypt::Password.create(opts[:password])
user.admin = false if opts[:admin].nil?
# Finalize
if user.changed?
msf_assign_timestamps(opts, user)
user.save!
end
user
}
end
# Update the attributes of a user entry with the values in opts.
# The values in opts should match the attributes to update.
#
# @param opts [Hash] Hash containing the updated values. Key should match the attribute to update. Must contain :id of record to update.
# @return [Mdm::User] The updated Mdm::User object.
def update_user(opts)
::ApplicationRecord.connection_pool.with_connection {
opts = opts.clone() # protect the original caller's opts
id = opts.delete(:id)
user = Mdm::User.find(id)
user.update!(opts)
return user
}
end
# Deletes user entries based on the IDs passed in.
#
# @param opts[:ids] [Array] Array containing Integers corresponding to the IDs of the user entries to delete.
# @return [Array] Array containing the Mdm::User objects that were successfully deleted.
def delete_user(opts)
raise ArgumentError.new("The following options are required: :ids") if opts[:ids].nil?
::ApplicationRecord.connection_pool.with_connection {
deleted = []
opts[:ids].each do |user_id|
user = Mdm::User.find(user_id)
begin
deleted << user.destroy
rescue # refs suck
elog("Forcibly deleting #{user}")
deleted << user.delete
end
end
return deleted
}
end
# Authenticates the user.
#
# @param opts[:ids] [Integer] ID of the user to authenticate.
# @param opts[:password] [String] The user's password.
# @return [Boolean] True if the user is successfully authenticated; otherwise, false.
def authenticate_user(opts)
raise ArgumentError.new("The following options are required: :id") if opts[:id].nil?
raise ArgumentError.new("The following options are required: :password") if opts[:password].nil?
user = Mdm::User.find(opts[:id])
begin
!user.nil? && BCrypt::Password.new(user.crypted_password) == opts[:password]
rescue BCrypt::Errors::InvalidHash
false
end
end
# Creates a new API token for the user.
#
# The opts parameter MUST contain:
# @param opts[:ids] [Integer] ID for the user.
#
# The opts parameter can contain:
# @param opts[:token_length] [Integer] Token length.
#
# @return [String] The new API token.
def create_new_user_token(opts)
raise ArgumentError.new("The following options are required: :id") if opts[:id].nil?
token_length = opts[:token_length] || MIN_TOKEN_LENGTH
# NOTE: repurposing persistence_token in the database as the API token
user = Mdm::User.find(opts[:id])
user.update!({persistence_token: SecureRandom.hex(token_length)})
user.persistence_token
end
end