dbalatero-evri_rpx 0.1.1 → 1.0.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/LICENSE CHANGED
@@ -1,4 +1,5 @@
1
- Copyright (c) 2009 David Balatero
1
+ Copyright (c) 2009 Evri, Inc
2
+ Authored by David Balatero <dbalatero@evri.com>
2
3
 
3
4
  Permission is hereby granted, free of charge, to any person obtaining
4
5
  a copy of this software and associated documentation files (the
data/README.markdown ADDED
@@ -0,0 +1,142 @@
1
+ evri_rpx
2
+ ========
3
+ The `evri_rpx` library provides an wrapper around RPXNow's universal sign-on API. To learn more about this API, you can read up at [https://rpxnow.com/docs](https://rpxnow.com/docs)
4
+
5
+ Features
6
+ --------
7
+ - Clean and simple API design
8
+ - Full SSL certificate validation
9
+ - Implements all RPX API calls, including ones available at the Pro level
10
+ - 100% spec coverage
11
+ - Clear documentation (and if not, let me know!)
12
+
13
+ TODO
14
+ ----
15
+ - Rails helper methods for building up the iframe/popup widget code.
16
+
17
+ Usage/Install
18
+ -------------
19
+ - Grab an API key/account from [http://rpxnow.com](http://rpxnow.com)
20
+ - As gem: `sudo gem install dbalatero-evri_rpx -s http://gems.github.com`
21
+ - The gem will be on RubyForge soon, but their project request page is messed up, so no dice for now.
22
+
23
+ Examples
24
+ ========
25
+
26
+ Here are examples of the features in `evri_rpx`. As well, you can browse the RDocs here: [http://rdoc.info/projects/dbalatero/evri_rpx](http://rdoc.info/projects/dbalatero/evri_rpx)
27
+
28
+ All interaction with the API goes through the public methods in `Evri::RPX::Session`, which often return complex objects. See [RDocs](http://rdoc.info/projects/dbalatero/evri_rpx) for all the methods available on these objects.
29
+
30
+ To see examples of raw JSON responses from RPX, see [http://github.com/dbalatero/evri_rpx/tree/master/spec/fixtures](http://github.com/dbalatero/evri_rpx/tree/master/spec/fixtures)
31
+
32
+ Validating tokens in your Rails app
33
+ -----------------------------------
34
+ class RPXController < ApplicationController
35
+ def process_token
36
+ if params[:token].blank?
37
+ flash[:notice] = 'You cancelled RPX login.'
38
+ redirect_to root_url
39
+ return
40
+ end
41
+
42
+ # Returns a User object.
43
+ @user = rpx.auth_info(params[:token])
44
+
45
+ # rest of your logic here
46
+ end
47
+
48
+ private
49
+ def rpx
50
+ @rpx ||= Evri::RPX::Session.new('myapikey')
51
+ end
52
+ end
53
+
54
+ Mapping your local user's primary keys to third-party providers
55
+ ---------------------------------------------------------
56
+ class RPXController < ApplicationController
57
+ def process_token
58
+ # Returns a User object.
59
+ @user = rpx.auth_info(params[:token])
60
+
61
+ # Get the corresponding user out of the database for a
62
+ # given email.
63
+ @user_in_mysql = User.find_by_email(@user.email)
64
+
65
+ # Map this user's local primary key to the 3rd-party provider
66
+ rpx.map(@user, @user_in_mysql.id)
67
+ end
68
+
69
+ private
70
+ def rpx
71
+ @rpx ||= Evri::RPX::Session.new('myapikey')
72
+ end
73
+ end
74
+
75
+ Authenticating already mapped users
76
+ -----------------------------------
77
+ class RPXController < ApplicationController
78
+ def process_token
79
+ # Returns a User object.
80
+ @rpx_user = rpx.auth_info(params[:token])
81
+
82
+ @user = User.find(:first, :conditions => ['id = ?', @rpx_user.identifier])
83
+ if @user
84
+ # log them in
85
+ self.current_user = @user
86
+ end
87
+ end
88
+
89
+ private
90
+ def rpx
91
+ @rpx ||= Evri::RPX::Session.new('myapikey')
92
+ end
93
+ end
94
+
95
+ Retrieving mappings for a given user's primary key
96
+ --------------------------------------------------
97
+ user = User.find_by_email('foo@bar.com')
98
+ rpx = Evri::RPX::Session.new('myapikey')
99
+ mappings = rpx.mappings(user.id)
100
+
101
+ Retrieving all mappings for your application
102
+ --------------------------------------------
103
+ rpx = Evri::RPX::Session.new('myapikey')
104
+ all_mappings = rpx.all_mappings
105
+
106
+ all_mappings.each do |identifier, mappings|
107
+ puts "#{identifier} has the following mappings: " <<
108
+ mappings.join(', ')
109
+ end
110
+
111
+ Unmapping a user's primary key and 3rd-party identifier
112
+ -------------------------------------------------------
113
+ user = User.find(50)
114
+
115
+ rpx = Evri::RPX::Session.new('myapikey')
116
+ rpx.unmap('http://brian.myopenid.com/', user.id)
117
+
118
+ Retrieving contact lists for users (requires RPX Pro)
119
+ -----------------------------------------------------
120
+ rpx = Evri::RPX::Session.new('myapikey')
121
+
122
+ # Without a User object, requires primary key.
123
+ user = User.find(50)
124
+ contact_list = rpx.get_contacts(user.id)
125
+
126
+ # With a user object that is mapped already
127
+ user = rpx.auth_info(params[:token])
128
+ contact_list = rpx.get_contacts(user)
129
+
130
+ provider? methods for Users
131
+ ------------------------------------
132
+ user = rpx.auth_info(params[:token])
133
+
134
+ if user.twitter?
135
+ # post an article to twitter via the API
136
+ elsif user.facebook?
137
+ # post an article to facebook via FB connect
138
+ end
139
+
140
+ Copyright
141
+ =========
142
+ Copyright (c) 2009 Evri, Inc. Authored by David Balatero <dbalatero at evri dot com>. See LICENSE for details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 1.0.0
data/evri_rpx.gemspec CHANGED
@@ -2,34 +2,46 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{evri_rpx}
5
- s.version = "0.1.1"
5
+ s.version = "1.0.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["David Balatero"]
9
- s.date = %q{2009-06-15}
9
+ s.date = %q{2009-06-16}
10
10
  s.email = %q{dbalatero@evri.com}
11
11
  s.extra_rdoc_files = [
12
12
  "LICENSE",
13
- "README.rdoc"
13
+ "README.markdown"
14
14
  ]
15
15
  s.files = [
16
16
  ".document",
17
17
  ".gitignore",
18
18
  "LICENSE",
19
- "README.rdoc",
19
+ "README.markdown",
20
20
  "Rakefile",
21
21
  "VERSION",
22
22
  "certs/cacert.pem",
23
23
  "evri_rpx.gemspec",
24
24
  "lib/evri/rpx.rb",
25
+ "lib/evri/rpx/contact.rb",
26
+ "lib/evri/rpx/contact_list.rb",
27
+ "lib/evri/rpx/credentials.rb",
25
28
  "lib/evri/rpx/mappings.rb",
26
29
  "lib/evri/rpx/session.rb",
27
30
  "lib/evri/rpx/user.rb",
28
31
  "lib/evri_rpx.rb",
32
+ "spec/evri/rpx/contact_list_spec.rb",
33
+ "spec/evri/rpx/contact_spec.rb",
34
+ "spec/evri/rpx/credentials_spec.rb",
29
35
  "spec/evri/rpx/mappings_spec.rb",
30
36
  "spec/evri/rpx/session_spec.rb",
31
37
  "spec/evri/rpx/user_spec.rb",
38
+ "spec/fixtures/contacts/bob_johnson.json",
39
+ "spec/fixtures/credentials/dbalatero_facebook.json",
40
+ "spec/fixtures/credentials/dbalatero_twitter.json",
41
+ "spec/fixtures/credentials/dbalatero_windowslive.json",
32
42
  "spec/fixtures/mappings/identifiers.json",
43
+ "spec/fixtures/session/all_mappings.json",
44
+ "spec/fixtures/session/get_contacts.json",
33
45
  "spec/fixtures/session/map.json",
34
46
  "spec/fixtures/session/normal_error.json",
35
47
  "spec/fixtures/session/service_down_error.json",
@@ -37,6 +49,7 @@ Gem::Specification.new do |s|
37
49
  "spec/fixtures/user/dbalatero_facebook.json",
38
50
  "spec/fixtures/user/dbalatero_gmail.json",
39
51
  "spec/fixtures/user/dbalatero_twitter.json",
52
+ "spec/fixtures/user/dbalatero_windows_live.json",
40
53
  "spec/fixtures/user/dbalatero_yahoo.json",
41
54
  "spec/spec_helper.rb"
42
55
  ]
@@ -46,7 +59,10 @@ Gem::Specification.new do |s|
46
59
  s.rubygems_version = %q{1.3.4}
47
60
  s.summary = %q{An API wrapper for the RPXNow.com login service.}
48
61
  s.test_files = [
49
- "spec/evri/rpx/mappings_spec.rb",
62
+ "spec/evri/rpx/contact_list_spec.rb",
63
+ "spec/evri/rpx/contact_spec.rb",
64
+ "spec/evri/rpx/credentials_spec.rb",
65
+ "spec/evri/rpx/mappings_spec.rb",
50
66
  "spec/evri/rpx/session_spec.rb",
51
67
  "spec/evri/rpx/user_spec.rb",
52
68
  "spec/spec_helper.rb"
@@ -0,0 +1,18 @@
1
+ module Evri
2
+ module RPX
3
+ class Contact
4
+ # Returns the person's display name, eg "Bob Johnson".
5
+ attr_reader :display_name
6
+
7
+ # Returns an array of emails, eg ['bob@johnson.com']
8
+ attr_reader :emails
9
+
10
+ def initialize(json)
11
+ @display_name = json['displayName']
12
+ @emails = json['emails'].map do |email|
13
+ email['value']
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ module Evri
2
+ module RPX
3
+ class ContactList
4
+ # Returns the total amount of contacts found for this user.
5
+ attr_reader :total_results
6
+
7
+ # Returns the current pagination index into the contact results
8
+ attr_reader :start_index
9
+
10
+ # Returns the number of contacts returned per page.
11
+ attr_reader :items_per_page
12
+
13
+ # Returns an array of Contact objects.
14
+ attr_reader :contacts
15
+
16
+ def initialize(json)
17
+ @total_results = json['response']['totalResults'] rescue 0
18
+ @start_index = json['response']['startIndex'] rescue nil
19
+ @items_per_page = json['response']['itemsPerPage']
20
+
21
+ @contacts = json['response']['entry'].map do |contact_json|
22
+ Contact.new(contact_json)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,65 @@
1
+ module Evri
2
+ module RPX
3
+ class Credentials
4
+ def initialize(json)
5
+ @json = json
6
+ end
7
+
8
+ # Returns the type of credentials:
9
+ # (Facebook|OAuth|WindowsLive)
10
+ #
11
+ # Generally, you should use the helper methods such
12
+ # as #facebook?, #oauth?, #windows_live?
13
+ def type
14
+ @json['type']
15
+ end
16
+
17
+ # Returns true if these credentials are Facebook.
18
+ def facebook?
19
+ type == 'Facebook'
20
+ end
21
+
22
+ # Returns the Facebook session key.
23
+ def facebook_session_key
24
+ @json['sessionKey']
25
+ end
26
+
27
+ # Returns when this Facebook session expires, as a Time
28
+ # object.
29
+ def facebook_expires
30
+ Time.at(@json['expires'].to_i)
31
+ end
32
+
33
+ # Returns the UID for the authorized Facebook user.
34
+ def facebook_uid
35
+ @json['uid']
36
+ end
37
+
38
+ # Returns true if these credentials are OAuth.
39
+ def oauth?
40
+ type == 'OAuth'
41
+ end
42
+
43
+ # Returns the OAuth token.
44
+ def oauth_token
45
+ @json['oauthToken']
46
+ end
47
+
48
+ # Returns the OAuth token secret.
49
+ def oauth_token_secret
50
+ @json['oauthTokenSecret']
51
+ end
52
+
53
+ # Returns true if these credentials are for Windows Live
54
+ def windows_live?
55
+ type == 'WindowsLive'
56
+ end
57
+
58
+ # Returns the Windows Live eact string, which contains the
59
+ # user's delegated authentication consent token.
60
+ def windows_live_eact
61
+ @json['eact']
62
+ end
63
+ end
64
+ end
65
+ end
@@ -1,6 +1,7 @@
1
1
  module Evri
2
2
  module RPX
3
3
  class Mappings
4
+ # Gives back the raw JSON returned by RPX.
4
5
  attr_reader :json
5
6
  alias :raw :json
6
7
 
@@ -8,6 +9,8 @@ module Evri
8
9
  @json = json
9
10
  end
10
11
 
12
+ # Returns a list of identifiers for a user, or an empty
13
+ # array if there are none.
11
14
  def identifiers
12
15
  @json['identifiers'] || []
13
16
  end
@@ -7,10 +7,14 @@ module Evri
7
7
  '..', '..', '..', 'certs',
8
8
  'cacert.pem'))
9
9
 
10
-
10
+ # This error is raised when the RPX service is unavailable.
11
11
  class ServiceUnavailableError < StandardError; end
12
+
13
+ # This error is raised when an API call is misformed,
14
+ # or there is bad configuration on the other end.
12
15
  class APICallError < StandardError; end
13
16
 
17
+ # Returns the current RPX api_key attached to the session.
14
18
  attr_reader :api_key
15
19
 
16
20
  def initialize(api_key)
@@ -40,13 +44,41 @@ module Evri
40
44
  User.new(json)
41
45
  end
42
46
 
47
+ # Get all stored mappings for a particular application.
48
+ #
49
+ # Returns a hash in this form:
50
+ # { 'identifier1' => ['mapping1', 'mapping2'],
51
+ # 'identifier2' => ['mapping3', 'mapping4'],
52
+ # ... }
53
+ def all_mappings
54
+ json = parse_response(get("/api/#{API_VERSION}/all_mappings",
55
+ :apiKey => @api_key))
56
+ json['mappings']
57
+ end
58
+
59
+ # Retrieve a list of contacts for an identifier in the
60
+ # Portable Contacts format.
61
+ #
62
+ # Takes either a string identifier, or a User object
63
+ # that responds to :identifier.
64
+ #
65
+ # This feature is only available for RPX Pro customers.
66
+ def get_contacts(user_or_identifier)
67
+ identifier = identifier_param(user_or_identifier)
68
+ json = parse_response(get("/api/#{API_VERSION}/get_contacts",
69
+ :apiKey => @api_key,
70
+ :identifier => identifier))
71
+ ContactList.new(json)
72
+ end
73
+
43
74
  # Returns the mappings for a given user's primary key, as a
44
75
  # Evri::RPX::Mappings object.
45
76
  #
46
77
  # Takes either a string of the user's primary key:
47
- # session.mappings('dbalatero')
78
+ # m = session.mappings('dbalatero')
48
79
  # or a User object with an attached primary key:
49
- # session.mappings(
80
+ # user = session.auth_info(params[:token])
81
+ # m = session.mappings(user)
50
82
  def mappings(user_or_primary_key)
51
83
  params = { 'apiKey' => @api_key }
52
84
  params['primaryKey'] = user_or_primary_key.respond_to?(:primary_key) ?
@@ -62,7 +94,7 @@ module Evri
62
94
  # this OpenID will return the mapped primaryKey in the auth_info
63
95
  # API response, which you may use to sign the user in.
64
96
  #
65
- #
97
+ # Returns true.
66
98
  def map(user_or_identifier, primary_key, options = {})
67
99
  params = { 'apiKey' => @api_key,
68
100
  'primaryKey' => primary_key,
@@ -75,6 +107,9 @@ module Evri
75
107
  json['stat'] == 'ok'
76
108
  end
77
109
 
110
+ # Remove (unmap) an OpenID from a primary key.
111
+ #
112
+ # Returns true.
78
113
  def unmap(user_or_identifier, primary_key)
79
114
  params = { 'apiKey' => @api_key,
80
115
  'primaryKey' => primary_key }
@@ -108,18 +143,18 @@ module Evri
108
143
  end
109
144
 
110
145
  def parse_response(response)
111
- if response.code.to_i >= 400
112
- result = JSON.parse(response.body)
146
+ result = JSON.parse(response.body)
113
147
 
148
+ if result['err']
114
149
  code = result['err']['code']
115
150
  if code == -1
116
151
  raise ServiceUnavailableError, "The RPX service is temporarily unavailable."
117
152
  else
118
153
  raise APICallError, "Got error: #{result['err']['msg']} (code: #{code}), HTTP status: #{response.code}"
119
154
  end
120
- else
121
- JSON.parse(response.body)
122
155
  end
156
+
157
+ result
123
158
  end
124
159
  end
125
160
  end
data/lib/evri/rpx/user.rb CHANGED
@@ -3,6 +3,10 @@ module Evri
3
3
  class User
4
4
  class InvalidUserJsonError < StandardError; end
5
5
 
6
+ # Returns a Credentials object for this user, or nil.
7
+ attr_reader :credentials
8
+
9
+ # Returns the raw JSON returned by RPX, in case you want it.
6
10
  attr_reader :json
7
11
  alias :raw :json
8
12
 
@@ -11,7 +15,12 @@ module Evri
11
15
  raise InvalidUserJsonError,
12
16
  'The JSON passed in is invalid!'
13
17
  end
18
+
14
19
  @json = json
20
+
21
+ if @json['accessCredentials']
22
+ @credentials = Credentials.new(@json['accessCredentials'])
23
+ end
15
24
  end
16
25
 
17
26
  # Returns the person's full name (aka David Balatero)
@@ -50,10 +59,6 @@ module Evri
50
59
  @json['profile']['url'] rescue nil
51
60
  end
52
61
 
53
- def credentials
54
- nil
55
- end
56
-
57
62
  # Returns a user's email.
58
63
  def email
59
64
  @json['profile']['email'] rescue nil
@@ -70,17 +75,25 @@ module Evri
70
75
  provider_name == 'Twitter'
71
76
  end
72
77
 
78
+ # Returns true if this is a Google login.
73
79
  def google?
74
80
  provider_name == 'Google'
75
81
  end
76
82
 
83
+ # Returns true if this is a Facebook login.
77
84
  def facebook?
78
85
  provider_name == 'Facebook'
79
86
  end
80
87
 
88
+ # Returns true if this is a Yahoo! login.
81
89
  def yahoo?
82
90
  provider_name == 'Yahoo!'
83
91
  end
92
+
93
+ # Returns true if this is a Windows Live login.
94
+ def windows_live?
95
+ provider_name == 'Windows Live'
96
+ end
84
97
  end
85
98
  end
86
99
  end
data/lib/evri_rpx.rb CHANGED
@@ -5,6 +5,9 @@ require 'net/http'
5
5
  require 'net/https'
6
6
 
7
7
  require 'evri/rpx'
8
+ require 'evri/rpx/contact'
9
+ require 'evri/rpx/contact_list'
10
+ require 'evri/rpx/credentials'
8
11
  require 'evri/rpx/mappings'
9
12
  require 'evri/rpx/session'
10
13
  require 'evri/rpx/user'
@@ -0,0 +1,39 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ describe Evri::RPX::ContactList do
4
+ before(:all) do
5
+ @list = Evri::RPX::ContactList.new(json_fixture('session/get_contacts.json'))
6
+ end
7
+
8
+ describe "total_results" do
9
+ it "should return the total results for a user's contact list" do
10
+ @list.total_results.should == 5
11
+ end
12
+ end
13
+
14
+ describe "start_index" do
15
+ it "should return the start index used in pagination" do
16
+ @list.start_index.should == 1
17
+ end
18
+ end
19
+
20
+ describe "items_per_page" do
21
+ it "should return the items per page, for pagination" do
22
+ @list.items_per_page.should == 5
23
+ end
24
+ end
25
+
26
+ describe "contacts" do
27
+ it "should return an array of Contact objects" do
28
+ @list.contacts.each do |contact|
29
+ contact.should be_a_kind_of(Evri::RPX::Contact)
30
+ end
31
+ end
32
+
33
+ it "should include Bob Johnson" do
34
+ @list.contacts.select { |contact|
35
+ contact.display_name == 'Bob Johnson'
36
+ }.should_not be_nil
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ describe Evri::RPX::Contact do
4
+ before(:all) do
5
+ @contact = Evri::RPX::Contact.new(json_fixture('contacts/bob_johnson.json'))
6
+ end
7
+
8
+ describe "display_name" do
9
+ it "should be the correct display name in the response" do
10
+ @contact.display_name.should == 'Bob Johnson'
11
+ end
12
+ end
13
+
14
+ describe "emails" do
15
+ it "should return a list of emails for a given user" do
16
+ @contact.emails.should == ['bob@example.com']
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,98 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ describe Evri::RPX::Credentials do
4
+ describe "parsing OAuth (twitter) credentials" do
5
+ before(:all) do
6
+ json = json_fixture('credentials/dbalatero_twitter.json')
7
+ @credentials = Evri::RPX::Credentials.new(json['accessCredentials'])
8
+ end
9
+
10
+ describe "oauth?" do
11
+ it "should be true" do
12
+ @credentials.oauth?.should be_true
13
+ end
14
+ end
15
+
16
+ describe "type" do
17
+ it "should be OAuth" do
18
+ @credentials.type.should == 'OAuth'
19
+ end
20
+ end
21
+
22
+ describe "oauth_token" do
23
+ it "should be the oauth token given" do
24
+ @credentials.oauth_token.should == '35834683-jBU3o-snip'
25
+ end
26
+ end
27
+
28
+ describe "oauth_token_secret" do
29
+ it "should be the secret given" do
30
+ @credentials.oauth_token_secret.should == '2GjoAgV5-snip'
31
+ end
32
+ end
33
+ end
34
+
35
+ describe "parsing Windows Live credentials" do
36
+ before(:all) do
37
+ json = json_fixture('credentials/dbalatero_windowslive.json')
38
+ @credentials = Evri::RPX::Credentials.new(json['accessCredentials'])
39
+ end
40
+
41
+ describe "windows_live?" do
42
+ it "should be true" do
43
+ @credentials.windows_live?.should be_true
44
+ end
45
+ end
46
+
47
+ describe "type" do
48
+ it "should be WindowsLive" do
49
+ @credentials.type.should == 'WindowsLive'
50
+ end
51
+ end
52
+
53
+ describe "windows_live_eact" do
54
+ it "should be the eact field given" do
55
+ @credentials.windows_live_eact.should == 'eact%3DJvtJUb4%252Bx1InXqjglTBWX-snip'
56
+ end
57
+ end
58
+ end
59
+
60
+
61
+ describe "parsing Facebook credentials" do
62
+ before(:all) do
63
+ json = json_fixture('credentials/dbalatero_facebook.json')
64
+ @credentials = Evri::RPX::Credentials.new(json['accessCredentials'])
65
+ end
66
+
67
+ describe "facebook?" do
68
+ it "should be true" do
69
+ @credentials.facebook?.should be_true
70
+ end
71
+ end
72
+
73
+ describe "type" do
74
+ it "should be Facebook" do
75
+ @credentials.type.should == 'Facebook'
76
+ end
77
+ end
78
+
79
+ describe "facebook_session_key" do
80
+ it "should be the session key given" do
81
+ @credentials.facebook_session_key.should == '2.7kr3H8W-snip'
82
+ end
83
+ end
84
+
85
+ describe "facebook_uid" do
86
+ it "should be the UID given" do
87
+ @credentials.facebook_uid.should == '10701789'
88
+ end
89
+ end
90
+
91
+ describe "facebook_expires" do
92
+ it "should be the correct Time object" do
93
+ @credentials.facebook_expires.should == Time.at(1245196800)
94
+ end
95
+ end
96
+
97
+ end
98
+ end
@@ -46,6 +46,46 @@ describe Evri::RPX::Session do
46
46
  end
47
47
  end
48
48
 
49
+ describe "all_mappings" do
50
+ it "should return a set of identifiers to mappings" do
51
+ FakeWeb.register_uri(:get,
52
+ 'https://rpxnow.com:443/api/v2/all_mappings',
53
+ :file => fixture_path('session/all_mappings.json'))
54
+ result = @session.all_mappings
55
+ result['1'].should == ['http://cygnus.myopenid.com/']
56
+ result['2'].should == ['http://brianellin.com/', 'http://brian.myopenid.com/']
57
+ end
58
+ end
59
+
60
+ describe "get_contacts" do
61
+ before(:each) do
62
+ FakeWeb.register_uri(:get,
63
+ 'https://rpxnow.com:443/api/v2/get_contacts',
64
+ :file => fixture_path('session/get_contacts.json'))
65
+ end
66
+
67
+ after(:each) do
68
+ FakeWeb.clean_registry
69
+ end
70
+
71
+ it "should return a contacts list for a identifier string" do
72
+ result = @session.get_contacts('http://brian.myopenid.com/')
73
+ result.should be_a_kind_of(Evri::RPX::ContactList)
74
+
75
+ result.contacts.should have(6).things
76
+ end
77
+
78
+ it "should return a contacts list for a user string" do
79
+ user = mock('user')
80
+ user.should_receive(:identifier).and_return('http://brian.myopenid.com/')
81
+
82
+ result = @session.get_contacts(user)
83
+ result.should be_a_kind_of(Evri::RPX::ContactList)
84
+
85
+ result.contacts.should have(6).things
86
+ end
87
+ end
88
+
49
89
  describe "map" do
50
90
  before(:each) do
51
91
  FakeWeb.register_uri(:get,
@@ -78,7 +78,7 @@ describe Evri::RPX::User do
78
78
 
79
79
  describe "credentials" do
80
80
  it "should not be nil" do
81
- pending
81
+ @user.credentials.should_not be_nil
82
82
  end
83
83
  end
84
84
 
@@ -215,7 +215,6 @@ describe Evri::RPX::User do
215
215
 
216
216
  describe "credentials" do
217
217
  it "should be set" do
218
- pending
219
218
  @user.credentials.should_not be_nil
220
219
  end
221
220
  end
@@ -300,4 +299,29 @@ describe Evri::RPX::User do
300
299
  end
301
300
  end
302
301
  end
302
+
303
+ describe "parsing Windows Live logins" do
304
+ before(:all) do
305
+ json = json_fixture('user/dbalatero_windows_live.json')
306
+ @user = Evri::RPX::User.new(json)
307
+ end
308
+
309
+ describe "windows_live?" do
310
+ it "should be true" do
311
+ @user.windows_live?.should be_true
312
+ end
313
+ end
314
+
315
+ describe "credentials" do
316
+ it "should not be nil" do
317
+ @user.credentials.should_not be_nil
318
+ end
319
+ end
320
+
321
+ describe "email" do
322
+ it "should be correct" do
323
+ @user.email.should == 'dbalatero16@hotmail.com'
324
+ end
325
+ end
326
+ end
303
327
  end
@@ -0,0 +1,9 @@
1
+ {
2
+ "displayName": "Bob Johnson",
3
+ "emails": [
4
+ {
5
+ "type": "other",
6
+ "value": "bob@example.com"
7
+ }
8
+ ]
9
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "profile": {
3
+ "name": {
4
+ "givenName": "David",
5
+ "familyName": "Balatero",
6
+ "formatted": "David Balatero"
7
+ },
8
+ "address": {
9
+ "region": "Washington",
10
+ "country": "United States",
11
+ "postalCode": "98115",
12
+ "locality": "Seattle"
13
+ },
14
+ "photo": "http:\/\/profile.ak.facebook.com\/v230\/745\/68\/n10701789_1299.jpg",
15
+ "displayName": "David Balatero",
16
+ "preferredUsername": "DavidBalatero",
17
+ "url": "http:\/\/www.facebook.com\/profile.php?id=10701789",
18
+ "utcOffset": "-07:00",
19
+ "gender": "male",
20
+ "birthday": "1986-08-31",
21
+ "providerName": "Facebook",
22
+ "primaryKey": "dbalatero",
23
+ "identifier": "http:\/\/www.facebook.com\/profile.php?id=10701789"
24
+ },
25
+ "accessCredentials": {
26
+ "expires": "1245196800",
27
+ "uid": "10701789",
28
+ "type": "Facebook",
29
+ "sessionKey": "2.7kr3H8W-snip"
30
+ },
31
+ "stat": "ok"
32
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "profile": {
3
+ "name": {
4
+ "formatted": "David Balatero"
5
+ },
6
+ "photo": "http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/196887137\/n10704766_41523711_7282_normal.jpg",
7
+ "displayName": "David Balatero",
8
+ "preferredUsername": "dbalatero",
9
+ "url": "http:\/\/twitter.com\/dbalatero",
10
+ "providerName": "Twitter",
11
+ "identifier": "http:\/\/twitter.com\/account\/profile?user_id=35834683"
12
+ },
13
+ "accessCredentials": {
14
+ "oauthToken": "35834683-jBU3o-snip",
15
+ "type": "OAuth",
16
+ "oauthTokenSecret": "2GjoAgV5-snip"
17
+ },
18
+ "stat": "ok"
19
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "profile": {
3
+ "displayName": "hit me with that motown funk",
4
+ "preferredUsername": "hit me with that motown funk",
5
+ "url": "http:\/\/cid-f032362d64442690.spaces.live.com\/",
6
+ "providerName": "Windows Live",
7
+ "identifier": "http:\/\/cid-f032362d64442690.spaces.live.com\/",
8
+ "email": "dbalatero16@hotmail.com"
9
+ },
10
+ "accessCredentials": {
11
+ "eact": "eact%3DJvtJUb4%252Bx1InXqjglTBWX-snip",
12
+ "type": "WindowsLive"
13
+ },
14
+ "stat": "ok"
15
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "mappings": {
3
+ "1": [
4
+ "http:\/\/cygnus.myopenid.com\/"
5
+ ],
6
+ "2": [
7
+ "http:\/\/brianellin.com\/",
8
+ "http:\/\/brian.myopenid.com\/"
9
+ ]
10
+ },
11
+ "stat": "ok"
12
+ }
@@ -0,0 +1,63 @@
1
+ {
2
+ "response": {
3
+ "totalResults": 5,
4
+ "startIndex": 1,
5
+ "entry": [
6
+ {
7
+ "displayName": "Bob Johnson",
8
+ "emails": [
9
+ {
10
+ "type": "other",
11
+ "value": "bob@example.com"
12
+ }
13
+ ]
14
+ },
15
+ {
16
+ "displayName": "Cindy Smith",
17
+ "emails": [
18
+ {
19
+ "type": "other",
20
+ "value": "cindy.smith@example.com"
21
+ }
22
+ ]
23
+ },
24
+ {
25
+ "displayName": "Fred Williams",
26
+ "emails": [
27
+ {
28
+ "type": "other",
29
+ "value": "fred.williams@example.com"
30
+ }
31
+ ]
32
+ },
33
+ {
34
+ "emails": [
35
+ {
36
+ "type": "other",
37
+ "value": "j.lewis@example.com"
38
+ }
39
+ ]
40
+ },
41
+ {
42
+ "displayName": "Mary Jones",
43
+ "emails": [
44
+ {
45
+ "type": "other",
46
+ "value": "mary.jones@example.com"
47
+ }
48
+ ]
49
+ },
50
+ {
51
+ "displayName": "Patricia Green",
52
+ "emails": [
53
+ {
54
+ "type": "other",
55
+ "value": "p.green@example.com"
56
+ }
57
+ ]
58
+ }
59
+ ],
60
+ "itemsPerPage": 5
61
+ },
62
+ "stat": "ok"
63
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "profile": {
3
+ "displayName": "hit me with that motown funk",
4
+ "preferredUsername": "hit me with that motown funk",
5
+ "url": "http:\/\/cid-f032362d64442690.spaces.live.com\/",
6
+ "providerName": "Windows Live",
7
+ "identifier": "http:\/\/cid-f032362d64442690.spaces.live.com\/",
8
+ "email": "dbalatero16@hotmail.com"
9
+ },
10
+ "accessCredentials": {
11
+ "eact": "--snip--",
12
+ "type": "WindowsLive"
13
+ },
14
+ "stat": "ok"
15
+ }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbalatero-evri_rpx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Balatero
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-15 00:00:00 -07:00
12
+ date: 2009-06-16 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -21,25 +21,37 @@ extensions: []
21
21
 
22
22
  extra_rdoc_files:
23
23
  - LICENSE
24
- - README.rdoc
24
+ - README.markdown
25
25
  files:
26
26
  - .document
27
27
  - .gitignore
28
28
  - LICENSE
29
- - README.rdoc
29
+ - README.markdown
30
30
  - Rakefile
31
31
  - VERSION
32
32
  - certs/cacert.pem
33
33
  - evri_rpx.gemspec
34
34
  - lib/evri/rpx.rb
35
+ - lib/evri/rpx/contact.rb
36
+ - lib/evri/rpx/contact_list.rb
37
+ - lib/evri/rpx/credentials.rb
35
38
  - lib/evri/rpx/mappings.rb
36
39
  - lib/evri/rpx/session.rb
37
40
  - lib/evri/rpx/user.rb
38
41
  - lib/evri_rpx.rb
42
+ - spec/evri/rpx/contact_list_spec.rb
43
+ - spec/evri/rpx/contact_spec.rb
44
+ - spec/evri/rpx/credentials_spec.rb
39
45
  - spec/evri/rpx/mappings_spec.rb
40
46
  - spec/evri/rpx/session_spec.rb
41
47
  - spec/evri/rpx/user_spec.rb
48
+ - spec/fixtures/contacts/bob_johnson.json
49
+ - spec/fixtures/credentials/dbalatero_facebook.json
50
+ - spec/fixtures/credentials/dbalatero_twitter.json
51
+ - spec/fixtures/credentials/dbalatero_windowslive.json
42
52
  - spec/fixtures/mappings/identifiers.json
53
+ - spec/fixtures/session/all_mappings.json
54
+ - spec/fixtures/session/get_contacts.json
43
55
  - spec/fixtures/session/map.json
44
56
  - spec/fixtures/session/normal_error.json
45
57
  - spec/fixtures/session/service_down_error.json
@@ -47,6 +59,7 @@ files:
47
59
  - spec/fixtures/user/dbalatero_facebook.json
48
60
  - spec/fixtures/user/dbalatero_gmail.json
49
61
  - spec/fixtures/user/dbalatero_twitter.json
62
+ - spec/fixtures/user/dbalatero_windows_live.json
50
63
  - spec/fixtures/user/dbalatero_yahoo.json
51
64
  - spec/spec_helper.rb
52
65
  has_rdoc: false
@@ -76,6 +89,9 @@ signing_key:
76
89
  specification_version: 3
77
90
  summary: An API wrapper for the RPXNow.com login service.
78
91
  test_files:
92
+ - spec/evri/rpx/contact_list_spec.rb
93
+ - spec/evri/rpx/contact_spec.rb
94
+ - spec/evri/rpx/credentials_spec.rb
79
95
  - spec/evri/rpx/mappings_spec.rb
80
96
  - spec/evri/rpx/session_spec.rb
81
97
  - spec/evri/rpx/user_spec.rb
data/README.rdoc DELETED
@@ -1,13 +0,0 @@
1
- = evri_rpx
2
-
3
- Description goes here.
4
-
5
- == Copyright
6
-
7
- == TODO
8
-
9
- * Implement #all_mappings
10
- * Implement #get_contacts
11
- * Helper methods for forms, etc.
12
-
13
- Copyright (c) 2009 David Balatero, Evri, Inc. <dbalatero at evri dot com>. See LICENSE for details.