Class: User

Constant Summary collapse

ACCESSIBLE_STRATEGY_WITHOUT_IDS =
{:descendant_ids => :descendants, :ancestor_ids => :ancestors}.freeze

Constants included from CustomAttributeMixin

CustomAttributeMixin::CUSTOM_ATTRIBUTES_PREFIX

Constants included from RelationshipMixin

RelationshipMixin::MEMOIZED_METHODS

Constants inherited from ApplicationRecord

ApplicationRecord::FIXTURE_DIR

Constants included from ArRegion

ArRegion::CID_OR_ID_MATCHER, ArRegion::COMPRESSED_ID_SEPARATOR, ArRegion::DEFAULT_RAILS_SEQUENCE_FACTOR, ArRegion::RE_COMPRESSED_ID

Class Method Summary collapse

Instance Method Summary collapse

Methods included from TimezoneMixin

#with_a_timezone, #with_current_user_timezone

Methods included from ActiveVmAggregationMixin

#active_vm_aggregation, #active_vms, #allocated_memory, #allocated_storage, #allocated_vcpu, #provisioned_storage

Methods included from CustomAttributeMixin

#miq_custom_delete, #miq_custom_get, #miq_custom_keys, #miq_custom_set, select_virtual_custom_attributes

Methods included from RelationshipMixin

#add_children, #add_relationship, #ancestor_ids, #ancestor_rels, #ancestors, #ancestors_count, #ancestry, #child_and_grandchild_rels, #child_count, #child_ids, #child_rels, #child_types, #children, #clear_relationships_cache, #depth, #descendant_count, #descendant_ids, #descendant_ids_arranged, #descendant_rels, #descendant_rels_arranged, #descendants, #descendants_arranged, #detect_ancestor, #fulltree, #fulltree_arranged, #fulltree_count, #fulltree_ids, #fulltree_ids_arranged, #fulltree_rels, #fulltree_rels_arranged, #grandchild_rels, #has_children?, #has_siblings?, #init_relationship, #is_ancestor_of?, #is_childless?, #is_descendant_of?, #is_only_child?, #is_root?, #parent, #parent=, #parent_count, #parent_id, #parent_ids, #parent_rel, #parent_rel_ids, #parent_rels, #parents, #path, #path_count, #path_ids, #path_rels, #puts_relationship_tree, #relationship, #relationship_ids, #relationship_type, #relationship_type=, #relationship_types, #relationships, #relationships_of, #reload, #remove_all_children, #remove_all_parents, #remove_all_relationships, #remove_children, #remove_parent, #replace_children, #replace_parent, #root, #root_id, #root_rel, #sibling_count, #sibling_ids, #sibling_rels, #siblings, #subtree, #subtree_arranged, #subtree_count, #subtree_ids, #subtree_ids_arranged, #subtree_rels, #subtree_rels_arranged, #with_relationship_type

Methods included from ArTableLock

#with_lock

Methods included from ToModelHash

#to_model_hash, #to_model_yaml

Methods included from ArLock

#lock

Methods included from ArRegion

anonymous_class_with_ar_region, #compressed_id, #in_current_region?, #miq_region, #my_region_number, #region_description, #region_number, #split_id

Methods inherited from ActiveRecord::Base

acts_as_miq_set, acts_as_miq_set_member, acts_as_miq_taggable, column_names_symbols, extract_ids, extract_objects, model_suffix, #number_of, paginate, truncate

Methods included from VirtualDelegates

select_from_alias, select_from_alias_table

Methods included from Vmdb::Logging

#_log

Class Method Details

.admin?(userid) ⇒ Boolean


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

def self.admin?(userid)
  userid == "admin"
end

.authenticate(username, password, request = nil, options = {}) ⇒ Object


154
155
156
# File 'app/models/user.rb', line 154

def self.authenticate(username, password, request = nil, options = {})
  authenticator(username).authenticate(username, password, request, options)
end

.authenticate_with_http_basic(username, password, request = nil, options = {}) ⇒ Object


158
159
160
# File 'app/models/user.rb', line 158

def self.authenticate_with_http_basic(username, password, request = nil, options = {})
  authenticator(username).authenticate_with_http_basic(username, password, request, options)
end

.authenticator(username = nil) ⇒ Object


150
151
152
# File 'app/models/user.rb', line 150

def self.authenticator(username = nil)
  Authenticator.for(::Settings.authentication.to_hash, username)
end

.authorize_user(userid) ⇒ Object


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

def self.authorize_user(userid)
  return if userid.blank? || admin?(userid)
  authenticator(userid).authorize_user(userid)
end

.current_tenantObject


231
232
233
# File 'app/models/user.rb', line 231

def self.current_tenant
  current_user.try(:current_tenant)
end

.current_userObject


257
258
259
# File 'app/models/user.rb', line 257

def self.current_user
  Thread.current[:user] ||= find_by_userid(current_userid)
end

.current_user=(user) ⇒ Object


247
248
249
250
# File 'app/models/user.rb', line 247

def self.current_user=(user)
  Thread.current[:userid] = user.try(:userid)
  Thread.current[:user] = user
end

.current_useridObject

avoid using this. pass current_user where possible


253
254
255
# File 'app/models/user.rb', line 253

def self.current_userid
  Thread.current[:userid]
end

.find_by_email(email) ⇒ Object


78
79
80
# File 'app/models/user.rb', line 78

def self.find_by_email(email)
  in_my_region.find_by(:email => email)
end

.find_by_lower_email(email, cache = []) ⇒ Object

find a user by lowercase email often we have the most probably user object onhand. so use that if possible


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

def self.find_by_lower_email(email, cache = [])
  email = email.downcase
  Array.wrap(cache).detect { |u| u.email.try(:downcase) == email } || find_by(['lower(email) = ?', email])
end

.find_by_userid(userid) ⇒ Object


70
71
72
# File 'app/models/user.rb', line 70

def self.find_by_userid(userid)
  in_my_region.find_by(:userid => userid)
end

.find_by_userid!(userid) ⇒ Object


74
75
76
# File 'app/models/user.rb', line 74

def self.find_by_userid!(userid)
  in_my_region.find_by!(:userid => userid)
end

.lookup_by_identity(username) ⇒ Object


162
163
164
# File 'app/models/user.rb', line 162

def self.lookup_by_identity(username)
  authenticator(username).lookup_by_identity(username)
end

.scope_by_tenant?Boolean


50
51
52
# File 'app/models/user.rb', line 50

def self.scope_by_tenant?
  true
end

.seedObject


265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'app/models/user.rb', line 265

def self.seed
  seed_data.each do |user_attributes|
    user_id = user_attributes[:userid]
    next if in_my_region.find_by_userid(user_id)
    log_attrs = user_attributes.slice(:name, :userid, :group)
    _log.info("Creating user with parameters #{log_attrs.inspect}")

    group_description = user_attributes.delete(:group)
    group = MiqGroup.in_my_region.find_by(:description => group_description)

    _log.info("Creating #{user_id} user...")
    user = create(user_attributes)
    user.miq_groups = [group] if group
    user.save
    _log.info("Creating #{user_id} user... Complete")
  end
end

.super_adminObject


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

def self.super_admin
  in_my_region.find_by_userid("admin")
end

.tenant_id_clause(user_or_group) ⇒ Object


56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'app/models/user.rb', line 56

def self.tenant_id_clause(user_or_group)
  strategy = Rbac.accessible_tenant_ids_strategy(self)
  tenant = user_or_group.try(:current_tenant)
  return [] if tenant.root?

  accessible_tenants = tenant.send(ACCESSIBLE_STRATEGY_WITHOUT_IDS[strategy])

  users_ids = accessible_tenants.collect(&:user_ids).flatten + tenant.user_ids

  return if users_ids.empty?

  {table_name => {:id => users_ids}}
end

.with_current_user_groupsObject


261
262
263
# File 'app/models/user.rb', line 261

def self.with_current_user_groups
  current_user.admin_user? ? all : includes(:miq_groups).where(:miq_groups => {:id => current_user.miq_group_ids})
end

.with_user(user, userid = nil) ⇒ Object

Save the current user from the session object as a thread variable to allow lookup from other areas of the code


236
237
238
239
240
241
242
243
244
245
# File 'app/models/user.rb', line 236

def self.with_user(user, userid = nil)
  saved_user   = Thread.current[:user]
  saved_userid = Thread.current[:userid]
  self.current_user = user
  Thread.current[:userid] = userid if userid
  yield
ensure
  Thread.current[:user]   = saved_user
  Thread.current[:userid] = saved_userid
end

Instance Method Details

#accessible_vmsObject


217
218
219
220
221
222
223
224
225
# File 'app/models/user.rb', line 217

def accessible_vms
  if limited_self_service?
    vms
  elsif self_service?
    (vms + miq_groups.includes(:vms).collect(&:vms).flatten).uniq
  else
    Vm.all
  end
end

#admin?Boolean


201
202
203
# File 'app/models/user.rb', line 201

def admin?
  self.class.admin?(userid)
end

#authenticate_bcryptObject

use authenticate_bcrypt rather than .authenticate to avoid confusion with the class method of the same name (User.authenticate)


45
# File 'app/models/user.rb', line 45

alias_method :authenticate_bcrypt, :authenticate

#change_password(oldpwd, newpwd) ⇒ Object


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

def change_password(oldpwd, newpwd)
  auth = self.class.authenticator(userid)
  unless auth.uses_stored_password?
    raise MiqException::MiqEVMLoginError,
          _("password change not allowed when authentication mode is %{name}") % {:name => auth.class.proper_name}
  end
  if auth.authenticate(userid, oldpwd)
    self.password = newpwd
    self.save!
  end
end

#current_group_by_description=(group_description) ⇒ Object


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

def current_group_by_description=(group_description)
  if group_description
    desired_group = miq_groups.detect { |g| g.description == group_description }
    desired_group ||= MiqGroup.find_by(:description => group_description) if super_admin_user?
    self.current_group = desired_group if desired_group
  end
end

#destroy_subscribed_widget_setsObject


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

def destroy_subscribed_widget_sets
  subscribed_widget_sets.destroy_all
end

#dummy_password_for_external_authObject


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

def dummy_password_for_external_auth
  if password.blank? && password_digest.blank? &&
     !self.class.authenticator(userid).uses_stored_password?
    self.password = "dummy"
  end
end

#get_expressions(db = nil) ⇒ Object


177
178
179
180
181
182
183
184
185
186
# File 'app/models/user.rb', line 177

def get_expressions(db = nil)
  sql = ["((search_type=? and search_key is null) or (search_type=? and search_key is null) or (search_type=? and search_key=?))",
         'default', 'global', 'user', userid
        ]
  unless db.nil?
    sql[0] += "and db=?"
    sql << db.to_s
  end
  MiqSearch.get_expressions(sql)
end

#get_timezoneObject


192
193
194
# File 'app/models/user.rb', line 192

def get_timezone
  settings.fetch_path(:display, :timezone) || self.class.server_timezone
end

#ldap_groupObject Also known as: miq_group_description


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

def ldap_group
  current_group.try(:description)
end

#logoffObject


171
172
173
174
175
# File 'app/models/user.rb', line 171

def logoff
  self.lastlogoff = Time.now.utc
  save
  AuditEvent.success(:event => "logoff", :message => "User #{userid} has logged off", :userid => userid)
end

#miq_groups=(groups) ⇒ Object


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

def miq_groups=(groups)
  super
  self.current_group = groups.first if current_group.nil? || !groups.include?(current_group)
end

#miq_user_role_nameObject


146
147
148
# File 'app/models/user.rb', line 146

def miq_user_role_name
  miq_user_role.try(:name)
end

#nil_email_field_if_blankObject


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

def nil_email_field_if_blank
  self.email = nil if email.blank?
end

#role_allows?(options = {}) ⇒ Boolean


138
139
140
# File 'app/models/user.rb', line 138

def role_allows?(options = {})
  Rbac.role_allows?(options.merge(:user => self))
end

#role_allows_any?(options = {}) ⇒ Boolean


142
143
144
# File 'app/models/user.rb', line 142

def role_allows_any?(options = {})
  Rbac.role_allows?(options.merge(:user => self, :any => true))
end

#subscribed_widget_setsObject


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

def subscribed_widget_sets
  MiqWidgetSet.subscribed_for_user(self)
end

#validateObject


94
95
96
# File 'app/models/user.rb', line 94

def validate
  errors.add(:userid, "'system' is reserved for EVM internal operations") unless (userid =~ /^system$/i).nil?
end

#with_my_timezone(&block) ⇒ Object


188
189
190
# File 'app/models/user.rb', line 188

def with_my_timezone(&block)
  with_a_timezone(get_timezone, &block)
end