gibbon 3.4.0 → 3.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6078387c488e567cb48e2c113c1201d412de3989ce740e04149bf77f37aaad97
4
- data.tar.gz: 7adbe131b1b495bb3e8296edd7682b50db0fd5e886eae80668d45e442662b46e
3
+ metadata.gz: 61103c56f7d3ff60ca48fab8a2ca7c71949c1c01c784abd7ddb062dbd74d4560
4
+ data.tar.gz: 93f18505844eb71b72d189622547c61c0bda3c416bdb2a2caa4ec0358899e52b
5
5
  SHA512:
6
- metadata.gz: ad43e961eba03d11441173b136e6b75315ab0a46ac54714caf85ea68d50a44fda5fb1e70f596fd61f3337a8759a7d3da878467e1be890927816ec290038ffeb8
7
- data.tar.gz: cc37182cfaf77bd044d01a812ef3ba5d7d5a5c3475aaceb1b4c84b915fa9772b8b33317dff78b0ac2878925a53885e1bcbc5cc41d978e04d1d05f9c5c047fb40
6
+ metadata.gz: 7e4203bc006c80cc20c5fff0217673543faa842a28b57eb3620a373a63409c0e1b5f503335d44ff05d8ba8d124db1f5b984dcf5f98632aaa8ee077d525d0a413
7
+ data.tar.gz: ecc7c39379e218a5a10d92c4597fdb9e5f28c90c8297ef5a19d04189044a0b86a0f84120151369ecca4c989c3d88bb359fcc651de9527497cba368b608225d9d
@@ -0,0 +1,3 @@
1
+ # These are supported funding model platforms
2
+
3
+ github: [amro]
data/.travis.yml CHANGED
@@ -9,4 +9,5 @@ rvm:
9
9
  - 2.6.5
10
10
  - 2.7
11
11
  - 3.0.0
12
-
12
+ - 3.1
13
+ - 3.2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
- ## [Unreleased][unreleased]
1
+ ## [3.5.0, unreleased] - 2022-06-05
2
+ - Remove support for retired Export API
2
3
 
4
+ ## [3.4.4] - 2022-02-24
5
+ - Remove non-alpha characters when parsing datacenter from API keys to prevent potential attackers from injecting a domain via the API key. This would only be possible if one were using user-provided API keys (e.g. from a form, etc.).
6
+
7
+ ## [3.4.3] - 2022-01-19
8
+ - Support for Faraday 2.0, which requires new syntax for basic auth
9
+
10
+ ## [3.4.2] - 2021-09-21
11
+ - Fixing the deprecation warning in version 3.4.2 requires moving to a minimum version of Faraday 1.0.0 (more than 2 years old).
12
+
13
+ ## [3.4.1] - 2021-09-12
14
+ - Fix deprecation warning for upcoming versions of Faraday (2.x.x)
3
15
 
4
16
  ## [3.4.0] - 2021-03-12
5
17
  - Support for Faraday 1.x.x and higer
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010-2020 Amro Mousa
1
+ Copyright (c) 2010-2022 Amro Mousa
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.markdown CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gibbon is an API wrapper for MailChimp's [API](http://kb.mailchimp.com/api/).
4
4
 
5
- [![Build Status](https://travis-ci.com/amro/gibbon.svg?branch=master)](https://travis-ci.com/amro/gibbon)
5
+ [![Build Status](https://travis-ci.com/amro/gibbon.svg?branch=master)](https://app.travis-ci.com/github/amro/gibbon)
6
6
 
7
7
  ## Important Notes
8
8
 
@@ -38,7 +38,7 @@ gibbon.open_timeout = 30
38
38
  You can read about `timeout` and `open_timeout` in the [Net::HTTP](https://ruby-doc.org/stdlib-2.3.3/libdoc/net/http/rdoc/Net/HTTP.html) doc.
39
39
 
40
40
  Now you can make requests using the resources defined in [MailChimp's docs](http://kb.mailchimp.com/api/resources). Resource IDs
41
- are specified inline and a `CRUD` (`create`, `retrieve`, `update`, `upsert`, or `delete`) verb initiates the request. `upsert` lets you update a record, if it exists, or insert it otherwise where supported by MailChimp's API.
41
+ are specified inline and a `CRUD` (`create`, `retrieve` (or `get`), `update`, `upsert`, or `delete`) verb initiates the request. `upsert` lets you update a record, if it exists, or insert it otherwise where supported by MailChimp's API.
42
42
 
43
43
  ***Note*** `upsert` requires Gibbon version 2.1.0 or newer!
44
44
 
@@ -48,6 +48,8 @@ You can specify `headers`, `params`, and `body` when calling a `CRUD` method. Fo
48
48
  gibbon.lists.retrieve(headers: {"SomeHeader": "SomeHeaderValue"}, params: {"query_param": "query_param_value"})
49
49
  ```
50
50
 
51
+ ***Note*** `get` can be substituted for `retrieve` as of Gibbon version 3.4.1 or newer!
52
+
51
53
  Of course, `body` is only supported on `create`, `update`, and `upsert` calls. Those map to HTTP `POST`, `PATCH`, and `PUT` verbs respectively.
52
54
 
53
55
  You can set `api_key`, `timeout`, `open_timeout`, `faraday_adapter`, `proxy`, `symbolize_keys`, `logger`, and `debug` globally:
@@ -178,6 +180,12 @@ Get a specific member's information (open/click rates etc.) from MailChimp:
178
180
  gibbon.lists(list_id).members(lower_case_md5_hashed_email_address).retrieve
179
181
  ```
180
182
 
183
+ Permanently delete a specific member from a list:
184
+
185
+ ```ruby
186
+ gibbon.lists(list_id).members(lower_case_md5_hashed_email_address).actions.delete_permanent.create
187
+ ```
188
+
181
189
  ### Tags
182
190
 
183
191
  [Tags](https://mailchimp.com/help/getting-started-tags/) are a flexible way to organize (slice and dice) your list: for example, you can send a campaign directly to one or more tags.
@@ -472,33 +480,6 @@ Gibbon 2.x+:
472
480
  ```ruby
473
481
  gibbon.lists(list_id).members.create(body: {email_address: "foo@bar.com", status: "subscribed", merge_fields: {FNAME: "Bob", LNAME: "Smith"}})
474
482
  ```
475
- ## Export API 1.0
476
-
477
- Gibbon 3.0.0+ supports MailChimp's [Export API 1.0](https://apidocs.mailchimp.com/export/1.0/). You can choose to handle the API response all at
478
- once or line by line by passing a block. To access the Export API with Gibbon, you must first create an instance of `Gibbon::Export`:
479
-
480
- ```ruby
481
- export = Gibbon::Export.new(api_key: "your_api_key")
482
- ```
483
-
484
- Next, call the method corresponding to the API endpoint you'd like to query:
485
-
486
- ```ruby
487
- export.list(id: list_id)
488
- ```
489
-
490
- This fetches and returns all of the results at once. Pass a block if you'd like to handle the response as individual lines:
491
-
492
- ```ruby
493
- export = Gibbon::Export.new(api_key: "your_api_key", timeout: 1200)
494
- export.list(id: list_id) do |row|
495
- puts row
496
- end
497
- ```
498
-
499
- This is useful when handling large sets of data. Setting the `timeout` here is optional, but a high value is recommended given the nature of the Export API. The default timeout is 600 seconds.
500
-
501
- Gibbon supports all current Export API endpoints: `/list`, `/ecommOrders`, and `/campaignSubscriberActivity`. They're mapped onto Ruby methods with similar names: `list()`, `ecomm_orders()`, and `campaign_subscriber_activity()` respectively. Please see [MailChimp's API documentation](https://developer.mailchimp.com/documentation/mailchimp/guides/how-to-use-the-export-api/) for supported parameters.
502
483
 
503
484
  ## Thanks
504
485
 
@@ -506,5 +487,5 @@ Thanks to everyone who has [contributed](https://github.com/amro/gibbon/contribu
506
487
 
507
488
  ## Copyright
508
489
 
509
- * Copyright (c) 2010-2020 Amro Mousa. See LICENSE.txt for details.
510
- * MailChimp (c) 2001-2020 The Rocket Science Group.
490
+ * Copyright (c) 2010-2022 Amro Mousa. See LICENSE.txt for details.
491
+ * MailChimp (c) 2001-2022 The Rocket Science Group.
data/gibbon.gemspec CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |s|
9
9
  s.email = ["amromousa@gmail.com"]
10
10
  s.homepage = "http://github.com/amro/gibbon"
11
11
 
12
- s.summary = %q{A wrapper for MailChimp API 3.0 and Export API}
13
- s.description = %q{A wrapper for MailChimp API 3.0 and Export API}
12
+ s.summary = %q{A wrapper for MailChimp API 3.0}
13
+ s.description = %q{A wrapper for MailChimp API 3.0}
14
14
  s.license = "MIT"
15
15
 
16
16
  s.files = `git ls-files`.split("\n")
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.require_paths = ["lib"]
20
20
  s.required_ruby_version = '>= 2.4.0'
21
21
 
22
- s.add_dependency('faraday', '>= 0.16.0')
22
+ s.add_dependency('faraday', '>= 1.0')
23
23
  s.add_dependency('multi_json', '>= 1.11.0')
24
24
 
25
25
  s.add_development_dependency 'rake'
@@ -152,8 +152,14 @@ module Gibbon
152
152
  if @request_builder.debug
153
153
  faraday.response :logger, @request_builder.logger, bodies: true
154
154
  end
155
+
156
+ if Faraday::VERSION.to_i >= 2
157
+ faraday.request :authorization, :basic, 'apikey', self.api_key
158
+ else
159
+ faraday.request :basic_auth, 'apikey', self.api_key
160
+ end
155
161
  end
156
- client.basic_auth('apikey', self.api_key)
162
+
157
163
  client
158
164
  end
159
165
 
@@ -5,8 +5,12 @@ module Gibbon
5
5
  data_center = ""
6
6
 
7
7
  if api_key && api_key["-"]
8
- # Add a period since the data_center is a subdomain and it keeps things dry
9
- data_center = "#{api_key.split('-').last}."
8
+ # Remove all non-alphanumberic characters in case someone attempts to inject
9
+ # a different domain into the API key (e.g. when consuming user form-provided keys)
10
+ # This approach avoids assuming a 3 letter prefix (e.g. is MC were to create
11
+ # a us10 DC, this would continue to work), and will continue to hit MC's server
12
+ # rather than a would-be attacker's servers.
13
+ data_center = "#{api_key.split('-').last.gsub(/[^0-9a-z ]/i, '')}."
10
14
  end
11
15
 
12
16
  data_center
@@ -61,6 +61,10 @@ module Gibbon
61
61
  reset
62
62
  end
63
63
 
64
+ def get(params: nil, headers: nil)
65
+ retrieve(params: params, headers: headers)
66
+ end
67
+
64
68
  def retrieve(params: nil, headers: nil)
65
69
  APIRequest.new(builder: self).get(params: params, headers: headers)
66
70
  ensure
@@ -1,3 +1,3 @@
1
1
  module Gibbon
2
- VERSION = "3.4.0"
2
+ VERSION = "3.5.0"
3
3
  end
data/lib/gibbon.rb CHANGED
@@ -9,7 +9,6 @@ require 'gibbon/mailchimp_error'
9
9
  require 'gibbon/request'
10
10
  require 'gibbon/api_request'
11
11
  require 'gibbon/response'
12
- require 'gibbon/export'
13
12
 
14
13
  module Gibbon
15
14
  end
@@ -14,6 +14,7 @@ describe Gibbon do
14
14
  @gibbon = Gibbon::Request.new
15
15
  expect(@gibbon.api_key).to be_nil
16
16
  end
17
+
17
18
  it "sets an API key in the constructor" do
18
19
  @gibbon = Gibbon::Request.new(api_key: @api_key)
19
20
  expect(@gibbon.api_key).to eq(@api_key)
@@ -162,6 +163,14 @@ describe Gibbon do
162
163
  @request = Gibbon::APIRequest.new(builder: @gibbon)
163
164
  expect {@request.validate_api_key}.not_to raise_error
164
165
  end
166
+
167
+ it "removes non-alpha characters from datacenter prefix" do
168
+ @api_key = "123-attacker.net/test/?"
169
+ @gibbon.api_key = @api_key
170
+ @gibbon.try
171
+ @request = Gibbon::APIRequest.new(builder: @gibbon)
172
+ expect(@request.api_url).to eq("https://attackernettest.api.mailchimp.com/3.0/try")
173
+ end
165
174
  end
166
175
 
167
176
  describe "class variables" do
@@ -213,7 +222,7 @@ describe Gibbon do
213
222
  it "set debug on new instances" do
214
223
  expect(Gibbon::Request.new.debug).to eq(Gibbon::Request.debug)
215
224
  end
216
-
225
+
217
226
  it "set faraday_adapter on new instances" do
218
227
  expect(Gibbon::Request.new.faraday_adapter).to eq(Gibbon::Request.faraday_adapter)
219
228
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gibbon
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.0
4
+ version: 3.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Amro Mousa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-12 00:00:00.000000000 Z
11
+ date: 2023-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.16.0
19
+ version: '1.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.16.0
26
+ version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: multi_json
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -80,7 +80,7 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '3.8'
83
- description: A wrapper for MailChimp API 3.0 and Export API
83
+ description: A wrapper for MailChimp API 3.0
84
84
  email:
85
85
  - amromousa@gmail.com
86
86
  executables: []
@@ -88,6 +88,7 @@ extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
90
  - ".document"
91
+ - ".github/FUNDING.yml"
91
92
  - ".gitignore"
92
93
  - ".travis.yml"
93
94
  - CHANGELOG.md
@@ -99,7 +100,6 @@ files:
99
100
  - gibbon.gemspec
100
101
  - lib/gibbon.rb
101
102
  - lib/gibbon/api_request.rb
102
- - lib/gibbon/export.rb
103
103
  - lib/gibbon/gibbon_error.rb
104
104
  - lib/gibbon/gibbon_helpers.rb
105
105
  - lib/gibbon/mailchimp_error.rb
@@ -107,7 +107,6 @@ files:
107
107
  - lib/gibbon/response.rb
108
108
  - lib/gibbon/version.rb
109
109
  - spec/gibbon/api_request_spec.rb
110
- - spec/gibbon/export_spec.rb
111
110
  - spec/gibbon/gibbon_spec.rb
112
111
  - spec/gibbon/mailchimp_error_spec.rb
113
112
  - spec/gibbon/upsert_spec.rb
@@ -131,13 +130,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
130
  - !ruby/object:Gem::Version
132
131
  version: '0'
133
132
  requirements: []
134
- rubygems_version: 3.2.14
133
+ rubygems_version: 3.2.27
135
134
  signing_key:
136
135
  specification_version: 4
137
- summary: A wrapper for MailChimp API 3.0 and Export API
136
+ summary: A wrapper for MailChimp API 3.0
138
137
  test_files:
139
138
  - spec/gibbon/api_request_spec.rb
140
- - spec/gibbon/export_spec.rb
141
139
  - spec/gibbon/gibbon_spec.rb
142
140
  - spec/gibbon/mailchimp_error_spec.rb
143
141
  - spec/gibbon/upsert_spec.rb
data/lib/gibbon/export.rb DELETED
@@ -1,93 +0,0 @@
1
- require 'net/https'
2
-
3
- module Gibbon
4
- class Export
5
- include Helpers
6
-
7
- attr_accessor :api_key, :timeout
8
-
9
- def initialize(api_key: nil, timeout: nil)
10
- @api_key = api_key || self.class.api_key || ENV['MAILCHIMP_API_KEY']
11
- @timeout = timeout || self.class.timeout || 600
12
- end
13
-
14
- def list(params = {}, &block)
15
- call("list", params, &block)
16
- end
17
-
18
- def ecomm_orders(params = {}, &block)
19
- call("ecommOrders", params, &block)
20
- end
21
-
22
- def campaign_subscriber_activity(params = {}, &block)
23
- call("campaignSubscriberActivity", params, &block)
24
- end
25
-
26
- protected
27
-
28
- def export_api_url
29
- "https://#{get_data_center_from_api_key(@api_key)}api.mailchimp.com/export/1.0/"
30
- end
31
-
32
- def call(method, params = {}, &block)
33
- rows = []
34
-
35
- api_url = export_api_url + method + "/"
36
- params = params.merge({ apikey: @api_key })
37
- block = Proc.new { |row| rows << row } unless block_given?
38
-
39
- ensure_api_key(params)
40
-
41
- url = URI.parse(api_url)
42
- req = Net::HTTP::Post.new(url.path, initheader = {'Content-Type' => 'application/json'})
43
- req.body = MultiJson.dump(params)
44
- Net::HTTP.start(url.host, url.port, read_timeout: @timeout, use_ssl: true, ssl_version: :TLSv1_2) do |http|
45
- # http://stackoverflow.com/questions/29598196/ruby-net-http-read-body-nethttpokread-body-called-twice-ioerror
46
- http.request req do |response|
47
- i = -1
48
- last = ''
49
- response.read_body do |chunk|
50
- next if chunk.nil? or chunk.strip.empty?
51
- infix = "\n" if last[-1, 1]==']'
52
- lines, last = try_parse_line("#{last}#{infix}#{chunk}")
53
- lines.each { |line| block.call(line, i += 1) }
54
- end
55
- block.call(parse_line(last), i += 1) unless last.nil? or last.empty?
56
- end
57
- end
58
- rows unless block_given?
59
- end
60
-
61
- def try_parse_line(res)
62
- lines = res.split("\n")
63
- last = lines.pop || ''
64
- lines.map! { |line| parse_line(line) }
65
- [lines.compact, last]
66
- rescue MultiJson::ParseError
67
- [[], last]
68
- end
69
-
70
-
71
- def parse_line(line)
72
- parsed_response = MultiJson.load(line)
73
- rescue MultiJson::ParseError
74
- return []
75
- end
76
-
77
- private
78
-
79
- def ensure_api_key(params)
80
- unless params[:apikey] && (get_data_center_from_api_key(params[:apikey]) != "")
81
- raise Gibbon::GibbonError, "You must set an api_key prior to making a call"
82
- end
83
- end
84
-
85
- class << self
86
- attr_accessor :api_key, :timeout
87
-
88
- def method_missing(sym, *args, &block)
89
- new(api_key: self.api_key, timeout: self.timeout).send(sym, *args, &block)
90
- end
91
- end
92
- end
93
- end
@@ -1,39 +0,0 @@
1
- require 'spec_helper'
2
- require 'webmock/rspec'
3
-
4
- describe Gibbon::Export do
5
- before do
6
- Gibbon::Export.send(:public, *Gibbon::Export.protected_instance_methods)
7
- @export = Gibbon::Export.new
8
- end
9
-
10
- it "doesn't allow empty api key" do
11
- expect {@export.list(id: "123456")}.to raise_error(Gibbon::GibbonError)
12
- end
13
-
14
- it "doesn't allow api key without data center" do
15
- @api_key = "123"
16
- @export.api_key = @api_key
17
- expect {@export.list(id: "123456")}.to raise_error(Gibbon::GibbonError)
18
- end
19
-
20
- it "sets an API key from the 'MAILCHIMP_API_KEY' ENV variable" do
21
- ENV['MAILCHIMP_API_KEY'] = 'TESTKEY-us1'
22
- @export = Gibbon::Export.new
23
- expect(@export.api_key).to eq('TESTKEY-us1')
24
- ENV.delete('MAILCHIMP_API_KEY')
25
- end
26
-
27
- it "sets correct endpoint from api key" do
28
- @api_key = "TESTKEY-us1"
29
- @export.api_key = @api_key
30
- expect(@export.export_api_url).to eq("https://us1.api.mailchimp.com/export/1.0/")
31
- end
32
-
33
- it "sets correct timeout" do
34
- @api_key = "TESTKEY-us1"
35
- @export.api_key = @api_key
36
- @export.timeout = 9
37
- expect(@export.timeout).to eq(9)
38
- end
39
- end