icontact-api 0.1 → 0.2
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.
- data.tar.gz.sig +0 -0
- data/History.txt +5 -1
- data/Manifest.txt +1 -1
- data/{README.rdoc → README.txt} +1 -3
- data/Rakefile +3 -1
- data/lib/icontact-api.rb +1 -2
- data/lib/icontact/api.rb +18 -28
- data/spec/api_spec.rb +28 -52
- metadata +11 -9
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
data/{README.rdoc → README.txt}
RENAMED
@@ -39,13 +39,11 @@ class BetaApi < Icontact::Api
|
|
39
39
|
API_USERNAME='username'
|
40
40
|
API_PASSWORD='password'
|
41
41
|
API_KEY = 'YOUR_API_KEY'
|
42
|
-
API_SECRET = 'YOUR_API_SECRET'
|
43
42
|
DOMAIN = "http://app.beta.icontact.com/icp"
|
44
43
|
|
45
44
|
def initialize(username = BetaApi::API_USERNAME, password = BetaApi::API_PASSWORD)
|
46
45
|
super(username, password)
|
47
|
-
self.
|
48
|
-
self.secret = API_SECRET
|
46
|
+
self.app_id = API_KEY
|
49
47
|
self.domain = DOMAIN
|
50
48
|
end
|
51
49
|
end
|
data/Rakefile
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
%w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
|
2
2
|
require File.dirname(__FILE__) + '/lib/icontact-api'
|
3
|
+
require 'hoe'
|
3
4
|
|
4
5
|
# Generate all the Rake tasks
|
5
6
|
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
6
|
-
$hoe = Hoe.
|
7
|
+
$hoe = Hoe.spec 'icontact-api' do |p|
|
8
|
+
p.version = Icontact::Api::VERSION
|
7
9
|
p.developer('Kevin Olbrich', 'kevin.olbrich@gmail.com')
|
8
10
|
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
9
11
|
p.rubyforge_name = p.name # TODO this is default value
|
data/lib/icontact-api.rb
CHANGED
data/lib/icontact/api.rb
CHANGED
@@ -1,27 +1,24 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'net/http'
|
3
|
-
require '
|
3
|
+
require 'net/https'
|
4
4
|
require 'json'
|
5
5
|
|
6
6
|
class Icontact
|
7
7
|
class Api
|
8
|
-
VERSION = "0.
|
8
|
+
VERSION = "0.2"
|
9
9
|
API_VERSION = "2.0"
|
10
|
-
DOMAIN = '
|
10
|
+
DOMAIN = 'https://app.icontact.com/icp'
|
11
11
|
API_KEY = "API_KEY"
|
12
|
-
API_SECRET = "API_SECRET"
|
13
12
|
attr_accessor :username
|
14
13
|
attr_accessor :password
|
15
|
-
attr_accessor :
|
16
|
-
attr_accessor :secret
|
14
|
+
attr_accessor :app_id
|
17
15
|
attr_accessor :domain
|
18
16
|
|
19
17
|
def initialize(username, password)
|
20
18
|
self.username = username
|
21
19
|
self.password = password
|
22
20
|
self.domain = DOMAIN
|
23
|
-
self.
|
24
|
-
self.secret = API_SECRET
|
21
|
+
self.app_id = API_KEY
|
25
22
|
end
|
26
23
|
|
27
24
|
# Package up any options into a query string and format it properly for the server
|
@@ -52,25 +49,17 @@ class Icontact
|
|
52
49
|
{'code'=>code, 'body' => (JSON.parse(response) rescue response)}
|
53
50
|
end
|
54
51
|
|
55
|
-
def request_signature(method, timestamp, random, url)
|
56
|
-
Digest::SHA1.hexdigest("#{secret}#{password}#{timestamp}#{random}#{method.to_s.upcase}#{url}")
|
57
|
-
end
|
58
|
-
|
59
52
|
# populate headers required by the icontact server on each request for authentication
|
60
53
|
# Accept and Content-Type are set to application/json to use JSON objects for the
|
61
54
|
# data exchange. Also accepts text/xml for either, but then you have to deal with XML encoding and decoding
|
62
55
|
# manually
|
63
|
-
def apply_headers(
|
64
|
-
|
65
|
-
|
66
|
-
req.add_field('API_VERSION', API_VERSION)
|
67
|
-
req.add_field('ACCEPT','application/json')
|
56
|
+
def apply_headers(req)
|
57
|
+
req.add_field('API-Version', API_VERSION)
|
58
|
+
req.add_field('accept','application/json')
|
68
59
|
req.add_field('Content-Type','application/json')
|
69
|
-
req.add_field('
|
70
|
-
req.add_field('
|
71
|
-
req.add_field('
|
72
|
-
req.add_field('API_NUMBER', random)
|
73
|
-
req.add_field('API_SIGNATURE', request_signature(method, timestamp, random, url))
|
60
|
+
req.add_field('API-Appid', self.app_id)
|
61
|
+
req.add_field('API-Username', self.username)
|
62
|
+
req.add_field('API-Password', self.password)
|
74
63
|
return req
|
75
64
|
end
|
76
65
|
|
@@ -98,15 +87,16 @@ class Icontact
|
|
98
87
|
# create an object of the class required to process this method
|
99
88
|
klass = Object.module_eval("::Net::HTTP::#{kind.to_s.capitalize}", __FILE__, __LINE__)
|
100
89
|
request = klass.new([full_url.path, full_url.query].compact.join('?'))
|
101
|
-
request = apply_headers(
|
102
|
-
|
90
|
+
request = apply_headers(request)
|
103
91
|
# take passed data and encode it
|
104
92
|
request.body = self.class.body_encoder(data) if data
|
105
93
|
|
106
|
-
Net::HTTP.
|
107
|
-
|
108
|
-
|
109
|
-
|
94
|
+
http = Net::HTTP.new(full_url.host, full_url.port)
|
95
|
+
http.use_ssl = true
|
96
|
+
response = http.start do |web|
|
97
|
+
web.request(request)
|
98
|
+
end
|
99
|
+
return self.class.parse_response(response.code, response.body)
|
110
100
|
end
|
111
101
|
end
|
112
102
|
end
|
data/spec/api_spec.rb
CHANGED
@@ -1,21 +1,16 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
2
|
|
3
3
|
describe Icontact::Api do
|
4
|
-
before(:each) do
|
5
|
-
@mock_time = mock('Time', :getgm => 999999)
|
6
|
-
Time.stub!(:now).and_return(@mock_time)
|
7
|
-
Kernel.stub!(:rand).and_return(111)
|
8
|
-
end
|
9
|
-
|
10
4
|
describe "api" do
|
11
5
|
before(:each) do
|
12
6
|
@api = Icontact::Api.new('mock_username', 'mock_password')
|
13
7
|
@response = mock('response',:code=>200, :body=>"body")
|
14
|
-
|
15
|
-
|
8
|
+
|
9
|
+
@mock_http_session = mock('http_session', :start=>@response, :use_ssl= => true)
|
10
|
+
Net::HTTP.stub!(:new).and_return(@mock_http_session)
|
16
11
|
end
|
17
12
|
|
18
|
-
describe "an
|
13
|
+
describe "an https request", :shared=>true do
|
19
14
|
it "should apply headers to the request" do
|
20
15
|
@mock_request = mock("Request", :body= => true)
|
21
16
|
@api.should_receive(:apply_headers).and_return(@mock_request)
|
@@ -27,8 +22,13 @@ describe Icontact::Api do
|
|
27
22
|
do_request(:limit=>10)
|
28
23
|
end
|
29
24
|
|
25
|
+
it "should use ssl" do
|
26
|
+
@mock_http_session.should_receive(:use_ssl=).with(true)
|
27
|
+
do_request
|
28
|
+
end
|
29
|
+
|
30
30
|
it "should send the request" do
|
31
|
-
|
31
|
+
@mock_http_session.should_receive(:start)
|
32
32
|
do_request
|
33
33
|
end
|
34
34
|
|
@@ -38,8 +38,8 @@ describe Icontact::Api do
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
describe "an
|
42
|
-
it_should_behave_like "an
|
41
|
+
describe "an https request with a body", :shared=>true do
|
42
|
+
it_should_behave_like "an https request"
|
43
43
|
|
44
44
|
it "should package the data into the body" do
|
45
45
|
@api.class.should_receive(:body_encoder)
|
@@ -53,7 +53,7 @@ describe Icontact::Api do
|
|
53
53
|
@api.get("/a", options)
|
54
54
|
end
|
55
55
|
|
56
|
-
it_should_behave_like "an
|
56
|
+
it_should_behave_like "an https request"
|
57
57
|
end
|
58
58
|
|
59
59
|
describe ".post" do
|
@@ -61,7 +61,7 @@ describe Icontact::Api do
|
|
61
61
|
@api.post("/a", {}, options)
|
62
62
|
end
|
63
63
|
|
64
|
-
it_should_behave_like "an
|
64
|
+
it_should_behave_like "an https request with a body"
|
65
65
|
end
|
66
66
|
|
67
67
|
describe ".put" do
|
@@ -69,7 +69,7 @@ describe Icontact::Api do
|
|
69
69
|
@api.put("/a", {}, options)
|
70
70
|
end
|
71
71
|
|
72
|
-
it_should_behave_like "an
|
72
|
+
it_should_behave_like "an https request with a body"
|
73
73
|
end
|
74
74
|
|
75
75
|
describe '.delete' do
|
@@ -77,25 +77,10 @@ describe Icontact::Api do
|
|
77
77
|
@api.delete("/a", options)
|
78
78
|
end
|
79
79
|
|
80
|
-
it_should_behave_like "an
|
80
|
+
it_should_behave_like "an https request"
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
-
describe ".request_signature" do
|
85
|
-
before(:each) do
|
86
|
-
@api = Icontact::Api.new('username','password')
|
87
|
-
Kernel.stub!(:rand).and_return(111)
|
88
|
-
@mock_time = mock('Time', :getgm => 999999)
|
89
|
-
Time.stub!(:now).and_return(@mock_time)
|
90
|
-
Digest::SHA1.stub!(:hexdigest).and_return('api_signature')
|
91
|
-
end
|
92
|
-
|
93
|
-
it "should generate an API Signature" do
|
94
|
-
Digest::SHA1.should_receive(:hexdigest).with('API_SECRETpasswordtimestamp/urlrandomGET').and_return('api_signature')
|
95
|
-
@api.request_signature('get','timestamp''/url', 'random', '').should == "api_signature"
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
84
|
describe ".apply_headers" do
|
100
85
|
before(:each) do
|
101
86
|
@request = mock('Request', :add_field=>true)
|
@@ -103,16 +88,16 @@ describe Icontact::Api do
|
|
103
88
|
end
|
104
89
|
|
105
90
|
def do_apply_headers
|
106
|
-
@api.apply_headers(
|
91
|
+
@api.apply_headers(@request)
|
107
92
|
end
|
108
93
|
|
109
|
-
it "should add an
|
110
|
-
@request.should_receive(:add_field).with('
|
94
|
+
it "should add an API-VERSION header to indicate we are using the 2.0 version of the API" do
|
95
|
+
@request.should_receive(:add_field).with('API-Version', @api.class::API_VERSION)
|
111
96
|
do_apply_headers
|
112
97
|
end
|
113
98
|
|
114
99
|
it "should add an ACCEPT header indicating we want a JSON object back" do
|
115
|
-
@request.should_receive(:add_field).with('
|
100
|
+
@request.should_receive(:add_field).with('accept', 'application/json')
|
116
101
|
do_apply_headers
|
117
102
|
end
|
118
103
|
|
@@ -121,31 +106,22 @@ describe Icontact::Api do
|
|
121
106
|
do_apply_headers
|
122
107
|
end
|
123
108
|
|
124
|
-
it "should add an
|
125
|
-
@request.should_receive(:add_field).with('
|
109
|
+
it "should add an API-AppId header to verify that our application is authrorized to use the API" do
|
110
|
+
@request.should_receive(:add_field).with('API-Appid', @api.class::API_KEY)
|
126
111
|
do_apply_headers
|
127
112
|
end
|
128
113
|
|
129
|
-
it "should add an
|
130
|
-
@request.should_receive(:add_field).with('
|
131
|
-
do_apply_headers
|
132
|
-
end
|
133
|
-
|
134
|
-
it "should add an API_TIMESTAMP header to prevent old requests from being replayed" do
|
135
|
-
@request.should_receive(:add_field).with('API_TIMESTAMP', 999999)
|
114
|
+
it "should add an API-Username header to verify that our user is authorized to use the API" do
|
115
|
+
@request.should_receive(:add_field).with('API-Username', 'username')
|
136
116
|
do_apply_headers
|
137
117
|
end
|
138
|
-
|
139
|
-
it "should add an
|
140
|
-
@request.should_receive(:add_field).with('
|
118
|
+
|
119
|
+
it "should add an API-Password header to verify that our user is authorized to use the API" do
|
120
|
+
@request.should_receive(:add_field).with('API-Password', 'password')
|
141
121
|
do_apply_headers
|
142
122
|
end
|
123
|
+
|
143
124
|
|
144
|
-
it "should add an API_SIGNATURE header to ensure this api request is valid" do
|
145
|
-
@api.should_receive(:request_signature).and_return('api_signature')
|
146
|
-
@request.should_receive(:add_field).with('API_SIGNATURE', 'api_signature')
|
147
|
-
do_apply_headers
|
148
|
-
end
|
149
125
|
end
|
150
126
|
|
151
127
|
describe "class methods" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: icontact-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "0.
|
4
|
+
version: "0.2"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Olbrich
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
4Umf0rf1f8h+GJia5xXYww==
|
31
31
|
-----END CERTIFICATE-----
|
32
32
|
|
33
|
-
date: 2009-
|
33
|
+
date: 2009-07-20 00:00:00 -04:00
|
34
34
|
default_executable:
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
@@ -51,7 +51,7 @@ dependencies:
|
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 1.
|
54
|
+
version: 1.5.1
|
55
55
|
version:
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: hoe
|
@@ -61,7 +61,7 @@ dependencies:
|
|
61
61
|
requirements:
|
62
62
|
- - ">="
|
63
63
|
- !ruby/object:Gem::Version
|
64
|
-
version:
|
64
|
+
version: 2.3.2
|
65
65
|
version:
|
66
66
|
description: This gem provides a thin wrapper around the iContact 2.0 API.
|
67
67
|
email:
|
@@ -73,11 +73,11 @@ extensions: []
|
|
73
73
|
extra_rdoc_files:
|
74
74
|
- History.txt
|
75
75
|
- Manifest.txt
|
76
|
-
- README.
|
76
|
+
- README.txt
|
77
77
|
files:
|
78
78
|
- History.txt
|
79
79
|
- Manifest.txt
|
80
|
-
- README.
|
80
|
+
- README.txt
|
81
81
|
- Rakefile
|
82
82
|
- lib/icontact-api.rb
|
83
83
|
- lib/icontact/api.rb
|
@@ -90,10 +90,12 @@ files:
|
|
90
90
|
- tasks/rspec.rake
|
91
91
|
has_rdoc: true
|
92
92
|
homepage:
|
93
|
+
licenses: []
|
94
|
+
|
93
95
|
post_install_message:
|
94
96
|
rdoc_options:
|
95
97
|
- --main
|
96
|
-
- README.
|
98
|
+
- README.txt
|
97
99
|
require_paths:
|
98
100
|
- lib
|
99
101
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -111,9 +113,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
111
113
|
requirements: []
|
112
114
|
|
113
115
|
rubyforge_project: icontact-api
|
114
|
-
rubygems_version: 1.3.
|
116
|
+
rubygems_version: 1.3.4
|
115
117
|
signing_key:
|
116
|
-
specification_version:
|
118
|
+
specification_version: 3
|
117
119
|
summary: This gem provides a thin wrapper around the iContact 2.0 API.
|
118
120
|
test_files: []
|
119
121
|
|
metadata.gz.sig
CHANGED
Binary file
|