omniauth-shootproof 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ad3161147032c70da2f50db9f0898b357c1e13c9
4
+ data.tar.gz: 64da2bc0e6684fbd88317ffb55ea28bb818f465c
5
+ SHA512:
6
+ metadata.gz: f93fc70cbbb3026e2826b595c4808e511ab03ec078fa6740e5c9eb3fc0a7413d44605114a18a5472064c43d441aa4425aa692cbdbb5e9b137765c79a91395e91
7
+ data.tar.gz: f24ef35ba36f9b780a784b1f26f37a2005ef5be6e56e9ce5c31f30f1a5b8b7a921fb820119045caa576048d9ace5216af6b3840fe2aebaba819b70e3137b300d
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .ruby-version
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ *.swp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format=progress
data/.travis.yml ADDED
@@ -0,0 +1,23 @@
1
+ before_install: gem install bundler
2
+ env:
3
+ global:
4
+ - JRUBY_OPTS="$JRUBY_OPTS --debug"
5
+ language: ruby
6
+ rvm:
7
+ - 1.8.7
8
+ - 1.9.3
9
+ - 2.0.0
10
+ - 2.1
11
+ - 2.2
12
+ - 2.3
13
+ - jruby-18mode
14
+ - jruby-19mode
15
+ - jruby-head
16
+ - rbx-2
17
+ - ruby-head
18
+ matrix:
19
+ allow_failures:
20
+ - rvm: jruby-head
21
+ - rvm: ruby-head
22
+ fast_finish: true
23
+ sudo: false
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "rake"
4
+
5
+ group :test do
6
+ gem "json", :platforms => [:jruby, :ruby_18, :ruby_19]
7
+ gem "mime-types", "~> 1.25", :platforms => [:jruby, :ruby_18]
8
+ gem "rack-test"
9
+ gem "rest-client", "~> 1.6.0", :platforms => [:jruby, :ruby_18]
10
+ gem "rspec", "~> 3.2"
11
+ gem "rubocop", ">= 0.30", :platforms => [:ruby_19, :ruby_20, :ruby_21, :ruby_22]
12
+ gem "webmock"
13
+ end
14
+
15
+ # Specify your gem's dependencies in omniauth-shootproof.gemspec
16
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2017 Paul Scarrone, Gary Newsome, and SavvySoftWorks LLC.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # OmniAuth Shootproof
2
+ ### Based off OmniAuth OAuth2
3
+
4
+ [![Gem Version](http://img.shields.io/gem/v/omniauth-shootproof.svg)][gem]
5
+ [![Build Status](https://travis-ci.org/SavvySoftWorksLLC/omniauth-shootproof.svg?branch=master)](https://travis-ci.org/SavvySoftWorksLLC/omniauth-shootproof)
6
+ [![Dependency Status](http://img.shields.io/gemnasium/SavvySoftWorksLLC/omniauth-shootproof.svg)][gemnasium]
7
+
8
+ [gem]: https://rubygems.org/gems/omniauth-shootproof
9
+ [travis]: http://travis-ci.org/SavvySoftWorksLLC/omniauth-shootproof
10
+ [gemnasium]:https://gemnasium.com/github.com/SavvySoftWorksLLC/omniauth-shootproof
11
+
12
+ This gem contains an OmniAuth strategy for Shootproof. It relies on the OAuth2 and OmniAuth-OAuth2 gems. Shootproof API does not conform exactly to the standard set forth with the base OAuth2 Client so some changes include:
13
+ - Access Tokens require the same params as the original Authorization request. The confusing part is the Token request is required POST so query string params are not included by default.
14
+ - The Access token requires the `redirect_uri` to match the `callback_url` from the Authorization request. Omniauth by default provides the query params from the Authorization callback in future `redirect_uri` params. This will no longer match so the query string is ditched.
15
+ - The Authorization endpoint does not pass-through any params os CSRF protection using the `state` param is not possible.
16
+
17
+ ## Configuring the Shootproof Strategy
18
+
19
+ ```ruby
20
+
21
+ Rails.application.config.middleware.use OmniAuth::Builder do
22
+ provider :shootproof, <SHOOTPROOF_APP_ID>,
23
+ scope: 'sp.event.get_list sp.event.get_photos sp.photo.info'
24
+ end
25
+ ```
26
+ That's pretty much it!
27
+
28
+ Like normal you will have to interpret the authenticaion response in your OmniAUth Session Controller.
29
+
30
+ The `info` response will contain the following hash
31
+ ```
32
+ {
33
+ token: <ACCESS TOKEN>,
34
+ refresh_token: <REFRESH TOKEN>,
35
+ expires_at: <WHEN THE TOKEN AND REFRESH EXPIRE>,
36
+ expires_in: <TIME LEFT UNTIL EXPIRATION>
37
+ }
38
+ ```
39
+
40
+ For convenience the `uid` will be populated with the Access Token
41
+
42
+ Paul Scarrone paul@savvysoftworks.com
43
+ Gary Newsome gary@savvysoftworks.com
44
+ SavvySoftWorks LLC.
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require "rspec/core/rake_task"
4
+
5
+ RSpec::Core::RakeTask.new
6
+
7
+ task :test => :spec
8
+
9
+ begin
10
+ require "rubocop/rake_task"
11
+ RuboCop::RakeTask.new
12
+ rescue LoadError
13
+ task :rubocop do
14
+ $stderr.puts "RuboCop is disabled"
15
+ end
16
+ end
17
+
18
+ task :default => [:spec, :rubocop]
@@ -0,0 +1,3 @@
1
+ require "omniauth-oauth2/version" # rubocop:disable FileName
2
+ require "omniauth/strategies/shootproof"
3
+ require "omniauth/shootproof/client"
@@ -0,0 +1,5 @@
1
+ module OmniAuth
2
+ module Shootproof
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,59 @@
1
+ require 'faraday'
2
+ require 'logger'
3
+
4
+ module OmniAuth
5
+ module Shootproof
6
+ class Client < ::OAuth2::Client # rubocop:disable Metrics/ClassLength
7
+ # Initializes an AccessToken by making a request to the token endpoint
8
+ #
9
+ # @param [Hash] params a Hash of params for the token endpoint
10
+ # @param [Hash] access token options, to pass to the AccessToken object
11
+ # @param [Class] class of access token for easier subclassing OAuth2::AccessToken
12
+ # @return [AccessToken] the initalized AccessToken
13
+ def get_token(params, access_token_opts = {}, access_token_class = ::OAuth2::AccessToken) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
14
+ params = ::OAuth2::Authenticator.new(id, secret, options[:auth_scheme]).apply(params)
15
+ opts = {:raise_errors => options[:raise_errors], :parse => params.delete(:parse)}
16
+ headers = params.delete(:headers) || {}
17
+ if options[:token_method] == :post
18
+ opts[:params] = params
19
+ opts[:params].merge!(redirection_params)
20
+ opts[:headers] = {'Content-Type' => 'application/x-www-form-urlencoded'}
21
+ else
22
+ error = Error.new('Must Be POST')
23
+ raise(error)
24
+ end
25
+ opts[:headers].merge!(headers)
26
+ response = request(options[:token_method], token_url, opts)
27
+ if options[:raise_errors] && !(response.parsed.is_a?(Hash) && response.parsed['access_token'])
28
+ error = Error.new(response)
29
+ raise(error)
30
+ end
31
+ access_token_class.from_hash(self, response.parsed.merge(access_token_opts))
32
+ end
33
+
34
+ # The redirect_uri parameters, if configured
35
+ #
36
+ # The redirect_uri query parameter is OPTIONAL (though encouraged) when
37
+ # requesting authorization. If it is provided at authorization time it MUST
38
+ # also be provided with the token exchange request.
39
+ #
40
+ # Providing the :redirect_uri to the OAuth2::Client instantiation will take
41
+ # care of managing this.
42
+ #
43
+ # @api semipublic
44
+ #
45
+ # @see https://tools.ietf.org/html/rfc6749#section-4.1
46
+ # @see https://tools.ietf.org/html/rfc6749#section-4.1.3
47
+ # @see https://tools.ietf.org/html/rfc6749#section-4.2.1
48
+ # @see https://tools.ietf.org/html/rfc6749#section-10.6
49
+ # @return [Hash] the params to add to a request or URL
50
+ def redirection_params
51
+ if options[:redirect_uri]
52
+ {:redirect_uri => options[:redirect_uri]}
53
+ else
54
+ {}
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,85 @@
1
+ require 'omniauth-oauth2'
2
+
3
+ module OmniAuth
4
+ module Strategies
5
+ class Shootproof < OmniAuth::Strategies::OAuth2
6
+
7
+ # Give your strategy a name.
8
+ option :name, 'shootproof'
9
+ option :scope, 'sp.event.get_list sp.event.get_photos sp.photo.info'
10
+ option :provider_ignores_state, true
11
+
12
+ option :client_options, {
13
+ site: 'https://auth.shootproof.com',
14
+ authorize_url: '/oauth2/authorization/new',
15
+ token_url: '/oauth2/authorization/token',
16
+ token_method: :post
17
+ }
18
+
19
+ option :authorize_options, [:scope, :state, :code]
20
+ option :token_options, [:scope, :state, :code]
21
+
22
+ # These are called after authentication has succeeded. If
23
+ # possible, you should try to set the UID without making
24
+ # additional calls (if the user id is returned with the token
25
+ # or as a URI parameter). This may not be possible with all
26
+ # providers.
27
+ uid{ raw_info[:token] }
28
+
29
+ info do
30
+ {
31
+ token: raw_info[:token],
32
+ refresh_token: raw_info[:refresh_token],
33
+ expires_at: raw_info[:expires_at],
34
+ expires_in: raw_info[:expires_in]
35
+ }
36
+ end
37
+
38
+ extra do
39
+ {
40
+ 'raw_info' => raw_info
41
+ }
42
+ end
43
+
44
+ def raw_info
45
+ @raw_info ||= {
46
+ token: access_token.token,
47
+ refresh_token: access_token.refresh_token,
48
+ expires_at: access_token.expires_at,
49
+ expires_in: access_token.expires_in
50
+ }
51
+ end
52
+
53
+ protected
54
+ def client
55
+ OmniAuth::Shootproof::Client.new(options.client_id, options.client_secret, deep_symbolize(options.client_options))
56
+ end
57
+
58
+ def callback_url
59
+ full_host + script_name + callback_path
60
+ end
61
+
62
+ # Initializes an AccessToken by making a request to the token endpoint
63
+ #
64
+ # @param [Hash] params a Hash of params for the token endpoint
65
+ # @param [Hash] access token options, to pass to the AccessToken object
66
+ # @param [Class] class of access token for easier subclassing OAuth2::AccessToken
67
+ # @return [AccessToken] the initalized AccessToken
68
+ def get_token(params, access_token_opts = {}, access_token_class = ::OAuth2::AccessToken) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
69
+ params = Authenticator.new(id, secret, options[:auth_scheme]).apply(params)
70
+ opts = {:raise_errors => options[:raise_errors], :parse => params.delete(:parse)}
71
+ headers = params.delete(:headers) || {}
72
+ opts[:params] = params
73
+ opts[:params].merge!(redirection_params)
74
+ opts[:headers] = {'Content-Type' => 'application/x-www-form-urlencoded'}
75
+ opts[:headers].merge!(headers)
76
+ response = request(options[:token_method], token_url, opts)
77
+ if options[:raise_errors] && !(response.parsed.is_a?(Hash) && response.parsed['access_token'])
78
+ error = Error.new(response)
79
+ raise(error)
80
+ end
81
+ access_token_class.from_hash(self, response.parsed.merge(access_token_opts))
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,23 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "omniauth-shootproof/version"
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.add_dependency "omniauth-oauth2", "~> 1.4"
7
+
8
+ gem.add_development_dependency "bundler", "~> 1.0"
9
+
10
+ gem.authors = ["Paul Scarrone", "Gary Newsome"]
11
+ gem.email = ["paul@savvysoftworks.com", "gary@savvysoftworks.com"]
12
+ gem.description = "OAuth2 Strategy for Shootproof based upon Omniauth-OAuth2."
13
+ gem.summary = gem.description
14
+ gem.homepage = "https://github.com/SavvySoftWorksLLC/omniauth-shootproof"
15
+ gem.licenses = %w(MIT)
16
+
17
+ gem.executables = `git ls-files -- bin/*`.split("\n").collect { |f| File.basename(f) }
18
+ gem.files = `git ls-files`.split("\n")
19
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ gem.name = "omniauth-shootproof"
21
+ gem.require_paths = %w(lib)
22
+ gem.version = OmniAuth::Shootproof::VERSION
23
+ end
data/spec/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ $LOAD_PATH.unshift File.expand_path("..", __FILE__)
2
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
3
+
4
+ require "rspec"
5
+ require "rack/test"
6
+ require "webmock/rspec"
7
+ require "omniauth"
8
+ require "omniauth-oauth2"
9
+ require "omniauth-shootproof"
10
+
11
+ RSpec.configure do |config|
12
+ config.expect_with :rspec do |c|
13
+ c.syntax = :expect
14
+ end
15
+ config.extend OmniAuth::Test::StrategyMacros, :type => :strategy
16
+ config.include Rack::Test::Methods
17
+ config.include WebMock::API
18
+ end
@@ -0,0 +1,81 @@
1
+ require "helper"
2
+
3
+ describe OmniAuth::Strategies::OAuth2 do
4
+ def app
5
+ lambda do |_env|
6
+ [200, {}, ["Hello."]]
7
+ end
8
+ end
9
+ let(:fresh_strategy) { Class.new(OmniAuth::Strategies::OAuth2) }
10
+
11
+ before do
12
+ OmniAuth.config.test_mode = true
13
+ end
14
+
15
+ after do
16
+ OmniAuth.config.test_mode = false
17
+ end
18
+
19
+ describe "#client" do
20
+ subject { fresh_strategy }
21
+
22
+ it "is initialized with symbolized client_options" do
23
+ instance = subject.new(app, :client_options => {"authorize_url" => "https://example.com"})
24
+ expect(instance.client.options[:authorize_url]).to eq("https://example.com")
25
+ end
26
+
27
+ it "sets ssl options as connection options" do
28
+ instance = subject.new(app, :client_options => {"ssl" => {"ca_path" => "foo"}})
29
+ expect(instance.client.options[:connection_opts][:ssl]).to eq(:ca_path => "foo")
30
+ end
31
+ end
32
+
33
+ describe "#authorize_params" do
34
+ subject { fresh_strategy }
35
+
36
+ it "includes any authorize params passed in the :authorize_params option" do
37
+ instance = subject.new("abc", "def", :authorize_params => {:foo => "bar", :baz => "zip"})
38
+ expect(instance.authorize_params["foo"]).to eq("bar")
39
+ expect(instance.authorize_params["baz"]).to eq("zip")
40
+ end
41
+
42
+ it "includes top-level options that are marked as :authorize_options" do
43
+ instance = subject.new("abc", "def", :authorize_options => [:scope, :foo, :state], :scope => "bar", :foo => "baz")
44
+ expect(instance.authorize_params["scope"]).to eq("bar")
45
+ expect(instance.authorize_params["foo"]).to eq("baz")
46
+ end
47
+
48
+ it "includes random state in the authorize params" do
49
+ instance = subject.new("abc", "def")
50
+ expect(instance.authorize_params.keys).to eq(["state"])
51
+ expect(instance.session["omniauth.state"]).not_to be_empty
52
+ end
53
+ end
54
+
55
+ describe "#token_params" do
56
+ subject { fresh_strategy }
57
+
58
+ it "includes any authorize params passed in the :authorize_params option" do
59
+ instance = subject.new("abc", "def", :token_params => {:foo => "bar", :baz => "zip"})
60
+ expect(instance.token_params).to eq("foo" => "bar", "baz" => "zip")
61
+ end
62
+
63
+ it "includes top-level options that are marked as :authorize_options" do
64
+ instance = subject.new("abc", "def", :token_options => [:scope, :foo], :scope => "bar", :foo => "baz")
65
+ expect(instance.token_params).to eq("scope" => "bar", "foo" => "baz")
66
+ end
67
+ end
68
+
69
+ describe "#callback_phase" do
70
+ subject { fresh_strategy }
71
+ it "calls fail with the client error received" do
72
+ instance = subject.new("abc", "def")
73
+ allow(instance).to receive(:request) do
74
+ double("Request", :params => {"error_reason" => "user_denied", "error" => "access_denied"})
75
+ end
76
+
77
+ expect(instance).to receive(:fail!).with("user_denied", anything)
78
+ instance.callback_phase
79
+ end
80
+ end
81
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: omniauth-shootproof
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Paul Scarrone
8
+ - Gary Newsome
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2017-06-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: omniauth-oauth2
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.4'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.4'
28
+ - !ruby/object:Gem::Dependency
29
+ name: bundler
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.0'
42
+ description: OAuth2 Strategy for Shootproof based upon Omniauth-OAuth2.
43
+ email:
44
+ - paul@savvysoftworks.com
45
+ - gary@savvysoftworks.com
46
+ executables: []
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - ".gitignore"
51
+ - ".rspec"
52
+ - ".travis.yml"
53
+ - Gemfile
54
+ - LICENSE.md
55
+ - README.md
56
+ - Rakefile
57
+ - lib/omniauth-shootproof.rb
58
+ - lib/omniauth-shootproof/version.rb
59
+ - lib/omniauth/shootproof/client.rb
60
+ - lib/omniauth/strategies/shootproof.rb
61
+ - omniauth-shootproof.gemspec
62
+ - spec/helper.rb
63
+ - spec/omniauth/strategies/shootproof_spec.rb
64
+ homepage: https://github.com/SavvySoftWorksLLC/omniauth-shootproof
65
+ licenses:
66
+ - MIT
67
+ metadata: {}
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubyforge_project:
84
+ rubygems_version: 2.6.12
85
+ signing_key:
86
+ specification_version: 4
87
+ summary: OAuth2 Strategy for Shootproof based upon Omniauth-OAuth2.
88
+ test_files:
89
+ - spec/helper.rb
90
+ - spec/omniauth/strategies/shootproof_spec.rb