omnicontacts 0.1.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.
- data/.gitignore +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +39 -0
- data/README.md +83 -0
- data/Rakefile +6 -0
- data/lib/omnicontacts.rb +12 -0
- data/lib/omnicontacts/authorization/oauth1.rb +122 -0
- data/lib/omnicontacts/authorization/oauth2.rb +84 -0
- data/lib/omnicontacts/builder.rb +30 -0
- data/lib/omnicontacts/http_utils.rb +88 -0
- data/lib/omnicontacts/importer.rb +9 -0
- data/lib/omnicontacts/importer/gmail.rb +54 -0
- data/lib/omnicontacts/importer/hotmail.rb +46 -0
- data/lib/omnicontacts/importer/yahoo.rb +64 -0
- data/lib/omnicontacts/middleware/base_oauth.rb +97 -0
- data/lib/omnicontacts/middleware/oauth1.rb +68 -0
- data/lib/omnicontacts/middleware/oauth2.rb +66 -0
- data/omnicontacts.gemspec +25 -0
- data/spec/omnicontacts/authorization/oauth1_spec.rb +82 -0
- data/spec/omnicontacts/authorization/oauth2_spec.rb +92 -0
- data/spec/omnicontacts/http_utils_spec.rb +68 -0
- data/spec/omnicontacts/importer/gmail_spec.rb +40 -0
- data/spec/omnicontacts/importer/hotmail_spec.rb +47 -0
- data/spec/omnicontacts/importer/yahoo_spec.rb +42 -0
- data/spec/omnicontacts/middleware/oauth1_spec.rb +71 -0
- data/spec/omnicontacts/middleware/oauth2_spec.rb +62 -0
- data/spec/spec_helper.rb +10 -0
- metadata +139 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "omnicontacts/authorization/oauth2"
|
3
|
+
|
4
|
+
describe OmniContacts::Authorization::OAuth2 do
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
OAuth2TestClass= Struct.new(:auth_host, :authorize_path, :client_id, :client_secret, :scope, :redirect_uri,:auth_token_path)
|
8
|
+
class OAuth2TestClass
|
9
|
+
include OmniContacts::Authorization::OAuth2
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:test_target) do
|
14
|
+
OAuth2TestClass.new("auth_host", "authorize_path", "client_id", "client_secret", "scope", "redirect_uri", "auth_token_path")
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "authorization_url" do
|
18
|
+
|
19
|
+
subject {test_target.authorization_url}
|
20
|
+
|
21
|
+
it {should include("https://#{test_target.auth_host}#{test_target.authorize_path}")}
|
22
|
+
it {should include("client_id=#{test_target.client_id}")}
|
23
|
+
it {should include("scope=#{test_target.scope}")}
|
24
|
+
it {should include("redirect_uri=#{test_target.redirect_uri}")}
|
25
|
+
it {should include("access_type=offline")}
|
26
|
+
it {should include("response_type=code")}
|
27
|
+
end
|
28
|
+
|
29
|
+
let(:access_token_response) {%[{"access_token": "access_token", "token_type":"token_type", "refresh_token":"refresh_token"}] }
|
30
|
+
|
31
|
+
describe "fetch_access_token" do
|
32
|
+
|
33
|
+
it "should provide all mandatory parameters in a https post request" do
|
34
|
+
code = "code"
|
35
|
+
test_target.should_receive(:https_post) do |host, path, params|
|
36
|
+
host.should eq(test_target.auth_host)
|
37
|
+
path.should eq(test_target.auth_token_path)
|
38
|
+
params[:code].should eq(code)
|
39
|
+
params[:client_id].should eq(test_target.client_id)
|
40
|
+
params[:client_secret].should eq(test_target.client_secret)
|
41
|
+
params[:redirect_uri].should eq(test_target.redirect_uri)
|
42
|
+
params[:grant_type].should eq("authorization_code")
|
43
|
+
access_token_response
|
44
|
+
end
|
45
|
+
test_target.fetch_access_token code
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should successfully parse the token from the JSON response" do
|
49
|
+
test_target.should_receive(:https_post).and_return(access_token_response)
|
50
|
+
(access_token, token_type, refresh_token) = test_target.fetch_access_token "code"
|
51
|
+
access_token.should eq("access_token")
|
52
|
+
token_type.should eq("token_type")
|
53
|
+
refresh_token.should eq("refresh_token")
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should raise if the http request fails" do
|
57
|
+
test_target.should_receive(:https_post).and_raise("Invalid code")
|
58
|
+
expect{test_target.fetch_access_token("code")}.should raise_error
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should raise an error if the JSON response contains an error field" do
|
62
|
+
test_target.should_receive(:https_post).and_return(%[{"error": "error_message"}])
|
63
|
+
expect{test_target.fetch_access_token("code")}.should raise_error
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "refresh_access_token" do
|
68
|
+
it "should provide all mandatory fields in a https post request" do
|
69
|
+
refresh_token = "refresh_token"
|
70
|
+
test_target.should_receive(:https_post) do |host, path, params|
|
71
|
+
host.should eq(test_target.auth_host)
|
72
|
+
path.should eq(test_target.auth_token_path)
|
73
|
+
params[:client_id].should eq(test_target.client_id)
|
74
|
+
params[:client_secret].should eq(test_target.client_secret)
|
75
|
+
params[:refresh_token].should eq(refresh_token)
|
76
|
+
params[:grant_type].should eq("refresh_token")
|
77
|
+
access_token_response
|
78
|
+
end
|
79
|
+
test_target.refresh_access_token refresh_token
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should successfully parse the token from the JSON response" do
|
83
|
+
test_target.should_receive(:https_post).and_return(access_token_response)
|
84
|
+
(access_token, token_type, refresh_token) = test_target.refresh_access_token "refresh_token"
|
85
|
+
access_token.should eq("access_token")
|
86
|
+
token_type.should eq("token_type")
|
87
|
+
refresh_token.should eq("refresh_token")
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "omnicontacts/http_utils"
|
3
|
+
|
4
|
+
describe OmniContacts::HTTPUtils do
|
5
|
+
|
6
|
+
describe "to_query_string" do
|
7
|
+
it "should create a query string from a map" do
|
8
|
+
OmniContacts::HTTPUtils.to_query_string(:name => "john", :surname => "doe").should eq("name=john&surname=doe")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "encode" do
|
13
|
+
it "should encode the space" do
|
14
|
+
OmniContacts::HTTPUtils.encode("name=\"john\"").should eq("name%3D%22john%22")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "query_string_to_map" do
|
19
|
+
it "should split a query string into a map" do
|
20
|
+
query_string = "name=john&surname=doe"
|
21
|
+
result = OmniContacts::HTTPUtils.query_string_to_map(query_string)
|
22
|
+
result["name"].should eq("john")
|
23
|
+
result["surname"].should eq("doe")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "host_url_from_rack_env" do
|
28
|
+
it "should calculate the host url using the HTTP_HOST variable" do
|
29
|
+
env = {"rack.url_scheme" => "http", "HTTP_HOST" => "localhost:8080","SERVER_NAME" => "localhost", "SERVER_PORT" => 8080}
|
30
|
+
OmniContacts::HTTPUtils.host_url_from_rack_env(env).should eq("http://localhost:8080")
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should calculate the host url using SERVER_NAME and SERVER_PORT variables" do
|
34
|
+
env = {"rack.url_scheme" => "http", "SERVER_NAME" => "localhost", "SERVER_PORT" => 8080}
|
35
|
+
OmniContacts::HTTPUtils.host_url_from_rack_env(env).should eq("http://localhost:8080")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "https_post" do
|
40
|
+
|
41
|
+
before(:each) do
|
42
|
+
@connection = double
|
43
|
+
Net::HTTP.should_receive(:new).and_return(@connection)
|
44
|
+
@connection.should_receive(:use_ssl=).with(true)
|
45
|
+
@test_target = Object.new
|
46
|
+
@test_target.extend OmniContacts::HTTPUtils
|
47
|
+
@response = double
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should execute a request with success" do
|
51
|
+
@test_target.should_receive(:ssl_ca_file).and_return(nil)
|
52
|
+
@connection.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
|
53
|
+
@connection.should_receive(:request_post).and_return(@response)
|
54
|
+
@response.should_receive(:code).and_return("200")
|
55
|
+
@response.should_receive(:body).and_return("some content")
|
56
|
+
@test_target.send(:https_post, "host", "path", {})
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should raise an exception with response code != 200" do
|
60
|
+
@test_target.should_receive(:ssl_ca_file).and_return(nil)
|
61
|
+
@connection.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
|
62
|
+
@connection.should_receive(:request_get).and_return(@response)
|
63
|
+
@response.should_receive(:code).and_return("500")
|
64
|
+
@response.should_receive(:body).and_return("some error message")
|
65
|
+
expect {@test_target.send(:https_get, "host", "path", {})}.should raise_error
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "omnicontacts/importer/gmail"
|
3
|
+
|
4
|
+
describe OmniContacts::Importer::Gmail do
|
5
|
+
|
6
|
+
let(:gmail) { OmniContacts::Importer::Gmail.new( {}, "client_id", "client_secret") }
|
7
|
+
|
8
|
+
let(:contacts_as_xml) {
|
9
|
+
"<entry xmlns:gd='http://schemas.google.com/g/2005'>
|
10
|
+
<gd:name>
|
11
|
+
<gd:fullName>Edward Bennet</gd:fullName>
|
12
|
+
</gd:name>
|
13
|
+
<gd:email rel='http://schemas.google.com/g/2005#work' primary='true' address='bennet@gmail.com'/>
|
14
|
+
</entry>"
|
15
|
+
}
|
16
|
+
|
17
|
+
describe "fetch_contacts_using_access_token" do
|
18
|
+
|
19
|
+
let(:token) { "token"}
|
20
|
+
let(:token_type) { "token_type" }
|
21
|
+
|
22
|
+
it "should request the contacts by specifying version and code in the http headers" do
|
23
|
+
gmail.should_receive(:https_get) do |host, path, params, headers|
|
24
|
+
headers["GData-Version"].should eq("3.0")
|
25
|
+
headers["Authorization"].should eq("#{token_type} #{token}")
|
26
|
+
contacts_as_xml
|
27
|
+
end
|
28
|
+
gmail.fetch_contacts_using_access_token token, token_type
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should correctly parse name and email" do
|
32
|
+
gmail.should_receive(:https_get).and_return(contacts_as_xml)
|
33
|
+
result = gmail.fetch_contacts_using_access_token token, token_type
|
34
|
+
result.size.should be(1)
|
35
|
+
result.first[:name].should eq("Edward Bennet")
|
36
|
+
result.first[:email].should eq("bennet@gmail.com")
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "omnicontacts/importer/hotmail"
|
3
|
+
|
4
|
+
describe OmniContacts::Importer::Hotmail do
|
5
|
+
|
6
|
+
let(:hotmail) {OmniContacts::Importer::Hotmail.new({}, "client_id", "client_secret") }
|
7
|
+
|
8
|
+
let(:contacts_as_json) {
|
9
|
+
"{
|
10
|
+
\"data\":
|
11
|
+
[{
|
12
|
+
\"id\": \"contact.b4466224b2ca42798c3d4ea90c75aa56\",
|
13
|
+
\"first_name\": null,
|
14
|
+
\"last_name\": null,
|
15
|
+
\"name\": \"henrik@hotmail.com\",
|
16
|
+
\"gender\": null,
|
17
|
+
\"is_friend\": false,
|
18
|
+
\"is_favorite\": false,
|
19
|
+
\"user_id\": null,
|
20
|
+
\"birth_day\": 29,
|
21
|
+
\"birth_month\": 3
|
22
|
+
}]
|
23
|
+
}"}
|
24
|
+
|
25
|
+
describe "fetch_contacts_using_access_token" do
|
26
|
+
|
27
|
+
let(:token) { "token"}
|
28
|
+
let(:token_type) { "token_type" }
|
29
|
+
|
30
|
+
it "should request the contacts by providing the token in the url" do
|
31
|
+
hotmail.should_receive(:https_get) do |host, path, params, headers|
|
32
|
+
params[:access_token].should eq(token)
|
33
|
+
contacts_as_json
|
34
|
+
end
|
35
|
+
hotmail.fetch_contacts_using_access_token token, token_type
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should correctly parse the contacts" do
|
39
|
+
hotmail.should_receive(:https_get).and_return(contacts_as_json)
|
40
|
+
result = hotmail.fetch_contacts_using_access_token token, token_type
|
41
|
+
result.size.should be(1)
|
42
|
+
result.first[:name].should be_nil
|
43
|
+
result.first[:email].should eq("henrik@hotmail.com")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "omnicontacts/importer/yahoo"
|
3
|
+
|
4
|
+
describe OmniContacts::Importer::Yahoo do
|
5
|
+
|
6
|
+
describe "fetch_contacts_from_token_and_verifier" do
|
7
|
+
let(:contacts_as_json) {
|
8
|
+
'{"contacts":
|
9
|
+
{"start":1, "count":1,
|
10
|
+
"contact":[{"id":10, "fields":[{"id":819, "type":"email", "value":"john@yahoo.com"},
|
11
|
+
{"type":"name", "value": { "givenName":"John", "familyName":"Doe"} }] }]
|
12
|
+
} }'}
|
13
|
+
|
14
|
+
let(:yahoo) { OmniContacts::Importer::Yahoo.new( {}, "consumer_key", "consumer_secret" ) }
|
15
|
+
|
16
|
+
it "should request the contacts by specifying all required parameters" do
|
17
|
+
yahoo.should_receive(:fetch_access_token).and_return(["access_token", "access_token_secret", "guid"])
|
18
|
+
yahoo.should_receive(:http_get) do |host, path, params|
|
19
|
+
params[:format].should eq("json")
|
20
|
+
params[:oauth_consumer_key].should eq("consumer_key")
|
21
|
+
params[:oauth_nonce].should_not be_nil
|
22
|
+
params[:oauth_signature_method].should eq("HMAC-SHA1")
|
23
|
+
params[:oauth_timestamp].should_not be_nil
|
24
|
+
params[:oauth_token].should eq("access_token")
|
25
|
+
params[:oauth_version].should eq("1.0")
|
26
|
+
params[:view].should eq("compact")
|
27
|
+
contacts_as_json
|
28
|
+
end
|
29
|
+
yahoo.fetch_contacts_from_token_and_verifier "auth_token", "auth_token_secret", "oauth_verifier"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should parse the contacts correctly" do
|
33
|
+
yahoo.should_receive(:fetch_access_token).and_return(["access_token", "access_token_secret", "guid"])
|
34
|
+
yahoo.should_receive(:http_get).and_return(contacts_as_json)
|
35
|
+
result = yahoo.fetch_contacts_from_token_and_verifier "auth_token", "auth_token_secret", "oauth_verifier"
|
36
|
+
result.size.should be(1)
|
37
|
+
result.first[:name].should eq("John Doe")
|
38
|
+
result.first[:email].should eq("john@yahoo.com")
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "omnicontacts/middleware/oauth1"
|
3
|
+
|
4
|
+
describe OmniContacts::Middleware::OAuth1 do
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
class OAuth1Middleware < OmniContacts::Middleware::OAuth1
|
8
|
+
def self.mock_auth_token_resp
|
9
|
+
@mock_auth_token_resp ||= Object.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def fetch_authorization_token
|
13
|
+
OAuth1Middleware.mock_auth_token_resp.body
|
14
|
+
end
|
15
|
+
|
16
|
+
def authorization_url auth_token
|
17
|
+
"http://www.example.com"
|
18
|
+
end
|
19
|
+
|
20
|
+
def fetch_contacts_from_token_and_verifier oauth_token, ouath_token_secret, oauth_verifier
|
21
|
+
[{:name => "John Doe", :email => "john@example.com"}]
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.mock_session
|
25
|
+
@mock_session ||= {}
|
26
|
+
end
|
27
|
+
def session
|
28
|
+
OAuth1Middleware.mock_session
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
let(:app) {
|
34
|
+
Rack::Builder.new do |b|
|
35
|
+
b.use OAuth1Middleware, "consumer_id", "consumer_secret"
|
36
|
+
b.run lambda{ |env| [200, {"Content-Type" => "text/html"}, ["Hello World"]] }
|
37
|
+
end.to_app
|
38
|
+
}
|
39
|
+
|
40
|
+
context "visiting the listening path" do
|
41
|
+
it "should save the authorization token and redirect to the authorization url" do
|
42
|
+
OAuth1Middleware.mock_auth_token_resp.should_receive(:body).and_return(["auth_token", "auth_token_secret"])
|
43
|
+
get "/contacts/oauth1middleware"
|
44
|
+
last_response.should be_redirect
|
45
|
+
last_response.headers['location'].should eq("http://www.example.com")
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should redirect to failure url if fetching the request token does not succeed" do
|
49
|
+
OAuth1Middleware.mock_auth_token_resp.should_receive(:body).and_raise("Request failed")
|
50
|
+
get "contacts/oauth1middleware"
|
51
|
+
last_response.should be_redirect
|
52
|
+
last_response.headers["location"].should eq("/contacts/failure?error_message=internal_error")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "visiting the callback url after authorization" do
|
57
|
+
it "should return the list of contacts" do
|
58
|
+
OAuth1Middleware.mock_session.should_receive(:[]).and_return("oauth_token_secret")
|
59
|
+
get "/contacts/oauth1middleware/callback?oauth_token=token&oauth_verifier=verifier"
|
60
|
+
last_response.should be_ok
|
61
|
+
last_request.env["omnicontacts.contacts"].size.should be(1)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should redirect to failure url if oauth_token_secret is not found in the session" do
|
65
|
+
OAuth1Middleware.mock_session.should_receive(:[]).and_return(nil)
|
66
|
+
get "/contacts/oauth1middleware/callback?oauth_token=token&oauth_verifier=verifier"
|
67
|
+
last_response.should be_redirect
|
68
|
+
last_response.headers["location"].should eq("/contacts/failure?error_message=not_authorized")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "omnicontacts/middleware/oauth2"
|
3
|
+
|
4
|
+
describe OmniContacts::Middleware::OAuth2 do
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
class OAuth2Middleware < OmniContacts::Middleware::OAuth2
|
8
|
+
def authorization_url
|
9
|
+
"http://www.example.com"
|
10
|
+
end
|
11
|
+
|
12
|
+
def redirect_path
|
13
|
+
"/redirect_path"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.mock_session
|
17
|
+
@mock_session ||= {}
|
18
|
+
end
|
19
|
+
|
20
|
+
def session
|
21
|
+
OAuth2Middleware.mock_session
|
22
|
+
end
|
23
|
+
|
24
|
+
def fetch_access_token code
|
25
|
+
["access_token", "token_type", "token_refresh"]
|
26
|
+
end
|
27
|
+
|
28
|
+
def fetch_contacts_using_access_token token, token_type
|
29
|
+
[{:name => "John Doe", :email => "john@example.com"}]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
let(:app) {
|
35
|
+
Rack::Builder.new do |b|
|
36
|
+
b.use OAuth2Middleware, "client_id", "client_secret"
|
37
|
+
b.run lambda{ |env| [200, {"Content-Type" => "text/html"}, ["Hello World"]] }
|
38
|
+
end.to_app
|
39
|
+
}
|
40
|
+
|
41
|
+
context "visiting the listening path" do
|
42
|
+
it "should redirect to authorization site when visiting the listening path" do
|
43
|
+
get "/contacts/oauth2middleware"
|
44
|
+
last_response.should be_redirect
|
45
|
+
last_response.headers['location'].should eq("http://www.example.com")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "visiting the callback url after authorization" do
|
50
|
+
it "should fetch the contacts" do
|
51
|
+
get '/redirect_path?code=ABC'
|
52
|
+
last_response.should be_ok
|
53
|
+
last_request.env["omnicontacts.contacts"].size.should be(1)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should redirect to failure page because user did not allow access to contacts list" do
|
57
|
+
get '/redirect_path?error=not_authorized'
|
58
|
+
last_response.should be_redirect
|
59
|
+
last_response.headers["location"].should eq("/contacts/failure?error_message=not_authorized")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: omnicontacts
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Diego Castorina
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-07 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rack
|
16
|
+
requirement: &1458910 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *1458910
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: json
|
27
|
+
requirement: &1453940 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *1453940
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: simplecov
|
38
|
+
requirement: &1452760 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *1452760
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: &1451690 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *1451690
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rack-test
|
60
|
+
requirement: &1450620 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *1450620
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: &1449560 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *1449560
|
80
|
+
description: A generalized Rack middleware for importing contacts from major email
|
81
|
+
providers.
|
82
|
+
email:
|
83
|
+
- diegocastorina@gmail.com
|
84
|
+
executables: []
|
85
|
+
extensions: []
|
86
|
+
extra_rdoc_files: []
|
87
|
+
files:
|
88
|
+
- .gitignore
|
89
|
+
- Gemfile
|
90
|
+
- Gemfile.lock
|
91
|
+
- README.md
|
92
|
+
- Rakefile
|
93
|
+
- lib/omnicontacts.rb
|
94
|
+
- lib/omnicontacts/authorization/oauth1.rb
|
95
|
+
- lib/omnicontacts/authorization/oauth2.rb
|
96
|
+
- lib/omnicontacts/builder.rb
|
97
|
+
- lib/omnicontacts/http_utils.rb
|
98
|
+
- lib/omnicontacts/importer.rb
|
99
|
+
- lib/omnicontacts/importer/gmail.rb
|
100
|
+
- lib/omnicontacts/importer/hotmail.rb
|
101
|
+
- lib/omnicontacts/importer/yahoo.rb
|
102
|
+
- lib/omnicontacts/middleware/base_oauth.rb
|
103
|
+
- lib/omnicontacts/middleware/oauth1.rb
|
104
|
+
- lib/omnicontacts/middleware/oauth2.rb
|
105
|
+
- omnicontacts.gemspec
|
106
|
+
- spec/omnicontacts/authorization/oauth1_spec.rb
|
107
|
+
- spec/omnicontacts/authorization/oauth2_spec.rb
|
108
|
+
- spec/omnicontacts/http_utils_spec.rb
|
109
|
+
- spec/omnicontacts/importer/gmail_spec.rb
|
110
|
+
- spec/omnicontacts/importer/hotmail_spec.rb
|
111
|
+
- spec/omnicontacts/importer/yahoo_spec.rb
|
112
|
+
- spec/omnicontacts/middleware/oauth1_spec.rb
|
113
|
+
- spec/omnicontacts/middleware/oauth2_spec.rb
|
114
|
+
- spec/spec_helper.rb
|
115
|
+
homepage: http://github.com/Diego81/omnicontacts
|
116
|
+
licenses: []
|
117
|
+
post_install_message:
|
118
|
+
rdoc_options: []
|
119
|
+
require_paths:
|
120
|
+
- lib
|
121
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
123
|
+
requirements:
|
124
|
+
- - ! '>='
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
|
+
none: false
|
129
|
+
requirements:
|
130
|
+
- - ! '>='
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 1.3.6
|
133
|
+
requirements: []
|
134
|
+
rubyforge_project:
|
135
|
+
rubygems_version: 1.8.17
|
136
|
+
signing_key:
|
137
|
+
specification_version: 3
|
138
|
+
summary: A generalized Rack middleware for importing contacts from major email providers.
|
139
|
+
test_files: []
|