passport 0.0.1 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +183 -1
- data/Rakefile +17 -17
- data/VERSION +1 -0
- data/lib/passport.rb +14 -30
- data/lib/passport/core/certification.rb +47 -0
- data/lib/passport/core/context.rb +74 -0
- data/lib/passport/core/installation.rb +40 -0
- data/lib/passport/core/settings.rb +75 -0
- data/lib/passport/core/state.rb +37 -0
- data/lib/passport/core/user.rb +63 -0
- data/lib/passport/engine.rb +15 -0
- data/lib/passport/helpers/core.rb +85 -0
- data/lib/passport/helpers/filter.rb +28 -0
- data/lib/passport/helpers/mixin.rb +15 -0
- data/lib/passport/helpers/rack-context.rb +72 -0
- data/lib/passport/oauth.rb +8 -0
- data/lib/passport/oauth/client/authorizable.rb +84 -0
- data/lib/passport/oauth/client/consumable.rb +47 -0
- data/lib/passport/oauth/client/defineable.rb +82 -0
- data/lib/passport/oauth/client/queryable.rb +23 -0
- data/lib/passport/oauth/client/restful.rb +36 -0
- data/lib/passport/oauth/helper.rb +18 -0
- data/lib/passport/oauth/oauth_token.rb +10 -0
- data/lib/passport/oauth/protocol.rb +12 -0
- data/lib/passport/oauth/protocol/context.rb +71 -0
- data/lib/passport/oauth/protocol/process.rb +59 -0
- data/lib/passport/oauth/protocol/record.rb +42 -0
- data/lib/passport/oauth/protocol/state.rb +46 -0
- data/lib/passport/oauth/tokens/agent_storm_token.rb +12 -0
- data/lib/passport/oauth/tokens/audio_box_token.rb +11 -0
- data/lib/passport/oauth/tokens/brightkite_token.rb +11 -0
- data/lib/passport/oauth/tokens/cliqset_token.rb +13 -0
- data/lib/passport/oauth/tokens/digg_token.rb +9 -0
- data/lib/passport/oauth/tokens/e_trade_token.rb +8 -0
- data/lib/passport/oauth/tokens/evernote_token.rb +10 -0
- data/lib/passport/oauth/tokens/expono_token.rb +10 -0
- data/lib/passport/oauth/tokens/facebook_token.rb +16 -0
- data/lib/passport/oauth/tokens/fat_secret_token.rb +6 -0
- data/lib/passport/oauth/tokens/foursquare_token.rb +14 -0
- data/lib/passport/oauth/tokens/freebase_token.rb +9 -0
- data/lib/passport/oauth/tokens/freshbooks_token.rb +12 -0
- data/lib/passport/oauth/tokens/friendfeed_oauth.rb +7 -0
- data/lib/passport/oauth/tokens/get_satisfaction_token.rb +9 -0
- data/lib/passport/oauth/tokens/github_token.rb +15 -0
- data/lib/passport/oauth/tokens/gliffy_token.rb +6 -0
- data/lib/passport/oauth/tokens/google_token.rb +41 -0
- data/lib/passport/oauth/tokens/gowalla_token.rb +12 -0
- data/lib/passport/oauth/tokens/launchpad_token.rb +7 -0
- data/lib/passport/oauth/tokens/linked_in_token.rb +19 -0
- data/lib/passport/oauth/tokens/live_work_token.rb +6 -0
- data/lib/passport/oauth/tokens/meetup_token.rb +12 -0
- data/lib/passport/oauth/tokens/mendeley_token.rb +7 -0
- data/lib/passport/oauth/tokens/myspace_token.rb +26 -0
- data/lib/passport/oauth/tokens/netflix_token.rb +10 -0
- data/lib/passport/oauth/tokens/ohloh_token.rb +9 -0
- data/lib/passport/oauth/tokens/photobucket_token.rb +11 -0
- data/lib/passport/oauth/tokens/plaxo_token.rb +3 -0
- data/lib/passport/oauth/tokens/praized_token.rb +6 -0
- data/lib/passport/oauth/tokens/remix_token.rb +6 -0
- data/lib/passport/oauth/tokens/salesforce_token.rb +9 -0
- data/lib/passport/oauth/tokens/simple_geo_token.rb +8 -0
- data/lib/passport/oauth/tokens/smug_mug_token.rb +12 -0
- data/lib/passport/oauth/tokens/soundcloud_token.rb +10 -0
- data/lib/passport/oauth/tokens/tribe_token.rb +9 -0
- data/lib/passport/oauth/tokens/trip_it_token.rb +6 -0
- data/lib/passport/oauth/tokens/twitter_token.rb +8 -0
- data/lib/passport/oauth/tokens/vimeo_token.rb +18 -0
- data/lib/passport/oauth/tokens/we_pay_token.rb +8 -0
- data/lib/passport/oauth/tokens/xero_token.rb +8 -0
- data/lib/passport/oauth/tokens/yahoo_token.rb +19 -0
- data/lib/passport/oauth/tokens/yammer_token.rb +10 -0
- data/lib/{open_id_authentication.rb → passport/openid/protocol.rb} +1 -1
- data/lib/passport/openid/tokens/aol_token.rb +0 -0
- data/lib/passport/openid/tokens/blogger_token.rb +0 -0
- data/lib/passport/openid/tokens/flickr_token.rb +0 -0
- data/lib/passport/openid/tokens/my_openid_token.rb +3 -0
- data/lib/passport/openid/tokens/openid_token.rb +9 -0
- data/lib/passport/passport.rb +23 -0
- data/lib/passport/support/active_record.rb +5 -0
- data/lib/passport/support/mongo.rb +9 -0
- data/lib/passport/support/object.rb +13 -0
- data/rails/init.rb +2 -2
- data/test/config.yml +55 -0
- data/test/config/tokens.yml +56 -0
- data/test/dummy/app.rb +50 -0
- data/test/dummy/database.rb +30 -0
- data/test/dummy/stubs.rb +20 -0
- data/test/dummy/user.rb +3 -0
- data/test/test_helper.rb +53 -0
- data/test/test_oauth.rb +250 -0
- data/test/test_passport.rb +23 -0
- metadata +105 -34
@@ -0,0 +1,75 @@
|
|
1
|
+
module Passport
|
2
|
+
class SettingsError < StandardError; end
|
3
|
+
|
4
|
+
module Settings
|
5
|
+
def self.included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
KEY = "services" unless defined?(KEY)
|
11
|
+
|
12
|
+
attr_accessor :config, :adapter, :root
|
13
|
+
|
14
|
+
def configure(value)
|
15
|
+
self.config = (value.is_a?(String) ? YAML.load_file(value) : value).recursively_symbolize_keys!
|
16
|
+
if self.config.has_key?(:connect)
|
17
|
+
self.config[:services] = self.config.delete(:connect)
|
18
|
+
puts "[Deprecation] change 'connect' to 'services' in Passport configuration"
|
19
|
+
end
|
20
|
+
self.config[:adapter] ||= "object"
|
21
|
+
self.adapter = config[:adapter]
|
22
|
+
|
23
|
+
install
|
24
|
+
|
25
|
+
self.config
|
26
|
+
end
|
27
|
+
|
28
|
+
def adapter=(string)
|
29
|
+
valid_adapters = %w(object active_record mongo)
|
30
|
+
unless valid_adapters.include?(string)
|
31
|
+
raise SettingsError.new("Adapter can only be 'object', 'active_record', or 'mongo'")
|
32
|
+
end
|
33
|
+
@adapter = string
|
34
|
+
end
|
35
|
+
|
36
|
+
def key(path)
|
37
|
+
result = self.config
|
38
|
+
path.to_s.split(".").each { |node| result = result[node.to_sym] if result }
|
39
|
+
result
|
40
|
+
end
|
41
|
+
|
42
|
+
def credentials(service)
|
43
|
+
result = key("#{KEY}.#{service.to_s}")
|
44
|
+
unless result && result.has_key?(:key) && result.has_key?(:secret)
|
45
|
+
raise SettingsError.new("Please specify both a key and secret for ':#{service}'")
|
46
|
+
end
|
47
|
+
result
|
48
|
+
end
|
49
|
+
|
50
|
+
def services
|
51
|
+
key(KEY)
|
52
|
+
end
|
53
|
+
|
54
|
+
def service_names
|
55
|
+
services.keys.collect(&:to_s)
|
56
|
+
end
|
57
|
+
|
58
|
+
def include?(service)
|
59
|
+
!credentials(service).nil?
|
60
|
+
end
|
61
|
+
|
62
|
+
def token(key, throw_error = true)
|
63
|
+
unless Passport.include?(key) and !key.to_s.empty?
|
64
|
+
raise SettingsError.new("can't find key '#{key.to_s}' in Passport.config" ) if throw_error
|
65
|
+
else
|
66
|
+
"#{key.to_s.camelcase}Token".constantize
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def consumer(key)
|
71
|
+
token(key).consumer
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Passport
|
2
|
+
module State
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def key?(key)
|
9
|
+
Rack::Context.key?(key)
|
10
|
+
end
|
11
|
+
|
12
|
+
def session_key?(key)
|
13
|
+
Rack::Context.session_key?(key)
|
14
|
+
end
|
15
|
+
|
16
|
+
def params_key?(key)
|
17
|
+
Rack::Context.params_key?(key)
|
18
|
+
end
|
19
|
+
|
20
|
+
def params?
|
21
|
+
!params.blank?
|
22
|
+
end
|
23
|
+
|
24
|
+
def session?
|
25
|
+
!session.blank?
|
26
|
+
end
|
27
|
+
|
28
|
+
def active?
|
29
|
+
Passport::Oauth::Protocol.active? || Passport::Oauth::Protocol.active?
|
30
|
+
end
|
31
|
+
|
32
|
+
def authenticating?(type)
|
33
|
+
authentication_type == type.to_s
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Passport
|
2
|
+
module User
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.validate :validate_passport, :if => lambda { Passport.authenticating?(:user) }
|
6
|
+
base.send :include, InstanceMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module InstanceMethods
|
10
|
+
|
11
|
+
def self.included(base)
|
12
|
+
base.class_eval do
|
13
|
+
has_many :access_tokens, :as => :user, :class_name => "AccessToken", :dependent => :destroy
|
14
|
+
accepts_nested_attributes_for :access_tokens
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def save(options = {}, &block)
|
19
|
+
block = nil if block_given? && Passport.process?
|
20
|
+
options[:validate] = true unless options.has_key?(:validate)
|
21
|
+
result = super(options, &block)
|
22
|
+
yield(result) unless block.nil?
|
23
|
+
result
|
24
|
+
end
|
25
|
+
|
26
|
+
def validate_passport
|
27
|
+
Passport.authenticate(self) do |token|
|
28
|
+
if token
|
29
|
+
access_tokens << token
|
30
|
+
else
|
31
|
+
errors.add("Passport validation error")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def update_attributes(attributes, &block)
|
37
|
+
self.attributes = attributes
|
38
|
+
save(:validate => true, &block)
|
39
|
+
end
|
40
|
+
|
41
|
+
def access_token(service)
|
42
|
+
self.access_tokens.detect { |token| token.service == service.to_s }
|
43
|
+
end
|
44
|
+
|
45
|
+
def access_token?(service)
|
46
|
+
access_token(service).blank?
|
47
|
+
end
|
48
|
+
|
49
|
+
# user.facebook_token
|
50
|
+
# user.facebook_token?
|
51
|
+
def method_missing(meth, *args, &block)
|
52
|
+
if meth.to_s =~ /(\w+)_token(\?)?/
|
53
|
+
service = $1
|
54
|
+
return access_token?(service) unless $2.blank?
|
55
|
+
return access_token(service)
|
56
|
+
end
|
57
|
+
|
58
|
+
super(meth, *args, &block)
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Passport
|
2
|
+
class Engine < Rails::Engine
|
3
|
+
|
4
|
+
initializer "passport.authentication_hook" do |app|
|
5
|
+
app.middleware.use Rack::Context
|
6
|
+
app.middleware.use Passport::Filter
|
7
|
+
app.middleware.use OpenIdAuthentication
|
8
|
+
end
|
9
|
+
|
10
|
+
initializer "passport.finalize", :after => "passport.authentication_hook" do |app|
|
11
|
+
OpenID::Util.logger = Rails.logger
|
12
|
+
ActionController::Base.send :include, OpenIdAuthentication
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# these are extensions I've found useful for this project
|
2
|
+
class String
|
3
|
+
# normalizes an OpenID according to http://openid.net/specs/openid-authentication-2_0.html#normalization
|
4
|
+
def normalize_identifier
|
5
|
+
# clean up whitespace
|
6
|
+
identifier = self.dup.strip
|
7
|
+
|
8
|
+
# if an XRI has a prefix, strip it.
|
9
|
+
identifier.gsub!(/xri:\/\//i, '')
|
10
|
+
|
11
|
+
# dodge XRIs -- TODO: validate, don't just skip.
|
12
|
+
unless ['=', '@', '+', '$', '!', '('].include?(identifier.at(0))
|
13
|
+
# does it begin with http? if not, add it.
|
14
|
+
identifier = "http://#{identifier}" unless identifier =~ /^http/i
|
15
|
+
|
16
|
+
# strip any fragments
|
17
|
+
identifier.gsub!(/\#(.*)$/, '')
|
18
|
+
|
19
|
+
begin
|
20
|
+
uri = URI.parse(identifier)
|
21
|
+
uri.scheme = uri.scheme.downcase # URI should do this
|
22
|
+
identifier = uri.normalize.to_s
|
23
|
+
rescue URI::InvalidURIError
|
24
|
+
raise InvalidOpenId.new("#{identifier} is not an OpenID identifier")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
return identifier
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Hash
|
33
|
+
def recursively_symbolize_keys!
|
34
|
+
self.symbolize_keys!
|
35
|
+
self.values.each do |v|
|
36
|
+
if v.is_a? Hash
|
37
|
+
v.recursively_symbolize_keys!
|
38
|
+
elsif v.is_a? Array
|
39
|
+
v.recursively_symbolize_keys!
|
40
|
+
end
|
41
|
+
end
|
42
|
+
self
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Array
|
47
|
+
def recursively_symbolize_keys!
|
48
|
+
self.each do |item|
|
49
|
+
if item.is_a? Hash
|
50
|
+
item.recursively_symbolize_keys!
|
51
|
+
elsif item.is_a? Array
|
52
|
+
item.recursively_symbolize_keys!
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
if defined?(ActionController::Base)
|
59
|
+
ActionController::Base.class_eval do
|
60
|
+
prepend_before_filter :set_rails_context
|
61
|
+
|
62
|
+
def set_rails_context
|
63
|
+
Thread.current[:rails_context] = self
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Rails 3beta4 backport
|
69
|
+
if defined?(ActiveSupport::HashWithIndifferentAccess)
|
70
|
+
ActiveSupport::HashWithIndifferentAccess.class_eval do
|
71
|
+
unless respond_to?(:symbolize_keys!)
|
72
|
+
def symbolize_keys!
|
73
|
+
symbolize_keys
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
Object.class_eval do
|
80
|
+
unless respond_to?(:symbolize_keys!)
|
81
|
+
def symbolize_keys!
|
82
|
+
symbolize_keys
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# http://github.com/manveru/innate/blob/master/lib/innate/current.rb
|
2
|
+
module Passport
|
3
|
+
class Filter
|
4
|
+
METHODS = %w(get head put post delete options)
|
5
|
+
|
6
|
+
def initialize(app)
|
7
|
+
@app = app
|
8
|
+
end
|
9
|
+
|
10
|
+
# this intercepts how the browser interprets the url.
|
11
|
+
# so we override it and say,
|
12
|
+
# "if we've stored a variable in the session called :auth_callback_method,
|
13
|
+
# then convert that into a POST call so we re-call the original method"
|
14
|
+
def call(env)
|
15
|
+
if env["rack.session"].nil?
|
16
|
+
raise "Make sure you are setting the session in Rack too! Place this in config/application.rb"
|
17
|
+
end
|
18
|
+
|
19
|
+
unless env["rack.session"][:auth_callback_method].blank?
|
20
|
+
method = env["rack.session"].delete(:auth_callback_method).to_s.downcase
|
21
|
+
method = "get" unless METHODS.include?(method)
|
22
|
+
env["REQUEST_METHOD"] = method.upcase
|
23
|
+
end
|
24
|
+
|
25
|
+
@app.call(env)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Passport
|
2
|
+
module Mixin
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def has_passport
|
9
|
+
include Passport::User
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
ActiveRecord::Base.send(:include, Passport::Mixin) if defined?(ActiveRecord::Base)
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Rack
|
2
|
+
class Context
|
3
|
+
def initialize(app)
|
4
|
+
@app = app
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
Thread.current[:rack_context] = Rack::Request.new(env)
|
9
|
+
@app.call(env)
|
10
|
+
end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def request
|
14
|
+
Thread.current[:rack_context]
|
15
|
+
end
|
16
|
+
|
17
|
+
def session
|
18
|
+
request.nil? ? nil : request.session
|
19
|
+
end
|
20
|
+
|
21
|
+
def params
|
22
|
+
request.nil? ? nil : request.params
|
23
|
+
end
|
24
|
+
|
25
|
+
def env
|
26
|
+
request.nil? ? nil : request.env
|
27
|
+
end
|
28
|
+
|
29
|
+
def find(key)
|
30
|
+
params_key(key) || session_key(key)
|
31
|
+
end
|
32
|
+
|
33
|
+
def key?(key)
|
34
|
+
!find(key).blank?
|
35
|
+
end
|
36
|
+
|
37
|
+
def session_key(key)
|
38
|
+
return nil if session.blank?
|
39
|
+
string = key.to_s
|
40
|
+
symbol = key.to_sym
|
41
|
+
return session[string] unless session[string].blank?
|
42
|
+
return session[symbol] unless session[symbol].blank?
|
43
|
+
end
|
44
|
+
|
45
|
+
def session_key?(key)
|
46
|
+
!session_key(key).blank?
|
47
|
+
end
|
48
|
+
|
49
|
+
def params_key(key)
|
50
|
+
return nil if params.blank?
|
51
|
+
string = key.to_s
|
52
|
+
symbol = key.to_sym
|
53
|
+
return params[string] unless params[string].blank?
|
54
|
+
return params[symbol] unless params[symbol].blank?
|
55
|
+
end
|
56
|
+
|
57
|
+
def params_key?(key)
|
58
|
+
!params_key(key).blank?
|
59
|
+
end
|
60
|
+
|
61
|
+
def find_pair(attribute)
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
def delete_session_key(key)
|
66
|
+
return if session.blank?
|
67
|
+
keys = key.is_a?(Symbol) ? [key, key.to_s] : [key, key.to_sym]
|
68
|
+
keys.each { |k| session.delete(k) }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
this = File.expand_path(File.dirname(__FILE__)) + '/oauth'
|
2
|
+
requirements = Dir["#{this}/client/*"] + Dir["#{this}/protocol/*"]
|
3
|
+
requirements += ["#{this}/oauth_token", "#{this}/protocol", "#{this}/helper"]
|
4
|
+
requirements += Dir["#{this}/tokens/*"]
|
5
|
+
|
6
|
+
requirements.each do |file|
|
7
|
+
require file
|
8
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Passport
|
2
|
+
module Oauth
|
3
|
+
module Authorizable
|
4
|
+
def self.included(base)
|
5
|
+
base.extend ClassMethods
|
6
|
+
base.send :include, InstanceMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
# first part in the sequece.
|
11
|
+
# returns a <Hash>:
|
12
|
+
# {:url => "x", :token => "y", :secret => "z"}
|
13
|
+
# if it's using Oauth 1.0, token and secret will be present.
|
14
|
+
# if it's using Oauth 2.0, token and secret are not present.
|
15
|
+
# for Oauth 1.0, save the token/secret in the session to use
|
16
|
+
# after the redirect.
|
17
|
+
def authorize(callback_url, options = {})
|
18
|
+
result = {}
|
19
|
+
|
20
|
+
if version == 1.0
|
21
|
+
options.reverse_merge!(:scope => consumer_settings[:scope]) if consumer_settings[:scope]
|
22
|
+
request = consumer.get_request_token({:oauth_callback => callback_url}, options)
|
23
|
+
result[:token] = request.token
|
24
|
+
result[:secret] = request.secret
|
25
|
+
result[:url] = request.authorize_url
|
26
|
+
else
|
27
|
+
options.merge!(:redirect_uri => callback_url)
|
28
|
+
result[:url] = consumer.web_server.authorize_url(options)
|
29
|
+
end
|
30
|
+
|
31
|
+
result
|
32
|
+
end
|
33
|
+
|
34
|
+
# get the access token
|
35
|
+
def access(options)
|
36
|
+
if version == 1.0
|
37
|
+
access_token = OAuth::RequestToken.new(consumer, options[:token], options[:secret]).get_access_token(:oauth_verifier => options[:oauth_verifier])
|
38
|
+
result = {:token => access_token.token.to_s, :secret => access_token.secret.to_s}
|
39
|
+
else
|
40
|
+
access_token = consumer.web_server.get_access_token(options[:secret], :redirect_uri => options[:callback_url])
|
41
|
+
result = {:token => access_token.token.to_s, :secret => options[:secret].to_s}
|
42
|
+
end
|
43
|
+
|
44
|
+
result[:key] = identify(access_token) unless options[:identify] == false
|
45
|
+
|
46
|
+
result
|
47
|
+
end
|
48
|
+
|
49
|
+
def credentials
|
50
|
+
@credentials ||= Passport.credentials(service)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
module InstanceMethods
|
55
|
+
# key is a way to 100% uniquely identify a user, even if token or secret change
|
56
|
+
# "token" passed from provider
|
57
|
+
# oauth "secret" passed from provider
|
58
|
+
|
59
|
+
attr_accessor :authorize_url
|
60
|
+
|
61
|
+
def authorize(callback_url, options = {})
|
62
|
+
hash = self.class.authorize(callback_url, options)
|
63
|
+
self.authorize_url = hash[:url]
|
64
|
+
self.token = hash[:token]
|
65
|
+
self.secret = hash[:secret]
|
66
|
+
hash
|
67
|
+
end
|
68
|
+
|
69
|
+
def access(options)
|
70
|
+
options = {:token => self.token, :secret => self.secret}.merge(options)
|
71
|
+
hash = self.class.access(options)
|
72
|
+
self.key = hash[:key]
|
73
|
+
self.token = hash[:token]
|
74
|
+
self.secret = hash[:secret]
|
75
|
+
hash
|
76
|
+
end
|
77
|
+
|
78
|
+
def credentials
|
79
|
+
self.class.credentials
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|