warden-salesforce 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.
@@ -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: