authinator 0.0.3 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b3d82624397aabd4fc7fb6b6b851dd6537779d39
4
- data.tar.gz: ff45303cba2e2fc51ccc166bc9ad4fb694d3a7d3
3
+ metadata.gz: 5bab186640c9c1e8c020d88808cea1d05389e743
4
+ data.tar.gz: fd3636d7972b4bda346d1c9b641d633f2e655053
5
5
  SHA512:
6
- metadata.gz: cf8e1d9e08b9eb1b3e3532b3366975f3f070111cc5de18b30cc61ee45e4bbb5c351a540c5ab9b560376519647b4abb1e207588d4c8bef0b57e3ad11141a117bf
7
- data.tar.gz: 4bca86ce9fa8a423bf222e7759f7e56b62a0a5800497e24a261e9795124f3067e62f0a24aa900170408a7856a289ab01a59918c59727e4b76e95335ee53c7fbd
6
+ metadata.gz: 84848419144e543347fac7faa7fe32e13b10da1ea8e282a9c32f0977dfad44e161313c310dd3114b85c65667d5764bf9c569fd843448074c67cf7635c1d55cb5
7
+ data.tar.gz: db8e6561e4032b1b6f7f71648d1f48219ff2b94d260a55fae5f0f237997a7d746904fe5a27e95de0ed9f5846ac60b37444d5763ff3f2d85b1baace23c608826d
data/Gemfile CHANGED
@@ -16,3 +16,6 @@ group :test do
16
16
  gem 'simplecov', '>= 0.9'
17
17
  gem 'webmock'
18
18
  end
19
+
20
+ # gem 'abstract_google_client', path: '/Users/abradner/foogi/google_client', require: 'google_client'
21
+ gem 'abstract_google_client', github: 'abradner/google_client', require: 'google_client'
data/lib/authinator.rb CHANGED
@@ -1,8 +1,10 @@
1
+ require 'active_support/all'
1
2
  require 'authinator/version'
3
+ require 'authinator/provider'
4
+ require 'authinator/configuration'
2
5
  require 'authinator/auth_code_exchanger'
3
6
  require 'authinator/end_point_listener'
4
7
  require 'authinator/client_token_issuer'
5
8
 
6
9
  module Authinator
7
- # Your code goes here...
8
10
  end
@@ -1,10 +1,7 @@
1
- # require 'omniauth/strategies/google_oauth2'
2
- # require 'omniauth-oauth2'
3
1
  require 'oauth2'
4
2
 
5
3
  module Authinator
6
4
  class AuthCodeExchanger
7
- VALID_PROVIDERS = [:stub, :google]
8
5
  STUB_SAMPLE_TOKEN = {
9
6
  token: 'ya29.token',
10
7
  refresh_token: '1/refresh',
@@ -12,46 +9,25 @@ module Authinator
12
9
  }
13
10
 
14
11
  attr_reader :provider
12
+ # attr_reader :client
15
13
 
16
14
  def self.valid_providers
17
- VALID_PROVIDERS
15
+ Authinator.configuration.providers
18
16
  end
19
17
 
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
-
18
+ def initialize(provider, _client_options = {})
42
19
  @provider = provider
43
- build_provider_hash(client_options)
44
20
  end
45
21
 
46
22
  def site_token_url
47
- @provider_hash[:site] + @provider_hash[:token_url]
23
+ @provider.site + @provider.token_url
48
24
  end
49
25
 
50
26
  def exchange(auth_code)
51
27
  # auth_code = params[:code]
52
28
  return if auth_code.nil? || auth_code.empty?
53
29
 
54
- case @provider.to_sym
30
+ case @provider.name
55
31
  when :google
56
32
  exchange_with_google(auth_code)
57
33
  when :stub
@@ -61,20 +37,16 @@ module Authinator
61
37
 
62
38
  private
63
39
 
64
- def build_provider_hash(client_options)
65
- @provider_hash = PROVIDER_HASHES[@provider.to_sym]
66
- @provider_hash[:client_id] = client_options.delete(:client_id) if client_options[:client_id]
67
- @provider_hash[:client_secret] = client_options.delete(:client_secret) if client_options[:client_secret]
68
- end
40
+ # def build_provider_hash(client_options)
41
+ # @provider_hash = Authinator.configuration.provider_for[@provider.to_sym]
42
+ # @provider_hash[:client_id] = client_options.delete(:client_id) if client_options[:client_id]
43
+ # @provider_hash[:client_secret] = client_options.delete(:client_secret) if client_options[:client_secret]
44
+ # end
69
45
 
70
46
  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)
47
+ @client = OAuth2::Client.new(@provider.client_id, @provider.client_secret, @provider.to_hash)
76
48
 
77
- token = @client.auth_code.get_token(code)
49
+ token = @client.auth_code.get_token(code, redirect_uri: 'http://localhost:4200')
78
50
 
79
51
  # response = token.get('/api/resource', :params => { 'query_foo' => 'bar' })
80
52
  # response.class.name
@@ -85,8 +57,8 @@ module Authinator
85
57
 
86
58
  def exchange_with_stub(_code)
87
59
  @client = OAuth2::Client.new(
88
- @provider_hash[:client_id],
89
- @provider_hash[:client_secret],
60
+ @provider.client_id,
61
+ @provider.client_secret,
90
62
  )
91
63
 
92
64
  OAuth2::AccessToken.new(
@@ -1,4 +1,226 @@
1
1
  module Authinator
2
+ class EmailNotVerifiedError < ArgumentError
3
+ end
4
+
2
5
  class ClientTokenIssuer
6
+ TEMP_RAW_INFO = {
7
+ email_verified: true,
8
+ email: 'a@b.c',
9
+ given_name: 'first',
10
+ family_name: 'last',
11
+ profile: 'xyz',
12
+ }.with_indifferent_access
13
+
14
+ # Options can
15
+ def initialize(params, options = {})
16
+ @params = params.with_indifferent_access
17
+ provider_name = (options.delete :provider if options[:provider]) || (@params[:provider].present? ? @params[:provider].to_sym : nil)
18
+ unless Authinator.configuration.providers.include? provider_name
19
+ fail ArgumentError,
20
+ "Provider #{provider_name} not in supported parameter list:\n" <<
21
+ Authinator.configuration.providers.inspect
22
+ end
23
+
24
+ @provider = Authinator.configuration.provider_for(provider_name)
25
+
26
+ @auth_code = (options.delete :auth_code if options[:auth_code]) || @params['code']
27
+ @app_name = (options.delete :app_name if options[:app_name]) || application_name
28
+ @valid_applications = (options.delete :valid_applications if options[:valid_applications]) || Authinator.configuration.valid_applications
29
+ end
30
+
31
+ def authorize!(options = {})
32
+ return { error: "Invalid Application #{@app_name}" }, :bad_request unless @valid_applications.include? @app_name
33
+
34
+ handler = EndPointListener.new(auth_code: @auth_code, provider: @provider)
35
+
36
+ if handler.valid?
37
+ return handle(options)
38
+
39
+ else
40
+ # Doorkeeper's defaut behaviour when the user signs in with login/password.
41
+ # TODO: kill this block
42
+ begin
43
+ response = strategy.authorize
44
+ headers.merge! response.headers
45
+ self.response_body = response.body.merge(user_id: (response.token.resource_owner_id && response.token.resource_owner_id.to_s)).to_json
46
+ self.status = response.status
47
+ rescue Doorkeeper::Errors::DoorkeeperError => e
48
+ handle_token_exception e
49
+ end
50
+
51
+ end
52
+ end
53
+
54
+ def handle(options = {})
55
+ application = Doorkeeper::Application.where(name: @app_name)
56
+ token_issuer = AuthCodeExchanger.new @provider
57
+ provider_access_token = token_issuer.exchange @auth_code
58
+
59
+ begin
60
+ info = load_info(provider_access_token)
61
+ rescue EmailNotVerifiedError => _e
62
+ return { error: 'Cannot create a Foogi account with an unverified email address' }, :bad_request
63
+ end
64
+
65
+ acc = find_or_create_account_from_info(info)
66
+ user = acc.user
67
+ expires_in = options.delete(:expires_in) || 2.hours
68
+ store_provider_credentials!(acc, provider_access_token)
69
+
70
+ client_access_token = Doorkeeper::AccessToken.create!(
71
+ application_id: application,
72
+ resource_owner_id: user.id,
73
+ expires_in: expires_in,
74
+ use_refresh_token: true,
75
+ )
76
+
77
+ token_data = {
78
+ access_token: client_access_token.token,
79
+ refresh_token: client_access_token.refresh_token,
80
+ token_type: 'bearer',
81
+ expires_in: client_access_token.expires_in,
82
+ user_id: user.id, # TODO: remove
83
+ provider_access_token: provider_access_token.token,
84
+ provider_expires_in: provider_access_token.expires_in,
85
+ # provider_id_token: provider_access_token.id_token,
86
+ }
87
+
88
+ [token_data.to_json, :ok]
89
+ end
90
+
91
+ def load_info(access_token)
92
+ # raw_info = provider_access_token.get('https://www.googleapis.com/plus/v1/people/me/openIdConnect').parsed
93
+
94
+ raw_info = case @provider.name
95
+ when :google
96
+ retrieve_user_from_google access_token
97
+ when :stub
98
+ TEMP_RAW_INFO
99
+ end
100
+ # raw_info = TEMP_RAW_INFO
101
+
102
+ verified_email = raw_info[:email_verified] ? raw_info[:email] : nil
103
+ fail EmailNotVerifiedError, 'Email not verified' unless verified_email.present?
104
+
105
+ # verified_email = raw_info['email']
106
+ # prune!(
107
+ # # email_verified: hash['emails'].first['type'].eql?('account'),
108
+ # email_verified: false,
109
+ # email: raw_info['emails'].first['value'],
110
+ # display_name: raw_info['displayName'],
111
+ # name: raw_info['name'],
112
+ # picture_url: raw_info['image']['url'],
113
+ # uid: raw_info['id'],
114
+ # language: raw_info['language'],
115
+ # )
116
+ # prune!(
117
+ # name: raw_info['name'],
118
+ # email: verified_email,
119
+ # first_name: raw_info['given_name'],
120
+ # last_name: raw_info['family_name'],
121
+ # image: raw_info['image_url'],
122
+ # uid: raw_info['sub'] || verified_email,
123
+ # urls: {
124
+ # @provider.name => raw_info['profile'],
125
+ # },
126
+ # )
127
+ raw_info
128
+ end
129
+
130
+ private
131
+
132
+ def find_or_create_account_from_info(info)
133
+ acc = Account.find_by email: info[:email], provider: @provider.name.to_s
134
+ if acc.blank?
135
+ user = User.find_by(primary_email: info[:email]) || User.create!(
136
+ primary_email: info[:email], display_name: info[:display_name],
137
+ name: info[:name], picture_url: info[:picture_url],
138
+ )
139
+ acc = user.create_account!(
140
+ email: info[:email],
141
+ provider: @provider.name.to_s,
142
+ provider_uid: info[:uid],
143
+ )
144
+ end
145
+ acc
146
+ end
147
+
148
+ def store_provider_credentials!(acc, access_token)
149
+ acc.credential.destroy unless acc.credential.blank?
150
+
151
+ acc.create_credential!(
152
+ access_token: access_token.token,
153
+ refresh_token: access_token.refresh_token,
154
+ expires_at: (Time.now.utc + access_token.expires_in),
155
+ expires: access_token.expires_in.present? ? true : false,
156
+ )
157
+ end
158
+
159
+ def application_name
160
+ @params['application_name'].present? ? @params['application_name'].to_sym : nil
161
+ end
162
+
163
+ def prune!(hash)
164
+ hash.delete_if do |_, v|
165
+ prune!(v) if v.is_a?(Hash)
166
+ v.nil? || (v.respond_to?(:empty?) && v.empty?)
167
+ end
168
+ end
169
+
170
+ def retrieve_user_from_google(access_token)
171
+ client = GoogleClient::Builder.new('plus', 'v1', 1)
172
+ result = client.execute access_token, client.service.people.get, userId: 'me'
173
+ process_google_info JSON.parse(result.body)
174
+ end
175
+
176
+ def process_google_info(hash)
177
+ {
178
+ email_verified: hash['emails'].first['type'].eql?('account'),
179
+ email: hash['emails'].first['value'],
180
+ display_name: hash['displayName'],
181
+ name: hash['name'],
182
+ picture_url: hash['image']['url'],
183
+ uid: hash['id'],
184
+ language: hash['language'],
185
+ }.with_indifferent_access
186
+
187
+ # {
188
+ # "kind" => "plus#person",
189
+ # "etag" => "\"xyz-something/abc\"",
190
+ # "gender" => "female",
191
+ # "emails" => [
192
+ # {
193
+ # "value" => "info@foogi.me",
194
+ # "type" => "account"
195
+ # }
196
+ # ],
197
+ # "objectType" => "person",
198
+ # "id" => "12345",
199
+ # "displayName" => "Leading Foogster",
200
+ # "name" => {
201
+ # "familyName" => "Foogster",
202
+ # "givenName" => "Leading"
203
+ # },
204
+ # "url" => "https://plus.google.com/+FoogiMe",
205
+ # "image" => {
206
+ # "url" => "https://someurl/photo.jpg?sz=50",
207
+ # "isDefault" => false
208
+ # },
209
+ # "placesLived" => [
210
+ # {
211
+ # "value" => "Sydney, Australia",
212
+ # "primary" => true
213
+ # },
214
+ # {
215
+ # "value" => "San Francisco, USA"
216
+ # }
217
+ # ],
218
+ # "isPlusUser" => true,
219
+ # "language" => "en_GB",
220
+ # "circledByCount" => 11225,
221
+ # "verified" => false,
222
+ # "domain" => "foogi.me"
223
+ # }
224
+ end
3
225
  end
4
226
  end
@@ -0,0 +1,71 @@
1
+ module Authinator
2
+ # Exception to handle a missing initializer
3
+ # class MissingConfiguration < StandardError
4
+ # def initialize
5
+ # super('Configuration for authinator missing. Do you have an Authinator initializer?')
6
+ # end
7
+ # end
8
+
9
+ # Module level methods
10
+ class << self
11
+ attr_accessor :configuration
12
+ end
13
+
14
+ def self.configure
15
+ self.configuration ||= Configuration.new
16
+ yield(configuration)
17
+ end
18
+
19
+ # def self.configuration
20
+ # @config || (fail MissingConfiguration.new)
21
+ # end
22
+
23
+ # Configuration class
24
+ class Configuration
25
+ attr_reader :providers
26
+ attr_accessor :valid_applications
27
+
28
+ def initialize
29
+ @providers = {}
30
+ add_provider(
31
+ :stub,
32
+ client_id: 'cl_id',
33
+ client_secret: 'cl_sec',
34
+ site: 'https://example.org',
35
+ token_url: '/extoken',
36
+ api_key: 'api_key',
37
+ user_info_url: 'http://example.org/info',
38
+ )
39
+ add_provider(
40
+ :google,
41
+ site: 'https://accounts.google.com',
42
+ token_url: '/o/oauth2/token',
43
+ user_info_url: 'https://www.googleapis.com/plus/v1/people/me/openIdConnect',
44
+ )
45
+ end
46
+
47
+ def providers
48
+ @providers.keys
49
+ end
50
+
51
+ def add_provider(provider_name, options = {})
52
+ @providers[provider_name] = Provider.new(provider_name, options)
53
+ end
54
+
55
+ def add_secrets(provider_name, options = {})
56
+ fail(
57
+ ArgumentError,
58
+ "#{provider_name} is not a configured provider.\n" \
59
+ "Valid Providers:\n" <<
60
+ providers.to_s,
61
+ ) if @providers[provider_name].blank?
62
+
63
+ @providers[provider_name].add_secrets(options)
64
+ end
65
+
66
+ # A more abstracted way of accessing the providers
67
+ def provider_for(provider_name)
68
+ @providers[provider_name]
69
+ end
70
+ end
71
+ end
@@ -1,9 +1,8 @@
1
1
  module Authinator
2
2
  class EndPointListener
3
- attr_reader :email, :provider, :auth_code, :options, :errors
3
+ attr_reader :provider, :auth_code, :options, :errors
4
4
 
5
5
  def initialize(hash = {})
6
- @email = hash.delete :email
7
6
  @provider = hash.delete :provider
8
7
  @auth_code = hash.delete :auth_code
9
8
  @options = hash
@@ -12,36 +11,24 @@ module Authinator
12
11
 
13
12
  def valid?
14
13
  validator_presence? &&
15
- validator_valid_email? &&
16
14
  validator_valid_provider?
17
15
  end
18
16
 
19
17
  private
20
18
 
21
19
  def validator_presence?
22
- email_present = present? @email
23
20
  provider_present = present? @provider
24
21
  auth_code_present = present? @auth_code
25
22
 
26
- return true if email_present && provider_present && auth_code_present
23
+ return true if provider_present && auth_code_present
27
24
  errors << 'A required param is missing'
28
- errors << '"email" field missing' unless email_present
29
25
  errors << '"provider" field missing' unless provider_present
30
26
  errors << '"auth_code" field missing' unless auth_code_present
31
27
  false
32
28
  end
33
29
 
34
- # Regexp lovingly borrowed from https://github.com/balexand/email_validator
35
- def validator_valid_email?
36
- name_validation = @options[:strict_mode] ? '-a-z0-9+._' : '^@\\s'
37
- regexp = /\A\s*([#{name_validation}]{1,64})@((?:[-a-z0-9]+\.)+[a-z]{2,})\s*\z/i
38
- return true if @email =~ regexp
39
- errors << "Email '#{@email}' is invalid"
40
- false
41
- end
42
-
43
30
  def validator_valid_provider?
44
- return true if Authinator::AuthCodeExchanger.valid_providers.include? @provider.to_sym
31
+ return true if Authinator.configuration.providers.include? @provider.name
45
32
  errors << "Provider '#{@provider}' is invalid"
46
33
  false
47
34
  end
@@ -0,0 +1,54 @@
1
+ module Authinator
2
+ class Provider
3
+ attr_reader :name
4
+ attr_accessor :client_id,
5
+ :client_secret,
6
+ :site,
7
+ :token_url,
8
+ :api_key,
9
+ :user_info_url
10
+
11
+ def initialize(name, options = {})
12
+ @name = name
13
+ @client_id = options.delete :client_id
14
+ @client_secret = options.delete :client_secret
15
+ @site = options.delete :site
16
+ @token_url = options.delete :token_url
17
+ @api_key = options.delete :api_key
18
+ @user_info_url = options.delete :user_info_url
19
+ end
20
+
21
+ def add_secrets(options = {})
22
+ @client_id = options.delete :client_id if options[:client_id]
23
+ @client_secret = options.delete :client_secret if options[:client_secret]
24
+ @api_key = options.delete :api_key if options[:api_key]
25
+ end
26
+
27
+ def secrets
28
+ sec = {}
29
+ sec[:client_id] = @client_id if @client_id
30
+ sec[:client_secret] = @client_secret if @client_secret
31
+ sec[:api_key] = @api_key if @api_key
32
+
33
+ sec
34
+ end
35
+
36
+ def to_hash
37
+ {
38
+ name: @name,
39
+ client_id: @client_id,
40
+ client_secret: @client_secret,
41
+ site: @site,
42
+ token_url: @token_url,
43
+ api_key: @api_key,
44
+ user_info_url: @user_info_url,
45
+ }
46
+ end
47
+
48
+ def empty?
49
+ to_hash.empty?
50
+ end
51
+
52
+ alias_method :inspect, :to_hash
53
+ end
54
+ end
@@ -1,3 +1,3 @@
1
1
  module Authinator
2
- VERSION = '0.0.3'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -3,6 +3,11 @@ require 'json'
3
3
 
4
4
  describe Authinator::AuthCodeExchanger do
5
5
  before :all do
6
+ Authinator.configure do |config|
7
+ config.add_secrets :google,
8
+ client_id: 'cl_id',
9
+ client_secret: 'cl_sec'
10
+ end
6
11
  @token_hash = {
7
12
  access_token: 'ya29.token',
8
13
  refresh_token: '1/refresh',
@@ -27,9 +32,29 @@ describe Authinator::AuthCodeExchanger do
27
32
  body: @token_hash.to_json,
28
33
  headers: { content_type: 'application/json' },
29
34
  }
35
+
36
+ @stub_provider = Authinator::Provider.new(
37
+ :stub,
38
+ client_id: 'cl_id',
39
+ client_secret: 'cl_sec',
40
+ site: 'https://example.org',
41
+ token_url: '/extoken',
42
+ api_key: 'api_key',
43
+ user_info_url: 'http://example.org/info',
44
+ )
45
+ @google_provider = Authinator::Provider.new(
46
+ :stub,
47
+ client_id: 'cl_id',
48
+ client_secret: 'cl_sec',
49
+ site: 'https://example.org',
50
+ token_url: '/extoken',
51
+ api_key: 'api_key',
52
+ user_info_url: 'http://example.org/info',
53
+ )
30
54
  end
55
+
31
56
  it 'should correctly process a generic (stub) token' do
32
- ace = Authinator::AuthCodeExchanger.new(:stub)
57
+ ace = Authinator::AuthCodeExchanger.new(@stub_provider)
33
58
  stub_request(:post, ace.site_token_url).
34
59
  with(body: @test_env,
35
60
  headers: @req_headers).
@@ -45,7 +70,8 @@ describe Authinator::AuthCodeExchanger do
45
70
  it 'should return an AccessToken for each provider' do
46
71
  klass = OAuth2::AccessToken
47
72
 
48
- Authinator::AuthCodeExchanger.valid_providers.each do |provider|
73
+ Authinator::AuthCodeExchanger.valid_providers.each do |provider_name|
74
+ provider = Authinator.configuration.provider_for provider_name
49
75
  ace = Authinator::AuthCodeExchanger.new(provider)
50
76
  stub_request(:post, ace.site_token_url).
51
77
  with(body: @test_env,
@@ -57,7 +83,7 @@ describe Authinator::AuthCodeExchanger do
57
83
  end
58
84
 
59
85
  it 'should correctly process a google token' do
60
- ace = Authinator::AuthCodeExchanger.new(:google)
86
+ ace = Authinator::AuthCodeExchanger.new(@google_provider)
61
87
  stub_request(:post, ace.site_token_url).
62
88
  with(body: @test_env,
63
89
  headers: @req_headers).
@@ -69,19 +95,4 @@ describe Authinator::AuthCodeExchanger do
69
95
  expect(result.refresh_token).to eq @token_hash[:refresh_token]
70
96
  expect(result.expires_in).to eq @token_hash[:expires_in]
71
97
  end
72
-
73
- it 'should gracefully not allow unsupported providers' do
74
- expect do
75
- Authinator::AuthCodeExchanger.new(:some_fake_provider)
76
- end.to raise_error(ArgumentError)
77
- end
78
-
79
- it 'should correctly handle client information provided as a parameter' do
80
- ace = Authinator::AuthCodeExchanger.new(:google, client_id: 'new_id', client_secret: 'new_secret')
81
-
82
- stub_request(:post, ace.site_token_url).
83
- with(body: @test_env.merge(client_id: 'new_id', client_secret: 'new_secret'),
84
- headers: @req_headers).
85
- to_return(@req_response)
86
- end
87
98
  end
@@ -5,4 +5,21 @@ describe Authinator::ClientTokenIssuer do
5
5
  it 'should generate our own set of tokens for the client if the provided ones exchanged successfully'
6
6
 
7
7
  it 'should all integrate to follow a standard flow to auth the api client'
8
+
9
+ it 'should gracefully not allow unsupported providers' do
10
+ pending
11
+ expect do
12
+ Authinator::AuthCodeExchanger.new(:some_fake_provider)
13
+ end.to raise_error(ArgumentError)
14
+ end
15
+
16
+ it 'should correctly handle client information provided as a parameter' do
17
+ pending
18
+ ace = Authinator::AuthCodeExchanger.new(:google, client_id: 'new_id', client_secret: 'new_secret')
19
+
20
+ stub_request(:post, ace.site_token_url).
21
+ with(body: @test_env.merge(client_id: 'new_id', client_secret: 'new_secret'),
22
+ headers: @req_headers).
23
+ to_return(@req_response)
24
+ end
8
25
  end
@@ -2,10 +2,18 @@ require 'spec_helper'
2
2
 
3
3
  describe Authinator::EndPointListener do
4
4
  before :each do
5
+ @stub_provider = Authinator::Provider.new(
6
+ :stub,
7
+ client_id: 'cl_id',
8
+ client_secret: 'cl_sec',
9
+ site: 'https://example.org',
10
+ token_url: '/extoken',
11
+ api_key: 'api_key',
12
+ user_info_url: 'http://example.org/info',
13
+ )
5
14
  @creds_hash = {
6
- email: 'test@foogi.me',
7
15
  auth_code: '4/auth_code',
8
- provider: 'google',
16
+ provider: @stub_provider,
9
17
  }
10
18
  end
11
19
  it 'should accept valid-looking credentials from the client' do
@@ -25,31 +33,30 @@ describe Authinator::EndPointListener do
25
33
  expect(listener.valid?).to be_falsey
26
34
  end
27
35
  it 'should return an error unless all three fields are provided' do
28
- listener1 = Authinator::EndPointListener.new(@creds_hash.dup.tap { |hs| hs.delete(:email) }) # remove email
29
36
  listener2 = Authinator::EndPointListener.new(@creds_hash.dup.tap { |hs| hs.delete(:auth_code) }) # remove ac
30
37
  listener3 = Authinator::EndPointListener.new(@creds_hash.dup.tap { |hs| hs.delete(:provider) }) # remove prov
31
38
 
32
- expect(listener1.valid?).to be_falsey
33
39
  expect(listener2.valid?).to be_falsey
34
40
  expect(listener3.valid?).to be_falsey
35
41
  end
36
- it 'should reject invalid emails' do
37
- bad_email_hash1 = @creds_hash.merge(email: 'abc')
38
- bad_email_hash2 = @creds_hash.merge(email: '')
39
- bad_email_hash3 = @creds_hash.merge(email: 'a@')
40
42
 
41
- listener1 = Authinator::EndPointListener.new(bad_email_hash1)
42
- listener2 = Authinator::EndPointListener.new(bad_email_hash2)
43
- listener3 = Authinator::EndPointListener.new(bad_email_hash3)
43
+ it 'should reject invalid providers' do
44
+ bad_provider_1 = Authinator::Provider.new(
45
+ :bad1,
46
+ client_id: 'cl_id',
47
+ client_secret: 'cl_sec',
48
+ site: 'https://example.org',
49
+ token_url: '/extoken',
50
+ api_key: 'api_key',
51
+ user_info_url: 'http://example.org/info',
52
+ )
44
53
 
45
- expect(listener1.valid?).to be_falsey
46
- expect(listener2.valid?).to be_falsey
47
- expect(listener3.valid?).to be_falsey
48
- end
54
+ bad_provider_2 = Authinator::Provider.new(
55
+ :bad2,
56
+ )
49
57
 
50
- it 'should reject invalid providers' do
51
- bad_provider_hash1 = @creds_hash.merge(provider: 'some_fake_provider')
52
- bad_provider_hash2 = @creds_hash.merge(provider: '')
58
+ bad_provider_hash1 = @creds_hash.merge(provider: bad_provider_1)
59
+ bad_provider_hash2 = @creds_hash.merge(provider: bad_provider_2)
53
60
 
54
61
  listener1 = Authinator::EndPointListener.new(bad_provider_hash1)
55
62
  listener2 = Authinator::EndPointListener.new(bad_provider_hash2)
@@ -63,7 +70,6 @@ describe Authinator::EndPointListener do
63
70
  listener.valid?
64
71
  expect(listener.errors).to eq [
65
72
  'A required param is missing',
66
- '"email" field missing',
67
73
  '"provider" field missing',
68
74
  '"auth_code" field missing',
69
75
  ]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authinator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Bradner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-23 00:00:00.000000000 Z
11
+ date: 2015-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oauth2
@@ -115,7 +115,9 @@ files:
115
115
  - lib/authinator.rb
116
116
  - lib/authinator/auth_code_exchanger.rb
117
117
  - lib/authinator/client_token_issuer.rb
118
+ - lib/authinator/configuration.rb
118
119
  - lib/authinator/end_point_listener.rb
120
+ - lib/authinator/provider.rb
119
121
  - lib/authinator/version.rb
120
122
  - spec/authinator/auth_code_exchanger_spec.rb
121
123
  - spec/authinator/client_token_issuer_spec.rb