forked from ManageIQ/manageiq
-
Notifications
You must be signed in to change notification settings - Fork 1
/
ownership_mixin.rb
115 lines (96 loc) · 3.85 KB
/
ownership_mixin.rb
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
module OwnershipMixin
extend ActiveSupport::Concern
included do
before_validation :set_tenant_from_group
belongs_to :evm_owner, :class_name => "User"
belongs_to :miq_group
virtual_delegate :email, :name, :userid, :to => :evm_owner, :prefix => true, :allow_nil => true, :type => :string
# Determine whether the selected object is owned by the current user
# Resulting SQL:
#
# (LOWER((SELECT "users"."userid"
# FROM "users"
# WHERE "users"."id" = "THIS_MODELS_TABLE"."evm_owner_id")) = 'some_userid')
#
# explination:
# At first it looks like a simple compare with evm_owner_id = current user id would suffice.
# i.e.: t.grouping(arel_table[:evm_owner_id]]).eq(User.current_user.try(:id)))
#
# But the code is written to support the same userid used across multiple regions. Assuming that they are
# all the same user.
virtual_attribute :owned_by_current_user, :boolean, :uses => :evm_owner, :arel => (lambda do |t|
userid = User.current_userid.to_s.downcase
t.grouping(t.lower(t[:evm_owner_userid]).eq(userid))
end)
virtual_delegate :owning_ldap_group, :to => "miq_group.description", :allow_nil => true, :type => :string
# Determine whether to return objects owned by the current user's miq_group
# or not.
#
# Resulting SQL:
#
# (LOWER((SELECT "miq_groups"."description"
# FROM "miq_groups"
# WHERE "miq_groups"."id" = "THIS_MODELS_TABLE"."miq_group_id")) = 'some_miq_group')
#
# Will result in the following when used with MiqExpression:
#
# WHERE (LOWER((SELECT "miq_groups"."description"
# FROM "miq_groups"
# WHERE "miq_groups"."id" = "THIS_MODELS_TABLE"."miq_group_id")) = 'some_miq_group') = 'true'
virtual_attribute :owned_by_current_ldap_group, :boolean, :arel => (lambda do |t|
ldap_group = User.current_user.try(:ldap_group).to_s.downcase
t.grouping(t.lower(t[:owning_ldap_group]).eq(ldap_group))
end)
end
module ClassMethods
def set_ownership(ids, options)
errors = ActiveModel::Errors.new(self)
objects = where(:id => ids)
missing = ids - objects.collect(&:id)
errors.add(:missing_ids, "Unable to find #{name.pluralize} with the following ids #{missing.inspect}") unless missing.empty?
objects.each do |obj|
options.each_key do |k|
col = case k
when :owner then :evm_owner
when :group then :miq_group
else
raise _("Unknown option, '%{name}'") % {:name => k}
end
obj.send(:"#{col}=", options[k])
end
obj.save
rescue => err
errors.add(:error_updating, "Error, '#{err.message}, updating #{name}: Name: [#{obj.name}], Id: [#{obj.id}]")
end
errors.empty? ? true : errors
end
def user_or_group_owned(user, miq_group)
if user && miq_group
user_owned(user).or(group_owned(miq_group))
elsif user
user_owned(user)
elsif miq_group
group_owned(miq_group)
else
none
end
end
private
def user_owned(user)
where(arel_table.grouping(arel_table.lower(arel_table[:evm_owner_userid]).eq(user.userid.downcase)))
end
def group_owned(miq_group)
where(arel_table.grouping(arel_table.lower(arel_table[:owning_ldap_group]).eq(miq_group.description.downcase)))
end
end
def owned_by_current_user
User.current_userid && evm_owner_userid && User.current_userid.downcase == evm_owner_userid.downcase
end
def owned_by_current_ldap_group
ldap_group = User.current_user.try(:ldap_group)
ldap_group && owning_ldap_group && (owning_ldap_group.downcase == ldap_group.downcase)
end
def set_tenant_from_group
self.tenant_id = miq_group.tenant_id if miq_group
end
end