google-ads-googleads 8.0.0 → 8.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -63,7 +63,8 @@ module Google
63
63
  yield @config
64
64
  else
65
65
  if config_path.nil?
66
- config_path = File.join(ENV['HOME'], DEFAULT_CONFIG_FILENAME)
66
+ config_path = ENV.fetch("GOOGLE_ADS_CONFIGURATION_FILE_PATH",
67
+ File.join(ENV['HOME'], DEFAULT_CONFIG_FILENAME))
67
68
  end
68
69
 
69
70
  unless File.exist?(config_path)
@@ -96,6 +97,23 @@ module Google
96
97
  yield @config
97
98
  end
98
99
 
100
+ def load_environment_config
101
+ # Generic variables
102
+ @config.refresh_token = ENV.fetch("GOOGLE_ADS_REFRESH_TOKEN", @config.refresh_token)
103
+ @config.client_id = ENV.fetch("GOOGLE_ADS_CLIENT_ID", @config.client_id)
104
+ @config.client_secret = ENV.fetch("GOOGLE_ADS_CLIENT_SECRET", @config.client_secret)
105
+ @config.keyfile = ENV.fetch("GOOGLE_ADS_JSON_KEY_FILE_PATH", @config.keyfile)
106
+ @config.impersonate = ENV.fetch("GOOGLE_ADS_IMPERSONATED_EMAIL", @config.impersonate)
107
+ @config.developer_token = ENV.fetch("GOOGLE_ADS_DEVELOPER_TOKEN", @config.developer_token)
108
+ @config.login_customer_id = ENV.fetch("GOOGLE_ADS_LOGIN_CUSTOMER_ID", @config.login_customer_id)
109
+ @config.linked_customer_id = ENV.fetch("GOOGLE_ADS_LINKED_CUSTOMER_ID", @config.linked_customer_id)
110
+ @config.api_endpoint = ENV.fetch("GOOGLE_ADS_ENDPOINT", @config.api_endpoint)
111
+
112
+ # Client library-specific variables
113
+ @config.log_level = ENV.fetch("GOOGLE_ADS_RUBY_LOG_LEVEL", @config.log_level)
114
+ @config.http_proxy = ENV.fetch("GOOGLE_ADS_RUBY_HTTP_PROXY", @config.http_proxy)
115
+ end
116
+
99
117
  # Return a service for the provided entity type. For example, passing
100
118
  # :Campaign will return an instantiated CampaignServiceClient.
101
119
  #
@@ -117,7 +135,7 @@ module Google
117
135
 
118
136
  def target
119
137
  default_target = "googleads.googleapis.com:443"
120
- target = ENV.fetch('GOOGLEADS_SERVICE_PATH', default_target)
138
+ target = @config.api_endpoint || default_target
121
139
  end
122
140
 
123
141
  def make_channel
@@ -34,7 +34,7 @@ module Google
34
34
  userEmail
35
35
  ]
36
36
  SEARCH_REQUEST_MASK =
37
- /customer_user_access.email_address|change_event.user_email/
37
+ /customer_user_access.email_address|change_event.user_email|feed.places_location_feed_data.email_address/
38
38
 
39
39
  MASK_REPLACEMENT = "REDACTED"
40
40
 
@@ -172,12 +172,16 @@ module Google
172
172
  metadata
173
173
  end
174
174
 
175
+ def clone_to_json(message)
176
+ JSON.parse(message.to_json)
177
+ end
178
+
175
179
  def sanitize_message(message)
176
180
  message_class = message.class.to_s.split("::").last
177
181
  if %w[SearchGoogleAdsStreamResponse SearchGoogleAdsResponse].include?(
178
182
  message_class)
179
183
  # Sanitize all known sensitive fields across all search responses.
180
- message = JSON.parse(message.to_json)
184
+ message = clone_to_json(message)
181
185
  message["fieldMask"].split(",").each do |path|
182
186
  if SEARCH_RESPONSE_FIELDS_TO_MASK.include?(path.split(".").last)
183
187
  message["results"].each do |result|
@@ -189,22 +193,41 @@ module Google
189
193
  elsif %w[SearchGoogleAdsRequest SearchGoogleAdsStreamRequest].include?(
190
194
  message_class)
191
195
  if SEARCH_REQUEST_MASK === message.query
192
- message = JSON.parse(message.to_json)
196
+ message = clone_to_json(message)
193
197
  message["query"] = MASK_REPLACEMENT
194
198
  end
195
199
  message
196
200
  elsif "CustomerUserAccess" == message_class
197
201
  # Sanitize sensitive fields specific to CustomerUserAccess get requests.
198
- message = JSON.parse(message.to_json)
202
+ message = clone_to_json(message)
199
203
  sanitize_customer_user_access(message)
200
204
  elsif "MutateCustomerUserAccessRequest" == message_class
201
205
  # Sanitize sensitive fields when mutating a CustomerUserAccess.
202
- message = JSON.parse(message.to_json)
206
+ message = clone_to_json(message)
203
207
  if message.include?("operation") && message["operation"].include?("update")
204
208
  message["operation"]["update"] =
205
209
  sanitize_customer_user_access(message["operation"]["update"])
206
210
  end
207
211
  message
212
+ elsif "Feed" == message_class
213
+ # Sanitize sensitive fields specific to Feed get requests.
214
+ message = clone_to_json(message)
215
+ if message.include?("placesLocationFeedData") &&
216
+ message["placesLocationFeedData"].include?("emailAddress")
217
+ message["placesLocationFeedData"]["emailAddress"] = MASK_REPLACEMENT
218
+ end
219
+ message
220
+ elsif "MutateFeedsRequest" == message_class
221
+ # Sanitize sensitive fields when mutating a Feed.
222
+ message = clone_to_json(message)
223
+ sanitize_feeds_request(message)
224
+ elsif "CreateCustomerClientRequest" == message_class
225
+ # Sanitize sensitive fields when creating a CustomerClient.
226
+ message = clone_to_json(message)
227
+ if message.include?("emailAddress")
228
+ message["emailAddress"] = MASK_REPLACEMENT
229
+ end
230
+ message
208
231
  else
209
232
  message
210
233
  end
@@ -220,6 +243,26 @@ module Google
220
243
  message
221
244
  end
222
245
 
246
+ def sanitize_feeds_request(message)
247
+ if message.include?("operations")
248
+ message["operations"].each do |operation|
249
+ if operation.include?("create")
250
+ operation = operation["create"]
251
+ elsif operation.include?("update")
252
+ operation = operation["update"]
253
+ else
254
+ # Only create and update can contain sensitive fields.
255
+ next
256
+ end
257
+ if operation.include?("placesLocationFeedData") &&
258
+ operation["placesLocationFeedData"].include?("emailAddress")
259
+ operation["placesLocationFeedData"]["emailAddress"] = MASK_REPLACEMENT
260
+ end
261
+ end
262
+ end
263
+ message
264
+ end
265
+
223
266
  def sanitize_field(object, path)
224
267
  split_path = path.split(".")
225
268
  target_field = split_path.last
@@ -67,26 +67,39 @@ module Google
67
67
  }
68
68
 
69
69
  if config.login_customer_id
70
- validate_login_customer_id
70
+ validate_customer_id(:login_customer_id)
71
71
  # header values must be strings
72
72
  headers[:"login-customer-id"] = config.login_customer_id.to_s
73
73
  end
74
74
 
75
+ if config.linked_customer_id
76
+ validate_customer_id(:linked_customer_id)
77
+ # header values must be strings
78
+ headers[:"linked-customer-id"] = config.linked_customer_id.to_s
79
+ end
80
+
75
81
  headers
76
82
  end
77
83
 
78
- def validate_login_customer_id
84
+ def validate_customer_id(field)
79
85
  begin
80
- login_customer_id = Integer(config.login_customer_id)
86
+ customer_id = -1
87
+ if field == :login_customer_id
88
+ customer_id = Integer(config.login_customer_id)
89
+ elsif field == :linked_customer_id
90
+ customer_id = Integer(config.linked_customer_id)
91
+ else
92
+ return
93
+ end
81
94
  rescue ArgumentError => e
82
95
  if e.message.start_with?("invalid value for Integer")
83
- raise ArgumentError.new("Invalid value for login_customer_id, must be integer")
96
+ raise ArgumentError.new("Invalid value for #{field.to_s}, must be integer")
84
97
  end
85
98
  end
86
- if login_customer_id <= 0 || login_customer_id > 9_999_999_999
99
+ if customer_id <= 0 || customer_id > 9_999_999_999
87
100
  raise ArgumentError.new(
88
- "Invalid login_customer_id. Must be an integer " \
89
- "0 < x <= 9,999,999,999. Got #{login_customer_id}"
101
+ "Invalid #{field.to_s}. Must be an integer " \
102
+ "0 < x <= 9,999,999,999. Got #{customer_id}"
90
103
  )
91
104
  end
92
105
  end
@@ -19,7 +19,7 @@
19
19
  module Google
20
20
  module Ads
21
21
  module GoogleAds
22
- CLIENT_LIB_VERSION = '8.0.0'.freeze
22
+ CLIENT_LIB_VERSION = '8.1.0'.freeze
23
23
  VERSION = CLIENT_LIB_VERSION
24
24
  end
25
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-ads-googleads
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.0.0
4
+ version: 8.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Google Inc
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-12 00:00:00.000000000 Z
11
+ date: 2020-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gapic-common