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 +2 -1
- data/README.markdown +142 -0
- data/VERSION +1 -1
- data/evri_rpx.gemspec +21 -5
- data/lib/evri/rpx/contact.rb +18 -0
- data/lib/evri/rpx/contact_list.rb +27 -0
- data/lib/evri/rpx/credentials.rb +65 -0
- data/lib/evri/rpx/mappings.rb +3 -0
- data/lib/evri/rpx/session.rb +43 -8
- data/lib/evri/rpx/user.rb +17 -4
- data/lib/evri_rpx.rb +3 -0
- data/spec/evri/rpx/contact_list_spec.rb +39 -0
- data/spec/evri/rpx/contact_spec.rb +19 -0
- data/spec/evri/rpx/credentials_spec.rb +98 -0
- data/spec/evri/rpx/session_spec.rb +40 -0
- data/spec/evri/rpx/user_spec.rb +26 -2
- data/spec/fixtures/contacts/bob_johnson.json +9 -0
- data/spec/fixtures/credentials/dbalatero_facebook.json +32 -0
- data/spec/fixtures/credentials/dbalatero_twitter.json +19 -0
- data/spec/fixtures/credentials/dbalatero_windowslive.json +15 -0
- data/spec/fixtures/session/all_mappings.json +12 -0
- data/spec/fixtures/session/get_contacts.json +63 -0
- data/spec/fixtures/user/dbalatero_windows_live.json +15 -0
- metadata +20 -4
- data/README.rdoc +0 -13
data/LICENSE
CHANGED
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.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.
|
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-
|
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.
|
13
|
+
"README.markdown"
|
14
14
|
]
|
15
15
|
s.files = [
|
16
16
|
".document",
|
17
17
|
".gitignore",
|
18
18
|
"LICENSE",
|
19
|
-
"README.
|
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/
|
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
|
data/lib/evri/rpx/mappings.rb
CHANGED
@@ -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
|
data/lib/evri/rpx/session.rb
CHANGED
@@ -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.
|
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
|
-
|
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
@@ -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,
|
data/spec/evri/rpx/user_spec.rb
CHANGED
@@ -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
|
-
|
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,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,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.
|
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-
|
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.
|
24
|
+
- README.markdown
|
25
25
|
files:
|
26
26
|
- .document
|
27
27
|
- .gitignore
|
28
28
|
- LICENSE
|
29
|
-
- README.
|
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.
|