├── .gitignore ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── lib ├── omniauth-stripe-connect.rb ├── omniauth-stripe-connect │ └── version.rb └── omniauth │ ├── strategies │ └── stripe_connect.rb │ └── stripe_connect.rb ├── omniauth-stripe-connect.gemspec └── spec ├── omniauth └── strategies │ └── stripe_connect_spec.rb └── spec_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | *.rvmrc 4 | .ruby-version 5 | .ruby-gemset 6 | .bundle 7 | .config 8 | .yardoc 9 | Gemfile.lock 10 | InstalledFiles 11 | _yardoc 12 | coverage 13 | doc/ 14 | lib/bundler/man 15 | pkg 16 | rdoc 17 | spec/reports 18 | test/tmp 19 | test/version_tmp 20 | tmp 21 | example 22 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gem 'rake' 3 | 4 | # Specify your gem's dependencies in omniauth-stripe-connect.gemspec 5 | gemspec 6 | 7 | group :test do 8 | gem 'rspec', '>= 2.14' 9 | end 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Isaac Sanders 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OmniAuth::StripeConnect 2 | 3 | Stripe Connect OAuth2 Strategy for OmniAuth 1.0. 4 | 5 | Supports the OAuth 2.0 server-side and client-side flows. 6 | Read the Stripe Connect docs for more details: https://stripe.com/connect 7 | 8 | ## Installation 9 | 10 | Add this line to your application's Gemfile: 11 | 12 | gem 'omniauth-stripe-connect' 13 | 14 | And then execute: 15 | 16 | $ bundle 17 | 18 | Or install it yourself as: 19 | 20 | $ gem install omniauth-stripe-connect 21 | 22 | ## Usage 23 | 24 | OmniAuth::Strategies::StripeConnect is simply a Rack middleware. Read the OmniAuth 25 | 1.0 docs for detailed instructions: https://github.com/intridea/omniauth. 26 | 27 | ### Non-Devise 28 | Here's a quick example, adding the middleware to a Rails app in 29 | `config/initializers/omniauth.rb`: 30 | 31 | ```ruby 32 | Rails.application.config.middleware.use OmniAuth::Builder do 33 | provider :stripe_connect, ENV['STRIPE_CONNECT_CLIENT_ID'], ENV['STRIPE_SECRET'] 34 | end 35 | ``` 36 | 37 | ### Devise 38 | 39 | You need to declare the provider in your `config/initializers/devise.rb`: 40 | 41 | ```ruby 42 | config.omniauth :stripe_connect, "STRIPE_CONNECT_CLIENT_ID", "STRIPE_SECRET" 43 | ``` 44 | 45 | You'll also need to add some configuration to your devise model (e.g. User in `app/models/user.rb`) along with any other OmniAuth providers you might have: 46 | ```ruby 47 | :omniauthable, :omniauth_providers => [:stripe_connect] 48 | ``` 49 | 50 | ### General Usage 51 | 52 | Your `STRIPE_CONNECT_CLIENT_ID` is application-specific and your `STRIPE_SECRET` is account-specific and may also be known as your Stripe API key or Stripe Private key. 53 | 54 | Edit your `routes.rb` file to have: 55 | `devise_for :users, :controllers => { :omniauth_callbacks => "omniauth_callbacks" }` 56 | 57 | And create a file called `omniauth_callbacks_controller.rb` which should have this inside: 58 | ```ruby 59 | class OmniauthCallbacksController < Devise::OmniauthCallbacksController 60 | 61 | def stripe_connect 62 | # Delete the code inside of this method and write your own. 63 | # The code below is to show you where to access the data. 64 | raise request.env["omniauth.auth"].to_yaml 65 | end 66 | end 67 | ``` 68 | 69 | Make sure to go to Stripe's Account Settings > Applications and set your Redirect URL to: 70 | `http://localhost:3003/users/auth/stripe_connect/callback` 71 | 72 | The Webhook URL will be something similar: 73 | `http://www.yourdomain.com/users/auth/stripe_connect/callback` 74 | 75 | Then you can hit `/auth/stripe_connect` 76 | 77 | If you hit `/auth/stripe_connect` with any query params, they will be passed along to Stripe. You can access these params from `request.env['omniauth.params']`. Read [Stripe's OAuth Reference](https://stripe.com/docs/connect/reference) for more information. 78 | 79 | ## Auth Hash 80 | 81 | Here is an example of the Auth Hash you get back from calling `request.env['omniauth.auth']`: 82 | 83 | ```ruby 84 | { 85 | "provider"=>"stripe_connect", 86 | "uid"=>"", 87 | "info"=> { 88 | "email"=>"email@example.com", 89 | "name"=>"Name", 90 | "nickname"=>"Nickname", 91 | "scope"=>"read_write", # or "read_only" 92 | "livemode"=>false, 93 | "stripe_publishable_key"=>"", 94 | }, 95 | "credentials"=> { 96 | "token"=>"", 97 | "refresh_token"=>"", 98 | "expires"=>false 99 | }, 100 | "extra"=> { 101 | "raw_info"=> { 102 | "token_type"=>"bearer", 103 | "stripe_user_id"=>"", 104 | "scope"=>"read_only", 105 | "stripe_publishable_key"=>"", 106 | "livemode"=>false 107 | }, 108 | "extra_info"=> { 109 | "business_logo"=>"https://stripe.com/business_logo.png", 110 | "business_name"=>"Business Name", 111 | "business_url"=>"example.com", 112 | "charges_enabled"=>true, 113 | "country"=>"US", 114 | "default_currency"=>"eur", 115 | "details_submitted"=>true, 116 | "display_name"=>"Business Name", 117 | "email"=>"email@example.com", 118 | "id"=>"", 119 | "managed"=>false, 120 | "object"=>"account", 121 | "statement_descriptor"=>"EXAMPLE.COM", 122 | "support_email"=>"support@example.com", 123 | "support_phone"=>"123456789", 124 | "timezone"=>"Europe/Berlin", 125 | "transfers_enabled"=>true 126 | } 127 | } 128 | } 129 | ``` 130 | 131 | ## Additional Tutorials 132 | [Stripe Connect in Rails Tutorial](https://web.archive.org/web/20160313043319/http://www.munocreative.com/nerd-notes/winvoice) 133 | 134 | ## Contributing 135 | 136 | 1. Fork it 137 | 2. Create your feature branch (`git checkout -b my-new-feature`) 138 | 3. Commit your changes (`git commit -am 'Added some feature'`) 139 | 4. Push to the branch (`git push origin my-new-feature`) 140 | 5. Create new Pull Request 141 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | require "bundler/gem_tasks" 3 | require 'rspec/core/rake_task' 4 | 5 | desc 'Default: run specs.' 6 | task :default => :spec 7 | 8 | desc "Run specs" 9 | RSpec::Core::RakeTask.new 10 | -------------------------------------------------------------------------------- /lib/omniauth-stripe-connect.rb: -------------------------------------------------------------------------------- 1 | require "omniauth-stripe-connect/version" 2 | require 'omniauth/stripe_connect' 3 | -------------------------------------------------------------------------------- /lib/omniauth-stripe-connect/version.rb: -------------------------------------------------------------------------------- 1 | module OmniAuth 2 | module StripeConnect 3 | VERSION = "2.10.1" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/omniauth/strategies/stripe_connect.rb: -------------------------------------------------------------------------------- 1 | require 'omniauth/strategies/oauth2' 2 | 3 | module OmniAuth 4 | module Strategies 5 | class StripeConnect < OmniAuth::Strategies::OAuth2 6 | option :name, :stripe_connect 7 | 8 | option :client_options, { 9 | :site => 'https://connect.stripe.com' 10 | } 11 | 12 | option :authorize_options, [:scope, :stripe_landing, :always_prompt] 13 | option :provider_ignores_state, true 14 | 15 | uid { raw_info[:stripe_user_id] } 16 | 17 | info do 18 | { 19 | :name => extra_info[:display_name] || extra_info[:business_name] || extra_info[:email], 20 | :email => extra_info[:email], 21 | :nickname => extra_info[:display_name], 22 | :scope => raw_info[:scope], 23 | :livemode => raw_info[:livemode], 24 | :stripe_publishable_key => raw_info[:stripe_publishable_key] 25 | } 26 | end 27 | 28 | extra do 29 | e = { 30 | :raw_info => raw_info 31 | } 32 | e[:extra_info] = extra_info unless skip_info? 33 | 34 | e 35 | end 36 | 37 | credentials do 38 | hash = {'token' => access_token.token} 39 | hash.merge!('refresh_token' => access_token.refresh_token) if access_token.refresh_token 40 | hash.merge!('expires_at' => access_token.expires_at) if access_token.expires? 41 | hash.merge!('expires' => access_token.expires?) 42 | hash 43 | end 44 | 45 | def raw_info 46 | @raw_info ||= deep_symbolize(access_token.params) 47 | end 48 | 49 | def extra_info 50 | @extra_info ||= deep_symbolize(access_token.get("https://api.stripe.com/v1/account").parsed) 51 | end 52 | 53 | def redirect_params 54 | if options.key?(:callback_path) || OmniAuth.config.full_host 55 | {:redirect_uri => callback_url} 56 | else 57 | {} 58 | end 59 | end 60 | 61 | # NOTE: We call redirect_params AFTER super in these methods intentionally 62 | # the OAuth2 strategy uses the authorize_params and token_params methods 63 | # to set up some state for testing that we need in redirect_params 64 | 65 | def authorize_params 66 | params = super 67 | params = params.merge(request_params) unless OmniAuth.config.test_mode 68 | redirect_params.merge(params) 69 | end 70 | 71 | def token_params 72 | params = super.to_hash(:symbolize_keys => true) \ 73 | .merge(:headers => { 'Authorization' => "Bearer #{client.secret}" }) 74 | 75 | redirect_params.merge(params) 76 | end 77 | 78 | def callback_url 79 | full_host + script_name + callback_path 80 | end 81 | 82 | def request_phase 83 | redirect client.auth_code.authorize_url(authorize_params) 84 | end 85 | 86 | def build_access_token 87 | verifier = request.params['code'] 88 | client.auth_code.get_token(verifier, token_params) 89 | end 90 | 91 | def request_params 92 | request.params.except(*request_blacklisted_params) 93 | end 94 | 95 | def request_blacklisted_params 96 | %w(_method) 97 | end 98 | end 99 | end 100 | end 101 | -------------------------------------------------------------------------------- /lib/omniauth/stripe_connect.rb: -------------------------------------------------------------------------------- 1 | require 'omniauth/strategies/stripe_connect' 2 | -------------------------------------------------------------------------------- /omniauth-stripe-connect.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | require File.expand_path('../lib/omniauth-stripe-connect/version', __FILE__) 3 | 4 | Gem::Specification.new do |gem| 5 | gem.authors = ["Isaac Sanders"] 6 | gem.email = ["isaac@isaacbfsanders.com"] 7 | gem.description = %q{Stripe Connect OAuth2 Strategy for OmniAuth 1.0.} 8 | gem.summary = %q{ 9 | Supports the OAuth 2.0 server-side and client-side flows. 10 | Read the Stripe Connect docs for more details: https://stripe.com/docs/connect 11 | } 12 | gem.homepage = "https://stripe.com/docs/connect" 13 | 14 | gem.files = `git ls-files | grep -v example`.split($\) 15 | gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } 16 | gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) 17 | gem.name = "omniauth-stripe-connect" 18 | gem.require_paths = ["lib"] 19 | gem.version = OmniAuth::StripeConnect::VERSION 20 | gem.license = "MIT" 21 | 22 | gem.add_dependency 'omniauth', '~> 2.0' 23 | gem.add_dependency 'omniauth-oauth2', '~> 1.4' 24 | end 25 | -------------------------------------------------------------------------------- /spec/omniauth/strategies/stripe_connect_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe OmniAuth::Strategies::StripeConnect do 4 | let(:fresh_strategy) { Class.new(OmniAuth::Strategies::StripeConnect) } 5 | 6 | 7 | before(:each) do 8 | OmniAuth.config.test_mode = true 9 | @old_host = OmniAuth.config.full_host 10 | end 11 | 12 | after(:each) do 13 | OmniAuth.config.full_host = @old_host 14 | OmniAuth.config.test_mode = false 15 | end 16 | 17 | describe '#authorize_params' do 18 | subject { fresh_strategy } 19 | 20 | it 'should include redirect_uri if full_host is set' do 21 | OmniAuth.config.full_host = 'https://foo.com/' 22 | instance = subject.new('abc', 'def') 23 | 24 | instance.authorize_params[:redirect_uri].should =~ /\Ahttps:\/\/foo\.com/ 25 | end 26 | 27 | it 'should include redirect_uri if callback_path is set' do 28 | # TODO: It would be nice to grab this from the request URL 29 | # instead of setting it on the config 30 | OmniAuth.config.full_host = 'https://foo.com/' 31 | instance = subject.new('abc', 'def', :callback_path => 'bar/baz') 32 | 33 | instance.authorize_params[:redirect_uri].should == 'https://foo.com/bar/baz' 34 | end 35 | 36 | it 'should not include redirect_uri by default' do 37 | instance = subject.new('abc', 'def') 38 | 39 | expect(instance.authorize_params[:redirect_uri]).to be_nil 40 | end 41 | end 42 | 43 | describe '#token_params' do 44 | subject { fresh_strategy } 45 | 46 | # NOTE: We call authorize_params first in each of these methods 47 | # since the OAuth2 gem uses it to setup some state for testing 48 | 49 | it 'should include redirect_uri if full_host is set' do 50 | OmniAuth.config.full_host = 'https://foo.com/' 51 | instance = subject.new('abc', 'def') 52 | 53 | instance.authorize_params 54 | instance.token_params[:redirect_uri].should =~ /\Ahttps:\/\/foo\.com/ 55 | end 56 | 57 | it 'should include redirect_uri if callback_path is set' do 58 | # TODO: It would be nice to grab this from the request URL 59 | # instead of setting it on the config 60 | OmniAuth.config.full_host = 'https://foo.com/' 61 | instance = subject.new('abc', 'def', :callback_path => 'bar/baz') 62 | 63 | instance.authorize_params 64 | instance.token_params[:redirect_uri].should == 'https://foo.com/bar/baz' 65 | end 66 | 67 | it 'should not include redirect_uri by default' do 68 | instance = subject.new('abc', 'def') 69 | 70 | instance.authorize_params 71 | expect(instance.token_params[:redirect_uri]).to be_nil 72 | end 73 | end 74 | 75 | describe '#callback_url' do 76 | subject { fresh_strategy } 77 | OmniAuth.config.full_host = 'https://foo.com/' 78 | 79 | it 'returns a url with the host and path' do 80 | instance = subject.new('abc', 'def', :callback_path => 'bar/baz') 81 | instance.authorize_params 82 | expect(instance.callback_url).to eq 'https://foo.com/bar/baz' 83 | end 84 | end 85 | end 86 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'rspec' 2 | require 'omniauth-stripe-connect' 3 | --------------------------------------------------------------------------------