warden-salesforce 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,8 @@
1
+ coverage
2
+ .bundle
3
+ pkg
4
+ .DS_Store
5
+ Gemfile.lock
6
+ vendor/gems
7
+ *.gem
8
+ .rbenv-version
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --order rand
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - jruby-18mode # JRuby in 1.8 mode
7
+ - jruby-19mode # JRuby in 1.9 mode
8
+ - rbx-18mode
9
+ - ree
10
+ - ruby-head
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source :rubygems
2
+
3
+ gem 'ruby-debug19', :platforms => :ruby_19
4
+ gem 'ruby-debug', :platforms => :ruby_18
5
+
6
+ # Specify your gem's dependencies in warden-github.gemspec
7
+ gemspec
8
+
9
+ # vim:ft=ruby
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Corey Donohoe
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,14 @@
1
+ warden-salesforce
2
+ =============
3
+
4
+ A [warden](http://github.com/hassox/warden) strategy that provides oauth authentication to salesforce.
5
+
6
+ To test it out on localhost set your callback url to 'http://localhost:9292/auth/salesforce/callback'
7
+
8
+ There's an example app in [spec/app.rb](/ejholmes/warden-salesforce/blob/master/spec/app.rb).
9
+
10
+ The Extension in Action
11
+ =======================
12
+ % gem install bundler
13
+ % bundle install
14
+ % SALESFORCE_CLIENT_ID="<from SF>" SALESFORCE_CLIENT_SECRET="<from GH>" bundle exec rackup -p9393 -E none
@@ -0,0 +1,12 @@
1
+ require 'rubygems/package_task'
2
+ require 'rubygems/specification'
3
+ require 'date'
4
+ require 'bundler'
5
+
6
+ task :default => [:spec]
7
+
8
+ require 'rspec/core/rake_task'
9
+ desc "Run specs"
10
+ RSpec::Core::RakeTask.new do |t|
11
+ t.pattern = 'spec/**/*_spec.rb'
12
+ end
@@ -0,0 +1,17 @@
1
+ ENV['RACK_ENV'] ||= 'development'
2
+
3
+ begin
4
+ require File.expand_path('../.bundle/environment', __FILE__)
5
+ rescue LoadError
6
+ require "rubygems"
7
+ require "bundler"
8
+ Bundler.setup
9
+ end
10
+
11
+ $LOAD_PATH << File.dirname(__FILE__) + '/lib'
12
+ require File.expand_path(File.join(File.dirname(__FILE__), 'lib', 'warden-salesforce'))
13
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec', 'app'))
14
+
15
+ run Example.app
16
+
17
+ # vim:ft=ruby
@@ -0,0 +1,13 @@
1
+ require 'warden'
2
+ require 'oauth2'
3
+ require 'yajl'
4
+
5
+ module Warden
6
+ module Salesforce
7
+ class SalesforceMisconfiguredError < StandardError; end
8
+ end
9
+ end
10
+
11
+ require 'warden-salesforce/version'
12
+ require 'warden-salesforce/user'
13
+ require 'warden-salesforce/strategy'
@@ -0,0 +1,88 @@
1
+ Warden::Strategies.add(:salesforce) do
2
+ # Need to make sure that we have a pure representation of the query string.
3
+ # Rails adds an "action" parameter which causes the openid gem to error
4
+ def params
5
+ @params ||= Rack::Utils.parse_query(request.query_string)
6
+ end
7
+
8
+ def authenticate!
9
+ if(params['code'] && params['state'] &&
10
+ env['rack.session']['salesforce_oauth_state'] &&
11
+ env['rack.session']['salesforce_oauth_state'].size > 0 &&
12
+ params['state'] == env['rack.session']['salesforce_oauth_state'])
13
+ begin
14
+ access_token = access_token(params['code'])
15
+
16
+ success!(Warden::Salesforce::User.new(access_token))
17
+ rescue OAuth2::Error
18
+ %(<p>Outdated ?code=#{params['code']}:</p><p>#{$!}</p><p><a href="/auth/salesforce">Retry</a></p>)
19
+ end
20
+ else
21
+ env['rack.session']['salesforce_oauth_state'] = state
22
+ env['rack.session']['return_to'] = env['REQUEST_URI']
23
+ throw(:warden, [ 302, {'Content-Type' => 'text/html', 'Location' => authorize_url}, [ ]])
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def client
30
+ @client ||= OAuth2::Client.new client_id, secret, {
31
+ :site => oauth_domain,
32
+ :token_url => '/services/oauth2/token',
33
+ :authorize_url => '/services/oauth2/authorize'
34
+ }
35
+ end
36
+
37
+ def authorize_url
38
+ client.auth_code.authorize_url(
39
+ :state => state,
40
+ :scope => scopes,
41
+ :redirect_uri => callback_url
42
+ )
43
+ end
44
+
45
+ def access_token(code)
46
+ client.auth_code.get_token(code, :redirect_uri => callback_url)
47
+ end
48
+
49
+ def state
50
+ @state ||= Digest::SHA1.hexdigest(rand(36**8).to_s(36))
51
+ end
52
+
53
+ def oauth_domain
54
+ config[:salesforce_oauth_domain]
55
+ end
56
+
57
+ def client_id
58
+ config[:salesforce_client_id]
59
+ end
60
+
61
+ def secret
62
+ config[:salesforce_secret]
63
+ end
64
+
65
+ def scopes
66
+ config[:salesforce_scopes]
67
+ end
68
+
69
+ def config
70
+ env['warden'].config
71
+ end
72
+
73
+ def callback_url
74
+ absolute_url(request, env['warden'].config[:salesforce_callback_url], env['HTTP_X_FORWARDED_PROTO'])
75
+ end
76
+
77
+ def absolute_url(request, suffix = nil, proto = "http")
78
+ port_part = case request.scheme
79
+ when "http"
80
+ request.port == 80 ? "" : ":#{request.port}"
81
+ when "https"
82
+ request.port == 443 ? "" : ":#{request.port}"
83
+ end
84
+
85
+ proto = "http" if proto.nil?
86
+ "#{proto}://#{request.host}#{port_part}#{suffix}"
87
+ end
88
+ end
@@ -0,0 +1,22 @@
1
+ module Warden
2
+ module Salesforce
3
+ class User
4
+ attr_reader :token
5
+ attr_reader :refresh_token
6
+ attr_reader :instance_url
7
+ attr_reader :raw_info
8
+
9
+ def initialize(access_token)
10
+ @token = access_token.token
11
+ @refresh_token = access_token.refresh_token
12
+ @instance_url = access_token.params['instance_url']
13
+ @raw_info = access_token.post(access_token['id']).parsed
14
+ end
15
+
16
+ def username
17
+ raw_info['username']
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ module Warden
2
+ module Salesforce
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,70 @@
1
+ require 'sinatra'
2
+
3
+ module Example
4
+ class App < Sinatra::Base
5
+ enable :sessions
6
+ enable :raise_errors
7
+ disable :show_exceptions
8
+
9
+ use Warden::Manager do |manager|
10
+ manager.default_strategies :salesforce
11
+ manager.failure_app = BadAuthentication
12
+
13
+ manager[:salesforce_client_id] = ENV['SALESFORCE_CLIENT_ID'] || 'ee9aa24b64d82c21535a'
14
+ manager[:salesforce_secret] = ENV['SALESFORCE_CLIENT_SECRET'] || 'ed8ff0c54067aefb808dab1ca265865405d08d6f'
15
+
16
+ manager[:salesforce_scopes] = 'api'
17
+ manager[:salesforce_oauth_domain] = ENV['SALESFORCE_OAUTH_DOMAIN'] || 'https://login.salesforce.com'
18
+ manager[:salesforce_callback_url] = '/auth/salesforce/callback'
19
+ end
20
+
21
+ helpers do
22
+ def ensure_authenticated
23
+ unless env['warden'].authenticate!
24
+ throw(:warden)
25
+ end
26
+ end
27
+
28
+ def user
29
+ env['warden'].user
30
+ end
31
+ end
32
+
33
+ get '/' do
34
+ ensure_authenticated
35
+ <<-EOS
36
+ <h2>Token, #{user.username}!</h2>
37
+ <h3>Instance URL, #{user.instance_url}</h3>
38
+ #{user.raw_info}
39
+ EOS
40
+ end
41
+
42
+ get '/redirect_to' do
43
+ ensure_authenticated
44
+ "Hello There, #{user.name}! return_to is working!"
45
+ end
46
+
47
+ get '/auth/salesforce/callback' do
48
+ ensure_authenticated
49
+ redirect '/'
50
+ end
51
+
52
+ get '/logout' do
53
+ env['warden'].logout
54
+ "Peace!"
55
+ end
56
+ end
57
+
58
+ class BadAuthentication < Sinatra::Base
59
+ get '/unauthenticated' do
60
+ status 403
61
+ "Unable to authenticate, sorry bud."
62
+ end
63
+ end
64
+
65
+ def self.app
66
+ @app ||= Rack::Builder.new do
67
+ run App
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,18 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "Warden::Salesforce" do
4
+ it "requesting an url that requires authentication redirects to salesforce" do
5
+ response = get "/"
6
+
7
+ uri = Addressable::URI.parse(response.headers["Location"])
8
+
9
+ uri.scheme.should eql('https')
10
+ uri.host.should eql('login.salesforce.com')
11
+
12
+ params = uri.query_values
13
+ params['response_type'].should eql('code')
14
+ params['scope'].should eql('api')
15
+ params['client_id'].should match(/\w{20}/)
16
+ params['redirect_uri'].should eql('http://example.org/auth/salesforce/callback')
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ Bundler.require(:default, :runtime, :test)
2
+
3
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'warden-salesforce')
4
+ require File.join(File.dirname(__FILE__), 'app')
5
+ require 'rack/test'
6
+ require 'webrat'
7
+ require 'addressable/uri'
8
+ require 'pp'
9
+
10
+ Webrat.configure do |config|
11
+ config.mode = :rack
12
+ config.application_port = 4567
13
+ end
14
+
15
+ RSpec.configure do |config|
16
+ config.include(Rack::Test::Methods)
17
+ config.include(Webrat::Methods)
18
+ config.include(Webrat::Matchers)
19
+
20
+ config.before(:each) do
21
+ end
22
+
23
+ def app
24
+ Example.app
25
+ end
26
+ end
@@ -0,0 +1,37 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ require 'warden-salesforce/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "warden-salesforce"
8
+ s.version = Warden::Salesforce::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["Eric Holmes"]
11
+ s.email = ["eric@ejholmes.net"]
12
+ s.homepage = "http://github.com/ejholmes/warden-salesforce"
13
+ s.summary = "A warden strategy for easy oauth integration with Salesforce.com and Databasedot.com"
14
+ s.description = s.summary
15
+
16
+ s.rubyforge_project = "warden-salesforce"
17
+
18
+ s.add_dependency "json", "~>1.5"
19
+ s.add_dependency "warden", "~>1.0"
20
+ s.add_dependency "oauth2", "~>0.5.2"
21
+ s.add_dependency "rest-client", "~>1.6.1"
22
+ s.add_dependency "yajl-ruby", "~>1.1"
23
+
24
+ s.add_development_dependency "rack", "~>1.4.0"
25
+ s.add_development_dependency "rake"
26
+ s.add_development_dependency "rspec", "~>2.8.0"
27
+ s.add_development_dependency "webrat"
28
+ s.add_development_dependency "sinatra"
29
+ s.add_development_dependency "shotgun"
30
+ s.add_development_dependency "addressable", "~>2.2.0"
31
+ s.add_development_dependency "rack-test", "~>0.5.3"
32
+
33
+ s.files = `git ls-files`.split("\n")
34
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
35
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
36
+ s.require_paths = ["lib"]
37
+ end
metadata ADDED
@@ -0,0 +1,209 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: warden-salesforce
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Eric Holmes
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: json
16
+ requirement: &70105052691400 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.5'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70105052691400
25
+ - !ruby/object:Gem::Dependency
26
+ name: warden
27
+ requirement: &70105052690900 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '1.0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70105052690900
36
+ - !ruby/object:Gem::Dependency
37
+ name: oauth2
38
+ requirement: &70105052690440 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 0.5.2
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70105052690440
47
+ - !ruby/object:Gem::Dependency
48
+ name: rest-client
49
+ requirement: &70105052689980 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.6.1
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70105052689980
58
+ - !ruby/object:Gem::Dependency
59
+ name: yajl-ruby
60
+ requirement: &70105052689520 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: '1.1'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *70105052689520
69
+ - !ruby/object:Gem::Dependency
70
+ name: rack
71
+ requirement: &70105052689060 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 1.4.0
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70105052689060
80
+ - !ruby/object:Gem::Dependency
81
+ name: rake
82
+ requirement: &70105052688680 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70105052688680
91
+ - !ruby/object:Gem::Dependency
92
+ name: rspec
93
+ requirement: &70105052688140 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ~>
97
+ - !ruby/object:Gem::Version
98
+ version: 2.8.0
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70105052688140
102
+ - !ruby/object:Gem::Dependency
103
+ name: webrat
104
+ requirement: &70105052687720 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *70105052687720
113
+ - !ruby/object:Gem::Dependency
114
+ name: sinatra
115
+ requirement: &70105052687260 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: *70105052687260
124
+ - !ruby/object:Gem::Dependency
125
+ name: shotgun
126
+ requirement: &70105052686840 !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: *70105052686840
135
+ - !ruby/object:Gem::Dependency
136
+ name: addressable
137
+ requirement: &70105052686340 !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ~>
141
+ - !ruby/object:Gem::Version
142
+ version: 2.2.0
143
+ type: :development
144
+ prerelease: false
145
+ version_requirements: *70105052686340
146
+ - !ruby/object:Gem::Dependency
147
+ name: rack-test
148
+ requirement: &70105052685840 !ruby/object:Gem::Requirement
149
+ none: false
150
+ requirements:
151
+ - - ~>
152
+ - !ruby/object:Gem::Version
153
+ version: 0.5.3
154
+ type: :development
155
+ prerelease: false
156
+ version_requirements: *70105052685840
157
+ description: A warden strategy for easy oauth integration with Salesforce.com and
158
+ Databasedot.com
159
+ email:
160
+ - eric@ejholmes.net
161
+ executables: []
162
+ extensions: []
163
+ extra_rdoc_files: []
164
+ files:
165
+ - .gitignore
166
+ - .rspec
167
+ - .travis.yml
168
+ - Gemfile
169
+ - LICENSE
170
+ - README.md
171
+ - Rakefile
172
+ - config.ru
173
+ - lib/warden-salesforce.rb
174
+ - lib/warden-salesforce/strategy.rb
175
+ - lib/warden-salesforce/user.rb
176
+ - lib/warden-salesforce/version.rb
177
+ - spec/app.rb
178
+ - spec/oauth_spec.rb
179
+ - spec/spec_helper.rb
180
+ - warden-salesforce.gemspec
181
+ homepage: http://github.com/ejholmes/warden-salesforce
182
+ licenses: []
183
+ post_install_message:
184
+ rdoc_options: []
185
+ require_paths:
186
+ - lib
187
+ required_ruby_version: !ruby/object:Gem::Requirement
188
+ none: false
189
+ requirements:
190
+ - - ! '>='
191
+ - !ruby/object:Gem::Version
192
+ version: '0'
193
+ required_rubygems_version: !ruby/object:Gem::Requirement
194
+ none: false
195
+ requirements:
196
+ - - ! '>='
197
+ - !ruby/object:Gem::Version
198
+ version: '0'
199
+ requirements: []
200
+ rubyforge_project: warden-salesforce
201
+ rubygems_version: 1.8.11
202
+ signing_key:
203
+ specification_version: 3
204
+ summary: A warden strategy for easy oauth integration with Salesforce.com and Databasedot.com
205
+ test_files:
206
+ - spec/app.rb
207
+ - spec/oauth_spec.rb
208
+ - spec/spec_helper.rb
209
+ has_rdoc: