spark_api 1.1.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +14 -0
- data/README.md +42 -233
- data/VERSION +1 -1
- data/lib/spark_api.rb +1 -0
- data/lib/spark_api/authentication/oauth2.rb +39 -9
- data/lib/spark_api/authentication/oauth2_impl/cli_provider.rb +96 -0
- data/lib/spark_api/authentication/oauth2_impl/faraday_middleware.rb +28 -0
- data/lib/spark_api/authentication/oauth2_impl/grant_type_base.rb +7 -2
- data/lib/spark_api/authentication/oauth2_impl/single_session_provider.rb +27 -0
- data/lib/spark_api/cli.rb +29 -10
- data/lib/spark_api/cli/api_auth.rb +1 -0
- data/lib/spark_api/cli/oauth2.rb +23 -8
- data/lib/spark_api/cli/setup.rb +31 -0
- data/lib/spark_api/configuration.rb +10 -2
- data/lib/spark_api/configuration/yaml.rb +6 -1
- data/lib/spark_api/connection.rb +1 -1
- data/lib/spark_api/errors.rb +48 -0
- data/lib/spark_api/models.rb +3 -0
- data/lib/spark_api/models/account.rb +9 -1
- data/lib/spark_api/models/base.rb +24 -19
- data/lib/spark_api/models/concerns.rb +7 -0
- data/lib/spark_api/models/concerns/destroyable.rb +32 -0
- data/lib/spark_api/models/concerns/savable.rb +66 -0
- data/lib/spark_api/models/contact.rb +6 -25
- data/lib/spark_api/models/dirty.rb +57 -0
- data/lib/spark_api/models/finders.rb +0 -4
- data/lib/spark_api/models/saved_search.rb +10 -0
- data/lib/spark_api/models/subresource.rb +5 -1
- data/lib/spark_api/models/subscription.rb +52 -0
- data/lib/spark_api/request.rb +17 -4
- data/lib/spark_api/response.rb +0 -37
- data/script/combined_flow_example.rb +3 -3
- data/script/oauth2_example.rb +3 -3
- data/spec/fixtures/base.json +3 -1
- data/spec/fixtures/contacts/new.json +2 -3
- data/spec/fixtures/contacts/new_empty.json +2 -3
- data/spec/fixtures/contacts/new_notify.json +1 -1
- data/spec/fixtures/{listings/saved_search.json → saved_searches/get.json} +1 -1
- data/spec/fixtures/saved_searches/new.json +8 -0
- data/spec/fixtures/saved_searches/post.json +12 -0
- data/spec/fixtures/saved_searches/update.json +6 -0
- data/spec/fixtures/subscriptions/get.json +19 -0
- data/spec/fixtures/subscriptions/new.json +13 -0
- data/spec/fixtures/subscriptions/post.json +10 -0
- data/spec/fixtures/subscriptions/put.json +12 -0
- data/spec/fixtures/subscriptions/subscribe.json +5 -0
- data/spec/fixtures/subscriptions/update.json +6 -0
- data/spec/mock_helper.rb +14 -6
- data/spec/oauth2_helper.rb +2 -0
- data/spec/spec_helper.rb +4 -7
- data/spec/unit/spark_api/authentication/api_auth_spec.rb +0 -1
- data/spec/unit/spark_api/authentication/oauth2_impl/faraday_middleware_spec.rb +32 -0
- data/spec/unit/spark_api/authentication/oauth2_impl/single_session_provider_spec.rb +9 -0
- data/spec/unit/spark_api/authentication/oauth2_spec.rb +29 -3
- data/spec/unit/spark_api/authentication_spec.rb +4 -10
- data/spec/unit/spark_api/configuration/yaml_spec.rb +4 -3
- data/spec/unit/spark_api/configuration_spec.rb +22 -8
- data/spec/unit/spark_api/models/account_spec.rb +5 -0
- data/spec/unit/spark_api/models/base_spec.rb +27 -0
- data/spec/unit/spark_api/models/concerns/destroyable_spec.rb +28 -0
- data/spec/unit/spark_api/models/concerns/savable_spec.rb +61 -0
- data/spec/unit/spark_api/models/contact_spec.rb +5 -5
- data/spec/unit/spark_api/models/dirty_spec.rb +46 -0
- data/spec/unit/spark_api/models/finders_spec.rb +0 -7
- data/spec/unit/spark_api/models/saved_search_spec.rb +34 -3
- data/spec/unit/spark_api/models/shared_listing_spec.rb +1 -1
- data/spec/unit/spark_api/models/subscription_spec.rb +106 -0
- data/spec/unit/spark_api/multi_client_spec.rb +14 -4
- data/spec/unit/spark_api/paginate_spec.rb +0 -1
- data/spec/unit/spark_api/request_spec.rb +10 -0
- data/spec/unit/spark_api_spec.rb +0 -3
- metadata +127 -45
- data/lib/spark_api/authentication/oauth2_impl/password_provider.rb +0 -24
data/script/oauth2_example.rb
CHANGED
@@ -15,8 +15,8 @@ SparkApi.configure do |config|
|
|
15
15
|
config.api_secret = "YOUR_CLIENT_SECRET"
|
16
16
|
config.callback = "YOUR_REDIRECT_URI"
|
17
17
|
config.version = "v1"
|
18
|
-
config.endpoint = "https://
|
19
|
-
config.auth_endpoint = "https://
|
18
|
+
config.endpoint = "https://sparkapi.com"
|
19
|
+
config.auth_endpoint = "https://sparkplatform.com/oauth2"
|
20
20
|
end
|
21
21
|
|
22
22
|
client = SparkApi.client
|
@@ -25,7 +25,7 @@ client = SparkApi.client
|
|
25
25
|
# Step 1:
|
26
26
|
# To get your code to post to /v1/oauth2/grant, send the end user to this URI, replacing the all-capped strings with
|
27
27
|
# the CGI-escaped credentials for your key:
|
28
|
-
# https://
|
28
|
+
# https://sparkplatform.com/oauth2?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI
|
29
29
|
# When the user has finished, they will land at:
|
30
30
|
# YOUR_REDIRECT_URI?code=CODE.
|
31
31
|
puts "Go here and log in to get your code: #{client.authenticator.authorization_url}"
|
data/spec/fixtures/base.json
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
{
|
2
|
+
"D": {
|
3
|
+
"Success": true,
|
4
|
+
"Results": [
|
5
|
+
{
|
6
|
+
"Id":"20101230223226074204000000",
|
7
|
+
"ResourceUri":"/v1/contacts/20101230223226074204000000",
|
8
|
+
"Name":"First subscription",
|
9
|
+
"RecipientIds": ["20101230223226074307000000"]
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"Id":"20101230223226074205000000",
|
13
|
+
"ResourceUri":"/v1/contacts/20101230223226074205000000",
|
14
|
+
"Name":"Second subscription",
|
15
|
+
"RecipientIds": []
|
16
|
+
}
|
17
|
+
]
|
18
|
+
}
|
19
|
+
}
|
data/spec/mock_helper.rb
CHANGED
@@ -32,15 +32,19 @@ def stub_api_delete(service_path, stub_fixture="success.json", opts={})
|
|
32
32
|
log_stub(s)
|
33
33
|
end
|
34
34
|
def stub_api_post(service_path, body, stub_fixture="success.json", opts={})
|
35
|
-
|
36
|
-
|
35
|
+
if body.is_a?(Hash)
|
36
|
+
body = { :D => body } unless body.empty?
|
37
|
+
elsif !body.nil?
|
38
|
+
body = MultiJson.load(fixture(body).read)
|
39
|
+
end
|
40
|
+
body_str = body.nil? ? body : MultiJson.dump(body)
|
37
41
|
params = {:ApiUser => "foobar", :AuthToken => "c401736bf3d3f754f07c04e460e09573"}.merge(opts)
|
38
42
|
sig = $test_client.authenticator.sign_token("/#{SparkApi.version}#{service_path}", params, body_str)
|
39
43
|
s=stub_request(:post, "#{SparkApi.endpoint}/#{SparkApi.version}#{service_path}").
|
40
44
|
with(:query => {
|
41
45
|
:ApiSig => sig
|
42
46
|
}.merge(params),
|
43
|
-
:body =>
|
47
|
+
:body => body
|
44
48
|
)
|
45
49
|
if(block_given?)
|
46
50
|
yield s
|
@@ -50,15 +54,19 @@ def stub_api_post(service_path, body, stub_fixture="success.json", opts={})
|
|
50
54
|
log_stub(s)
|
51
55
|
end
|
52
56
|
def stub_api_put(service_path, body, stub_fixture="success.json", opts={})
|
53
|
-
|
54
|
-
|
57
|
+
if body.is_a? Hash
|
58
|
+
body = { :D => body }
|
59
|
+
elsif !body.nil?
|
60
|
+
body = MultiJson.load(fixture(body).read)
|
61
|
+
end
|
62
|
+
body_str = body.nil? ? body : MultiJson.dump(body)
|
55
63
|
params = {:ApiUser => "foobar", :AuthToken => "c401736bf3d3f754f07c04e460e09573"}.merge(opts)
|
56
64
|
sig = $test_client.authenticator.sign_token("/#{SparkApi.version}#{service_path}", params, body_str)
|
57
65
|
s=stub_request(:put, "#{SparkApi.endpoint}/#{SparkApi.version}#{service_path}").
|
58
66
|
with(:query => {
|
59
67
|
:ApiSig => sig
|
60
68
|
}.merge(params),
|
61
|
-
:body =>
|
69
|
+
:body => body
|
62
70
|
)
|
63
71
|
if(block_given?)
|
64
72
|
yield s
|
data/spec/oauth2_helper.rb
CHANGED
@@ -7,6 +7,7 @@ class TestOAuth2Provider < SparkApi::Authentication::BaseOAuth2Provider
|
|
7
7
|
@redirect_uri = "https://exampleapp.fbsdata.com/oauth-callback"
|
8
8
|
@client_id="example-id"
|
9
9
|
@client_secret="example-password"
|
10
|
+
@sparkbar_uri = "https://test.sparkplatform.com/appbar/authorize"
|
10
11
|
@session_cache = {}
|
11
12
|
end
|
12
13
|
|
@@ -56,6 +57,7 @@ class TestCLIOAuth2Provider < SparkApi::Authentication::BaseOAuth2Provider
|
|
56
57
|
nil
|
57
58
|
end
|
58
59
|
def session_timeout; 60; end
|
60
|
+
|
59
61
|
end
|
60
62
|
|
61
63
|
|
data/spec/spec_helper.rb
CHANGED
@@ -31,15 +31,12 @@ end
|
|
31
31
|
|
32
32
|
SparkApi.logger.info("Setup gem for rspec testing")
|
33
33
|
|
34
|
+
include SparkApi::Models
|
35
|
+
|
34
36
|
def reset_config
|
35
37
|
SparkApi.reset
|
36
|
-
SparkApi.configure
|
37
|
-
config.api_user = "foobar"
|
38
|
-
end
|
38
|
+
SparkApi.configure { |c| c.api_user = "foobar" }
|
39
39
|
end
|
40
|
-
reset_config
|
41
|
-
|
42
|
-
include SparkApi::Models
|
43
40
|
|
44
41
|
RSpec.configure do |config|
|
45
42
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
@@ -47,5 +44,5 @@ RSpec.configure do |config|
|
|
47
44
|
config.alias_example_to :on_put_it, :method => 'PUT'
|
48
45
|
config.alias_example_to :on_post_it, :method => 'POST'
|
49
46
|
config.alias_example_to :on_delete_it, :method => 'DELETE'
|
47
|
+
config.before(:all) { reset_config }
|
50
48
|
end
|
51
|
-
|
@@ -140,7 +140,6 @@ describe SparkApi::Authentication::ApiAuth do
|
|
140
140
|
|
141
141
|
context "when the server says the session is expired (even if we disagree)" do
|
142
142
|
it "should reset the session and reauthenticate" do
|
143
|
-
reset_config
|
144
143
|
count = 0
|
145
144
|
# Make sure the auth request goes out twice.
|
146
145
|
stub_request(:post, "https://api.sparkapi.com/#{SparkApi.version}/session").
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require './spec/spec_helper'
|
2
|
+
require './spec/oauth2_helper'
|
3
|
+
|
4
|
+
describe SparkApi::Authentication::OAuth2Impl::SparkbarFaradayMiddleware do
|
5
|
+
subject { SparkApi::Authentication::OAuth2Impl::SparkbarFaradayMiddleware.new("test") }
|
6
|
+
# Make sure the client boostraps the right plugin based on configuration.
|
7
|
+
it "should parse token on successful response" do
|
8
|
+
env = {
|
9
|
+
:body => '{"token":"sp4rkb4rt0k3n"}',
|
10
|
+
:status => 201
|
11
|
+
}
|
12
|
+
subject.on_complete env
|
13
|
+
env[:body]["token"].should eq("sp4rkb4rt0k3n")
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should raise error on unsuccessful response" do
|
17
|
+
env = {
|
18
|
+
:body => '{"token":"sp4rkb4rt0k3n"}',
|
19
|
+
:status => 500
|
20
|
+
}
|
21
|
+
expect {subject.on_complete env }.to raise_error(SparkApi::ClientError)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should raise error on invalid json" do
|
25
|
+
env = {
|
26
|
+
:body => '{"BORKBORKBORK"}',
|
27
|
+
:status => 200
|
28
|
+
}
|
29
|
+
expect {subject.on_complete env }.to raise_error(MultiJson::DecodeError)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SparkApi::Authentication::SingleSessionProvider do
|
4
|
+
subject { SparkApi::Authentication::SingleSessionProvider.new({ :access_token => "the_token" }) }
|
5
|
+
it "should initialize a new session with access_token" do
|
6
|
+
subject.load_session.should respond_to(:access_token)
|
7
|
+
subject.load_session.access_token.should eq("the_token")
|
8
|
+
end
|
9
|
+
end
|
@@ -2,8 +2,12 @@ require './spec/spec_helper'
|
|
2
2
|
require './spec/oauth2_helper'
|
3
3
|
|
4
4
|
describe SparkApi::Authentication::OAuth2 do
|
5
|
+
before(:all) { SparkApi.reset } # dump api user stuff from other tests
|
5
6
|
let(:provider) { TestOAuth2Provider.new() }
|
6
|
-
let(:client) { SparkApi::Client.new({
|
7
|
+
let(:client) { SparkApi::Client.new({
|
8
|
+
:authentication_mode => SparkApi::Authentication::OAuth2,
|
9
|
+
:oauth2_provider => provider,
|
10
|
+
:sparkbar_uri => "https://test.sparkplatform.com/appbar/authorize"}) }
|
7
11
|
subject {client.authenticator }
|
8
12
|
# Make sure the client boostraps the right plugin based on configuration.
|
9
13
|
describe "plugin" do
|
@@ -50,7 +54,6 @@ describe SparkApi::Authentication::OAuth2 do
|
|
50
54
|
end
|
51
55
|
end
|
52
56
|
|
53
|
-
|
54
57
|
describe "logout" do
|
55
58
|
let(:session) { mock_oauth_session }
|
56
59
|
it "should logout when there is an active session" do
|
@@ -96,6 +99,24 @@ describe SparkApi::Authentication::OAuth2 do
|
|
96
99
|
subject.request(:post, "/#{SparkApi.version}/contacts", contact, args).status.should eq(201)
|
97
100
|
end
|
98
101
|
end
|
102
|
+
|
103
|
+
describe "sparkbar_token" do
|
104
|
+
let(:session) { mock_oauth_session }
|
105
|
+
it "should fetch a sparkbar token" do
|
106
|
+
c = stub_request(:post, "https://test.sparkplatform.com/appbar/authorize").
|
107
|
+
with(:body => "access_token=#{session.access_token}").
|
108
|
+
to_return(:body => '{"token":"sp4rkb4rt0k3n"}')
|
109
|
+
subject.session = session
|
110
|
+
subject.sparkbar_token.should eq("sp4rkb4rt0k3n")
|
111
|
+
end
|
112
|
+
it "should raise an error on missing sparkbar token" do
|
113
|
+
c = stub_request(:post, "https://test.sparkplatform.com/appbar/authorize").
|
114
|
+
with(:body => "access_token=#{session.access_token}").
|
115
|
+
to_return(:body => '{"foo":"bar"}')
|
116
|
+
subject.session = session
|
117
|
+
expect {subject.sparkbar_token }.to raise_error(SparkApi::ClientError)
|
118
|
+
end
|
119
|
+
end
|
99
120
|
|
100
121
|
context "with an expired session" do
|
101
122
|
context "and a valid refresh token" do
|
@@ -246,7 +267,7 @@ describe "password authentication" do
|
|
246
267
|
end
|
247
268
|
describe SparkApi::Authentication::OAuth2Impl do
|
248
269
|
it "should load a provider" do
|
249
|
-
example = "SparkApi::Authentication::OAuth2Impl::
|
270
|
+
example = "SparkApi::Authentication::OAuth2Impl::CLIProvider"
|
250
271
|
SparkApi::Authentication::OAuth2Impl.load_provider(example,{}).class.to_s.should eq(example)
|
251
272
|
prefix = "::#{example}"
|
252
273
|
SparkApi::Authentication::OAuth2Impl.load_provider(prefix,{}).class.to_s.should eq(example)
|
@@ -282,4 +303,9 @@ describe SparkApi::Authentication::OAuthSession do
|
|
282
303
|
session.start_time.should eq(DateTime.parse(args[:start_time]))
|
283
304
|
JSON.parse(session.to_json).should eq(JSON.parse(args.to_json))
|
284
305
|
end
|
306
|
+
|
307
|
+
it "should not expire if expires_in is nil" do
|
308
|
+
session = SparkApi::Authentication::OAuthSession.new
|
309
|
+
session.expired?.should eq(false)
|
310
|
+
end
|
285
311
|
end
|
@@ -1,19 +1,12 @@
|
|
1
1
|
require './spec/spec_helper'
|
2
2
|
|
3
3
|
describe SparkApi::Authentication do
|
4
|
-
before(:all) do
|
5
|
-
SparkApi.reset
|
6
|
-
end
|
7
|
-
|
8
|
-
after(:all) do
|
9
|
-
reset_config
|
10
|
-
end
|
11
|
-
|
12
4
|
it "should give me a session object" do
|
13
5
|
stub_auth_request
|
14
6
|
stub_request(:get, "#{SparkApi.endpoint}/#{SparkApi.version}/session/c401736bf3d3f754f07c04e460e09573").
|
15
7
|
with(:query => {
|
16
|
-
:ApiSig => "
|
8
|
+
:ApiSig => "d4cea51b4a6b9eb930e4320866aae7d0",
|
9
|
+
:ApiUser => "foobar",
|
17
10
|
:AuthToken => "c401736bf3d3f754f07c04e460e09573"
|
18
11
|
}).
|
19
12
|
to_return(:body => fixture("session.json"))
|
@@ -26,7 +19,8 @@ describe SparkApi::Authentication do
|
|
26
19
|
stub_auth_request
|
27
20
|
stub_request(:delete, "#{SparkApi.endpoint}/#{SparkApi.version}/session/c401736bf3d3f754f07c04e460e09573").
|
28
21
|
with(:query => {
|
29
|
-
:ApiSig => "
|
22
|
+
:ApiSig => "d4cea51b4a6b9eb930e4320866aae7d0",
|
23
|
+
:ApiUser => "foobar",
|
30
24
|
:AuthToken => "c401736bf3d3f754f07c04e460e09573"
|
31
25
|
}).
|
32
26
|
to_return(:body => fixture("success.json"))
|
@@ -8,11 +8,12 @@ describe SparkApi::Configuration::YamlConfig, "Yaml Config" do
|
|
8
8
|
subject.api_env.should eq("development")
|
9
9
|
subject.load_file(api_file)
|
10
10
|
subject.oauth2?.should eq(false)
|
11
|
+
subject.ssl_verify?.should eq(false)
|
11
12
|
subject.api_key.should eq("demo_key")
|
12
13
|
subject.api_secret.should eq("t3sts3cr3t")
|
13
14
|
subject.endpoint.should eq("https://developers.sparkapi.com")
|
14
15
|
subject.name.should eq("test_key")
|
15
|
-
subject.client_keys.keys.should =~ [:api_key, :api_secret, :endpoint]
|
16
|
+
subject.client_keys.keys.should =~ [:api_key, :api_secret, :endpoint, :ssl_verify]
|
16
17
|
subject.oauth2_keys.keys.should eq([])
|
17
18
|
end
|
18
19
|
it "should load a configured api key for production" do
|
@@ -47,7 +48,7 @@ describe SparkApi::Configuration::YamlConfig, "Yaml Config" do
|
|
47
48
|
subject.oauth2_provider.should eq("SparkApi::TestOAuth2Provider")
|
48
49
|
subject.name.should eq("test_oauth")
|
49
50
|
subject.client_keys.keys.should =~ [:endpoint, :oauth2_provider]
|
50
|
-
subject.oauth2_keys.keys.should =~ [:authorization_uri, :client_id, :access_uri, :client_secret, :redirect_uri]
|
51
|
+
subject.oauth2_keys.keys.should =~ [:authorization_uri, :client_id, :access_uri, :client_secret, :redirect_uri, :sparkbar_uri]
|
51
52
|
end
|
52
53
|
it "should load a configured api key for production" do
|
53
54
|
subject.stub(:env){ {"SPARK_API_ENV" => "production"} }
|
@@ -66,7 +67,7 @@ describe SparkApi::Configuration::YamlConfig, "Yaml Config" do
|
|
66
67
|
|
67
68
|
it "should list available keys" do
|
68
69
|
SparkApi::Configuration::YamlConfig.stub(:config_path) { "spec/config/spark_api" }
|
69
|
-
subject.class.config_keys.should =~ ["test_key", "test_oauth"]
|
70
|
+
subject.class.config_keys.should =~ ["test_key", "test_oauth", "test_single_session_oauth"]
|
70
71
|
end
|
71
72
|
end
|
72
73
|
end
|