authinator 0.0.1

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: d74ae2cc632fa497d66db160895f23b467ecf229
4
+ data.tar.gz: b94bb79f1f6a8a2bf4590f3bda38c67cee7cdf1c
5
+ SHA512:
6
+ metadata.gz: cb6b27be793d25bee657b48791648ffe740a0efa52f0e07d7a704ffb4b51e0b6c4c775f36888c1cd130acb364eb14f2ebcc5ceb673e8d34f8fb85eedd4d452bb
7
+ data.tar.gz: a536e204bae88a4a8daf8492d83fd1fa22b1013d8812e0716e29e4a4a47603d019bbe5db6c0d6127cd9e44c0255fccaa7c958f74f6c4d4f3bcbd5f52a9aedc98
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/.rubocop.yml ADDED
@@ -0,0 +1,49 @@
1
+ AllCops:
2
+ Exclude:
3
+ - 'authinator.gemspec'
4
+
5
+ Metrics/BlockNesting:
6
+ Max: 2
7
+
8
+ Metrics/LineLength:
9
+ AllowURI: true
10
+ Enabled: false
11
+
12
+ Metrics/MethodLength:
13
+ CountComments: false
14
+ Max: 15
15
+
16
+ Metrics/ParameterLists:
17
+ Max: 4
18
+ CountKeywordArgs: true
19
+
20
+ Style/AccessModifierIndentation:
21
+ EnforcedStyle: outdent
22
+
23
+ Style/CollectionMethods:
24
+ PreferredMethods:
25
+ map: 'collect'
26
+ reduce: 'inject'
27
+ find: 'detect'
28
+ find_all: 'select'
29
+
30
+ Style/Documentation:
31
+ Enabled: false
32
+
33
+ Style/DotPosition:
34
+ EnforcedStyle: trailing
35
+
36
+ Style/DoubleNegation:
37
+ Enabled: false
38
+
39
+ Style/EachWithObject:
40
+ Enabled: false
41
+
42
+ Style/Encoding:
43
+ Enabled: false
44
+
45
+ Style/Lambda:
46
+ Enabled: false
47
+
48
+ Style/TrailingComma:
49
+ EnforcedStyleForMultiline: 'comma'
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ authinator
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.1.5
data/.travis.yml ADDED
@@ -0,0 +1,19 @@
1
+ bundler_args: --without development
2
+ env:
3
+ global:
4
+ - JRUBY_OPTS="$JRUBY_OPTS --debug"
5
+ language: ruby
6
+ rvm:
7
+ - 1.9.3
8
+ - 2.0.0
9
+ - 2.1
10
+ - jruby-19mode
11
+ - jruby-head
12
+ - rbx-2
13
+ - ruby-head
14
+ matrix:
15
+ allow_failures:
16
+ - rvm: jruby-head
17
+ - rvm: ruby-head
18
+ fast_finish: true
19
+ sudo: false
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in authinator.gemspec
4
+ gemspec
5
+
6
+ gem 'rake'
7
+
8
+ group :test do
9
+ gem 'coveralls'
10
+ gem 'json', platforms: [:jruby, :ruby_18, :ruby_19]
11
+ gem 'mime-types', '~> 1.25', platforms: [:jruby, :ruby_18]
12
+ gem 'rack-test'
13
+ gem 'rest-client', '~> 1.6.0', platforms: [:jruby, :ruby_18]
14
+ gem 'rspec', '~> 3.0.0'
15
+ gem 'rubocop', '>= 0.28', platforms: [:ruby_19, :ruby_20, :ruby_21]
16
+ gem 'simplecov', '>= 0.9'
17
+ gem 'webmock'
18
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Alexander Bradner
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.
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # Authinator
2
+ [![Gem Version](http://img.shields.io/gem/v/authinator.svg)][gem]
3
+ [![Build Status](http://img.shields.io/travis/abradner/authinator.svg)][travis]
4
+ [![Dependency Status](http://img.shields.io/gemnasium/abradner/authinator.svg)][gemnasium]
5
+ [![Code Climate](http://img.shields.io/codeclimate/github/abradner/authinator.svg)][codeclimate]
6
+ [![Coverage Status](http://img.shields.io/coveralls/abradner/authinator.svg)][coveralls]
7
+
8
+ [gem]: https://rubygems.org/gems/authinator
9
+ [travis]: http://travis-ci.org/abradner/authinator
10
+ [gemnasium]: https://gemnasium.com/abradner/authinator
11
+ [codeclimate]: https://codeclimate.com/github/abradner/authinator
12
+ [coveralls]: https://coveralls.io/r/abradner/authinator
13
+
14
+ TODO: Write a gem description
15
+
16
+ ## Installation
17
+
18
+ Add this line to your application's Gemfile:
19
+
20
+ ```ruby
21
+ gem 'authinator'
22
+ ```
23
+
24
+ And then execute:
25
+
26
+ $ bundle
27
+
28
+ Or install it yourself as:
29
+
30
+ $ gem install authinator
31
+
32
+ ## Usage
33
+
34
+ TODO: Write usage instructions here
35
+
36
+ ## Contributing
37
+
38
+ 1. Fork it ( https://github.com/abradner/authinator/fork )
39
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
40
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
41
+ 4. Push to the branch (`git push origin my-new-feature`)
42
+ 5. Create a new Pull Request
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,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'authinator/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'authinator'
8
+ spec.version = Authinator::VERSION
9
+ spec.authors = ['Alexander Bradner']
10
+ spec.email = ['alex@bradner.net']
11
+ spec.summary = 'Single-Sign-On for the front and rails backend of a Single-Page-App'
12
+ # spec.description = ''
13
+ spec.homepage = 'https://github.com/abradner/authinator'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_runtime_dependency 'oauth2', '~> 1.0'
22
+ spec.add_runtime_dependency 'doorkeeper', '~> 2.0'
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.7'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ spec.add_development_dependency 'rspec', '~> 3'
27
+ spec.add_development_dependency 'rubocop'
28
+ end
data/lib/authinator.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'authinator/version'
2
+ require 'authinator/auth_code_exchanger'
3
+
4
+ module Authinator
5
+ # Your code goes here...
6
+ end
@@ -0,0 +1,100 @@
1
+ # require 'omniauth/strategies/google_oauth2'
2
+ # require 'omniauth-oauth2'
3
+ require 'oauth2'
4
+
5
+ # module Authinator
6
+ class AuthCodeExchanger
7
+ VALID_PROVIDERS = [:stub, :google]
8
+ STUB_SAMPLE_TOKEN = {
9
+ token: 'ya29.token',
10
+ refresh_token: '1/refresh',
11
+ expires_in: 3600,
12
+ }
13
+
14
+ attr_reader :provider
15
+
16
+ def self.valid_providers
17
+ VALID_PROVIDERS
18
+ end
19
+
20
+ PROVIDER_HASHES = {
21
+ google: {
22
+ client_id: 'cl_id',
23
+ client_secret: 'cl_sec',
24
+ site: 'https://accounts.google.com',
25
+ token_url: '/o/oauth2/token',
26
+ },
27
+ stub: {
28
+ client_id: 'cl_id',
29
+ client_secret: 'cl_sec',
30
+ site: 'https://example.org',
31
+ token_url: '/extoken',
32
+ },
33
+ }
34
+
35
+ def initialize(provider, client_options = {})
36
+ unless VALID_PROVIDERS.include? provider
37
+ fail ArgumentError,
38
+ "Provider #{provider} not in supported parameter list:\n" <<
39
+ VALID_PROVIDERS.inspect
40
+ end
41
+
42
+ @provider = provider
43
+ build_provider_hash(client_options)
44
+ end
45
+
46
+ def site_token_url
47
+ @provider_hash[:site] + @provider_hash[:token_url]
48
+ end
49
+
50
+ def exchange(auth_code)
51
+ # auth_code = params[:code]
52
+ return if auth_code.nil? || auth_code.empty?
53
+
54
+ case @provider.to_sym
55
+ when :google
56
+ exchange_with_google(auth_code)
57
+ when :stub
58
+ exchange_with_stub(auth_code)
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def build_provider_hash(client_options)
65
+ @provider_hash = PROVIDER_HASHES[provider]
66
+ @provider_hash = client_options.delete(:client_id) if client_options[:client_id]
67
+ @provider_hash = client_options.delete(:client_secret) if client_options[:client_secret]
68
+ end
69
+
70
+ def exchange_with_google(code)
71
+ provider_hash = @provider_hash.dup
72
+
73
+ client_id = provider_hash.delete(:client_id)
74
+ client_secret = provider_hash.delete(:client_secret)
75
+ @client = OAuth2::Client.new(client_id, client_secret, provider_hash)
76
+
77
+ token = @client.auth_code.get_token(code)
78
+
79
+ # response = token.get('/api/resource', :params => { 'query_foo' => 'bar' })
80
+ # response.class.name
81
+ # => OAuth2::Response
82
+
83
+ token
84
+ end
85
+
86
+ def exchange_with_stub(_code)
87
+ @client = OAuth2::Client.new(
88
+ @provider_hash[:client_id],
89
+ @provider_hash[:client_secret],
90
+ )
91
+
92
+ OAuth2::AccessToken.new(
93
+ @client,
94
+ STUB_SAMPLE_TOKEN[:token],
95
+ refresh_token: STUB_SAMPLE_TOKEN[:refresh_token],
96
+ expires_in: STUB_SAMPLE_TOKEN[:expires_in],
97
+ )
98
+ end
99
+ end
100
+ # end
@@ -0,0 +1,3 @@
1
+ module Authinator
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+ require 'json'
3
+
4
+ describe AuthCodeExchanger do
5
+ before :all do
6
+ @token_hash = {
7
+ access_token: 'ya29.token',
8
+ refresh_token: '1/refresh',
9
+ expires_in: 3600,
10
+ token_type: 'Bearer',
11
+ }
12
+ @test_env = {
13
+ client_id: 'cl_id',
14
+ client_secret: 'cl_sec',
15
+ code: '4/code',
16
+ grant_type: 'authorization_code',
17
+ }
18
+
19
+ @req_headers = {
20
+ accept: '*/*',
21
+ content_type: 'application/x-www-form-urlencoded',
22
+ user_agent: 'Faraday v0.9.0',
23
+ }
24
+
25
+ @req_response = {
26
+ status: 200,
27
+ body: @token_hash.to_json,
28
+ headers: { content_type: 'application/json' },
29
+ }
30
+ end
31
+ it 'should correctly process a generic (stub) token' do
32
+ ace = AuthCodeExchanger.new(:stub)
33
+ stub_request(:post, ace.site_token_url).
34
+ with(body: @test_env,
35
+ headers: @req_headers).
36
+ to_return(@req_response)
37
+
38
+ result = ace.exchange(@test_env[:code])
39
+
40
+ expect(result.token).to eq @token_hash[:access_token]
41
+ expect(result.refresh_token).to eq @token_hash[:refresh_token]
42
+ expect(result.expires_in).to eq @token_hash[:expires_in]
43
+ end
44
+
45
+ it 'should return an AccessToken for each provider' do
46
+ klass = OAuth2::AccessToken
47
+
48
+ AuthCodeExchanger.valid_providers.each do |provider|
49
+ ace = AuthCodeExchanger.new(provider)
50
+ stub_request(:post, ace.site_token_url).
51
+ with(body: @test_env,
52
+ headers: @req_headers).
53
+ to_return(@req_response)
54
+
55
+ expect(ace.exchange(@test_env[:code])).to be_a klass
56
+ end
57
+ end
58
+
59
+ it 'should correctly process a google token' do
60
+ ace = AuthCodeExchanger.new(:google)
61
+ stub_request(:post, ace.site_token_url).
62
+ with(body: @test_env,
63
+ headers: @req_headers).
64
+ to_return(@req_response)
65
+
66
+ result = ace.exchange(@test_env[:code])
67
+
68
+ expect(result.token).to eq @token_hash[:access_token]
69
+ expect(result.refresh_token).to eq @token_hash[:refresh_token]
70
+ expect(result.expires_in).to eq @token_hash[:expires_in]
71
+ end
72
+
73
+ it 'should gracefully not allow unsupported providers' do
74
+ expect do
75
+ AuthCodeExchanger.new(:some_fake_provider)
76
+ end.to raise_error(ArgumentError)
77
+ end
78
+ end
79
+
80
+ describe 'ClientTokenIssuer' do
81
+ pending
82
+ it 'should accept valid-looking credentials from the client'
83
+ it 'should exchange client-provided credentials for auth codes'
84
+ it 'should return an error to the client if the credentials were invalid'
85
+ it 'should verify that the tokens belong to the provided email before returning them'
86
+ it 'should generate our own set of tokens for the client if the provided ones exchanged successfully'
87
+
88
+ it 'should all integrate to follow a standard flow to auth the api client'
89
+ end
@@ -0,0 +1,31 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ if RUBY_VERSION >= '1.9'
5
+ require 'simplecov'
6
+ require 'coveralls'
7
+
8
+ SimpleCov.formatters = [
9
+ SimpleCov::Formatter::HTMLFormatter,
10
+ Coveralls::SimpleCov::Formatter,
11
+ ]
12
+
13
+ SimpleCov.start do
14
+ minimum_coverage(76)
15
+ end
16
+ end
17
+
18
+ require 'rspec'
19
+ require 'rack/test'
20
+ require 'webmock/rspec'
21
+ require 'authinator' # and any other gems you need
22
+
23
+ RSpec.configure do |config|
24
+ config.expect_with :rspec do |c|
25
+ c.syntax = :expect
26
+ end
27
+ config.include Rack::Test::Methods
28
+ config.include WebMock::API
29
+
30
+ # some (optional) config here
31
+ end
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: authinator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Alexander Bradner
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: oauth2
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: doorkeeper
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.7'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description:
98
+ email:
99
+ - alex@bradner.net
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".rspec"
106
+ - ".rubocop.yml"
107
+ - ".ruby-gemset"
108
+ - ".ruby-version"
109
+ - ".travis.yml"
110
+ - Gemfile
111
+ - LICENSE.txt
112
+ - README.md
113
+ - Rakefile
114
+ - authinator.gemspec
115
+ - lib/authinator.rb
116
+ - lib/authinator/auth_code_exchanger.rb
117
+ - lib/authinator/version.rb
118
+ - spec/authinator/authinator_spec.rb
119
+ - spec/spec_helper.rb
120
+ homepage: https://github.com/abradner/authinator
121
+ licenses:
122
+ - MIT
123
+ metadata: {}
124
+ post_install_message:
125
+ rdoc_options: []
126
+ require_paths:
127
+ - lib
128
+ required_ruby_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ required_rubygems_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ requirements: []
139
+ rubyforge_project:
140
+ rubygems_version: 2.4.3
141
+ signing_key:
142
+ specification_version: 4
143
+ summary: Single-Sign-On for the front and rails backend of a Single-Page-App
144
+ test_files:
145
+ - spec/authinator/authinator_spec.rb
146
+ - spec/spec_helper.rb