panjiva-oauth-plugin 0.4.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 +15 -0
- data/.gitignore +12 -0
- data/CHANGELOG +178 -0
- data/Gemfile +27 -0
- data/Guardfile +8 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +531 -0
- data/Rakefile +2 -0
- data/UPGRADE.rdoc +21 -0
- data/generators/oauth_consumer/USAGE +10 -0
- data/generators/oauth_consumer/oauth_consumer_generator.rb +50 -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/migration.rb +20 -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_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/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 +136 -0
- data/lib/oauth/controllers/consumer_controller.rb +150 -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 +27 -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 +93 -0
- data/lib/oauth/provider/authorizer.rb +83 -0
- data/lib/oauth/rack/oauth_filter.rb +93 -0
- data/oauth-plugin.gemspec +39 -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 +362 -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(20)[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
|
+
callback_url.nil? || callback_url.downcase == '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"
|
data/install.rb
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'rails/generators/active_record'
|
|
2
|
+
|
|
3
|
+
module ActiveRecord
|
|
4
|
+
module Generators
|
|
5
|
+
class OauthConsumerGenerator < 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,11 @@
|
|
|
1
|
+
require 'oauth/models/consumers/token'
|
|
2
|
+
class ConsumerToken < ActiveRecord::Base
|
|
3
|
+
include Oauth::Models::Consumers::Token
|
|
4
|
+
|
|
5
|
+
# You can safely remove this callback if you don't allow login from any of your services
|
|
6
|
+
before_create :create_user
|
|
7
|
+
|
|
8
|
+
# Modify this with class_name etc to match your application
|
|
9
|
+
belongs_to :user
|
|
10
|
+
|
|
11
|
+
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, :length => 100
|
|
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, :expires_at
|
|
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,20 @@
|
|
|
1
|
+
class Oauth2Token < AccessToken
|
|
2
|
+
attr_accessor :state
|
|
3
|
+
def as_json(options={})
|
|
4
|
+
d = {:access_token=>token, :token_type => 'bearer'}
|
|
5
|
+
d[:expires_in] = expires_in if expires_at
|
|
6
|
+
d
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def to_query
|
|
10
|
+
q = "access_token=#{token}&token_type=bearer"
|
|
11
|
+
q << "&state=#{URI.escape(state)}" if @state
|
|
12
|
+
q << "&expires_in=#{expires_in}" if expires_at
|
|
13
|
+
q << "&scope=#{URI.escape(scope)}" if scope
|
|
14
|
+
q
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def expires_in
|
|
18
|
+
expires_at.to_i - Time.now.to_i
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
class Oauth2Verifier < OauthToken
|
|
2
|
+
validates_presence_of :user
|
|
3
|
+
attr_accessor :state
|
|
4
|
+
|
|
5
|
+
def exchange!(params={})
|
|
6
|
+
OauthToken.transaction do
|
|
7
|
+
token = Oauth2Token.create! :user=>user,:client_application=>client_application, :scope => scope
|
|
8
|
+
invalidate!
|
|
9
|
+
token
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def code
|
|
14
|
+
token
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def redirect_url
|
|
18
|
+
callback_url
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def to_query
|
|
22
|
+
q = "code=#{token}"
|
|
23
|
+
q << "&state=#{URI.escape(state)}" if @state
|
|
24
|
+
q
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
protected
|
|
28
|
+
|
|
29
|
+
def generate_keys
|
|
30
|
+
self.token = OAuth::Helper.generate_key(20)[0,20]
|
|
31
|
+
self.expires_at = 10.minutes.from_now
|
|
32
|
+
self.authorized_at = Time.now
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|