oauth-plugin 0.3.14 → 0.4.0.pre1

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 (110) hide show
  1. data/CHANGELOG +10 -0
  2. data/README.rdoc +44 -9
  3. data/Rakefile +2 -2
  4. data/VERSION +1 -1
  5. data/generators/oauth_consumer/templates/migration.rb +1 -1
  6. data/generators/oauth_provider/oauth_provider_generator.rb +6 -0
  7. data/generators/oauth_provider/templates/access_token.rb +2 -2
  8. data/generators/oauth_provider/templates/client_application.rb +8 -6
  9. data/generators/oauth_provider/templates/client_applications.yml +6 -6
  10. data/generators/oauth_provider/templates/clients_controller_spec.rb +130 -193
  11. data/generators/oauth_provider/templates/controller.rb +12 -0
  12. data/generators/oauth_provider/templates/controller_spec.rb +762 -291
  13. data/generators/oauth_provider/templates/controller_spec_helper.rb +49 -63
  14. data/generators/oauth_provider/templates/migration.rb +6 -5
  15. data/generators/oauth_provider/templates/oauth2_authorize.html.erb +16 -0
  16. data/generators/oauth_provider/templates/oauth2_authorize.html.haml +17 -0
  17. data/generators/oauth_provider/templates/oauth2_token.rb +6 -0
  18. data/generators/oauth_provider/templates/oauth2_token_spec.rb +29 -0
  19. data/generators/oauth_provider/templates/oauth2_verifier.rb +28 -0
  20. data/generators/oauth_provider/templates/oauth2_verifier_spec.rb +54 -0
  21. data/generators/oauth_provider/templates/oauth_nonce_test.rb +1 -1
  22. data/generators/oauth_provider/templates/oauth_token.rb +3 -4
  23. data/generators/oauth_provider/templates/request_token.rb +1 -1
  24. data/lib/generators/active_record/oauth_consumer_generator.rb +33 -0
  25. data/lib/generators/active_record/oauth_consumer_templates/consumer_token.rb +5 -0
  26. data/lib/generators/active_record/oauth_consumer_templates/migration.rb +20 -0
  27. data/lib/generators/active_record/oauth_provider_generator.rb +39 -0
  28. data/lib/generators/active_record/oauth_provider_templates/access_token.rb +16 -0
  29. data/lib/generators/active_record/oauth_provider_templates/client_application.rb +57 -0
  30. data/lib/generators/active_record/oauth_provider_templates/migration.rb +47 -0
  31. data/lib/generators/active_record/oauth_provider_templates/oauth2_token.rb +5 -0
  32. data/lib/generators/active_record/oauth_provider_templates/oauth2_verifier.rb +28 -0
  33. data/lib/generators/active_record/oauth_provider_templates/oauth_nonce.rb +13 -0
  34. data/lib/generators/active_record/oauth_provider_templates/oauth_token.rb +30 -0
  35. data/lib/generators/active_record/oauth_provider_templates/request_token.rb +40 -0
  36. data/lib/generators/erb/oauth_consumer_generator.rb +14 -0
  37. data/lib/generators/erb/oauth_consumer_templates/index.html.erb +29 -0
  38. data/lib/generators/erb/oauth_consumer_templates/show.html.erb +7 -0
  39. data/lib/generators/erb/oauth_provider_generator.rb +21 -0
  40. data/lib/generators/erb/oauth_provider_templates/_form.html.erb +17 -0
  41. data/lib/generators/erb/oauth_provider_templates/authorize.html.erb +14 -0
  42. data/lib/generators/erb/oauth_provider_templates/authorize_failure.html.erb +1 -0
  43. data/lib/generators/erb/oauth_provider_templates/authorize_success.html.erb +1 -0
  44. data/lib/generators/erb/oauth_provider_templates/edit.html.erb +7 -0
  45. data/lib/generators/erb/oauth_provider_templates/index.html.erb +43 -0
  46. data/lib/generators/erb/oauth_provider_templates/new.html.erb +5 -0
  47. data/lib/generators/erb/oauth_provider_templates/oauth2_authorize.html.erb +16 -0
  48. data/lib/generators/erb/oauth_provider_templates/show.html.erb +27 -0
  49. data/lib/generators/haml/oauth_consumer_generator.rb +21 -0
  50. data/lib/generators/haml/oauth_consumer_templates/index.html.haml +18 -0
  51. data/lib/generators/haml/oauth_consumer_templates/show.html.haml +8 -0
  52. data/lib/generators/haml/oauth_provider_generator.rb +28 -0
  53. data/lib/generators/haml/oauth_provider_templates/_form.html.haml +21 -0
  54. data/lib/generators/haml/oauth_provider_templates/authorize.html.haml +16 -0
  55. data/lib/generators/haml/oauth_provider_templates/authorize_failure.html.haml +1 -0
  56. data/lib/generators/haml/oauth_provider_templates/authorize_success.html.haml +1 -0
  57. data/lib/generators/haml/oauth_provider_templates/edit.html.haml +4 -0
  58. data/lib/generators/haml/oauth_provider_templates/index.html.haml +39 -0
  59. data/lib/generators/haml/oauth_provider_templates/new.html.haml +5 -0
  60. data/lib/generators/haml/oauth_provider_templates/oauth2_authorize.html.haml +17 -0
  61. data/lib/generators/haml/oauth_provider_templates/show.html.haml +30 -0
  62. data/lib/generators/mongoid/oauth_consumer_generator.rb +15 -0
  63. data/lib/generators/mongoid/oauth_consumer_templates/consumer_token.rb +14 -0
  64. data/lib/generators/mongoid/oauth_provider_generator.rb +21 -0
  65. data/lib/generators/mongoid/oauth_provider_templates/access_token.rb +16 -0
  66. data/lib/generators/mongoid/oauth_provider_templates/client_application.rb +71 -0
  67. data/lib/generators/mongoid/oauth_provider_templates/oauth2_token.rb +5 -0
  68. data/lib/generators/mongoid/oauth_provider_templates/oauth2_verifier.rb +25 -0
  69. data/lib/generators/mongoid/oauth_provider_templates/oauth_nonce.rb +24 -0
  70. data/lib/generators/mongoid/oauth_provider_templates/oauth_token.rb +44 -0
  71. data/lib/generators/mongoid/oauth_provider_templates/request_token.rb +36 -0
  72. data/lib/generators/oauth_consumer/USAGE +8 -0
  73. data/lib/generators/oauth_consumer/oauth_consumer_generator.rb +27 -0
  74. data/lib/generators/oauth_consumer/templates/controller.rb +19 -0
  75. data/lib/generators/oauth_consumer/templates/oauth_config.rb +46 -0
  76. data/lib/generators/oauth_inflections.rb +6 -0
  77. data/lib/generators/oauth_plugin.rb +0 -0
  78. data/lib/generators/oauth_provider/USAGE +18 -0
  79. data/lib/generators/oauth_provider/oauth_provider_generator.rb +47 -0
  80. data/lib/generators/oauth_provider/templates/clients_controller.rb +52 -0
  81. data/lib/generators/oauth_provider/templates/controller.rb +23 -0
  82. data/lib/generators/rspec/oauth_provider_generator.rb +39 -0
  83. data/lib/generators/rspec/templates/client_application_spec.rb +29 -0
  84. data/lib/generators/rspec/templates/client_applications.yml +23 -0
  85. data/lib/generators/rspec/templates/clients_controller_spec.rb +176 -0
  86. data/lib/generators/rspec/templates/controller_spec.rb +838 -0
  87. data/lib/generators/rspec/templates/controller_spec_helper.rb +66 -0
  88. data/lib/generators/rspec/templates/oauth2_token_spec.rb +29 -0
  89. data/lib/generators/rspec/templates/oauth2_verifier_spec.rb +54 -0
  90. data/lib/generators/rspec/templates/oauth_nonce_spec.rb +24 -0
  91. data/lib/generators/rspec/templates/oauth_nonces.yml +13 -0
  92. data/lib/generators/rspec/templates/oauth_token_spec.rb +309 -0
  93. data/lib/generators/rspec/templates/oauth_tokens.yml +17 -0
  94. data/lib/generators/test_unit/oauth_provider_generator.rb +37 -0
  95. data/lib/generators/test_unit/templates/client_application_test.rb +42 -0
  96. data/lib/generators/test_unit/templates/client_applications.yml +23 -0
  97. data/lib/generators/test_unit/templates/clients_controller_test.rb +280 -0
  98. data/lib/generators/test_unit/templates/controller_test.rb +310 -0
  99. data/lib/generators/test_unit/templates/controller_test_helper.rb +115 -0
  100. data/lib/generators/test_unit/templates/oauth_nonce_test.rb +26 -0
  101. data/lib/generators/test_unit/templates/oauth_nonces.yml +13 -0
  102. data/lib/generators/test_unit/templates/oauth_token_test.rb +57 -0
  103. data/lib/generators/test_unit/templates/oauth_tokens.yml +17 -0
  104. data/lib/oauth/controllers/application_controller_methods.rb +169 -66
  105. data/lib/oauth/controllers/provider_controller.rb +154 -38
  106. data/lib/oauth/models/consumers/service_loader.rb +2 -0
  107. data/lib/oauth/models/consumers/token.rb +0 -1
  108. data/oauth-plugin.gemspec +97 -10
  109. data/rails/init.rb +6 -2
  110. metadata +119 -12
@@ -1,80 +1,66 @@
1
+ require 'oauth/client/action_controller_request'
1
2
  module OAuthControllerSpecHelper
2
- def login
3
- controller.stub!(:local_request?).and_return(true)
4
- @user = mock_model(User)
5
- controller.stub!(:current_user).and_return(@user)
6
- @tokens = []
7
- @tokens.stub!(:find).and_return(@tokens)
8
- @user.stub!(:tokens).and_return(@tokens)
9
- User.stub!(:find_by_id).and_return(@user)
3
+
4
+ def current_user
5
+ @user||=users(:aaron)
6
+ end
7
+
8
+ def current_client_application
9
+ @client_application||=client_applications(:one)
10
+ end
11
+
12
+ def access_token
13
+ @access_token||=AccessToken.create :user=>current_user,:client_application=>current_client_application
14
+ end
15
+
16
+ def request_token
17
+ @request_token||=RequestToken.create :client_application=>current_client_application, :callback_url=>"http://application/callback"
18
+ end
19
+
20
+ def consumer_request_token
21
+ OAuth::RequestToken.new current_consumer,request_token.token,request_token.secret
22
+ end
23
+
24
+ def consumer_access_token
25
+ OAuth::AccessToken.new current_consumer,access_token.token,access_token.secret
26
+ end
27
+
28
+ if defined?(Devise)
29
+ include Devise::TestHelpers
30
+ def login
31
+ sign_in :user, current_user
32
+ end
33
+ else
34
+ def login
35
+ controller.stub!(:current_user).and_return(current_user)
36
+ end
10
37
  end
11
38
 
12
39
  def login_as_application_owner
40
+ @user = users(:quentin)
13
41
  login
14
- @client_application = mock_model(ClientApplication)
15
- @client_applications = [@client_application]
16
-
17
- @user.stub!(:client_applications).and_return(@client_applications)
18
- @client_applications.stub!(:find).and_return(@client_application)
19
42
  end
20
-
21
- def setup_oauth
22
- controller.stub!(:local_request?).and_return(true)
23
- @user||=mock_model(User)
24
-
25
- User.stub!(:find_by_id).and_return(@user)
26
-
27
- @server = OAuth::Server.new "http://test.host"
28
- @consumer = OAuth::Consumer.new('key', 'secret',{:site => "http://test.host"})
29
-
30
- @client_application = mock_model(ClientApplication)
31
- controller.stub!(:current_client_application).and_return(@client_application)
32
- ClientApplication.stub!(:find_by_key).and_return(@client_application)
33
- @client_application.stub!(:key).and_return(@consumer.key)
34
- @client_application.stub!(:secret).and_return(@consumer.secret)
35
- @client_application.stub!(:name).and_return("Client Application name")
36
- @client_application.stub!(:callback_url).and_return("http://application/callback")
37
- @request_token = mock_model(RequestToken, :token => 'request_token', :client_application => @client_application, :secret => "request_secret", :user => @user)
38
- @request_token.stub!(:invalidated?).and_return(false)
39
- ClientApplication.stub!(:find_token).and_return(@request_token)
40
-
41
- @request_token_string="oauth_token=request_token&oauth_token_secret=request_secret"
42
- @request_token.stub!(:to_query).and_return(@request_token_string)
43
- @request_token.stub!(:expired?).and_return(false)
44
- @request_token.stub!(:callback_url).and_return(nil)
45
- @request_token.stub!(:verifier).and_return("verifyme")
46
- @request_token.stub!(:oauth10?).and_return(false)
47
- @request_token.stub!(:oob?).and_return(true)
48
-
49
- @access_token = mock_model(AccessToken, :token => 'access_token', :client_application => @client_application, :secret => "access_secret", :user => @user)
50
- @access_token.stub!(:invalidated?).and_return(false)
51
- @access_token.stub!(:authorized?).and_return(true)
52
- @access_token.stub!(:expired?).and_return(false)
53
- @access_token_string="oauth_token=access_token&oauth_token_secret=access_secret"
54
- @access_token.stub!(:to_query).and_return(@access_token_string)
55
-
56
- @client_application.stub!(:authorize_request?).and_return(true)
57
- # @client_application.stub!(:sign_request_with_oauth_token).and_return(@request_token)
58
- @client_application.stub!(:exchange_for_access_token).and_return(@access_token)
43
+
44
+ def current_consumer
45
+ @consumer ||= OAuth::Consumer.new(current_client_application.key,current_client_application.secret,{:site => "http://test.host"})
59
46
  end
60
47
 
61
48
  def setup_oauth_for_user
62
49
  login
63
- setup_oauth
64
- @tokens = [@request_token]
65
- @tokens.stub!(:find).and_return(@tokens)
66
- @tokens.stub!(:find_by_token).and_return(@request_token)
67
- @user.stub!(:tokens).and_return(@tokens)
68
50
  end
69
51
 
70
52
  def sign_request_with_oauth(token=nil,options={})
71
53
  ActionController::TestRequest.use_oauth=true
72
- @request.configure_oauth(@consumer,token,options)
54
+ @request.configure_oauth(current_consumer,token,options)
55
+ end
56
+
57
+ def two_legged_sign_request_with_oauth(consumer=nil,options={})
58
+ ActionController::TestRequest.use_oauth=true
59
+ @request.configure_oauth(consumer,nil,options)
73
60
  end
74
61
 
75
- def setup_to_authorize_request
76
- setup_oauth
77
- OauthToken.stub!(:find_by_token).with( @access_token.token).and_return(@access_token)
78
- @access_token.stub!(:is_a?).and_return(true)
62
+ def add_oauth2_token_header(token,options={})
63
+ request.env['HTTP_AUTHORIZATION'] = "OAuth #{token.token}"
79
64
  end
80
- end
65
+
66
+ end
@@ -5,27 +5,28 @@ class CreateOauthTables < ActiveRecord::Migration
5
5
  t.string :url
6
6
  t.string :support_url
7
7
  t.string :callback_url
8
- t.string :key, :limit => 20
8
+ t.string :key, :limit => 40
9
9
  t.string :secret, :limit => 40
10
10
  t.integer :user_id
11
11
 
12
12
  t.timestamps
13
13
  end
14
- add_index :client_applications, :key, :unique
14
+ add_index :client_applications, :key, :unique => true
15
15
 
16
16
  create_table :oauth_tokens do |t|
17
17
  t.integer :user_id
18
18
  t.string :type, :limit => 20
19
19
  t.integer :client_application_id
20
- t.string :token, :limit => 20
20
+ t.string :token, :limit => 40
21
21
  t.string :secret, :limit => 40
22
22
  t.string :callback_url
23
23
  t.string :verifier, :limit => 20
24
- t.timestamp :authorized_at, :invalidated_at
24
+ t.string :scope
25
+ t.timestamp :authorized_at, :invalidated_at, :valid_to
25
26
  t.timestamps
26
27
  end
27
28
 
28
- add_index :oauth_tokens, :token, :unique
29
+ add_index :oauth_tokens, :token, :unique => true
29
30
 
30
31
  create_table :oauth_nonces do |t|
31
32
  t.string :nonce
@@ -0,0 +1,16 @@
1
+ <h1>Authorize access to your account</h1>
2
+ <p>Would you like to authorize <%%= link_to @token.client_application.name,@token.client_application.url %> (<%%= link_to @token.client_application.url,@token.client_application.url %>) to access your account?</p>
3
+ <%% form_tag authorize_url do %>
4
+ <%%= hidden_field_tag "response_type", params[:response_type]%>
5
+ <%%= hidden_field_tag "client_id", params[:client_id]%>
6
+ <%%= hidden_field_tag "redirect_url", params[:redirect_url]%>
7
+ <%%= hidden_field_tag "state", params[:state]%>
8
+ <%%= hidden_field_tag "scope", params[:scope]%>
9
+
10
+ <p>
11
+ <%%= check_box_tag 'authorize' %> authorize access
12
+ </p>
13
+ <p>
14
+ <%%= submit_tag %>
15
+ </p>
16
+ <%% end %>
@@ -0,0 +1,17 @@
1
+ %h1 Authorize access to your account
2
+ %p
3
+ Would you like to authorize
4
+ = link_to @client_application.name,@client_application.url
5
+ (
6
+ = link_to @client_application.url,@client_application.url
7
+ ) to access your account?
8
+ - form_tag authorize_url do
9
+ = hidden_field_tag "response_type", params[:response_type]
10
+ = hidden_field_tag "client_id", params[:client_id]
11
+ = hidden_field_tag "redirect_url", params[:redirect_url]
12
+ = hidden_field_tag "state", params[:state]
13
+ = hidden_field_tag "scope", params[:scope]
14
+ = check_box_tag 'authorize'
15
+ authorize access
16
+ %p
17
+ = submit_tag
@@ -0,0 +1,6 @@
1
+ class Oauth2Token < AccessToken
2
+
3
+ def as_json(options={})
4
+ {:access_token=>token}
5
+ end
6
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Oauth2Token do
4
+ fixtures :client_applications, :users, :oauth_tokens
5
+ before(:each) do
6
+ @token = Oauth2Token.create :client_application => client_applications(:one), :user=>users(:aaron)
7
+ end
8
+
9
+ it "should be valid" do
10
+ @token.should be_valid
11
+ end
12
+
13
+ it "should have a token" do
14
+ @token.token.should_not be_nil
15
+ end
16
+
17
+ it "should have a secret" do
18
+ @token.secret.should_not be_nil
19
+ end
20
+
21
+ it "should be authorized" do
22
+ @token.should be_authorized
23
+ end
24
+
25
+ it "should not be invalidated" do
26
+ @token.should_not be_invalidated
27
+ end
28
+
29
+ end
@@ -0,0 +1,28 @@
1
+ class Oauth2Verifier < OauthToken
2
+ validates_presence_of :user
3
+
4
+ def exchange!(params={})
5
+ OauthToken.transaction do
6
+ token = Oauth2Token.create! :user=>user,:client_application=>client_application
7
+ invalidate!
8
+ token
9
+ end
10
+ end
11
+
12
+ def code
13
+ token
14
+ end
15
+
16
+ def redirect_url
17
+ callback_url
18
+ end
19
+
20
+ protected
21
+
22
+ def generate_keys
23
+ self.token = OAuth::Helper.generate_key(20)[0,20]
24
+ self.valid_to = 10.minutes.from_now
25
+ self.authorized_at = Time.now
26
+ end
27
+
28
+ end
@@ -0,0 +1,54 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Oauth2Verifier do
4
+ fixtures :client_applications, :users, :oauth_tokens
5
+ before(:each) do
6
+ @verifier = Oauth2Verifier.create :client_application => client_applications(:one), :user=>users(:aaron)
7
+ end
8
+
9
+ it "should be valid" do
10
+ @verifier.should be_valid
11
+ end
12
+
13
+ it "should have a code" do
14
+ @verifier.code.should_not be_nil
15
+ end
16
+
17
+ it "should not have a secret" do
18
+ @verifier.secret.should be_nil
19
+ end
20
+
21
+ it "should be authorized" do
22
+ @verifier.should be_authorized
23
+ end
24
+
25
+ it "should not be invalidated" do
26
+ @verifier.should_not be_invalidated
27
+ end
28
+
29
+ describe "exchange for oauth2 token" do
30
+ before(:each) do
31
+ @token = @verifier.exchange!
32
+ end
33
+
34
+ it "should invalidate verifier" do
35
+ @verifier.should be_invalidated
36
+ end
37
+
38
+ it "should set user on token" do
39
+ @token.user.should==@verifier.user
40
+ end
41
+
42
+ it "should set client application on token" do
43
+ @token.client_application.should == @verifier.client_application
44
+ end
45
+
46
+ it "should be authorized" do
47
+ @token.should be_authorized
48
+ end
49
+
50
+ it "should not be invalidated" do
51
+ @token.should_not be_invalidated
52
+ end
53
+ end
54
+ end
@@ -1,5 +1,5 @@
1
- require 'oauth/helper'
2
1
  require File.dirname(__FILE__) + '/../test_helper'
2
+ require 'oauth/helper'
3
3
 
4
4
  class ClientNoneTest < ActiveSupport::TestCase
5
5
  include OAuth::Helper
@@ -2,7 +2,7 @@ class OauthToken < ActiveRecord::Base
2
2
  belongs_to :client_application
3
3
  belongs_to :user
4
4
  validates_uniqueness_of :token
5
- validates_presence_of :client_application, :token, :secret
5
+ validates_presence_of :client_application, :token
6
6
  before_validation_on_create :generate_keys
7
7
 
8
8
  def invalidated?
@@ -24,8 +24,7 @@ class OauthToken < ActiveRecord::Base
24
24
  protected
25
25
 
26
26
  def generate_keys
27
- oauth_token = client_application.oauth_server.generate_credentials
28
- self.token = oauth_token[0][0,20]
29
- self.secret = oauth_token[1][0,40]
27
+ self.token = OAuth::Helper.generate_key(40)[0,40]
28
+ self.secret = OAuth::Helper.generate_key(40)[0,40]
30
29
  end
31
30
  end
@@ -6,7 +6,7 @@ class RequestToken < OauthToken
6
6
  return false if authorized?
7
7
  self.user = user
8
8
  self.authorized_at = Time.now
9
- self.verifier=OAuth::Helper.generate_key(16)[0,20] unless oauth10?
9
+ self.verifier=OAuth::Helper.generate_key(20)[0,20] unless oauth10?
10
10
  self.save
11
11
  end
12
12
 
@@ -0,0 +1,33 @@
1
+ require 'rails/generators/active_record'
2
+
3
+ module ActiveRecord
4
+ module Generators
5
+ class OauthProviderGenerator < Rails::Generators::Base
6
+ include Rails::Generators::Migration
7
+
8
+ source_root File.expand_path('../oauth_consumer_templates', __FILE__)
9
+
10
+ # Implement the required interface for Rails::Generators::Migration.
11
+ def self.next_migration_number(dirname) #:nodoc:
12
+ next_migration_number = current_migration_number(dirname) + 1
13
+ if ActiveRecord::Base.timestamped_migrations
14
+ [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max
15
+ else
16
+ "%.3d" % next_migration_number
17
+ end
18
+ end
19
+
20
+ def check_class_collisions
21
+ class_collisions '', %w(ConsumerToken)
22
+ end
23
+
24
+ def copy_models
25
+ template 'consumer_token.rb', File.join('app/models', 'consumer_token.rb')
26
+ end
27
+
28
+ def copy_migration
29
+ migration_template 'migration.rb', 'db/migrate/create_oauth_consumer_tokens'
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ require 'oauth/models/consumers/token'
2
+ class ConsumerToken < ActiveRecord::Base
3
+ include Oauth::Models::Consumers::Token
4
+ belongs_to :user
5
+ end
@@ -0,0 +1,20 @@
1
+ class CreateOauthConsumerTokens < ActiveRecord::Migration
2
+ def self.up
3
+
4
+ create_table :consumer_tokens do |t|
5
+ t.integer :user_id
6
+ t.string :type, :limit => 30
7
+ t.string :token, :limit => 1024 # This has to be huge because of Yahoo's excessively large tokens
8
+ t.string :secret
9
+ t.timestamps
10
+ end
11
+
12
+ add_index :consumer_tokens, :token, :unique => true
13
+
14
+ end
15
+
16
+ def self.down
17
+ drop_table :consumer_tokens
18
+ end
19
+
20
+ end
@@ -0,0 +1,39 @@
1
+ require 'rails/generators/active_record'
2
+
3
+ module ActiveRecord
4
+ module Generators
5
+ class OauthProviderGenerator < Rails::Generators::Base
6
+ include Rails::Generators::Migration
7
+
8
+ source_root File.expand_path('../oauth_provider_templates', __FILE__)
9
+
10
+ # Implement the required interface for Rails::Generators::Migration.
11
+ def self.next_migration_number(dirname) #:nodoc:
12
+ next_migration_number = current_migration_number(dirname) + 1
13
+ if ActiveRecord::Base.timestamped_migrations
14
+ [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max
15
+ else
16
+ "%.3d" % next_migration_number
17
+ end
18
+ end
19
+
20
+ def check_class_collisions
21
+ class_collisions '', %w(ClientApplication OauthNonce RequestToken AccessToken OauthToken)
22
+ end
23
+
24
+ def copy_models
25
+ template 'client_application.rb', File.join('app/models', 'client_application.rb')
26
+ template 'oauth_token.rb', File.join('app/models', 'oauth_token.rb')
27
+ template 'request_token.rb', File.join('app/models', 'request_token.rb')
28
+ template 'access_token.rb', File.join('app/models', 'access_token.rb')
29
+ template 'oauth2_token.rb', File.join('app/models', 'oauth2_token.rb')
30
+ template 'oauth2_verifier.rb', File.join('app/models', 'oauth2_verifier.rb')
31
+ template 'oauth_nonce.rb', File.join('app/models', 'oauth_nonce.rb')
32
+ end
33
+
34
+ def copy_migration
35
+ migration_template 'migration.rb', 'db/migrate/create_oauth_tables'
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,16 @@
1
+ class AccessToken < OauthToken
2
+ validates_presence_of :user, :secret
3
+ before_create :set_authorized_at
4
+
5
+ # Implement this to return a hash or array of the capabilities the access token has
6
+ # This is particularly useful if you have implemented user defined permissions.
7
+ # def capabilities
8
+ # {:invalidate=>"/oauth/invalidate",:capabilities=>"/oauth/capabilities"}
9
+ # end
10
+
11
+ protected
12
+
13
+ def set_authorized_at
14
+ self.authorized_at = Time.now
15
+ end
16
+ end
@@ -0,0 +1,57 @@
1
+ require 'oauth'
2
+ class ClientApplication < ActiveRecord::Base
3
+ belongs_to :user
4
+ has_many :tokens, :class_name => "OauthToken"
5
+ has_many :access_tokens
6
+ has_many :oauth2_verifiers
7
+ has_many :oauth_tokens
8
+ validates_presence_of :name, :url, :key, :secret
9
+ validates_uniqueness_of :key
10
+ before_validation :generate_keys, :on => :create
11
+
12
+ validates_format_of :url, :with => /\Ahttp(s?):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/i
13
+ validates_format_of :support_url, :with => /\Ahttp(s?):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/i, :allow_blank=>true
14
+ validates_format_of :callback_url, :with => /\Ahttp(s?):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/i, :allow_blank=>true
15
+
16
+ attr_accessor :token_callback_url
17
+
18
+ def self.find_token(token_key)
19
+ token = OauthToken.find_by_token(token_key, :include => :client_application)
20
+ if token && token.authorized?
21
+ token
22
+ else
23
+ nil
24
+ end
25
+ end
26
+
27
+ def self.verify_request(request, options = {}, &block)
28
+ begin
29
+ signature = OAuth::Signature.build(request, options, &block)
30
+ return false unless OauthNonce.remember(signature.request.nonce, signature.request.timestamp)
31
+ value = signature.verify
32
+ value
33
+ rescue OAuth::Signature::UnknownSignatureMethod => e
34
+ false
35
+ end
36
+ end
37
+
38
+ def oauth_server
39
+ @oauth_server ||= OAuth::Server.new("http://your.site")
40
+ end
41
+
42
+ def credentials
43
+ @oauth_client ||= OAuth::Consumer.new(key, secret)
44
+ end
45
+
46
+ # If your application requires passing in extra parameters handle it here
47
+ def create_request_token(params={})
48
+ RequestToken.create :client_application => self, :callback_url=>self.token_callback_url
49
+ end
50
+
51
+ protected
52
+
53
+ def generate_keys
54
+ self.key = OAuth::Helper.generate_key(40)[0,40]
55
+ self.secret = OAuth::Helper.generate_key(40)[0,40]
56
+ end
57
+ end
@@ -0,0 +1,47 @@
1
+ class CreateOauthTables < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :client_applications do |t|
4
+ t.string :name
5
+ t.string :url
6
+ t.string :support_url
7
+ t.string :callback_url
8
+ t.string :key, :limit => 40
9
+ t.string :secret, :limit => 40
10
+ t.integer :user_id
11
+
12
+ t.timestamps
13
+ end
14
+ add_index :client_applications, :key, :unique => true
15
+
16
+ create_table :oauth_tokens do |t|
17
+ t.integer :user_id
18
+ t.string :type, :limit => 20
19
+ t.integer :client_application_id
20
+ t.string :token, :limit => 40
21
+ t.string :secret, :limit => 40
22
+ t.string :callback_url
23
+ t.string :verifier, :limit => 20
24
+ t.string :scope
25
+ t.timestamp :authorized_at, :invalidated_at, :valid_to
26
+ t.timestamps
27
+ end
28
+
29
+ add_index :oauth_tokens, :token, :unique => true
30
+
31
+ create_table :oauth_nonces do |t|
32
+ t.string :nonce
33
+ t.integer :timestamp
34
+
35
+ t.timestamps
36
+ end
37
+ add_index :oauth_nonces,[:nonce, :timestamp], :unique => true
38
+
39
+ end
40
+
41
+ def self.down
42
+ drop_table :client_applications
43
+ drop_table :oauth_tokens
44
+ drop_table :oauth_nonces
45
+ end
46
+
47
+ end
@@ -0,0 +1,5 @@
1
+ class Oauth2Token < AccessToken
2
+ def as_json(options={})
3
+ {:access_token=>token}
4
+ end
5
+ end
@@ -0,0 +1,28 @@
1
+ class Oauth2Verifier < OauthToken
2
+ validates_presence_of :user
3
+
4
+ def exchange!(params={})
5
+ OauthToken.transaction do
6
+ token = Oauth2Token.create! :user=>user,:client_application=>client_application
7
+ invalidate!
8
+ token
9
+ end
10
+ end
11
+
12
+ def code
13
+ token
14
+ end
15
+
16
+ def redirect_url
17
+ callback_url
18
+ end
19
+
20
+ protected
21
+
22
+ def generate_keys
23
+ self.token = OAuth::Helper.generate_key(20)[0,20]
24
+ self.valid_to = 10.minutes.from_now
25
+ self.authorized_at = Time.now
26
+ end
27
+
28
+ end
@@ -0,0 +1,13 @@
1
+ # Simple store of nonces. The OAuth Spec requires that any given pair of nonce and timestamps are unique.
2
+ # Thus you can use the same nonce with a different timestamp and viceversa.
3
+ class OauthNonce < ActiveRecord::Base
4
+ validates_presence_of :nonce, :timestamp
5
+ validates_uniqueness_of :nonce, :scope => :timestamp
6
+
7
+ # Remembers a nonce and it's associated timestamp. It returns false if it has already been used
8
+ def self.remember(nonce, timestamp)
9
+ oauth_nonce = OauthNonce.create(:nonce => nonce, :timestamp => timestamp)
10
+ return false if oauth_nonce.new_record?
11
+ oauth_nonce
12
+ end
13
+ end
@@ -0,0 +1,30 @@
1
+ class OauthToken < ActiveRecord::Base
2
+ belongs_to :client_application
3
+ belongs_to :user
4
+ validates_uniqueness_of :token
5
+ validates_presence_of :client_application, :token
6
+ before_validation :generate_keys, :on => :create
7
+
8
+ def invalidated?
9
+ invalidated_at != nil
10
+ end
11
+
12
+ def invalidate!
13
+ update_attribute(:invalidated_at, Time.now)
14
+ end
15
+
16
+ def authorized?
17
+ authorized_at != nil && !invalidated?
18
+ end
19
+
20
+ def to_query
21
+ "oauth_token=#{token}&oauth_token_secret=#{secret}"
22
+ end
23
+
24
+ protected
25
+
26
+ def generate_keys
27
+ self.token = OAuth::Helper.generate_key(40)[0,40]
28
+ self.secret = OAuth::Helper.generate_key(40)[0,40]
29
+ end
30
+ end