icontact-api 0.1 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|