insights-api-common 3.7.0 → 3.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/insights/api/common/application_controller_mixins/parameters.rb +5 -1
- data/lib/insights/api/common/filter.rb +44 -21
- data/lib/insights/api/common/open_api/generator.rb +3 -9
- data/lib/insights/api/common/paginated_response_v2.rb +100 -10
- data/lib/insights/api/common/rbac/access.rb +47 -27
- data/lib/insights/api/common/rbac/service.rb +4 -4
- data/lib/insights/api/common/version.rb +1 -1
- data/spec/support/rbac_shared_contexts.rb +9 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d2889f1fb8a92c64f95de6f5d4a97f111d35e796a2ab4fb6a6b54ade5bbef05
|
4
|
+
data.tar.gz: 951defb8fb43a566b3f16b49e76f340d95d68f839831c1d6896b72c91dd0428d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 37ea90782a5dad4f376bcc9b99f051394e855b02f4689c93c8049f7a292cf373da4e4f20f8730efd4f8830e6a680b14e61849c2bf3c5198104b5efb9c167b9ef
|
7
|
+
data.tar.gz: 8d331fdbfa57116010b32374e8dfc0ef016249336db7e86dc40d5f685f2f382ff2277064aea57dc9eca451e8be1248f40039828f97762358f3d0d7f9c121f9ed
|
@@ -90,7 +90,11 @@ module Insights
|
|
90
90
|
|
91
91
|
def filtered
|
92
92
|
check_if_openapi_enabled
|
93
|
-
Insights::API::Common::Filter.new(model, safe_params_for_list[:filter], api_doc_definition).apply
|
93
|
+
Insights::API::Common::Filter.new(model, safe_params_for_list[:filter], api_doc_definition, extra_attributes_for_filtering).apply
|
94
|
+
end
|
95
|
+
|
96
|
+
def extra_attributes_for_filtering
|
97
|
+
{}
|
94
98
|
end
|
95
99
|
|
96
100
|
def pagination_limit
|
@@ -5,13 +5,30 @@ module Insights
|
|
5
5
|
INTEGER_COMPARISON_KEYWORDS = ["eq", "gt", "gte", "lt", "lte", "nil", "not_nil"].freeze
|
6
6
|
STRING_COMPARISON_KEYWORDS = ["contains", "contains_i", "eq", "eq_i", "starts_with", "starts_with_i", "ends_with", "ends_with_i", "nil", "not_nil"].freeze
|
7
7
|
|
8
|
-
attr_reader :apply, :arel_table, :api_doc_definition
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
attr_reader :apply, :arel_table, :api_doc_definition, :extra_filterable_attributes, :model
|
9
|
+
|
10
|
+
# Instantiates a new Filter object
|
11
|
+
#
|
12
|
+
# == Parameters:
|
13
|
+
# model::
|
14
|
+
# An AR model that acts as the base collection to be filtered
|
15
|
+
# raw_filter::
|
16
|
+
# The filter from the request query string
|
17
|
+
# api_doc_definition::
|
18
|
+
# The documented object definition from the OpenAPI doc
|
19
|
+
# extra_filterable_attributes::
|
20
|
+
# Attributes that can be used for filtering but are not documented in the OpenAPI doc. Something like `{"undocumented_column" => {"type" => "string"}}`
|
21
|
+
#
|
22
|
+
# == Returns:
|
23
|
+
# A new Filter object, call #apply to get the filtered set of results.
|
24
|
+
#
|
25
|
+
def initialize(model, raw_filter, api_doc_definition, extra_filterable_attributes = {})
|
26
|
+
self.query = model
|
27
|
+
@api_doc_definition = api_doc_definition
|
28
|
+
@arel_table = model.arel_table
|
29
|
+
@extra_filterable_attributes = extra_filterable_attributes
|
30
|
+
@model = model
|
31
|
+
@raw_filter = raw_filter
|
15
32
|
end
|
16
33
|
|
17
34
|
def apply
|
@@ -34,11 +51,13 @@ module Insights
|
|
34
51
|
private
|
35
52
|
|
36
53
|
attr_accessor :query
|
54
|
+
delegate(:arel_attribute, :to => :model)
|
37
55
|
|
38
56
|
class Error < ArgumentError; end
|
39
57
|
|
40
58
|
def attribute_for_key(key)
|
41
59
|
attribute = api_doc_definition.properties[key.to_s]
|
60
|
+
attribute ||= extra_filterable_attributes[key.to_s]
|
42
61
|
return attribute if attribute
|
43
62
|
errors << "found unpermitted parameter: #{key}"
|
44
63
|
nil
|
@@ -108,66 +127,70 @@ module Insights
|
|
108
127
|
end
|
109
128
|
end
|
110
129
|
|
130
|
+
def arel_lower(key)
|
131
|
+
Arel::Nodes::NamedFunction.new("LOWER", [arel_attribute(key)])
|
132
|
+
end
|
133
|
+
|
111
134
|
def comparator_contains(key, value)
|
112
135
|
return value.each { |v| comparator_contains(key, v) } if value.kind_of?(Array)
|
113
136
|
|
114
|
-
self.query = query.where(
|
137
|
+
self.query = query.where(arel_attribute(key).matches("%#{query.sanitize_sql_like(value)}%", nil, true))
|
115
138
|
end
|
116
139
|
|
117
140
|
def comparator_contains_i(key, value)
|
118
141
|
return value.each { |v| comparator_contains_i(key, v) } if value.kind_of?(Array)
|
119
142
|
|
120
|
-
self.query = query.where(arel_table
|
143
|
+
self.query = query.where(arel_table.grouping(arel_lower(key).matches("%#{query.sanitize_sql_like(value.downcase)}%", nil, true)))
|
121
144
|
end
|
122
145
|
|
123
146
|
def comparator_starts_with(key, value)
|
124
|
-
self.query = query.where(
|
147
|
+
self.query = query.where(arel_attribute(key).matches("#{query.sanitize_sql_like(value)}%", nil, true))
|
125
148
|
end
|
126
149
|
|
127
150
|
def comparator_starts_with_i(key, value)
|
128
|
-
self.query = query.where(arel_table
|
151
|
+
self.query = query.where(arel_table.grouping(arel_lower(key).matches("#{query.sanitize_sql_like(value.downcase)}%", nil, true)))
|
129
152
|
end
|
130
153
|
|
131
154
|
def comparator_ends_with(key, value)
|
132
|
-
self.query = query.where(
|
155
|
+
self.query = query.where(arel_attribute(key).matches("%#{query.sanitize_sql_like(value)}", nil, true))
|
133
156
|
end
|
134
157
|
|
135
158
|
def comparator_ends_with_i(key, value)
|
136
|
-
self.query = query.where(arel_table
|
159
|
+
self.query = query.where(arel_table.grouping(arel_lower(key).matches("%#{query.sanitize_sql_like(value.downcase)}", nil, true)))
|
137
160
|
end
|
138
161
|
|
139
162
|
def comparator_eq(key, value)
|
140
|
-
self.query = query.where(key
|
163
|
+
self.query = query.where(arel_attribute(key).eq_any(Array(value)))
|
141
164
|
end
|
142
165
|
|
143
166
|
def comparator_eq_i(key, value)
|
144
167
|
values = Array(value).map { |v| query.sanitize_sql_like(v.downcase) }
|
145
168
|
|
146
|
-
self.query = query.where(arel_table
|
169
|
+
self.query = query.where(arel_table.grouping(arel_lower(key).matches_any(values)))
|
147
170
|
end
|
148
171
|
|
149
172
|
def comparator_gt(key, value)
|
150
|
-
self.query = query.where(
|
173
|
+
self.query = query.where(arel_attribute(key).gt(value))
|
151
174
|
end
|
152
175
|
|
153
176
|
def comparator_gte(key, value)
|
154
|
-
self.query = query.where(
|
177
|
+
self.query = query.where(arel_attribute(key).gteq(value))
|
155
178
|
end
|
156
179
|
|
157
180
|
def comparator_lt(key, value)
|
158
|
-
self.query = query.where(
|
181
|
+
self.query = query.where(arel_attribute(key).lt(value))
|
159
182
|
end
|
160
183
|
|
161
184
|
def comparator_lte(key, value)
|
162
|
-
self.query = query.where(
|
185
|
+
self.query = query.where(arel_attribute(key).lteq(value))
|
163
186
|
end
|
164
187
|
|
165
188
|
def comparator_nil(key, _value = nil)
|
166
|
-
self.query = query.where(key
|
189
|
+
self.query = query.where(arel_attribute(key).eq(nil))
|
167
190
|
end
|
168
191
|
|
169
192
|
def comparator_not_nil(key, _value = nil)
|
170
|
-
self.query = query.where.not(key
|
193
|
+
self.query = query.where.not(arel_attribute(key).eq(nil))
|
171
194
|
end
|
172
195
|
end
|
173
196
|
end
|
@@ -96,11 +96,6 @@ module Insights
|
|
96
96
|
"description" => "ID of the resource",
|
97
97
|
"pattern" => "^\\d+$",
|
98
98
|
"readOnly" => true,
|
99
|
-
},
|
100
|
-
"SortByAttribute" => {
|
101
|
-
"type" => "string",
|
102
|
-
"description" => "Attribute with optional order to sort the result set by.",
|
103
|
-
"pattern" => "^[a-z\\-_]+(:asc|:desc)?$"
|
104
99
|
}
|
105
100
|
}
|
106
101
|
end
|
@@ -179,11 +174,10 @@ module Insights
|
|
179
174
|
"name" => "sort_by",
|
180
175
|
"description" => "The list of attribute and order to sort the result set by.",
|
181
176
|
"required" => false,
|
177
|
+
"style" => "deepObject",
|
178
|
+
"explode" => true,
|
182
179
|
"schema" => {
|
183
|
-
"
|
184
|
-
{ "$ref" => "##{SCHEMAS_PATH}/SortByAttribute" },
|
185
|
-
{ "type" => "array", "items" => { "$ref" => "##{SCHEMAS_PATH}/SortByAttribute" } }
|
186
|
-
]
|
180
|
+
"type" => "object"
|
187
181
|
}
|
188
182
|
}
|
189
183
|
}
|
@@ -2,35 +2,125 @@ module Insights
|
|
2
2
|
module API
|
3
3
|
module Common
|
4
4
|
class PaginatedResponseV2 < PaginatedResponse
|
5
|
+
# GraphQL name regex: /[_A-Za-z][_0-9A-Za-z]*/
|
6
|
+
ASSOCIATION_COUNT_ATTR = "__count".freeze
|
7
|
+
|
5
8
|
attr_reader :limit, :offset, :sort_by
|
6
9
|
|
10
|
+
def records
|
11
|
+
@records ||= begin
|
12
|
+
res = @base_query.order(:id).limit(limit).offset(offset)
|
13
|
+
|
14
|
+
select_for_associations, group_by_associations = sort_by_associations_query_parameters
|
15
|
+
res = res.select(*select_for_associations) if select_for_associations.present?
|
16
|
+
res = res.left_outer_joins(*sort_by_associations) if sort_by_associations.present?
|
17
|
+
res = res.group(group_by_associations) if group_by_associations.present?
|
18
|
+
|
19
|
+
order_options = sort_by_options(res.klass)
|
20
|
+
res = res.reorder(order_options) if order_options.present?
|
21
|
+
res
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Condenses parameter values for handling multi-level associations
|
26
|
+
# and returns an array of key, value pairs.
|
27
|
+
#
|
28
|
+
# Examples:
|
29
|
+
#
|
30
|
+
# Input: { "association" => { "attribute" => "value" }, "direct_attribute" => "value2" }
|
31
|
+
# Output: [["association.attribute", "value"], ["direct_attribute", "value2"]]
|
32
|
+
#
|
33
|
+
# Input: { "association" => { "attribute" => "value" }, "association2" => { "attribute2" => "value2" } }
|
34
|
+
# Output: [["association.attribute", "value"], ["association2.attribute2", "value2"]]
|
35
|
+
#
|
36
|
+
# Input: { "association" => { "attribute1" => "value1", "attribute2" => "value2" } }
|
37
|
+
# Output: [["association.attribute1", "value1"], ["association.attribute2", "value2"]]
|
38
|
+
#
|
39
|
+
def compact_parameter(param)
|
40
|
+
result = []
|
41
|
+
return result if param.blank?
|
42
|
+
|
43
|
+
param.each do |k, v|
|
44
|
+
result += if v.kind_of?(Hash) || v.kind_of?(ActionController::Parameters)
|
45
|
+
Hash(v).map { |ak, av| ["#{k}.#{ak}", av] }
|
46
|
+
else
|
47
|
+
[[k, v]]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
result
|
51
|
+
end
|
52
|
+
|
7
53
|
private
|
8
54
|
|
9
55
|
def sort_by_options(model)
|
10
56
|
@sort_by_options ||= begin
|
11
|
-
|
12
|
-
return sort_options if sort_by.blank?
|
13
|
-
|
14
|
-
sort_by.each do |sort_attr, sort_order|
|
57
|
+
compact_parameter(sort_by).collect do |sort_attr, sort_order|
|
15
58
|
sort_order = "asc" if sort_order.blank?
|
16
|
-
arel =
|
17
|
-
|
18
|
-
|
59
|
+
arel = if sort_attr.include?('.')
|
60
|
+
association, sort_attr = sort_attr.split('.')
|
61
|
+
association_class = association.classify.constantize
|
62
|
+
if sort_attr == ASSOCIATION_COUNT_ATTR
|
63
|
+
Arel.sql("COUNT (#{association_class.table_name}.id)")
|
64
|
+
else
|
65
|
+
association_class.arel_attribute(sort_attr)
|
66
|
+
end
|
67
|
+
else
|
68
|
+
model.arel_attribute(sort_attr)
|
69
|
+
end
|
70
|
+
(sort_order == "desc") ? arel.desc : arel.asc
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def sort_by_associations
|
76
|
+
@sort_by_associations ||= begin
|
77
|
+
compact_parameter(sort_by).collect do |sort_attr, sort_order|
|
78
|
+
next unless sort_attr.include?('.')
|
79
|
+
|
80
|
+
sort_attr.split('.').first.to_sym
|
81
|
+
end.compact.uniq
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def sort_by_associations_query_parameters
|
86
|
+
select_for_associations = []
|
87
|
+
group_by_associations = []
|
88
|
+
count_selects = []
|
89
|
+
|
90
|
+
compact_parameter(sort_by).each do |sort_attr, _sort_order|
|
91
|
+
next unless sort_attr.include?('.')
|
92
|
+
|
93
|
+
association, attr = sort_attr.split('.')
|
94
|
+
|
95
|
+
base_id = "#{@base_query.table_name}.id"
|
96
|
+
base_all = "#{@base_query.table_name}.*"
|
97
|
+
select_for_associations << base_id << base_all if select_for_associations.empty?
|
98
|
+
group_by_associations << base_id << base_all if group_by_associations.empty?
|
99
|
+
|
100
|
+
if attr == ASSOCIATION_COUNT_ATTR
|
101
|
+
count_selects << Arel.sql("COUNT (#{association.classify.constantize.table_name}.id)")
|
102
|
+
else
|
103
|
+
arel_attr = association.classify.constantize.arel_attribute(attr)
|
104
|
+
association_attr = "#{association}_#{attr}"
|
105
|
+
select_for_associations << arel_attr.as(association_attr)
|
106
|
+
group_by_associations << association_attr
|
19
107
|
end
|
20
|
-
sort_options
|
21
108
|
end
|
109
|
+
select_for_associations.append(*count_selects) unless count_selects.empty?
|
110
|
+
|
111
|
+
[select_for_associations.compact.uniq, group_by_associations.compact.uniq]
|
22
112
|
end
|
23
113
|
|
24
114
|
def validate_sort_by
|
25
115
|
return unless sort_by.present?
|
26
116
|
raise ArgumentError, "Invalid sort_by parameter specified \"#{sort_by}\"" unless sort_by.kind_of?(ActionController::Parameters) || sort_by.kind_of?(Hash)
|
27
117
|
|
28
|
-
sort_by.each { |sort_attr, sort_order| validate_sort_by_directive(sort_attr, sort_order) }
|
118
|
+
compact_parameter(sort_by).each { |sort_attr, sort_order| validate_sort_by_directive(sort_attr, sort_order) }
|
29
119
|
end
|
30
120
|
|
31
121
|
def validate_sort_by_directive(sort_attr, sort_order)
|
32
122
|
order = sort_order.blank? ? "asc" : sort_order
|
33
|
-
raise ArgumentError, "Invalid sort_by directive specified \"#{sort_attr}=#{sort_order}\"" unless sort_attr.match?(/^[a-z
|
123
|
+
raise ArgumentError, "Invalid sort_by directive specified \"#{sort_attr}=#{sort_order}\"" unless sort_attr.match?(/^[a-z\-_\.]+$/) && order.match?(/^(asc|desc)$/)
|
34
124
|
end
|
35
125
|
end
|
36
126
|
end
|
@@ -5,32 +5,45 @@ module Insights
|
|
5
5
|
class Access
|
6
6
|
attr_reader :acl
|
7
7
|
DEFAULT_LIMIT = 500
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
ADMIN_SCOPE = "admin"
|
9
|
+
GROUP_SCOPE = "group"
|
10
|
+
USER_SCOPE = "user"
|
11
|
+
|
12
|
+
def initialize(app_name_filter = ENV["APP_NAME"])
|
13
|
+
@app_name_filter = app_name_filter
|
13
14
|
end
|
14
15
|
|
15
16
|
def process
|
16
17
|
Service.call(RBACApiClient::AccessApi) do |api|
|
17
|
-
@
|
18
|
-
@regexp.match?(item.permission)
|
19
|
-
end
|
18
|
+
@acls ||= Service.paginate(api, :get_principal_access, {:limit => DEFAULT_LIMIT}, @app_name_filter).to_a
|
20
19
|
end
|
21
20
|
self
|
22
21
|
end
|
23
22
|
|
24
|
-
def
|
25
|
-
|
23
|
+
def scopes(resource, verb, app_name = ENV['APP_NAME'])
|
24
|
+
regexp = create_regexp(app_name, resource, verb)
|
25
|
+
@acls.each_with_object([]) do |item, memo|
|
26
|
+
if regexp.match?(item.permission)
|
27
|
+
memo << all_scopes(item)
|
28
|
+
end
|
29
|
+
end.flatten.uniq.sort
|
30
|
+
end
|
31
|
+
|
32
|
+
def accessible?(resource, verb, app_name = ENV['APP_NAME'])
|
33
|
+
regexp = create_regexp(app_name, resource, verb)
|
34
|
+
@acls.any? { |item| regexp.match?(item.permission) }
|
35
|
+
end
|
36
|
+
|
37
|
+
def admin_scope?(resource, verb, app_name = ENV['APP_NAME'])
|
38
|
+
scope?(app_name, resource, verb, ADMIN_SCOPE)
|
26
39
|
end
|
27
40
|
|
28
|
-
def
|
29
|
-
|
41
|
+
def group_scope?(resource, verb, app_name = ENV['APP_NAME'])
|
42
|
+
scope?(app_name, resource, verb, GROUP_SCOPE)
|
30
43
|
end
|
31
44
|
|
32
|
-
def
|
33
|
-
|
45
|
+
def user_scope?(resource, verb, app_name = ENV['APP_NAME'])
|
46
|
+
scope?(app_name, resource, verb, USER_SCOPE)
|
34
47
|
end
|
35
48
|
|
36
49
|
def self.enabled?
|
@@ -39,26 +52,33 @@ module Insights
|
|
39
52
|
|
40
53
|
private
|
41
54
|
|
42
|
-
def
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
55
|
+
def scope?(app_name, resource, verb, scope)
|
56
|
+
regexp = create_regexp(app_name, resource, verb)
|
57
|
+
@acls.any? do |item|
|
58
|
+
regexp.match?(item.permission) && scope_matches?(item, scope)
|
59
|
+
end
|
60
|
+
end
|
47
61
|
|
48
|
-
|
49
|
-
|
62
|
+
def scope_matches?(item, scope)
|
63
|
+
item.resource_definitions.any? do |rd|
|
64
|
+
rd.attribute_filter.key == 'scope' &&
|
65
|
+
rd.attribute_filter.operation == 'equal' &&
|
66
|
+
rd.attribute_filter.value == scope
|
50
67
|
end
|
51
68
|
end
|
52
69
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
rd.attribute_filter.
|
57
|
-
|
58
|
-
rd.attribute_filter.value == '{{username}}'
|
70
|
+
def all_scopes(item)
|
71
|
+
item.resource_definitions.each_with_object([]) do |rd, memo|
|
72
|
+
if rd.attribute_filter.key == 'scope' &&
|
73
|
+
rd.attribute_filter.operation == 'equal'
|
74
|
+
memo << rd.attribute_filter.value
|
59
75
|
end
|
60
76
|
end
|
61
77
|
end
|
78
|
+
|
79
|
+
def create_regexp(app_name, resource, verb)
|
80
|
+
Regexp.new("(#{Regexp.escape(app_name)}):(#{Regexp.escape(resource)}):(#{Regexp.escape(verb)})")
|
81
|
+
end
|
62
82
|
end
|
63
83
|
end
|
64
84
|
end
|
@@ -8,9 +8,9 @@ module Insights
|
|
8
8
|
class TimedOutError < StandardError; end
|
9
9
|
|
10
10
|
class Service
|
11
|
-
def self.call(klass)
|
11
|
+
def self.call(klass, extra_headers = {})
|
12
12
|
setup
|
13
|
-
yield init(klass)
|
13
|
+
yield init(klass, extra_headers)
|
14
14
|
rescue RBACApiClient::ApiError => err
|
15
15
|
raise TimedOutError.new('Connection timed out') if err.code.nil?
|
16
16
|
raise NetworkError.new(err.message) if err.code.zero?
|
@@ -55,8 +55,8 @@ module Insights
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
-
private_class_method def self.init(klass)
|
59
|
-
headers = Insights::API::Common::Request.current_forwardable
|
58
|
+
private_class_method def self.init(klass, extra_headers)
|
59
|
+
headers = Insights::API::Common::Request.current_forwardable.merge(extra_headers)
|
60
60
|
klass.new.tap do |api|
|
61
61
|
api.api_client.default_headers = api.api_client.default_headers.merge(headers)
|
62
62
|
end
|
@@ -24,10 +24,19 @@ RSpec.shared_context "rbac_objects" do
|
|
24
24
|
let(:resource_def3) { instance_double(RBACApiClient::ResourceDefinition, :attribute_filter => filter3) }
|
25
25
|
let(:filter4) { instance_double(RBACApiClient::ResourceDefinitionFilter, :key => 'id', :operation => 'equal', :value => '*') }
|
26
26
|
let(:resource_def4) { instance_double(RBACApiClient::ResourceDefinition, :attribute_filter => filter4) }
|
27
|
+
let(:filter5) { instance_double(RBACApiClient::ResourceDefinitionFilter, :key => 'scope', :operation => 'equal', :value => 'admin') }
|
28
|
+
let(:resource_def5) { instance_double(RBACApiClient::ResourceDefinition, :attribute_filter => filter5) }
|
29
|
+
let(:filter6) { instance_double(RBACApiClient::ResourceDefinitionFilter, :key => 'scope', :operation => 'equal', :value => 'group') }
|
30
|
+
let(:resource_def6) { instance_double(RBACApiClient::ResourceDefinition, :attribute_filter => filter6) }
|
31
|
+
let(:filter7) { instance_double(RBACApiClient::ResourceDefinitionFilter, :key => 'scope', :operation => 'equal', :value => 'user') }
|
32
|
+
let(:resource_def7) { instance_double(RBACApiClient::ResourceDefinition, :attribute_filter => filter7) }
|
27
33
|
let(:access1) { instance_double(RBACApiClient::Access, :permission => "#{app_name}:#{resource}:read", :resource_definitions => [resource_def1]) }
|
28
34
|
let(:access2) { instance_double(RBACApiClient::Access, :permission => "#{app_name}:#{resource}:write", :resource_definitions => [resource_def2]) }
|
29
35
|
let(:access3) { instance_double(RBACApiClient::Access, :permission => "#{app_name}:#{resource}:order", :resource_definitions => []) }
|
30
36
|
let(:admin_access) { instance_double(RBACApiClient::Access, :permission => "#{app_name}:#{resource}:read", :resource_definitions => [resource_def4]) }
|
37
|
+
let(:admin_scope) { instance_double(RBACApiClient::Access, :permission => "#{app_name}:#{resource}:read", :resource_definitions => [resource_def5]) }
|
38
|
+
let(:group_scope) { instance_double(RBACApiClient::Access, :permission => "#{app_name}:#{resource}:read", :resource_definitions => [resource_def6]) }
|
39
|
+
let(:user_scope) { instance_double(RBACApiClient::Access, :permission => "#{app_name}:#{resource}:read", :resource_definitions => [resource_def7]) }
|
31
40
|
let(:group_uuids) { [group1.uuid, group2.uuid, group3.uuid] }
|
32
41
|
let(:api_instance) { double }
|
33
42
|
let(:rs_class) { class_double("Insights::API::Common::RBAC::Service").as_stubbed_const(:transfer_nested_constants => true) }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: insights-api-common
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Insights Authors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-03-
|
11
|
+
date: 2020-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: acts_as_tenant
|