houston-oauth-plugin 0.5.1
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.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/CHANGELOG +187 -0
- data/Gemfile +27 -0
- data/Guardfile +8 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +542 -0
- data/Rakefile +1 -0
- data/UPGRADE.rdoc +21 -0
- data/generators/oauth_consumer/USAGE +10 -0
- data/generators/oauth_consumer/oauth_consumer_generator.rb +52 -0
- data/generators/oauth_consumer/templates/consumer_token.rb +11 -0
- data/generators/oauth_consumer/templates/controller.rb +27 -0
- data/generators/oauth_consumer/templates/index.html.erb +29 -0
- data/generators/oauth_consumer/templates/index.html.haml +18 -0
- data/generators/oauth_consumer/templates/index.html.slim +15 -0
- data/generators/oauth_consumer/templates/migration.rb +23 -0
- data/generators/oauth_consumer/templates/oauth_config.rb +73 -0
- data/generators/oauth_consumer/templates/show.html.erb +7 -0
- data/generators/oauth_consumer/templates/show.html.haml +8 -0
- data/generators/oauth_consumer/templates/show.html.slim +8 -0
- data/generators/oauth_provider/USAGE +20 -0
- data/generators/oauth_provider/lib/insert_routes.rb +67 -0
- data/generators/oauth_provider/oauth_provider_generator.rb +127 -0
- data/generators/oauth_provider/templates/_form.html.erb +17 -0
- data/generators/oauth_provider/templates/_form.html.haml +21 -0
- data/generators/oauth_provider/templates/access_token.rb +16 -0
- data/generators/oauth_provider/templates/authorize.html.erb +14 -0
- data/generators/oauth_provider/templates/authorize.html.haml +16 -0
- data/generators/oauth_provider/templates/authorize_failure.html.erb +1 -0
- data/generators/oauth_provider/templates/authorize_failure.html.haml +1 -0
- data/generators/oauth_provider/templates/authorize_success.html.erb +1 -0
- data/generators/oauth_provider/templates/authorize_success.html.haml +1 -0
- data/generators/oauth_provider/templates/client_application.rb +57 -0
- data/generators/oauth_provider/templates/client_application_spec.rb +29 -0
- data/generators/oauth_provider/templates/client_application_test.rb +42 -0
- data/generators/oauth_provider/templates/client_applications.yml +23 -0
- data/generators/oauth_provider/templates/clients_controller.rb +52 -0
- data/generators/oauth_provider/templates/clients_controller_spec.rb +176 -0
- data/generators/oauth_provider/templates/clients_controller_test.rb +280 -0
- data/generators/oauth_provider/templates/controller.rb +23 -0
- data/generators/oauth_provider/templates/edit.html.erb +7 -0
- data/generators/oauth_provider/templates/edit.html.haml +4 -0
- data/generators/oauth_provider/templates/index.html.erb +43 -0
- data/generators/oauth_provider/templates/index.html.haml +39 -0
- data/generators/oauth_provider/templates/migration.rb +47 -0
- data/generators/oauth_provider/templates/new.html.erb +5 -0
- data/generators/oauth_provider/templates/new.html.haml +5 -0
- data/generators/oauth_provider/templates/oauth2_authorize.html.erb +16 -0
- data/generators/oauth_provider/templates/oauth2_authorize.html.haml +17 -0
- data/generators/oauth_provider/templates/oauth2_token.rb +20 -0
- data/generators/oauth_provider/templates/oauth2_token_spec.rb +52 -0
- data/generators/oauth_provider/templates/oauth2_verifier.rb +35 -0
- data/generators/oauth_provider/templates/oauth2_verifier_spec.rb +44 -0
- data/generators/oauth_provider/templates/oauth_nonce.rb +13 -0
- data/generators/oauth_provider/templates/oauth_nonce_spec.rb +24 -0
- data/generators/oauth_provider/templates/oauth_nonce_test.rb +26 -0
- data/generators/oauth_provider/templates/oauth_nonces.yml +13 -0
- data/generators/oauth_provider/templates/oauth_token.rb +30 -0
- data/generators/oauth_provider/templates/oauth_token_spec.rb +309 -0
- data/generators/oauth_provider/templates/oauth_token_test.rb +57 -0
- data/generators/oauth_provider/templates/oauth_tokens.yml +17 -0
- data/generators/oauth_provider/templates/request_token.rb +40 -0
- data/generators/oauth_provider/templates/show.html.erb +27 -0
- data/generators/oauth_provider/templates/show.html.haml +30 -0
- data/init.rb +1 -0
- data/install.rb +2 -0
- data/lib/generators/active_record/oauth_consumer_generator.rb +33 -0
- data/lib/generators/active_record/oauth_consumer_templates/consumer_token.rb +11 -0
- data/lib/generators/active_record/oauth_consumer_templates/migration.rb +20 -0
- data/lib/generators/active_record/oauth_provider_generator.rb +39 -0
- data/lib/generators/active_record/oauth_provider_templates/access_token.rb +16 -0
- data/lib/generators/active_record/oauth_provider_templates/client_application.rb +57 -0
- data/lib/generators/active_record/oauth_provider_templates/migration.rb +47 -0
- data/lib/generators/active_record/oauth_provider_templates/oauth2_token.rb +20 -0
- data/lib/generators/active_record/oauth_provider_templates/oauth2_verifier.rb +35 -0
- data/lib/generators/active_record/oauth_provider_templates/oauth_nonce.rb +13 -0
- data/lib/generators/active_record/oauth_provider_templates/oauth_token.rb +30 -0
- data/lib/generators/active_record/oauth_provider_templates/request_token.rb +40 -0
- data/lib/generators/erb/oauth_consumer_generator.rb +14 -0
- data/lib/generators/erb/oauth_consumer_templates/index.html.erb +29 -0
- data/lib/generators/erb/oauth_consumer_templates/show.html.erb +7 -0
- data/lib/generators/erb/oauth_provider_generator.rb +23 -0
- data/lib/generators/erb/oauth_provider_templates/_form.html.erb +17 -0
- data/lib/generators/erb/oauth_provider_templates/authorize.html.erb +14 -0
- data/lib/generators/erb/oauth_provider_templates/authorize_failure.html.erb +1 -0
- data/lib/generators/erb/oauth_provider_templates/authorize_success.html.erb +1 -0
- data/lib/generators/erb/oauth_provider_templates/edit.html.erb +7 -0
- data/lib/generators/erb/oauth_provider_templates/index.html.erb +43 -0
- data/lib/generators/erb/oauth_provider_templates/new.html.erb +5 -0
- data/lib/generators/erb/oauth_provider_templates/oauth2_authorize.html.erb +16 -0
- data/lib/generators/erb/oauth_provider_templates/show.html.erb +27 -0
- data/lib/generators/haml/oauth_consumer_generator.rb +21 -0
- data/lib/generators/haml/oauth_consumer_templates/index.html.haml +18 -0
- data/lib/generators/haml/oauth_consumer_templates/show.html.haml +8 -0
- data/lib/generators/haml/oauth_provider_generator.rb +28 -0
- data/lib/generators/haml/oauth_provider_templates/_form.html.haml +21 -0
- data/lib/generators/haml/oauth_provider_templates/authorize.html.haml +16 -0
- data/lib/generators/haml/oauth_provider_templates/authorize_failure.html.haml +1 -0
- data/lib/generators/haml/oauth_provider_templates/authorize_success.html.haml +1 -0
- data/lib/generators/haml/oauth_provider_templates/edit.html.haml +4 -0
- data/lib/generators/haml/oauth_provider_templates/index.html.haml +39 -0
- data/lib/generators/haml/oauth_provider_templates/new.html.haml +5 -0
- data/lib/generators/haml/oauth_provider_templates/oauth2_authorize.html.haml +17 -0
- data/lib/generators/haml/oauth_provider_templates/show.html.haml +30 -0
- data/lib/generators/mongoid/oauth_consumer_generator.rb +15 -0
- data/lib/generators/mongoid/oauth_consumer_templates/consumer_token.rb +41 -0
- data/lib/generators/mongoid/oauth_provider_generator.rb +21 -0
- data/lib/generators/mongoid/oauth_provider_templates/access_token.rb +16 -0
- data/lib/generators/mongoid/oauth_provider_templates/client_application.rb +71 -0
- data/lib/generators/mongoid/oauth_provider_templates/oauth2_token.rb +20 -0
- data/lib/generators/mongoid/oauth_provider_templates/oauth2_verifier.rb +35 -0
- data/lib/generators/mongoid/oauth_provider_templates/oauth_nonce.rb +24 -0
- data/lib/generators/mongoid/oauth_provider_templates/oauth_token.rb +44 -0
- data/lib/generators/mongoid/oauth_provider_templates/request_token.rb +36 -0
- data/lib/generators/oauth_consumer/USAGE +11 -0
- data/lib/generators/oauth_consumer/oauth_consumer_generator.rb +31 -0
- data/lib/generators/oauth_consumer/templates/controller.rb +59 -0
- data/lib/generators/oauth_consumer/templates/oauth_config.rb +68 -0
- data/lib/generators/oauth_inflections.rb +6 -0
- data/lib/generators/oauth_plugin.rb +0 -0
- data/lib/generators/oauth_provider/USAGE +18 -0
- data/lib/generators/oauth_provider/oauth_provider_generator.rb +37 -0
- data/lib/generators/oauth_provider/templates/clients_controller.rb +52 -0
- data/lib/generators/oauth_provider/templates/controller.rb +23 -0
- data/lib/generators/rspec/oauth_provider_generator.rb +35 -0
- data/lib/generators/rspec/templates/client_application_spec.rb +29 -0
- data/lib/generators/rspec/templates/client_applications.yml +23 -0
- data/lib/generators/rspec/templates/clients_controller_spec.rb +176 -0
- data/lib/generators/rspec/templates/oauth2_token_spec.rb +52 -0
- data/lib/generators/rspec/templates/oauth2_verifier_spec.rb +44 -0
- data/lib/generators/rspec/templates/oauth_nonce_spec.rb +24 -0
- data/lib/generators/rspec/templates/oauth_nonces.yml +13 -0
- data/lib/generators/rspec/templates/oauth_token_spec.rb +309 -0
- data/lib/generators/rspec/templates/oauth_tokens.yml +17 -0
- data/lib/generators/slim/oauth_consumer_generator.rb +21 -0
- data/lib/generators/slim/oauth_consumer_templates/index.html.slim +15 -0
- data/lib/generators/slim/oauth_consumer_templates/show.html.slim +8 -0
- data/lib/generators/test_unit/oauth_provider_generator.rb +33 -0
- data/lib/generators/test_unit/templates/client_application_test.rb +42 -0
- data/lib/generators/test_unit/templates/client_applications.yml +23 -0
- data/lib/generators/test_unit/templates/clients_controller_test.rb +280 -0
- data/lib/generators/test_unit/templates/oauth_nonce_test.rb +26 -0
- data/lib/generators/test_unit/templates/oauth_nonces.yml +13 -0
- data/lib/generators/test_unit/templates/oauth_token_test.rb +57 -0
- data/lib/generators/test_unit/templates/oauth_tokens.yml +17 -0
- data/lib/oauth-plugin.rb +24 -0
- data/lib/oauth-plugin/version.rb +5 -0
- data/lib/oauth/controllers/application_controller_methods.rb +140 -0
- data/lib/oauth/controllers/consumer_controller.rb +153 -0
- data/lib/oauth/controllers/provider_controller.rb +181 -0
- data/lib/oauth/models/consumers/service_loader.rb +28 -0
- data/lib/oauth/models/consumers/services/agree2_token.rb +15 -0
- data/lib/oauth/models/consumers/services/fireeagle_token.rb +39 -0
- data/lib/oauth/models/consumers/services/google_token.rb +21 -0
- data/lib/oauth/models/consumers/services/oauth2_token.rb +49 -0
- data/lib/oauth/models/consumers/services/opentransact_token.rb +15 -0
- data/lib/oauth/models/consumers/services/picomoney_token.rb +17 -0
- data/lib/oauth/models/consumers/services/twitter_token.rb +24 -0
- data/lib/oauth/models/consumers/simple_client.rb +50 -0
- data/lib/oauth/models/consumers/token.rb +121 -0
- data/lib/oauth/provider/authorizer.rb +83 -0
- data/lib/oauth/rack/oauth_filter.rb +97 -0
- data/oauth-plugin.gemspec +40 -0
- data/rails/init.rb +1 -0
- data/spec/dummy_provider_models.rb +53 -0
- data/spec/oauth/provider/authorizer_spec.rb +202 -0
- data/spec/rack/oauth_filter_spec.rb +244 -0
- data/spec/spec_helper.rb +3 -0
- data/tasks/oauth_tasks.rake +4 -0
- data/uninstall.rb +1 -0
- metadata +373 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'oauth/controllers/consumer_controller'
|
|
2
|
+
|
|
3
|
+
# Goes through the entries in your OAUTH_CREDENTIALS and either loads the class required
|
|
4
|
+
# or subclasses ConsumerToken with the name.
|
|
5
|
+
#
|
|
6
|
+
# So an entry called "my_service" will create a class MyServiceToken which you can
|
|
7
|
+
# connect with has_one to your user model.
|
|
8
|
+
if defined? ConsumerToken && defined? OAUTH_CREDENTIALS
|
|
9
|
+
require File.join(File.dirname(__FILE__), 'services', 'oauth2_token')
|
|
10
|
+
|
|
11
|
+
OAUTH_CREDENTIALS.each do |key, value|
|
|
12
|
+
class_name=value[:class_name]||"#{key.to_s.classify}Token"
|
|
13
|
+
unless Object.const_defined?(class_name.to_sym)
|
|
14
|
+
if File.exists?(File.join(File.dirname(__FILE__), "services","#{key.to_s}_token.rb"))
|
|
15
|
+
Rails.logger.info File.join(File.dirname(__FILE__), "services","#{key.to_s}_token")
|
|
16
|
+
require File.join(File.dirname(__FILE__), "services","#{key.to_s}_token")
|
|
17
|
+
else
|
|
18
|
+
begin
|
|
19
|
+
# Let Rails auto-load from the models folder
|
|
20
|
+
eval class_name
|
|
21
|
+
rescue NameError
|
|
22
|
+
super_class = value[:super_class]||value[:oauth_version].to_i>=2 ? "Oauth2Token" : "ConsumerToken"
|
|
23
|
+
eval "class #{class_name} < #{super_class} ;end"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'agree2'
|
|
2
|
+
class Agree2Token < ConsumerToken
|
|
3
|
+
AGREE2_SETTINGS={:site=>"https://agree2.com"}
|
|
4
|
+
def self.consumer
|
|
5
|
+
@consumer||=OAuth::Consumer.new credentials[:key],credentials[:secret],AGREE2_SETTINGS
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def self.agree2_client
|
|
9
|
+
@agree2_client||=Agree2::Client.new credentials[:key],credentials[:secret]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def client
|
|
13
|
+
@client||=Agree2Token.agree2_client.user(token,secret)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'fireeagle'
|
|
2
|
+
# For more information on FireEagle
|
|
3
|
+
# http://fireeagle.rubyforge.org/
|
|
4
|
+
class FireeagleToken < ConsumerToken
|
|
5
|
+
FIREEAGLE_SETTINGS={
|
|
6
|
+
:site=>"https://fireeagle.yahooapis.com",
|
|
7
|
+
:authorize_url=>"https://fireeagle.yahoo.net/oauth/authorize"}
|
|
8
|
+
|
|
9
|
+
def self.consumer
|
|
10
|
+
@consumer||=OAuth::Consumer.new credentials[:key],credentials[:secret],FIREEAGLE_SETTINGS
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def client
|
|
14
|
+
@client||=FireEagle::Client.new :consumer_key => FireeagleToken.consumer.key,
|
|
15
|
+
:consumer_secret => FireeagleToken.consumer.secret,
|
|
16
|
+
:access_token => token,
|
|
17
|
+
:access_token_secret => secret
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Returns the FireEagle User object
|
|
21
|
+
# http://fireeagle.rubyforge.org/classes/FireEagle/User.html
|
|
22
|
+
def fireeagle_user
|
|
23
|
+
@fireeagle_user||=client.user
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# gives you the best guess of a location for user.
|
|
27
|
+
# This returns the FireEagle Location object:
|
|
28
|
+
# http://fireeagle.rubyforge.org/classes/FireEagle/Location.html
|
|
29
|
+
def location
|
|
30
|
+
fireeagle_user.best_guess.name
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Updates thes users location
|
|
34
|
+
# see: http://fireeagle.rubyforge.org/classes/FireEagle/Client.html#M000026
|
|
35
|
+
def update_location(location={})
|
|
36
|
+
client.update(location)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
class GoogleToken < ConsumerToken
|
|
2
|
+
GOOGLE_SETTINGS={
|
|
3
|
+
:site=>"https://www.google.com",
|
|
4
|
+
:request_token_path => "/accounts/OAuthGetRequestToken",
|
|
5
|
+
:authorize_path => "/accounts/OAuthAuthorizeToken",
|
|
6
|
+
:access_token_path => "/accounts/OAuthGetAccessToken",
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
def self.consumer
|
|
10
|
+
@consumer||=create_consumer
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.create_consumer(options={})
|
|
14
|
+
OAuth::Consumer.new credentials[:key],credentials[:secret],GOOGLE_SETTINGS.merge(options)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.get_request_token(callback_url, scope=nil)
|
|
18
|
+
consumer.get_request_token({:oauth_callback=>callback_url}, :scope=>scope||credentials[:scope]||"http://www-opensocial.googleusercontent.com/api/people")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'oauth2'
|
|
2
|
+
class Oauth2Token < ConsumerToken
|
|
3
|
+
after_initialize :ensure_access, if: :expired_and_existing?
|
|
4
|
+
|
|
5
|
+
def self.consumer
|
|
6
|
+
@consumer||=create_consumer
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.create_consumer(options={})
|
|
10
|
+
@consumer||=OAuth2::Client.new credentials[:key],credentials[:secret],credentials[:options]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.authorize_url(callback_url)
|
|
14
|
+
options = {:redirect_uri=>callback_url}
|
|
15
|
+
options[:scope] = credentials[:scope] if credentials[:scope].present?
|
|
16
|
+
consumer.auth_code.authorize_url(options)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.access_token(user, code, redirect_uri)
|
|
20
|
+
access_token = consumer.auth_code.get_token(code, :redirect_uri => redirect_uri)
|
|
21
|
+
find_or_create_from_access_token user, access_token
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def client
|
|
25
|
+
@client ||= OAuth2::AccessToken.new self.class.consumer, token, {refresh_token: refresh_token, expires_at: expires_at, expires_in: expires_in }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @return [Boolean] Is the access token expired and does the record exist in the datastore?
|
|
29
|
+
def expired_and_existing?
|
|
30
|
+
return true if !self.new_record? and Time.now.to_i >= self.expires_at.to_i
|
|
31
|
+
false
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Refreshes the access token to ensure access
|
|
35
|
+
def ensure_access
|
|
36
|
+
self.class.find_or_create_from_access_token user, self, client.refresh!
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Returns the expiration date (expires_in, expires_at)
|
|
40
|
+
#
|
|
41
|
+
# @return [String, String] Expires_in and expires_at, respectively
|
|
42
|
+
# @note It will return the default expiration time as defined in the OAuth 2.0 spec when no options are set
|
|
43
|
+
def expiration_date(token)
|
|
44
|
+
return token.expires_in, token.expires_at if !token.expires_in.nil? and !token.expires_at.nil?
|
|
45
|
+
return token.expires_in, (Time.now.to_i + token.expires_in.to_i) if token.expires_at.nil? and !token.expires_in.nil?
|
|
46
|
+
return (token.expires_at.to_i - Time.now.to_i), token.expires_at if token.expires_in.nil? and !token.expires_at.nil?
|
|
47
|
+
return "3600", (Time.now.to_i + 3600)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'opentransact'
|
|
2
|
+
class OpenTransactToken < ConsumerToken
|
|
3
|
+
|
|
4
|
+
# def self.server
|
|
5
|
+
# @consumer||=OpenTransact::Server.new credentials
|
|
6
|
+
# end
|
|
7
|
+
|
|
8
|
+
# def self.consumer
|
|
9
|
+
# @consumer||=server.consumer
|
|
10
|
+
# end
|
|
11
|
+
|
|
12
|
+
def client
|
|
13
|
+
@client ||= OpenTransact::Client.new self.class.credentials.merge( {:token=>token, :secret=>secret})
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__),'opentransact_token')
|
|
2
|
+
|
|
3
|
+
class PicomoneyToken < OpenTransactToken
|
|
4
|
+
|
|
5
|
+
def self.credentials
|
|
6
|
+
@credentials||={
|
|
7
|
+
:site=>"https://picomoney.com",
|
|
8
|
+
:consumer_key => super[:key],
|
|
9
|
+
:consumer_secret => super[:secret]
|
|
10
|
+
}.merge(super)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def about_user
|
|
14
|
+
client.get("/about_user")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class TwitterToken < ConsumerToken
|
|
2
|
+
TWITTER_SETTINGS={
|
|
3
|
+
:site => "https://api.twitter.com",
|
|
4
|
+
:request_token_path => "/oauth/request_token",
|
|
5
|
+
:authorize_path => "/oauth/authorize",
|
|
6
|
+
:access_token_path => "/oauth/access_token",
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
def self.consumer(options={})
|
|
10
|
+
@consumer ||= OAuth::Consumer.new(credentials[:key], credentials[:secret], TWITTER_SETTINGS.merge(options))
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def client
|
|
14
|
+
@client ||= begin
|
|
15
|
+
if self.class.credentials[:client].to_sym == :oauth_gem
|
|
16
|
+
super
|
|
17
|
+
else
|
|
18
|
+
require 'twitter'
|
|
19
|
+
Twitter::Client.new(:consumer_key => self.class.consumer.key, :consumer_secret => self.class.consumer.secret)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
module Oauth
|
|
3
|
+
module Models
|
|
4
|
+
module Consumers
|
|
5
|
+
# This is just a simple
|
|
6
|
+
class SimpleClient
|
|
7
|
+
attr_reader :token
|
|
8
|
+
|
|
9
|
+
def initialize(token)
|
|
10
|
+
@token = token
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def put(path,params={})
|
|
15
|
+
parse(token.put(path,params, {'Accept' => 'application/json'}))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def delete(path)
|
|
19
|
+
parse(token.delete(path, {'Accept' => 'application/json'}))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def post(path,params={})
|
|
23
|
+
parse(token.post(path,params, {'Accept' => 'application/json'}))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def get(path)
|
|
27
|
+
parse(token.get(path, {'Accept' => 'application/json'}))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
protected
|
|
31
|
+
|
|
32
|
+
def parse(response)
|
|
33
|
+
return false unless response
|
|
34
|
+
if ["200","201"].include? response.code
|
|
35
|
+
unless response.body.blank?
|
|
36
|
+
JSON.parse(response.body)
|
|
37
|
+
else
|
|
38
|
+
true
|
|
39
|
+
end
|
|
40
|
+
else
|
|
41
|
+
logger.debug "Got Response code: #{response.code}"
|
|
42
|
+
false
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
require 'oauth/consumer'
|
|
2
|
+
require File.join(File.dirname(__FILE__), 'simple_client')
|
|
3
|
+
|
|
4
|
+
module Oauth
|
|
5
|
+
module Models
|
|
6
|
+
module Consumers
|
|
7
|
+
module Token
|
|
8
|
+
def self.included(model)
|
|
9
|
+
model.class_eval do
|
|
10
|
+
validates_presence_of :user, :token
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
model.send(:include, InstanceMethods)
|
|
14
|
+
model.send(:extend, ClassMethods)
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
module ClassMethods
|
|
19
|
+
|
|
20
|
+
def service_name
|
|
21
|
+
@service_name||=self.to_s.underscore.scan(/^(.*?)(_token)?$/)[0][0].to_sym
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def consumer
|
|
25
|
+
options = credentials[:options] || {}
|
|
26
|
+
@consumer||=OAuth::Consumer.new credentials[:key],credentials[:secret],options
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def get_request_token(callback_url)
|
|
30
|
+
consumer.get_request_token(:oauth_callback=>callback_url)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def find_or_create_from_request_token(user,token,secret,oauth_verifier)
|
|
34
|
+
request_token=OAuth::RequestToken.new consumer,token,secret
|
|
35
|
+
options={}
|
|
36
|
+
options[:oauth_verifier]=oauth_verifier if oauth_verifier
|
|
37
|
+
access_token=request_token.get_access_token options
|
|
38
|
+
find_or_create_from_access_token user, access_token
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Finds, creates or updates a ConsumerToken by finding the token
|
|
42
|
+
# or taking it when it's given. It then updates the attributes and saves the changes/new record to a datastore.
|
|
43
|
+
# @param user [User] The user to which the access token should belong to
|
|
44
|
+
# @param access_token [AccessToken || Oauth2Token] Either a request token taken from the service or a ConsumerToken
|
|
45
|
+
# @param new_token [AccessToken] A new access token, used for refreshing the access token with OAuth 2.
|
|
46
|
+
#
|
|
47
|
+
# Usage example:
|
|
48
|
+
# find_or_create_from_access_token(current_user, access_token) <-- Find or create a new access token
|
|
49
|
+
# find_or_create_from_access-token(current_user, Oauth2Token.last, client.refresh!) <-- Edits existing record with new refreshed information
|
|
50
|
+
def find_or_create_from_access_token(user, access_token, new_token = nil)
|
|
51
|
+
if access_token.class.ancestors.include?(Oauth2Token)
|
|
52
|
+
token = access_token
|
|
53
|
+
else
|
|
54
|
+
if user
|
|
55
|
+
token = self.find_or_initialize_by(user_id: user.id, token: access_token.token)
|
|
56
|
+
else
|
|
57
|
+
token = self.find_or_initialize_by(token: access_token.token)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
token = if new_token then set_details(new_token, access_token) else set_details(access_token, token) end
|
|
62
|
+
|
|
63
|
+
token.save! if token.new_record? or token.changed?
|
|
64
|
+
|
|
65
|
+
token
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Set the details such as the secret, refresh token and expiration time to an instance of ConsumerToken
|
|
69
|
+
# @return [ConsumerToken] A ConsumerToken
|
|
70
|
+
def set_details(access_token, token)
|
|
71
|
+
secret = access_token.respond_to?(:secret) ? access_token.secret : nil
|
|
72
|
+
refresh_token = access_token.respond_to?(:refresh_token) ? access_token.refresh_token : nil
|
|
73
|
+
expires_in, expires_at = token.expiration_date(access_token) if token.class.ancestors.include?(Oauth2Token)
|
|
74
|
+
|
|
75
|
+
token.token = access_token.token
|
|
76
|
+
token.refresh_token = refresh_token
|
|
77
|
+
token.secret = secret
|
|
78
|
+
token.expires_at = expires_at
|
|
79
|
+
token.expires_in = expires_in
|
|
80
|
+
|
|
81
|
+
token
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def build_user_from_token
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def credentials
|
|
88
|
+
@credentials||=OAUTH_CREDENTIALS[service_name]
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
module InstanceMethods
|
|
94
|
+
|
|
95
|
+
# Main client for interfacing with remote service. Override this to use
|
|
96
|
+
# preexisting library eg. Twitter gem.
|
|
97
|
+
def client
|
|
98
|
+
@client||=OAuth::AccessToken.new self.class.consumer,token,secret
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def simple_client
|
|
102
|
+
@simple_client||=SimpleClient.new client
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Override this to return user data from service
|
|
106
|
+
def params_for_user
|
|
107
|
+
{}
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def create_user
|
|
111
|
+
self.user ||= begin
|
|
112
|
+
User.new params_for_user
|
|
113
|
+
user.save(:validate=>false)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require 'uri'
|
|
2
|
+
|
|
3
|
+
module OAuth
|
|
4
|
+
module Provider
|
|
5
|
+
class Authorizer
|
|
6
|
+
attr_accessor :user, :params, :app
|
|
7
|
+
|
|
8
|
+
def initialize(user, authorized, params = {})
|
|
9
|
+
@user = user
|
|
10
|
+
@params = params
|
|
11
|
+
@authorized = authorized
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def app
|
|
15
|
+
@app ||= ::ClientApplication.find_by_key!(params[:client_id])
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def code
|
|
19
|
+
@code ||= ::Oauth2Verifier.create! :client_application => app,
|
|
20
|
+
:user => @user,
|
|
21
|
+
:scope => @params[:scope],
|
|
22
|
+
:callback_url => @params[:redirect_uri]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def token
|
|
26
|
+
@token ||= ::Oauth2Token.create! :client_application => app,
|
|
27
|
+
:user => @user,
|
|
28
|
+
:scope => @params[:scope],
|
|
29
|
+
:callback_url => @params[:redirect_uri]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def authorized?
|
|
33
|
+
@authorized == true
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def redirect_uri
|
|
37
|
+
uri = base_uri
|
|
38
|
+
if params[:response_type] == 'code'
|
|
39
|
+
if uri.query
|
|
40
|
+
uri.query << '&'
|
|
41
|
+
else
|
|
42
|
+
uri.query = ''
|
|
43
|
+
end
|
|
44
|
+
uri.query << encode_response
|
|
45
|
+
else
|
|
46
|
+
uri.fragment = encode_response
|
|
47
|
+
end
|
|
48
|
+
uri.to_s
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def response
|
|
52
|
+
r = {}
|
|
53
|
+
if ['token','code'].include? params[:response_type]
|
|
54
|
+
if authorized?
|
|
55
|
+
if params[:response_type] == 'code'
|
|
56
|
+
r[:code] = code.token
|
|
57
|
+
else
|
|
58
|
+
r[:access_token] = token.token
|
|
59
|
+
end
|
|
60
|
+
else
|
|
61
|
+
r[:error] = 'access_denied'
|
|
62
|
+
end
|
|
63
|
+
else
|
|
64
|
+
r[:error] = 'unsupported_response_type'
|
|
65
|
+
end
|
|
66
|
+
r[:state] = params[:state] if params[:state]
|
|
67
|
+
r
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def encode_response
|
|
71
|
+
response.map do |k, v|
|
|
72
|
+
[URI.escape(k.to_s),URI.escape(v)] * "="
|
|
73
|
+
end * "&"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
protected
|
|
77
|
+
|
|
78
|
+
def base_uri
|
|
79
|
+
URI.parse(params[:redirect_uri] || app.callback_url)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|