oauth-plugin 0.4.0.pre4 → 0.4.0.pre5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/.gitignore +2 -0
  2. data/CHANGELOG +11 -0
  3. data/Gemfile.lock +66 -0
  4. data/Guardfile +8 -0
  5. data/README.rdoc +50 -4
  6. data/generators/oauth_consumer/templates/controller.rb +8 -0
  7. data/generators/oauth_consumer/templates/oauth_config.rb +23 -1
  8. data/generators/oauth_provider/oauth_provider_generator.rb +0 -4
  9. data/generators/oauth_provider/templates/oauth2_authorize.html.erb +2 -2
  10. data/generators/oauth_provider/templates/oauth2_authorize.html.haml +1 -1
  11. data/generators/oauth_provider/templates/request_token.rb +2 -2
  12. data/lib/generators/active_record/oauth_provider_templates/request_token.rb +2 -2
  13. data/lib/generators/erb/oauth_provider_templates/oauth2_authorize.html.erb +1 -1
  14. data/lib/generators/haml/oauth_provider_templates/oauth2_authorize.html.haml +1 -1
  15. data/lib/generators/mongoid/oauth_consumer_templates/consumer_token.rb +10 -8
  16. data/lib/generators/mongoid/oauth_provider_templates/request_token.rb +2 -2
  17. data/lib/generators/oauth_consumer/oauth_consumer_generator.rb +5 -1
  18. data/lib/generators/oauth_consumer/templates/controller.rb +9 -0
  19. data/lib/generators/oauth_consumer/templates/oauth_config.rb +21 -0
  20. data/lib/generators/rspec/oauth_provider_generator.rb +0 -4
  21. data/lib/generators/test_unit/oauth_provider_generator.rb +0 -4
  22. data/lib/oauth-plugin/version.rb +1 -1
  23. data/lib/oauth/controllers/application_controller_methods.rb +24 -127
  24. data/lib/oauth/controllers/consumer_controller.rb +60 -8
  25. data/lib/oauth/controllers/provider_controller.rb +4 -7
  26. data/lib/oauth/models/consumers/service_loader.rb +3 -1
  27. data/lib/oauth/models/consumers/services/google_token.rb +7 -13
  28. data/lib/oauth/models/consumers/services/oauth2_token.rb +27 -0
  29. data/lib/oauth/models/consumers/services/twitter_token.rb +18 -11
  30. data/lib/oauth/models/consumers/token.rb +10 -6
  31. data/lib/oauth/rack/oauth_filter.rb +57 -12
  32. data/oauth-plugin.gemspec +11 -3
  33. data/spec/rack/oauth_filter_spec.rb +136 -0
  34. data/spec/spec_helper.rb +3 -0
  35. metadata +105 -38
  36. data/generators/oauth_provider/templates/controller_spec.rb +0 -838
  37. data/generators/oauth_provider/templates/controller_spec_helper.rb +0 -66
  38. data/generators/oauth_provider/templates/controller_test.rb +0 -310
  39. data/generators/oauth_provider/templates/controller_test_helper.rb +0 -115
  40. data/lib/generators/rspec/templates/controller_spec.rb +0 -838
  41. data/lib/generators/rspec/templates/controller_spec_helper.rb +0 -66
  42. data/lib/generators/test_unit/templates/controller_test.rb +0 -310
  43. data/lib/generators/test_unit/templates/controller_test_helper.rb +0 -115
@@ -9,10 +9,6 @@ module Rspec
9
9
  class_option :fixture, :type => :boolean
10
10
 
11
11
  def copy_controller_spec_files
12
- template 'controller_spec_helper.rb',
13
- File.join('spec/controllers', class_path, "#{file_name}_controller_spec_helper.rb")
14
- template 'controller_spec.rb',
15
- File.join('spec/controllers', class_path, "#{file_name}_controller_spec.rb")
16
12
  template 'clients_controller_spec.rb',
17
13
  File.join('spec/controllers', class_path, "#{file_name}_clients_controller_spec.rb")
18
14
  end
@@ -9,10 +9,6 @@ module TestUnit
9
9
  class_option :fixture, :type => :boolean
10
10
 
11
11
  def copy_controller_test_files
12
- template 'controller_test_helper.rb',
13
- File.join('test', class_path, "#{file_name}_controller_test_helper.rb")
14
- template 'controller_test.rb',
15
- File.join('test/functional', class_path, "#{file_name}_controller_test.rb")
16
12
  template 'clients_controller_test.rb',
17
13
  File.join('test/functional', class_path, "#{file_name}_clients_controller_test.rb")
18
14
  end
@@ -1,5 +1,5 @@
1
1
  module Oauth
2
2
  module Plugin
3
- VERSION = "0.4.0.pre4"
3
+ VERSION = "0.4.0.pre5"
4
4
  end
5
5
  end
@@ -1,4 +1,3 @@
1
- require 'oauth/signature'
2
1
  module OAuth
3
2
  module Controllers
4
3
 
@@ -41,27 +40,11 @@ module OAuth
41
40
  @strategies = strategies
42
41
  end
43
42
 
44
- def params
45
- controller.send :params
46
- end
47
-
48
- def request
49
- controller.send :request
50
- end
51
-
52
- def env
53
- request.env
54
- end
55
-
56
- def using_rack_filter?
57
- request.env["oauth_plugin"]
58
- end
59
-
60
43
  def allow?
61
- if @strategies.any? do |strategy|
62
- @strategy = strategy.to_sym
63
- send @strategy
64
- end
44
+ if @strategies.include?(:interactive) && interactive
45
+ true
46
+ elsif !(@strategies & env["oauth.strategies"].to_a).empty?
47
+ @controller.send :current_user=, token.user if token
65
48
  true
66
49
  else
67
50
  if @strategies.include?(:interactive)
@@ -73,106 +56,43 @@ module OAuth
73
56
  end
74
57
 
75
58
  def oauth20_token
76
- return false unless defined?(Oauth2Token)
77
- token, options = token_and_options
78
- token ||= params[:oauth_token] || params[:access_token]
79
- if !token.blank?
80
- @oauth2_token = Oauth2Token.find_by_token(token)
81
- if @oauth2_token && @oauth2_token.authorized?
82
- controller.send :current_token=, @oauth2_token
83
- end
84
- end
85
- @oauth2_token!=nil
59
+ env["oauth.version"]==2 && env["oauth.token"]
86
60
  end
87
61
 
88
62
  def oauth10_token
89
- if using_rack_filter?
90
- if env["oauth.token"]
91
- @oauth_token = env["oauth.token"]
92
- controller.send :current_token=, @oauth_token
93
- true
94
- else
95
- false
96
- end
97
- else
98
- begin
99
- if ClientApplication.verify_request(request) do |request_proxy|
100
- @oauth_token = ClientApplication.find_token(request_proxy.token)
101
- if @oauth_token.respond_to?(:provided_oauth_verifier=)
102
- @oauth_token.provided_oauth_verifier=request_proxy.oauth_verifier
103
- end
104
- # return the token secret and the consumer secret
105
- [(@oauth_token.nil? ? nil : @oauth_token.secret), (@oauth_token.client_application.nil? ? nil : @oauth_token.client_application.secret)]
106
- end
107
- controller.send :current_token=, @oauth_token
108
- true
109
- else
110
- false
111
- end
112
- rescue
113
- false
114
- end
115
- end
63
+ env["oauth.version"]==1 && env["oauth.token"]
116
64
  end
117
65
 
118
66
  def oauth10_request_token
119
- oauth10_token && @oauth_token.is_a?(::RequestToken)
67
+ oauth10_token && oauth10_token.is_a?(::RequestToken) ? oauth10_token : nil
120
68
  end
121
69
 
122
70
  def oauth10_access_token
123
- oauth10_token && @oauth_token.is_a?(::AccessToken)
71
+ oauth10_token && oauth10_token.is_a?(::AccessToken) ? oauth10_token : nil
124
72
  end
125
73
 
126
74
  def token
127
- oauth20_token || oauth10_access_token
75
+ oauth20_token || oauth10_access_token || nil
128
76
  end
129
-
130
- def two_legged
131
- if using_rack_filter?
132
- if env["oauth.client_application"]
133
- @client_application = env["oauth.client_application"]
134
- controller.send :current_client_application=, @client_application
135
- end
136
- else
137
- begin
138
- if ClientApplication.verify_request(request) do |request_proxy|
139
- @client_application = ClientApplication.find_by_key(request_proxy.consumer_key)
140
77
 
141
- # Store this temporarily in client_application object for use in request token generation
142
- @client_application.token_callback_url=request_proxy.oauth_callback if request_proxy.oauth_callback
78
+ def client_application
79
+ env["oauth.version"]==1 && env["oauth.client_application"] || oauth20_token.try(:client_application)
80
+ end
143
81
 
144
- # return the token secret and the consumer secret
145
- [nil, @client_application.secret]
146
- end
147
- controller.send :current_client_application=, @client_application
148
- true
149
- else
150
- false
151
- end
152
- rescue
153
- false
154
- end
155
- end
82
+ def two_legged
83
+ env["oauth.version"]==1 && client_application
156
84
  end
157
85
 
158
86
  def interactive
159
87
  @controller.send :logged_in?
160
88
  end
161
-
162
- # Blatantly stolen from http://github.com/technoweenie/http_token_authentication
163
- # Parses the token and options out of the OAuth authorization header. If
164
- # the header looks like this:
165
- # Authorization: OAuth abc
166
- # Then the returned token is "abc", and the options is {:nonce => "def"}
167
- #
168
- # request - ActionController::Request instance with the current headers.
169
- #
170
- # Returns an Array of [String, Hash] if a token is present.
171
- # Returns nil if no token is found.
172
- def token_and_options
173
- if header = (request.respond_to?(:authorization) ? request.authorization : ActionController::HttpAuthentication::Basic.authorization(request)).to_s[/^OAuth (.*)/]
174
- [$1.strip, {}]
175
- end
89
+
90
+ def env
91
+ request.env
92
+ end
93
+
94
+ def request
95
+ controller.send :request
176
96
  end
177
97
 
178
98
  end
@@ -180,15 +100,15 @@ module OAuth
180
100
  protected
181
101
 
182
102
  def current_token
183
- @current_token
103
+ request.env["oauth.token"]
184
104
  end
185
105
 
186
106
  def current_client_application
187
- @current_client_application
107
+ request.env["oauth.version"]==1 && env["oauth.client_application"] || current_token.try(:client_application)
188
108
  end
189
109
 
190
110
  def oauth?
191
- current_token!=nil
111
+ current_token
192
112
  end
193
113
 
194
114
  # use in a before_filter. Note this is for compatibility purposes. Better to use oauthenticate now
@@ -211,29 +131,6 @@ module OAuth
211
131
  head 401
212
132
  end
213
133
 
214
- private
215
-
216
- def current_token=(token)
217
- @current_token=token
218
- if @current_token
219
- @current_user=@current_token.user
220
- @current_client_application=@current_token.client_application
221
- else
222
- @current_user = nil
223
- @current_client_application = nil
224
- end
225
- @current_token
226
- end
227
-
228
- def current_client_application=(app)
229
- if app
230
- @current_client_application = app
231
- @current_user = app.user
232
- else
233
- @current_client_application = nil
234
- @current_user = nil
235
- end
236
- end
237
134
  end
238
135
  end
239
136
  end
@@ -18,14 +18,39 @@ module Oauth
18
18
  # If user is already connected it displays a page with an option to disconnect and redo
19
19
  def show
20
20
  unless @token
21
- @request_token=@consumer.get_request_token(callback_oauth_consumer_url(params[:id]))
22
- session[@request_token.token]=@request_token.secret
23
- if @request_token.callback_confirmed?
24
- redirect_to @request_token.authorize_url
21
+ if @consumer.ancestors.include?(Oauth2Token)
22
+ request_url = callback2_oauth_consumer_url(params[:id]) + '?' + request.query_string
23
+ redirect_to @consumer.authorize_url(request_url)
25
24
  else
26
- redirect_to(@request_token.authorize_url + "&oauth_callback=#{callback_oauth_consumer_url(params[:id])}")
25
+ request_url = callback_oauth_consumer_url(params[:id]) + '?' + request.query_string
26
+ @request_token = @consumer.get_request_token(request_url)
27
+ session[@request_token.token]=@request_token.secret
28
+ if @request_token.callback_confirmed?
29
+ redirect_to @request_token.authorize_url
30
+ else
31
+ redirect_to(@request_token.authorize_url + "&oauth_callback=#{callback_oauth_consumer_url(params[:id])}")
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ def callback2
38
+ @token = @consumer.access_token(current_user,params[:code], callback2_oauth_consumer_url(params[:id]))
39
+ logger.info @token.inspect
40
+ if @token
41
+ # Log user in
42
+ if logged_in?
43
+ flash[:notice] = "#{params[:id].humanize} was successfully connected to your account"
44
+ else
45
+ self.current_user = @token.user
46
+ flash[:notice] = "You logged in with #{params[:id].humanize}"
27
47
  end
48
+ go_back
49
+ else
50
+ flash[:error] = "An error happened, please try connecting again"
51
+ redirect_to oauth_consumer_url(params[:id])
28
52
  end
53
+
29
54
  end
30
55
 
31
56
  def callback
@@ -51,6 +76,26 @@ module Oauth
51
76
 
52
77
  end
53
78
 
79
+ def client
80
+ method = request.method.downcase.to_sym
81
+ path = "/#{params[:endpoint]}?#{request.query_string}"
82
+ if consumer_credentials[:expose]
83
+ if @token
84
+ oauth_response = @token.client.send(method, path)
85
+ if oauth_response.is_a? Net::HTTPRedirection
86
+ # follow redirect
87
+ oauth_response = @token.client.send(method, oauth_response['Location'])
88
+ end
89
+
90
+ render :text => oauth_response.body
91
+ else
92
+ render :text => "Token needed.", :status => 403
93
+ end
94
+ else
95
+ render :text => "Not allowed", :status => 403
96
+ end
97
+ end
98
+
54
99
  def destroy
55
100
  throw RecordNotFound unless @token
56
101
  @token.destroy
@@ -70,10 +115,17 @@ module Oauth
70
115
  redirect_to root_url
71
116
  end
72
117
 
118
+ def consumer_credentials
119
+ OAUTH_CREDENTIALS[consumer_key]
120
+ end
121
+
122
+ def consumer_key
123
+ @consumer_key ||= params[:id].to_sym
124
+ end
125
+
73
126
  def load_consumer
74
- consumer_key=params[:id].to_sym
75
127
  throw RecordNotFound unless OAUTH_CREDENTIALS.include?(consumer_key)
76
- deny_access! unless logged_in? || OAUTH_CREDENTIALS[consumer_key][:allow_login]
128
+ deny_access! unless logged_in? || consumer_credentials[:allow_login]
77
129
  @consumer="#{consumer_key.to_s.camelcase}Token".constantize
78
130
  @token=@consumer.find(:first, :conditions=>{:user_id=>current_user.id.to_s}) if logged_in?
79
131
  end
@@ -85,4 +137,4 @@ module Oauth
85
137
 
86
138
  end
87
139
  end
88
- end
140
+ end
@@ -121,7 +121,7 @@ module OAuth
121
121
  def oauth2_authorize_code
122
122
  @client_application = ClientApplication.find_by_key params[:client_id]
123
123
  if request.post?
124
- @redirect_url = URI.parse(params[:redirect_url] || @client_application.callback_url)
124
+ @redirect_url = URI.parse(params[:redirect_uri] || @client_application.callback_url)
125
125
  if user_authorizes_token?
126
126
  @verification_code = Oauth2Verifier.create :client_application=>@client_application, :user=>current_user, :callback_url=>@redirect_url.to_s
127
127
 
@@ -151,14 +151,11 @@ module OAuth
151
151
  def oauth2_authorize_token
152
152
  @client_application = ClientApplication.find_by_key params[:client_id]
153
153
  if request.post?
154
- @redirect_url = URI.parse(params[:redirect_url] || @client_application.callback_url)
154
+ @redirect_url = URI.parse(params[:redirect_uri] || @client_application.callback_url)
155
155
  if user_authorizes_token?
156
156
  @token = Oauth2Token.create :client_application=>@client_application, :user=>current_user, :scope=>params[:scope]
157
157
  unless @redirect_url.to_s.blank?
158
- @redirect_url.query = @redirect_url.query.blank? ?
159
- "access_token=#{@token.token}" :
160
- @redirect_url.query + "&access_token=#{@token.token}"
161
- redirect_to @redirect_url.to_s
158
+ redirect_to "#{@redirect_url.to_s}#access_token=#{@token.token}"
162
159
  else
163
160
  render :action => "authorize_success"
164
161
  end
@@ -184,7 +181,7 @@ module OAuth
184
181
  oauth2_error
185
182
  return
186
183
  end
187
- if @verification_code.redirect_url != params[:redirect_url]
184
+ if @verification_code.redirect_url != params[:redirect_uri]
188
185
  oauth2_error
189
186
  return
190
187
  end
@@ -6,6 +6,8 @@ require 'oauth/controllers/consumer_controller'
6
6
  # So an entry called "my_service" will create a class MyServiceToken which you can
7
7
  # connect with has_one to your user model.
8
8
  if defined? ConsumerToken && defined? OAUTH_CREDENTIALS
9
+ require File.join(File.dirname(__FILE__), 'services', 'oauth2_token')
10
+
9
11
  OAUTH_CREDENTIALS.each do |key, value|
10
12
  class_name=value[:class_name]||"#{key.to_s.classify}Token"
11
13
  unless Object.const_defined?(class_name.to_sym)
@@ -17,7 +19,7 @@ if defined? ConsumerToken && defined? OAUTH_CREDENTIALS
17
19
  # Let Rails auto-load from the models folder
18
20
  eval class_name
19
21
  rescue NameError
20
- super_class = value[:super_class]||"ConsumerToken"
22
+ super_class = value[:super_class]||value[:oauth_version].to_i>=2 ? "Oauth2Token" : "ConsumerToken"
21
23
  eval "class #{class_name} < #{super_class} ;end"
22
24
  end
23
25
  end
@@ -1,27 +1,21 @@
1
- require 'portablecontacts'
2
-
3
1
  class GoogleToken < ConsumerToken
4
2
  GOOGLE_SETTINGS={
5
- :site=>"https://www.google.com",
3
+ :site=>"https://www.google.com",
6
4
  :request_token_path => "/accounts/OAuthGetRequestToken",
7
5
  :authorize_path => "/accounts/OAuthAuthorizeToken",
8
6
  :access_token_path => "/accounts/OAuthGetAccessToken",
9
7
  }
10
-
8
+
11
9
  def self.consumer
12
10
  @consumer||=create_consumer
13
- end
14
-
11
+ end
12
+
15
13
  def self.create_consumer(options={})
16
14
  OAuth::Consumer.new credentials[:key],credentials[:secret],GOOGLE_SETTINGS.merge(options)
17
15
  end
18
-
16
+
19
17
  def self.get_request_token(callback_url, scope=nil)
20
18
  consumer.get_request_token({:oauth_callback=>callback_url}, :scope=>scope||credentials[:scope]||"http://www-opensocial.googleusercontent.com/api/people")
21
19
  end
22
-
23
- def portable_contacts
24
- @portable_contacts||= PortableContacts::Client.new "http://www-opensocial.googleusercontent.com/api/people", client
25
- end
26
-
27
- end
20
+
21
+ end
@@ -0,0 +1,27 @@
1
+ require 'oauth2'
2
+ class Oauth2Token < ConsumerToken
3
+
4
+ def self.consumer
5
+ @consumer||=create_consumer
6
+ end
7
+
8
+ def self.create_consumer(options={})
9
+ @consumer||=OAuth2::Client.new credentials[:key],credentials[:secret],credentials[:options]
10
+ end
11
+
12
+ def self.authorize_url(callback_url)
13
+ options = {:redirect_uri=>callback_url}
14
+ options[:scope] = credentials[:scope] if credentials[:scope].present?
15
+ consumer.web_server.authorize_url(options)
16
+ end
17
+
18
+ def self.access_token(user, code, redirect_uri)
19
+ access_token = consumer.web_server.get_access_token(code, :redirect_uri => redirect_uri)
20
+ find_or_create_from_access_token user, access_token
21
+ end
22
+
23
+ def client
24
+ @client ||= OAuth2::AccessToken.new self.class.consumer, token
25
+ end
26
+
27
+ end