lasso 0.0.0 → 0.1.0
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.
- data/README.rdoc +90 -2
- data/Rakefile +3 -1
- data/VERSION +1 -1
- data/lasso.gemspec +26 -4
- data/lib/lasso.rb +26 -0
- data/lib/lasso/controller/base.rb +14 -0
- data/lib/lasso/controller/instance.rb +58 -0
- data/lib/lasso/controller/settings.rb +7 -0
- data/lib/lasso/model/base.rb +23 -0
- data/lib/lasso/model/instance.rb +12 -0
- data/lib/lasso/model/oauth_one.rb +38 -0
- data/lib/lasso/model/oauth_two.rb +19 -0
- data/lib/lasso/model/settings.rb +29 -0
- data/spec/controllers.rb +26 -0
- data/spec/db/database.yml +3 -0
- data/spec/db/models.rb +45 -0
- data/spec/db/schema.rb +12 -0
- data/spec/db/test.sqlite3 +0 -0
- data/spec/lasso_spec.rb +137 -3
- data/spec/spec_helper.rb +18 -0
- metadata +46 -4
data/README.rdoc
CHANGED
@@ -1,6 +1,94 @@
|
|
1
|
-
=
|
1
|
+
= Lasso
|
2
2
|
|
3
|
-
|
3
|
+
== Identity herding with OAuth
|
4
|
+
|
5
|
+
Lasso makes it damn easy to add SSO to your Rails application. Just load in your configuration, add a couple associations, and you are set to hit the trail running, partner.
|
6
|
+
|
7
|
+
== Gettings started
|
8
|
+
|
9
|
+
I haven't made generators for anything but that's ok cause Lasso mostly works via decorators.
|
10
|
+
|
11
|
+
Lasso creates OAuth tokens via nested attributes on whichever object you deem to be the owner of those keys (e.g, current_user, current_user.account, User.new) which makes it one-to-many and quite flexible.
|
12
|
+
|
13
|
+
=== Schema
|
14
|
+
|
15
|
+
You are going to want a model with a schema that at least looks like this, you can call it what you wish:
|
16
|
+
|
17
|
+
create_table :access_keys, :force => true do |t|
|
18
|
+
t.string "token_a", "token_b", :limit => 999
|
19
|
+
t.string "service", "type", :null => false
|
20
|
+
t.string "owner_type"
|
21
|
+
t.integer "owner_id"
|
22
|
+
t.datetime "created_at", "updated_at", :null => false
|
23
|
+
end
|
24
|
+
|
25
|
+
=== Model
|
26
|
+
|
27
|
+
Go ahead and add your provider details to the model, like so:
|
28
|
+
|
29
|
+
class AccessKey < ActiveRecord::Base
|
30
|
+
oauth do
|
31
|
+
provider '37signals' do
|
32
|
+
key 'YOUR_KEY_HERE'
|
33
|
+
secret 'YOUR_SECRET_HERE'
|
34
|
+
site 'https://launchpad.37signals.com'
|
35
|
+
authorize_path '/authorization/new'
|
36
|
+
access_token_path '/authorization/token'
|
37
|
+
end
|
38
|
+
provider 'LinkedIn' do
|
39
|
+
key 'YOUR_KEY_HERE'
|
40
|
+
secret 'YOUR_SECRET_HERE'
|
41
|
+
site 'https://api.linkedin.com'
|
42
|
+
authorize_path '/uas/oauth/authorize'
|
43
|
+
access_token_path '/uas/oauth/accessToken'
|
44
|
+
request_token_path '/uas/oauth/requestToken'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
=== Controller
|
50
|
+
|
51
|
+
You are going to want a controller that is able to handle the requests:
|
52
|
+
|
53
|
+
class OauthController < ApplicationController
|
54
|
+
ssl_required :create
|
55
|
+
processes_oauth_transactions_for :access_keys,
|
56
|
+
:through => lambda { current_user },
|
57
|
+
:callback => lambda { oauth_callback_url }
|
58
|
+
end
|
59
|
+
|
60
|
+
class AccessKeysController < ApplicationController
|
61
|
+
|
62
|
+
def index
|
63
|
+
@access_keys = current_user.access_keys
|
64
|
+
end
|
65
|
+
|
66
|
+
def show
|
67
|
+
@access_key = current_user.access_keys.find(params[:id])
|
68
|
+
end
|
69
|
+
|
70
|
+
def delete
|
71
|
+
access_key = current_user.access_keys.find(params[:id])
|
72
|
+
access_key.destroy
|
73
|
+
redirect_to access_keys_path
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
=== Routes
|
79
|
+
|
80
|
+
And maybe some routes:
|
81
|
+
|
82
|
+
map.resources :access_keys, :only => [:index, :show, :delete]
|
83
|
+
|
84
|
+
map.oauth_authorize '/:service/oauth/start', :controller => 'oauth', :action => 'new'
|
85
|
+
map.oauth_callback '/:service/oauth/callback', :controller => 'oauth', :action => 'create', :protocol => 'https'
|
86
|
+
|
87
|
+
=== Usage
|
88
|
+
|
89
|
+
Now OAuth is as simple as adding a link:
|
90
|
+
|
91
|
+
<%= link_to 'Integrate your account with your 37signals account', oauth_authorize_path(:service => '37signals') %>
|
4
92
|
|
5
93
|
== Note on Patches/Pull Requests
|
6
94
|
|
data/Rakefile
CHANGED
@@ -6,11 +6,13 @@ begin
|
|
6
6
|
Jeweler::Tasks.new do |gem|
|
7
7
|
gem.name = "lasso"
|
8
8
|
gem.summary = %Q{Identity herding with OAuth}
|
9
|
-
gem.description = %Q{
|
9
|
+
gem.description = %Q{Identity herding with OAuth}
|
10
10
|
gem.email = "james@marginleft.com"
|
11
11
|
gem.homepage = "http://github.com/jamesdaniels/lasso"
|
12
12
|
gem.authors = ["James Daniels"]
|
13
13
|
gem.add_development_dependency "rspec", ">= 1.2.9"
|
14
|
+
gem.add_dependency "oauth2", ">= 0.0.10"
|
15
|
+
gem.add_dependency "oauth"
|
14
16
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
17
|
end
|
16
18
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.1.0
|
data/lasso.gemspec
CHANGED
@@ -5,12 +5,12 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{lasso}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["James Daniels"]
|
12
|
-
s.date = %q{2010-06-
|
13
|
-
s.description = %q{
|
12
|
+
s.date = %q{2010-06-26}
|
13
|
+
s.description = %q{Identity herding with OAuth}
|
14
14
|
s.email = %q{james@marginleft.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
@@ -25,6 +25,19 @@ Gem::Specification.new do |s|
|
|
25
25
|
"VERSION",
|
26
26
|
"lasso.gemspec",
|
27
27
|
"lib/lasso.rb",
|
28
|
+
"lib/lasso/controller/base.rb",
|
29
|
+
"lib/lasso/controller/instance.rb",
|
30
|
+
"lib/lasso/controller/settings.rb",
|
31
|
+
"lib/lasso/model/base.rb",
|
32
|
+
"lib/lasso/model/instance.rb",
|
33
|
+
"lib/lasso/model/oauth_one.rb",
|
34
|
+
"lib/lasso/model/oauth_two.rb",
|
35
|
+
"lib/lasso/model/settings.rb",
|
36
|
+
"spec/controllers.rb",
|
37
|
+
"spec/db/database.yml",
|
38
|
+
"spec/db/models.rb",
|
39
|
+
"spec/db/schema.rb",
|
40
|
+
"spec/db/test.sqlite3",
|
28
41
|
"spec/lasso_spec.rb",
|
29
42
|
"spec/spec.opts",
|
30
43
|
"spec/spec_helper.rb"
|
@@ -35,7 +48,10 @@ Gem::Specification.new do |s|
|
|
35
48
|
s.rubygems_version = %q{1.3.6}
|
36
49
|
s.summary = %q{Identity herding with OAuth}
|
37
50
|
s.test_files = [
|
38
|
-
"spec/
|
51
|
+
"spec/controllers.rb",
|
52
|
+
"spec/db/models.rb",
|
53
|
+
"spec/db/schema.rb",
|
54
|
+
"spec/lasso_spec.rb",
|
39
55
|
"spec/spec_helper.rb"
|
40
56
|
]
|
41
57
|
|
@@ -45,11 +61,17 @@ Gem::Specification.new do |s|
|
|
45
61
|
|
46
62
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
47
63
|
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
64
|
+
s.add_runtime_dependency(%q<oauth2>, [">= 0.0.10"])
|
65
|
+
s.add_runtime_dependency(%q<oauth>, [">= 0"])
|
48
66
|
else
|
49
67
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
68
|
+
s.add_dependency(%q<oauth2>, [">= 0.0.10"])
|
69
|
+
s.add_dependency(%q<oauth>, [">= 0"])
|
50
70
|
end
|
51
71
|
else
|
52
72
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
73
|
+
s.add_dependency(%q<oauth2>, [">= 0.0.10"])
|
74
|
+
s.add_dependency(%q<oauth>, [">= 0"])
|
53
75
|
end
|
54
76
|
end
|
55
77
|
|
data/lib/lasso.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_record'
|
3
|
+
require 'action_controller'
|
4
|
+
require 'oauth2'
|
5
|
+
require 'oauth'
|
6
|
+
|
7
|
+
module Lasso
|
8
|
+
|
9
|
+
autoload :Controller, 'lasso/controller/base'
|
10
|
+
autoload :Model, 'lasso/model/base'
|
11
|
+
|
12
|
+
def processes_oauth_transactions_for(model, settings = {})
|
13
|
+
include Lasso::Controller
|
14
|
+
self.oauth_model = model
|
15
|
+
self.oauth_settings = settings
|
16
|
+
end
|
17
|
+
|
18
|
+
def oauth
|
19
|
+
include Lasso::Model
|
20
|
+
yield if block_given?
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
ActiveRecord::Base.extend Lasso
|
26
|
+
ActionController::Base.extend Lasso
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Lasso
|
2
|
+
module Controller
|
3
|
+
autoload :Settings, 'lasso/controller/settings'
|
4
|
+
autoload :InstanceMethods, 'lasso/controller/instance'
|
5
|
+
def self.included(base)
|
6
|
+
base.class_eval do
|
7
|
+
extend Lasso::Controller::Settings
|
8
|
+
include InstanceMethods
|
9
|
+
cattr_accessor :oauth_model
|
10
|
+
cattr_accessor :oauth_settings
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Lasso
|
2
|
+
module Controller
|
3
|
+
module InstanceMethods
|
4
|
+
def new
|
5
|
+
@oauth = type.new(:service => params[:service])
|
6
|
+
redirect
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
@oauth = type.new(:service => params[:service])
|
11
|
+
#@oauth = oauth_settings[:through].call.send(oauth_model).new(:service => params[:service])
|
12
|
+
parse_response
|
13
|
+
@owner = oauth_settings[:through].bind(self).call
|
14
|
+
nested = {"#{oauth_model}_attributes" => [@oauth.attributes]}
|
15
|
+
if @owner.update_attributes(nested)
|
16
|
+
redirect_to send("#{oauth_model.to_s.singularize}_path", @owner.send(oauth_model).last)
|
17
|
+
else
|
18
|
+
render :text => @oauth.to_yaml
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
def type
|
25
|
+
"OAuth#{version_one? && 'One' || 'Two'}#{oauth_model_constant}".constantize
|
26
|
+
end
|
27
|
+
|
28
|
+
def oauth_model_constant
|
29
|
+
oauth_model.to_s.singularize.camelcase.constantize
|
30
|
+
end
|
31
|
+
|
32
|
+
def version_one?
|
33
|
+
@version_one ||= oauth_model_constant.oauth_providers[params[:service]][:oauth_version] == 1
|
34
|
+
end
|
35
|
+
|
36
|
+
def parse_response
|
37
|
+
if version_one?
|
38
|
+
request_token = session[:request_token]
|
39
|
+
access_token = request_token.get_access_token(:oauth_verifier => params[:oauth_verifier])
|
40
|
+
@oauth.attributes = {:oauth_token => access_token.params[:oauth_token], :oauth_token_secret => access_token.params[:oauth_token_secret]}
|
41
|
+
else
|
42
|
+
access_token = @oauth.client.web_server.get_access_token(params[:code], :redirect_uri => oauth_settings[:callback].bind(self).call)
|
43
|
+
@oauth.attributes = {:refresh_token => access_token.refresh_token, :access_token => access_token.token}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def redirect
|
48
|
+
if version_one?
|
49
|
+
@request_token = @oauth.consumer.get_request_token(:oauth_callback => oauth_settings[:callback].bind(self).call)
|
50
|
+
session[:request_token] = @request_token
|
51
|
+
redirect_to @request_token.authorize_url
|
52
|
+
else
|
53
|
+
redirect_to @oauth.client.web_server.authorize_url(:redirect_uri => oauth_settings[:callback].bind(self).call)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'lasso/model/oauth_one'
|
2
|
+
require 'lasso/model/oauth_two'
|
3
|
+
|
4
|
+
module Lasso
|
5
|
+
module Model
|
6
|
+
autoload :Settings, 'lasso/model/settings'
|
7
|
+
autoload :InstanceMethods, 'lasso/model/instance'
|
8
|
+
def self.included(base)
|
9
|
+
unless ("OAuthOne".constantize rescue false)
|
10
|
+
base.class_eval do
|
11
|
+
extend Lasso::Model::Settings
|
12
|
+
include InstanceMethods
|
13
|
+
validates_presence_of :service
|
14
|
+
belongs_to :owner, :polymorphic => true
|
15
|
+
before_create :set_type
|
16
|
+
cattr_accessor :oauth_providers
|
17
|
+
end
|
18
|
+
define_oauth_one(base)
|
19
|
+
define_oauth_two(base)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
def define_oauth_one(parent)
|
2
|
+
eval <<OAUTHONE
|
3
|
+
class OAuthOne#{parent} < #{parent}
|
4
|
+
|
5
|
+
alias_attribute :oauth_token, :token_a
|
6
|
+
alias_attribute :oauth_token_secret, :token_b
|
7
|
+
|
8
|
+
validates_presence_of :oauth_token, :oauth_token_secret
|
9
|
+
|
10
|
+
def consumer
|
11
|
+
@consumer ||= OAuth::Consumer.new(config(:key), config(:secret), :site => config(:site), :request_token_path => config(:request_token_path), :authorize_path => config(:authorize_path), :access_token_path => config(:access_token_path))
|
12
|
+
end
|
13
|
+
|
14
|
+
def client
|
15
|
+
@client ||= case service
|
16
|
+
when 'linkedin'
|
17
|
+
LinkedIn::Client.new(config(:key), config(:secret))
|
18
|
+
when 'twitter'
|
19
|
+
Twitter::OAuth.new(config(:key), config(:secret))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def access
|
24
|
+
unless @access
|
25
|
+
client.authorize_from_access(oauth_token, oauth_token_secret)
|
26
|
+
@access ||= case service
|
27
|
+
when 'linkedin'
|
28
|
+
client
|
29
|
+
when 'twitter'
|
30
|
+
Twitter::Base.new(client)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
@access
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
OAUTHONE
|
38
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
def define_oauth_two(parent)
|
2
|
+
eval <<OAUTHTWO
|
3
|
+
class OAuthTwo#{parent} < #{parent}
|
4
|
+
|
5
|
+
alias_attribute :access_token, :token_a
|
6
|
+
alias_attribute :refresh_token, :token_b
|
7
|
+
|
8
|
+
validates_presence_of :access_token
|
9
|
+
|
10
|
+
def client
|
11
|
+
@client ||= OAuth2::Client.new(config(:key), config(:secret), :site => config(:site), :authorize_path => config(:authorize_path), :type => 'web_server', :access_token_path => config(:access_token_path))
|
12
|
+
end
|
13
|
+
|
14
|
+
def access
|
15
|
+
@access ||= OAuth2::AccessToken.new(client, access_token, refresh_token)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
OAUTHTWO
|
19
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Lasso
|
2
|
+
module Model
|
3
|
+
module Settings
|
4
|
+
class Provider
|
5
|
+
def method_missing(symbol, *args)
|
6
|
+
@settings ||= {}
|
7
|
+
@settings[symbol] = args.first
|
8
|
+
end
|
9
|
+
def to_h
|
10
|
+
@settings || {}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
RequiredSettings = [:site, :key, :secret, :site, :authorize_path, :access_token_path]
|
14
|
+
def provider(name, &block)
|
15
|
+
raise ArgumentError, 'Need to define the name' if name.blank?
|
16
|
+
p = Lasso::Model::Settings::Provider.new
|
17
|
+
block.bind(p).call
|
18
|
+
settings = p.to_h
|
19
|
+
settings[:oauth_version] = settings[:request_token_path].blank? && 2 || 1
|
20
|
+
missing_settings = RequiredSettings.map{|s| settings[s].blank? && s || nil}.compact
|
21
|
+
raise ArgumentError, "Need to define #{missing_settings.join(', ')} for any provider" unless missing_settings.empty?
|
22
|
+
raise ArgumentError, "Need to define request_token_path for OAuth 1 providers" if settings[:oauth_version] == 1 && settings[:request_token_path].blank?
|
23
|
+
self.oauth_providers ||= {}
|
24
|
+
self.oauth_providers[name] = settings
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
data/spec/controllers.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
class ApplicationController < ActionController::Base
|
2
|
+
|
3
|
+
helper_method :current_user
|
4
|
+
|
5
|
+
def current_user
|
6
|
+
@mock_user ||= mock(User, :id => 1, :login => 'someone')
|
7
|
+
User.stub!('find').with(1).and_return(@mock_user)
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
class SimpleOauthsController < ApplicationController
|
13
|
+
|
14
|
+
processes_oauth_transactions_for :simple_oauths,
|
15
|
+
:through => lambda { current_user },
|
16
|
+
:callback => lambda { "https://localhost/#{params[:service]}/callback" }
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
class OauthRegistrationController < ApplicationController
|
21
|
+
|
22
|
+
processes_oauth_transactions_for :simple_oauths,
|
23
|
+
:through => lambda { User.new },
|
24
|
+
:callback => lambda { "https://localhost/#{params[:service]}/callback" }
|
25
|
+
|
26
|
+
end
|
data/spec/db/models.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
class SimpleOauth < ActiveRecord::Base
|
2
|
+
|
3
|
+
oauth do
|
4
|
+
provider 'Someone' do
|
5
|
+
key 'asdf'
|
6
|
+
secret 'asdf'
|
7
|
+
site 'https://www.google.com'
|
8
|
+
authorize_path 'asdf'
|
9
|
+
access_token_path 'asdf'
|
10
|
+
request_token_path 'asdfff'
|
11
|
+
end
|
12
|
+
provider 'GitHub' do
|
13
|
+
key 'asdf'
|
14
|
+
secret 'asdf'
|
15
|
+
site 'https://www.github.com'
|
16
|
+
authorize_path 'asdf'
|
17
|
+
access_token_path 'asdf'
|
18
|
+
end
|
19
|
+
provider 'Facebook' do
|
20
|
+
key 'asdf'
|
21
|
+
secret 'asdf'
|
22
|
+
site 'https://www.facebook.com'
|
23
|
+
authorize_path 'asdf'
|
24
|
+
access_token_path 'asdf'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
class User < ActiveRecord::Base
|
31
|
+
|
32
|
+
has_many :simple_oauths, :dependent => :destroy, :as => :owner
|
33
|
+
|
34
|
+
accepts_nested_attributes_for :simple_oauths
|
35
|
+
|
36
|
+
with_options :unless => :using_sso? do |without_sso|
|
37
|
+
without_sso.validates_presence_of :username, :password
|
38
|
+
without_sso.validates_confirmation_of :password
|
39
|
+
end
|
40
|
+
|
41
|
+
def using_sso?
|
42
|
+
!simple_oauths.empty?
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
data/spec/db/schema.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
ActiveRecord::Schema.define(:version => 1) do
|
2
|
+
create_table :simple_oauths, :force => true do |t|
|
3
|
+
t.string "token_a", "token_b", :limit => 999
|
4
|
+
t.string "service", "type", :null => false
|
5
|
+
t.string "owner_type"
|
6
|
+
t.integer "owner_id"
|
7
|
+
t.datetime "created_at", "updated_at", :null => false
|
8
|
+
end
|
9
|
+
create_table :users, :force => true do |t|
|
10
|
+
t.string 'login', 'password'
|
11
|
+
end
|
12
|
+
end
|
Binary file
|
data/spec/lasso_spec.rb
CHANGED
@@ -1,7 +1,141 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
# Test extension
|
4
|
+
[SimpleOauth, SimpleOauthsController, OauthRegistrationController, ActiveRecord::Base, ActionController::Base].each do |klass|
|
5
|
+
describe klass do
|
6
|
+
it 'should extend out module' do
|
7
|
+
klass.is_a?(Lasso).should be_true
|
8
|
+
end
|
9
|
+
[:processes_oauth_transactions_for, :oauth].each do |method|
|
10
|
+
it "should respond to #{method}" do
|
11
|
+
klass.respond_to?(method).should be_true
|
12
|
+
end
|
13
|
+
end
|
6
14
|
end
|
7
15
|
end
|
16
|
+
|
17
|
+
{SimpleOauth => :model, SimpleOauthsController => :controller, OauthRegistrationController => :controller}.each do |klass, type|
|
18
|
+
describe klass do
|
19
|
+
{
|
20
|
+
Lasso::Model => (type == :model),
|
21
|
+
Lasso::Model::InstanceMethods => (type == :model),
|
22
|
+
Lasso::Controller => (type == :controller),
|
23
|
+
Lasso::Controller::InstanceMethods => (type == :controller)
|
24
|
+
}.each do |included, truthiness|
|
25
|
+
it "should #{truthiness && '' || 'not '}include #{included}" do
|
26
|
+
klass.include?(included).should eql(truthiness)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
{
|
30
|
+
Lasso::Model::Settings => (type == :model),
|
31
|
+
Lasso::Controller::Settings => (type == :controller)
|
32
|
+
}.each do |extended, truthiness|
|
33
|
+
it "should #{truthiness && '' || 'not '}extend #{extended}" do
|
34
|
+
klass.is_a?(extended).should eql(truthiness)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe SimpleOauth do
|
41
|
+
describe 'Settings' do
|
42
|
+
describe 'Existing' do
|
43
|
+
it 'should have a GitHub provider' do
|
44
|
+
SimpleOauth.oauth_providers['GitHub'].blank?.should be_false
|
45
|
+
end
|
46
|
+
it 'should have a Facebook provider' do
|
47
|
+
SimpleOauth.oauth_providers['Facebook'].blank?.should be_false
|
48
|
+
end
|
49
|
+
it 'should have a Someone provider' do
|
50
|
+
SimpleOauth.oauth_providers['Someone'].blank?.should be_false
|
51
|
+
end
|
52
|
+
it 'should have the right GitHub settings' do
|
53
|
+
SimpleOauth.oauth_providers['GitHub'].should eql({:key => 'asdf', :secret => 'asdf', :site => 'https://www.github.com', :authorize_path => 'asdf', :access_token_path => 'asdf', :oauth_version => 2})
|
54
|
+
end
|
55
|
+
it 'should have the right Facebook settings' do
|
56
|
+
SimpleOauth.oauth_providers['Facebook'].should eql({:key => 'asdf', :secret => 'asdf', :site => 'https://www.facebook.com', :authorize_path => 'asdf', :access_token_path => 'asdf', :oauth_version => 2})
|
57
|
+
end
|
58
|
+
it 'should have the right Someone settings' do
|
59
|
+
SimpleOauth.oauth_providers['Someone'].should eql({:key => 'asdf', :secret => 'asdf', :site => 'https://www.google.com', :authorize_path => 'asdf', :access_token_path => 'asdf', :oauth_version => 1, :request_token_path=>"asdfff"})
|
60
|
+
end
|
61
|
+
end
|
62
|
+
describe 'New' do
|
63
|
+
Settings = {:key => 'asdf', :secret => 'asdf', :site => 'https://www.google.com', :authorize_path => 'asdf', :access_token_path => 'asdf', :oauth_version => 1, :request_token_path=>"asdfff"}
|
64
|
+
it 'should be able to add a new provider' do
|
65
|
+
SimpleOauth.class_eval do
|
66
|
+
oauth do
|
67
|
+
provider 'ASDF' do
|
68
|
+
key Settings[:key]
|
69
|
+
secret Settings[:secret]
|
70
|
+
site Settings[:site]
|
71
|
+
authorize_path Settings[:authorize_path]
|
72
|
+
access_token_path Settings[:access_token_path]
|
73
|
+
request_token_path Settings[:request_token_path]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
it 'should have the proper settings' do
|
79
|
+
SimpleOauth.oauth_providers['ASDF'].should eql(Settings)
|
80
|
+
end
|
81
|
+
Lasso::Model::Settings::RequiredSettings.each do |required_key|
|
82
|
+
it "should require #{required_key} be set" do
|
83
|
+
lambda {
|
84
|
+
SimpleOauth.class_eval do
|
85
|
+
oauth do
|
86
|
+
provider 'ASDF' do
|
87
|
+
key Settings[:key] unless required_key == :key
|
88
|
+
secret Settings[:secret] unless required_key == :secret
|
89
|
+
site Settings[:site] unless required_key == :site
|
90
|
+
authorize_path Settings[:authorize_path] unless required_key == :authorize_path
|
91
|
+
access_token_path Settings[:access_token_path] unless required_key == :access_token_path
|
92
|
+
request_token_path Settings[:request_token_path] unless required_key == :request_token_path
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
}.should raise_error(ArgumentError)
|
97
|
+
end
|
98
|
+
it "should require #{required_key} to have a non-empty value" do
|
99
|
+
lambda {
|
100
|
+
settings = Settings.merge(required_key => '')
|
101
|
+
SimpleOauth.class_eval do
|
102
|
+
oauth do
|
103
|
+
provider 'ASDF' do
|
104
|
+
key settings[:key]
|
105
|
+
secret settings[:secret]
|
106
|
+
site settings[:site]
|
107
|
+
authorize_path settings[:authorize_path]
|
108
|
+
access_token_path settings[:access_token_path]
|
109
|
+
request_token_path settings[:request_token_path]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
}.should raise_error(ArgumentError)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe User do
|
121
|
+
it 'should require password/username without sso' do
|
122
|
+
User.new.should_not be_valid
|
123
|
+
end
|
124
|
+
it 'should work with nested attributes' do
|
125
|
+
(user = User.new(:simple_oauths_attributes => [{ :token_a => 'asdf', :token_b => 'adsf', :service => 'GitHub' }])).should be_valid
|
126
|
+
user.save!
|
127
|
+
user.reload
|
128
|
+
user.simple_oauths.empty?.should be_false
|
129
|
+
user.simple_oauths.first.class.should eql(OAuthTwoSimpleOauth)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe SimpleOauthsController do
|
134
|
+
describe 'Settings' do
|
135
|
+
describe 'Existing' do
|
136
|
+
it 'should have an oauth_model' do
|
137
|
+
SimpleOauthsController.oauth_model.should eql(:simple_oauths)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,9 +1,27 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
2
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
3
|
require 'lasso'
|
4
|
+
require 'active_record'
|
5
|
+
require 'active_record/fixtures'
|
6
|
+
require 'action_controller'
|
7
|
+
require 'active_support'
|
4
8
|
require 'spec'
|
5
9
|
require 'spec/autorun'
|
6
10
|
|
11
|
+
# establish the database connection
|
12
|
+
ActiveRecord::Base.configurations = YAML::load(IO.read(File.dirname(__FILE__) + '/db/database.yml'))
|
13
|
+
ActiveRecord::Base.establish_connection('active_record_merge_test')
|
14
|
+
|
15
|
+
# load the schema
|
16
|
+
$stdout = File.open('/dev/null', 'w')
|
17
|
+
load(File.dirname(__FILE__) + "/db/schema.rb")
|
18
|
+
$stdout = STDOUT
|
19
|
+
|
20
|
+
# load the models
|
21
|
+
require File.dirname(__FILE__) + '/db/models'
|
22
|
+
require File.dirname(__FILE__) + '/controllers'
|
23
|
+
|
24
|
+
|
7
25
|
Spec::Runner.configure do |config|
|
8
26
|
|
9
27
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
+
- 1
|
7
8
|
- 0
|
8
|
-
|
9
|
-
version: 0.0.0
|
9
|
+
version: 0.1.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- James Daniels
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-06-
|
17
|
+
date: 2010-06-26 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -31,7 +31,33 @@ dependencies:
|
|
31
31
|
version: 1.2.9
|
32
32
|
type: :development
|
33
33
|
version_requirements: *id001
|
34
|
-
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: oauth2
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
- 0
|
44
|
+
- 10
|
45
|
+
version: 0.0.10
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: oauth
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 0
|
57
|
+
version: "0"
|
58
|
+
type: :runtime
|
59
|
+
version_requirements: *id003
|
60
|
+
description: Identity herding with OAuth
|
35
61
|
email: james@marginleft.com
|
36
62
|
executables: []
|
37
63
|
|
@@ -49,6 +75,19 @@ files:
|
|
49
75
|
- VERSION
|
50
76
|
- lasso.gemspec
|
51
77
|
- lib/lasso.rb
|
78
|
+
- lib/lasso/controller/base.rb
|
79
|
+
- lib/lasso/controller/instance.rb
|
80
|
+
- lib/lasso/controller/settings.rb
|
81
|
+
- lib/lasso/model/base.rb
|
82
|
+
- lib/lasso/model/instance.rb
|
83
|
+
- lib/lasso/model/oauth_one.rb
|
84
|
+
- lib/lasso/model/oauth_two.rb
|
85
|
+
- lib/lasso/model/settings.rb
|
86
|
+
- spec/controllers.rb
|
87
|
+
- spec/db/database.yml
|
88
|
+
- spec/db/models.rb
|
89
|
+
- spec/db/schema.rb
|
90
|
+
- spec/db/test.sqlite3
|
52
91
|
- spec/lasso_spec.rb
|
53
92
|
- spec/spec.opts
|
54
93
|
- spec/spec_helper.rb
|
@@ -83,5 +122,8 @@ signing_key:
|
|
83
122
|
specification_version: 3
|
84
123
|
summary: Identity herding with OAuth
|
85
124
|
test_files:
|
125
|
+
- spec/controllers.rb
|
126
|
+
- spec/db/models.rb
|
127
|
+
- spec/db/schema.rb
|
86
128
|
- spec/lasso_spec.rb
|
87
129
|
- spec/spec_helper.rb
|