filiptepper-oauth-plugin 0.3.11

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.
Files changed (74) hide show
  1. data/.gitignore +5 -0
  2. data/CHANGELOG +101 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +376 -0
  5. data/Rakefile +38 -0
  6. data/VERSION +1 -0
  7. data/generators/oauth_consumer/USAGE +10 -0
  8. data/generators/oauth_consumer/oauth_consumer_generator.rb +50 -0
  9. data/generators/oauth_consumer/templates/consumer_token.rb +5 -0
  10. data/generators/oauth_consumer/templates/controller.rb +19 -0
  11. data/generators/oauth_consumer/templates/index.html.erb +29 -0
  12. data/generators/oauth_consumer/templates/index.html.haml +18 -0
  13. data/generators/oauth_consumer/templates/migration.rb +20 -0
  14. data/generators/oauth_consumer/templates/oauth_config.rb +41 -0
  15. data/generators/oauth_consumer/templates/show.html.erb +7 -0
  16. data/generators/oauth_consumer/templates/show.html.haml +8 -0
  17. data/generators/oauth_provider/USAGE +20 -0
  18. data/generators/oauth_provider/lib/insert_routes.rb +67 -0
  19. data/generators/oauth_provider/oauth_provider_generator.rb +125 -0
  20. data/generators/oauth_provider/templates/_form.html.erb +17 -0
  21. data/generators/oauth_provider/templates/_form.html.haml +21 -0
  22. data/generators/oauth_provider/templates/access_token.rb +16 -0
  23. data/generators/oauth_provider/templates/authorize.html.erb +14 -0
  24. data/generators/oauth_provider/templates/authorize.html.haml +16 -0
  25. data/generators/oauth_provider/templates/authorize_failure.html.erb +1 -0
  26. data/generators/oauth_provider/templates/authorize_failure.html.haml +1 -0
  27. data/generators/oauth_provider/templates/authorize_success.html.erb +1 -0
  28. data/generators/oauth_provider/templates/authorize_success.html.haml +1 -0
  29. data/generators/oauth_provider/templates/client_application.rb +55 -0
  30. data/generators/oauth_provider/templates/client_application_spec.rb +29 -0
  31. data/generators/oauth_provider/templates/client_application_test.rb +42 -0
  32. data/generators/oauth_provider/templates/client_applications.yml +23 -0
  33. data/generators/oauth_provider/templates/clients_controller.rb +52 -0
  34. data/generators/oauth_provider/templates/clients_controller_spec.rb +239 -0
  35. data/generators/oauth_provider/templates/clients_controller_test.rb +280 -0
  36. data/generators/oauth_provider/templates/controller.rb +11 -0
  37. data/generators/oauth_provider/templates/controller_spec.rb +367 -0
  38. data/generators/oauth_provider/templates/controller_spec_helper.rb +80 -0
  39. data/generators/oauth_provider/templates/controller_test.rb +310 -0
  40. data/generators/oauth_provider/templates/controller_test_helper.rb +115 -0
  41. data/generators/oauth_provider/templates/edit.html.erb +7 -0
  42. data/generators/oauth_provider/templates/edit.html.haml +4 -0
  43. data/generators/oauth_provider/templates/index.html.erb +43 -0
  44. data/generators/oauth_provider/templates/index.html.haml +39 -0
  45. data/generators/oauth_provider/templates/migration.rb +46 -0
  46. data/generators/oauth_provider/templates/new.html.erb +5 -0
  47. data/generators/oauth_provider/templates/new.html.haml +5 -0
  48. data/generators/oauth_provider/templates/oauth_nonce.rb +13 -0
  49. data/generators/oauth_provider/templates/oauth_nonce_spec.rb +24 -0
  50. data/generators/oauth_provider/templates/oauth_nonce_test.rb +26 -0
  51. data/generators/oauth_provider/templates/oauth_nonces.yml +13 -0
  52. data/generators/oauth_provider/templates/oauth_token.rb +31 -0
  53. data/generators/oauth_provider/templates/oauth_token_spec.rb +309 -0
  54. data/generators/oauth_provider/templates/oauth_token_test.rb +57 -0
  55. data/generators/oauth_provider/templates/oauth_tokens.yml +17 -0
  56. data/generators/oauth_provider/templates/request_token.rb +40 -0
  57. data/generators/oauth_provider/templates/show.html.erb +27 -0
  58. data/generators/oauth_provider/templates/show.html.haml +30 -0
  59. data/init.rb +1 -0
  60. data/install.rb +2 -0
  61. data/lib/oauth-plugin.rb +1 -0
  62. data/lib/oauth/controllers/application_controller_methods.rb +110 -0
  63. data/lib/oauth/controllers/consumer_controller.rb +76 -0
  64. data/lib/oauth/controllers/provider_controller.rb +111 -0
  65. data/lib/oauth/models/consumers/service_loader.rb +18 -0
  66. data/lib/oauth/models/consumers/services/agree2_token.rb +15 -0
  67. data/lib/oauth/models/consumers/services/fireeagle_token.rb +39 -0
  68. data/lib/oauth/models/consumers/services/twitter_token.rb +18 -0
  69. data/lib/oauth/models/consumers/token.rb +60 -0
  70. data/oauth-plugin.gemspec +112 -0
  71. data/rails/init.rb +7 -0
  72. data/tasks/oauth_tasks.rake +4 -0
  73. data/uninstall.rb +1 -0
  74. metadata +136 -0
@@ -0,0 +1,57 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class RequestTokenTest < ActiveSupport::TestCase
4
+
5
+ fixtures :client_applications, :users, :oauth_tokens
6
+
7
+ def setup
8
+ @token = RequestToken.create :client_application=>client_applications(:one)
9
+ end
10
+
11
+ def test_should_be_valid
12
+ assert @token.valid?
13
+ end
14
+
15
+ def test_should_not_have_errors
16
+ assert @token.errors.empty?
17
+ end
18
+
19
+ def test_should_have_a_token
20
+ assert_not_nil @token.token
21
+ end
22
+
23
+ def test_should_have_a_secret
24
+ assert_not_nil @token.secret
25
+ end
26
+
27
+ def test_should_not_be_authorized
28
+ assert !@token.authorized?
29
+ end
30
+
31
+ def test_should_not_be_invalidated
32
+ assert !@token.invalidated?
33
+ end
34
+
35
+ def test_should_authorize_request
36
+ @token.authorize!(users(:quentin))
37
+ assert @token.authorized?
38
+ assert_not_nil @token.authorized_at
39
+ assert_equal users(:quentin), @token.user
40
+ end
41
+
42
+ def test_should_not_exchange_without_approval
43
+ assert_equal false, @token.exchange!
44
+ assert_equal false, @token.invalidated?
45
+ end
46
+
47
+ def test_should_not_exchange_without_approval
48
+ @token.authorize!(users(:quentin))
49
+ @access = @token.exchange!
50
+ assert_not_equal false, @access
51
+ assert @token.invalidated?
52
+
53
+ assert_equal users(:quentin), @access.user
54
+ assert @access.authorized?
55
+ end
56
+
57
+ end
@@ -0,0 +1,17 @@
1
+ # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2
+ one:
3
+ id: 1
4
+ user_id: 1
5
+ client_application_id: 1
6
+ token: one
7
+ secret: MyString
8
+ created_at: 2007-11-19 07:31:46
9
+ updated_at: 2007-11-19 07:31:46
10
+ two:
11
+ id: 2
12
+ user_id: 1
13
+ client_application_id: 1
14
+ token: two
15
+ secret: MyString
16
+ created_at: 2007-11-19 07:31:46
17
+ updated_at: 2007-11-19 07:31:46
@@ -0,0 +1,40 @@
1
+ class RequestToken < OauthToken
2
+
3
+ attr_accessor :provided_oauth_verifier
4
+
5
+ def authorize!(user)
6
+ return false if authorized?
7
+ self.user = user
8
+ self.authorized_at = Time.now
9
+ self.verifier=OAuth::Helper.generate_key(16)[0,20] unless oauth10?
10
+ self.save
11
+ end
12
+
13
+ def exchange!
14
+ return false unless authorized?
15
+ return false unless oauth10? || verifier==provided_oauth_verifier
16
+
17
+ RequestToken.transaction do
18
+ access_token = AccessToken.create(:user => user, :client_application => client_application)
19
+ invalidate!
20
+ access_token
21
+ end
22
+ end
23
+
24
+ def to_query
25
+ if oauth10?
26
+ super
27
+ else
28
+ "#{super}&oauth_callback_confirmed=true"
29
+ end
30
+ end
31
+
32
+ def oob?
33
+ self.callback_url=='oob'
34
+ end
35
+
36
+ def oauth10?
37
+ (defined? OAUTH_10_SUPPORT) && OAUTH_10_SUPPORT && self.callback_url.blank?
38
+ end
39
+
40
+ end
@@ -0,0 +1,27 @@
1
+ <h1>OAuth details for <%%=@client_application.name %></h1>
2
+ <p>
3
+ <strong>Consumer Key:</strong>
4
+ <code><%%=@client_application.key %></code>
5
+ </p>
6
+ <p>
7
+ <strong>Consumer Secret:</strong>
8
+ <code><%%=@client_application.secret %></code>
9
+ </p>
10
+ <p>
11
+ <strong>Request Token URL</strong>
12
+ <code>http<%%='s' if request.ssl? %>://<%%= request.host_with_port %><%%=@client_application.oauth_server.request_token_path %></code>
13
+ </p>
14
+ <p>
15
+ <strong>Access Token URL</strong>
16
+ <code>http<%%='s' if request.ssl? %>://<%%= request.host_with_port %><%%=@client_application.oauth_server.access_token_path %></code>
17
+ </p>
18
+ <p>
19
+ <strong>Authorize URL</strong>
20
+ <code>http<%%='s' if request.ssl? %>://<%%= request.host_with_port %><%%=@client_application.oauth_server.authorize_path %></code>
21
+ </p>
22
+
23
+ <p>
24
+ We support hmac-sha1 (recommended) as well as plain text in ssl mode.
25
+ </p>
26
+ <%%= link_to 'Edit', edit_oauth_client_path(@client_application) %> |
27
+ <%%= link_to 'Back', oauth_clients_path %>
@@ -0,0 +1,30 @@
1
+ %h1
2
+ OAuth details for
3
+ =@client_application.name
4
+ %p
5
+ %strong Consumer Key:
6
+ %code=@client_application.key
7
+ %p
8
+ %strong Consumer Secret:
9
+ %code=@client_application.secret
10
+
11
+ %p
12
+ %strong Request Token URL
13
+ %code
14
+ ="http#{'s' if request.ssl?}://#{request.host_with_port}#{@client_application.oauth_server.request_token_path}"
15
+
16
+ %p
17
+ %strong Access Token URL
18
+ %code
19
+ ="http#{'s' if request.ssl?}://#{request.host_with_port}#{@client_application.oauth_server.access_token_path}"
20
+
21
+ %p
22
+ %strong Authorize URL
23
+ %code
24
+ ="http#{'s' if request.ssl?}://#{request.host_with_port}#{@client_application.oauth_server.authorize_path}"
25
+
26
+ %p
27
+ We support hmac-sha1 (recommended) as well as plain text in ssl mode.
28
+
29
+ = link_to 'Edit', edit_oauth_client_path(@client_application)
30
+ = link_to 'Back', oauth_clients_path
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + "/rails/init"
@@ -0,0 +1,2 @@
1
+ #should we do any text formatting?
2
+ puts IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
@@ -0,0 +1 @@
1
+ # leaving this empty
@@ -0,0 +1,110 @@
1
+ require 'oauth/signature'
2
+ module OAuth
3
+ module Controllers
4
+
5
+ module ApplicationControllerMethods
6
+ protected
7
+
8
+ def current_token
9
+ @current_token
10
+ end
11
+
12
+ def current_client_application
13
+ @current_client_application
14
+ end
15
+
16
+ def oauthenticate
17
+ verified=verify_oauth_signature
18
+ return verified && current_token.is_a?(::AccessToken)
19
+ end
20
+
21
+ def oauth?
22
+ current_token!=nil
23
+ end
24
+
25
+ # use in a before_filter
26
+ def oauth_required
27
+ if oauthenticate
28
+ if authorized?
29
+ return true
30
+ else
31
+ invalid_oauth_response
32
+ end
33
+ else
34
+ invalid_oauth_response
35
+ end
36
+ end
37
+
38
+ # This requies that you have an acts_as_authenticated compatible authentication plugin installed
39
+ def login_or_oauth_required
40
+ if oauthenticate
41
+ if authorized?
42
+ return true
43
+ else
44
+ invalid_oauth_response
45
+ end
46
+ else
47
+ login_required
48
+ end
49
+ end
50
+
51
+
52
+ # verifies a request token request
53
+ def verify_oauth_consumer_signature
54
+ begin
55
+ valid = ClientApplication.verify_request(request) do |request_proxy|
56
+ @current_client_application = ClientApplication.find_by_key(request_proxy.consumer_key)
57
+
58
+ # Store this temporarily in client_application object for use in request token generation
59
+ @current_client_application.token_callback_url=request_proxy.oauth_callback if request_proxy.oauth_callback
60
+
61
+ # return the token secret and the consumer secret
62
+ [nil, @current_client_application.secret]
63
+ end
64
+ rescue
65
+ valid=false
66
+ end
67
+
68
+ invalid_oauth_response unless valid
69
+ end
70
+
71
+ def verify_oauth_request_token
72
+ verify_oauth_signature && current_token.is_a?(::RequestToken)
73
+ end
74
+
75
+ def invalid_oauth_response(code=401,message="Invalid OAuth Request")
76
+ render :text => message, :status => code
77
+ end
78
+
79
+ private
80
+
81
+ def current_token=(token)
82
+ @current_token=token
83
+ if @current_token
84
+ @current_user=@current_token.user
85
+ @current_client_application=@current_token.client_application
86
+ end
87
+ @current_token
88
+ end
89
+
90
+ # Implement this for your own application using app-specific models
91
+ def verify_oauth_signature
92
+ begin
93
+ valid = ClientApplication.verify_request(request) do |request_proxy|
94
+ self.current_token = ClientApplication.find_token(request_proxy.token)
95
+ if self.current_token.respond_to?(:provided_oauth_verifier=)
96
+ self.current_token.provided_oauth_verifier=request_proxy.oauth_verifier
97
+ end
98
+ # return the token secret and the consumer secret
99
+ [(current_token.nil? ? nil : current_token.secret), (current_client_application.nil? ? nil : current_client_application.secret)]
100
+ end
101
+ # reset @current_user to clear state for restful_...._authentication
102
+ @current_user = nil if (!valid)
103
+ valid
104
+ rescue
105
+ false
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,76 @@
1
+ module Oauth
2
+ module Controllers
3
+ module ConsumerController
4
+ def self.included(controller)
5
+ controller.class_eval do
6
+ before_filter :login_required
7
+ before_filter :load_consumer, :except=>:index
8
+ skip_before_filter :verify_authenticity_token,:only=>:callback
9
+ end
10
+ end
11
+
12
+ def index
13
+ @consumer_tokens=ConsumerToken.all :conditions=>{:user_id=>current_user.id}
14
+ # The services the user hasn't already connected to
15
+ @services=OAUTH_CREDENTIALS.keys-@consumer_tokens.collect{|c| c.class.service_name}
16
+ end
17
+
18
+
19
+ # creates request token and redirects on to oauth provider's auth page
20
+ # If user is already connected it displays a page with an option to disconnect and redo
21
+ def show
22
+ unless @token
23
+ @request_token=@consumer.get_request_token(callback_oauth_consumer_url(params[:id]))
24
+ session[@request_token.token]=@request_token.secret
25
+ if @request_token.callback_confirmed?
26
+ redirect_to @request_token.authorize_url
27
+ else
28
+ redirect_to(@request_token.authorize_url + "&oauth_callback=#{callback_oauth_consumer_url(params[:id])}")
29
+ end
30
+ end
31
+ end
32
+
33
+ def callback
34
+ @request_token_secret=session[params[:oauth_token]]
35
+ if @request_token_secret
36
+ @token=@consumer.create_from_request_token(current_user,params[:oauth_token],@request_token_secret,params[:oauth_verifier])
37
+ if @token
38
+ flash[:notice] = "#{params[:id].humanize} was successfully connected to your account"
39
+ go_back
40
+ else
41
+ flash[:error] = "An error happened, please try connecting again"
42
+ redirect_to oauth_consumer_url(params[:id])
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ def destroy
49
+ throw RecordNotFound unless @token
50
+ @token.destroy
51
+ if params[:commit]=="Reconnect"
52
+ redirect_to oauth_consumer_url(params[:id])
53
+ else
54
+ flash[:notice] = "#{params[:id].humanize} was successfully disconnected from your account"
55
+
56
+ go_back
57
+ end
58
+ end
59
+
60
+ protected
61
+
62
+ # Override this in your controller to decide where you want to redirect user to after callback is finished.
63
+ def go_back
64
+ redirect_to root_url
65
+ end
66
+
67
+ def load_consumer
68
+ consumer_key=params[:id].to_sym
69
+ throw RecordNotFound unless OAUTH_CREDENTIALS.include?(consumer_key)
70
+ @consumer="#{consumer_key.to_s.camelcase}Token".constantize
71
+ @token=@consumer.find_by_user_id current_user.id
72
+ end
73
+
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,111 @@
1
+ module OAuth
2
+ module Controllers
3
+
4
+ module ProviderController
5
+ def self.included(controller)
6
+ controller.class_eval do
7
+ before_filter :login_required, :only => [:authorize,:revoke]
8
+ before_filter :login_or_oauth_required, :only => [:test_request]
9
+ before_filter :oauth_required, :only => [:invalidate,:capabilities]
10
+ before_filter :verify_oauth_consumer_signature, :only => [:request_token]
11
+ before_filter :verify_oauth_request_token, :only => [:access_token]
12
+ skip_before_filter :verify_authenticity_token, :only=>[:request_token, :access_token, :invalidate, :test_request]
13
+ end
14
+ end
15
+
16
+ def request_token
17
+ @token = current_client_application.create_request_token
18
+ if @token
19
+ render :text => @token.to_query
20
+ else
21
+ render :nothing => true, :status => 401
22
+ end
23
+ end
24
+
25
+ def access_token
26
+ @token = current_token && current_token.exchange!
27
+ if @token
28
+ render :text => @token.to_query
29
+ else
30
+ render :nothing => true, :status => 401
31
+ end
32
+ end
33
+
34
+ def test_request
35
+ render :text => params.collect{|k,v|"#{k}=#{v}"}.join("&")
36
+ end
37
+
38
+ def authorize
39
+ @token = ::RequestToken.find_by_token params[:oauth_token]
40
+ unless @token
41
+ render :action=>"authorize_failure"
42
+ return
43
+ end
44
+
45
+ unless @token.invalidated?
46
+ if request.post?
47
+ if user_authorizes_token?
48
+ @token.authorize!(current_user)
49
+ if @token.oauth10?
50
+ @redirect_url = params[:oauth_callback] || @token.client_application.callback_url
51
+ else
52
+ @redirect_url = @token.oob? ? @token.client_application.callback_url : @token.callback_url
53
+ end
54
+
55
+ if @redirect_url
56
+ if @token.oauth10?
57
+ redirect_to "#{@redirect_url}?oauth_token=#{@token.token}"
58
+ else
59
+ redirect_to "#{@redirect_url}?oauth_token=#{@token.token}&oauth_verifier=#{@token.verifier}"
60
+ end
61
+ else
62
+ render :action => "authorize_success"
63
+ end
64
+ else
65
+ @token.invalidate!
66
+ render :action => "authorize_failure"
67
+ end
68
+ end
69
+ else
70
+ render :action => "authorize_failure"
71
+ end
72
+ end
73
+
74
+ def revoke
75
+ @token = current_user.tokens.find_by_token params[:token]
76
+ if @token
77
+ @token.invalidate!
78
+ flash[:notice] = "You've revoked the token for #{@token.client_application.name}"
79
+ end
80
+ redirect_to oauth_clients_url
81
+ end
82
+
83
+ # Invalidate current token
84
+ def invalidate
85
+ current_token.invalidate!
86
+ head :status=>410
87
+ end
88
+
89
+ # Capabilities of current_token
90
+ def capabilities
91
+ if current_token.respond_to?(:capabilities)
92
+ @capabilities=current_token.capabilities
93
+ else
94
+ @capabilities={:invalidate=>url_for(:action=>:invalidate)}
95
+ end
96
+
97
+ respond_to do |format|
98
+ format.json {render :json=>@capabilities}
99
+ format.xml {render :xml=>@capabilities}
100
+ end
101
+ end
102
+
103
+ protected
104
+
105
+ # Override this to match your authorization page form
106
+ def user_authorizes_token?
107
+ params[:authorize] == '1'
108
+ end
109
+ end
110
+ end
111
+ end