rails_api_auth 0.0.8 → 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: 5d0b7ae4fd9d87b7e8c46bc340021b799a5cb573
4
- data.tar.gz: cffacdb178138d081f4200ef380b2151503f5237
3
+ metadata.gz: 6d3b332bf7ec25029ebba034d2fec9b3aacb1a84
4
+ data.tar.gz: 725a73434ac1a2cc8064bb64fc152f146c5c469b
5
5
  SHA512:
6
- metadata.gz: a5604e3aa7352dcd1eaab660762f59e15fdc485acc80b4b59d0bbfbefeddb498c12e3ac58230618d43e34712355b9e92e8aafa4d4a0f24057977a6669e3f29d6
7
- data.tar.gz: 6eb2bf72a1d4789a4e4c97265382dcd1a091f76744d7de0f2d79e2bb8fb0ad82031f7bfa47ea65a47b05ea9299a9c8681b5ed17ae4a44f1e0cf20cd3beed9db5
6
+ metadata.gz: b30ef6301e45b23cbcd03e27625c6a88a23c93660824986d959c886a43c81cbb2b2ab5b0be54b68e4dcc71687793d8731e4fd107d1e16e29c091fe8f41771e08
7
+ data.tar.gz: be7fbc8b495e9e4ff3ec77eb77491b39333636a45c62ecc91c32306990f2a2ae967896c0770043885df42753efdeeea84946e5ed93b60368c97e89b1b06a8c46
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015-2017 simplabs GmbH
3
+ Copyright (c) 2015-2018 simplabs GmbH and contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/Rakefile CHANGED
@@ -4,7 +4,7 @@ rescue LoadError
4
4
  puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
5
  end
6
6
 
7
- APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__)
7
+ APP_RAKEFILE = File.expand_path('spec/dummy/Rakefile', __dir__)
8
8
  load 'rails/tasks/engine.rake'
9
9
 
10
10
  load 'rails/tasks/statistics.rake'
@@ -18,6 +18,8 @@ class Oauth2Controller < ApplicationController
18
18
  authenticate_with_google(params[:auth_code])
19
19
  when 'edx_auth_code'
20
20
  authenticate_with_edx(params[:username], params[:auth_code])
21
+ when 'github_auth_code'
22
+ authenticate_with_github(params[:auth_state], params[:auth_code])
21
23
  else
22
24
  oauth2_error('unsupported_grant_type')
23
25
  end
@@ -76,8 +78,19 @@ class Oauth2Controller < ApplicationController
76
78
  head 502
77
79
  end
78
80
 
81
+ def authenticate_with_github(auth_state, auth_code)
82
+ oauth2_error('no_authorization_code') && return unless auth_code.present?
83
+ oauth2_error('no_auth_state') && return unless auth_state.present?
84
+
85
+ login = GithubAuthenticator.new(auth_state, auth_code).authenticate!
86
+
87
+ render json: { access_token: login.oauth2_token }
88
+ rescue GithubAuthenticator::ApiError
89
+ head 502
90
+ end
91
+
79
92
  def oauth2_error(error)
80
- render json: { error: error }, status: 400
93
+ render json: { error: error }, status: :bad_request
81
94
  end
82
95
 
83
96
  end
@@ -3,7 +3,7 @@
3
3
  # @!visibility private
4
4
  class LoginNotFound
5
5
 
6
- def authenticate(_)
6
+ def authenticate(_password)
7
7
  false
8
8
  end
9
9
 
@@ -48,7 +48,7 @@ class EdxAuthenticator < BaseAuthenticator
48
48
 
49
49
  def get_user(access_token)
50
50
  headers = { 'Authorization' => "Bearer #{access_token}" }
51
- @edx_user ||= begin
51
+ @get_user ||= begin
52
52
  get_request(user_url, headers).parsed_response.symbolize_keys
53
53
  end
54
54
  end
@@ -31,7 +31,7 @@ class FacebookAuthenticator < BaseAuthenticator
31
31
  end
32
32
 
33
33
  def get_user(access_token)
34
- @facebook_user ||= begin
34
+ @get_user ||= begin
35
35
  parsed_response = get_request(user_url(access_token)).parsed_response
36
36
  parsed_response.symbolize_keys
37
37
  end
@@ -0,0 +1,61 @@
1
+ require 'httparty'
2
+
3
+ # Handles Github authentication
4
+ #
5
+ # @!visibility private
6
+ class GithubAuthenticator < BaseAuthenticator
7
+
8
+ PROVIDER = 'github'.freeze
9
+ TOKEN_URL = 'https://github.com/login/oauth/access_token'.freeze
10
+ USER_URL = 'https://api.github.com/user?access_token=%{access_token}'.freeze
11
+
12
+ def initialize(auth_state, auth_code)
13
+ @auth_code = auth_code
14
+ @auth_state = auth_state
15
+ end
16
+
17
+ private
18
+
19
+ def connect_login_to_account(login, user)
20
+ login.update_attributes!(uid: user[:id], provider: PROVIDER)
21
+ end
22
+
23
+ def create_login_from_account(user)
24
+ login_attributes = {
25
+ identification: user[:email],
26
+ uid: user[:id],
27
+ provider: PROVIDER
28
+ }
29
+
30
+ Login.create!(login_attributes)
31
+ end
32
+
33
+ def access_token
34
+ response = HTTParty.post(TOKEN_URL, token_options)
35
+ response.parsed_response['access_token']
36
+ end
37
+
38
+ def get_user(access_token)
39
+ @get_user ||= begin
40
+ get_request(user_url(access_token)).parsed_response.symbolize_keys
41
+ end
42
+ end
43
+
44
+ def user_url(access_token)
45
+ USER_URL % { access_token: access_token }
46
+ end
47
+
48
+ def token_options
49
+ @token_options ||= {
50
+ headers: { 'Accept' => 'application/json' },
51
+ body: {
52
+ code: @auth_code,
53
+ client_id: RailsApiAuth.github_client_id,
54
+ client_secret: RailsApiAuth.github_client_secret,
55
+ redirect_uri: RailsApiAuth.github_redirect_uri,
56
+ state: @auth_state
57
+ }
58
+ }
59
+ end
60
+
61
+ end
@@ -31,7 +31,7 @@ class GoogleAuthenticator < BaseAuthenticator
31
31
  end
32
32
 
33
33
  def get_user(access_token)
34
- @google_user ||= begin
34
+ @get_user ||= begin
35
35
  get_request(user_url(access_token)).parsed_response.symbolize_keys
36
36
  end
37
37
  end
@@ -36,6 +36,18 @@ module RailsApiAuth
36
36
  # The Google App's redirect URI.
37
37
  mattr_accessor :google_redirect_uri
38
38
 
39
+ # @!attribute [rw] github_client_id
40
+ # The Github client ID.
41
+ mattr_accessor :github_client_id
42
+
43
+ # @!attribute [rw] github_client_secret
44
+ # The Github client secret.
45
+ mattr_accessor :github_client_secret
46
+
47
+ # @!attribute [rw] github_redirect_uri
48
+ # The Github App's redirect URI.
49
+ mattr_accessor :github_redirect_uri
50
+
39
51
  # @!attribute [rw] edx_client_id
40
52
  # The Edx client ID.
41
53
  mattr_accessor :edx_client_id
@@ -1,5 +1,5 @@
1
1
  module RailsApiAuth
2
2
 
3
- VERSION = '0.0.8'.freeze
3
+ VERSION = '0.1.0'.freeze
4
4
 
5
5
  end
@@ -1,6 +1,6 @@
1
1
  # Add your own tasks in files placed in lib/tasks ending in .rake,
2
2
  # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
3
 
4
- require File.expand_path('../config/application', __FILE__)
4
+ require File.expand_path('config/application', __dir__)
5
5
 
6
6
  Rails.application.load_tasks
@@ -10,9 +10,9 @@ class AccessOnceController < ApplicationController
10
10
 
11
11
  def index
12
12
  if Rails::VERSION::MAJOR < 4
13
- render text: 'zuper content', status: 200
13
+ render text: 'zuper content', status: :ok
14
14
  else
15
- render plain: 'zuper content', status: 200
15
+ render plain: 'zuper content', status: :ok
16
16
  end
17
17
  end
18
18
 
@@ -10,9 +10,9 @@ class AuthenticatedController < ApplicationController
10
10
 
11
11
  def index
12
12
  if Rails::VERSION::MAJOR < 4
13
- render text: 'zuper content', status: 200
13
+ render text: 'zuper content', status: :ok
14
14
  else
15
- render plain: 'zuper content', status: 200
15
+ render plain: 'zuper content', status: :ok
16
16
  end
17
17
  end
18
18
 
@@ -10,9 +10,9 @@ class CustomAuthenticatedController < ApplicationController
10
10
 
11
11
  def index
12
12
  if Rails::VERSION::MAJOR < 4
13
- render text: 'zuper content', status: 200
13
+ render text: 'zuper content', status: :ok
14
14
  else
15
- render plain: 'zuper content', status: 200
15
+ render plain: 'zuper content', status: :ok
16
16
  end
17
17
  end
18
18
 
@@ -1,4 +1,4 @@
1
- require File.expand_path('../boot', __FILE__)
1
+ require File.expand_path('boot', __dir__)
2
2
 
3
3
  require 'active_record/railtie'
4
4
  require 'action_controller/railtie'
@@ -1,5 +1,5 @@
1
1
  # Set up gems listed in the Gemfile.
2
- ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../Gemfile', __dir__)
3
3
 
4
4
  require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
5
- $LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__)
5
+ $LOAD_PATH.unshift File.expand_path('../../../lib', __dir__)
@@ -1,5 +1,5 @@
1
1
  # Load the Rails application.
2
- require File.expand_path('../application', __FILE__)
2
+ require File.expand_path('application', __dir__)
3
3
 
4
4
  # Initialize the Rails application.
5
5
  Rails.application.initialize!
@@ -9,6 +9,10 @@ RailsApiAuth.tap do |raa|
9
9
  raa.google_client_secret = 'google_client_secret'
10
10
  raa.google_redirect_uri = 'google_redirect_uri'
11
11
 
12
+ raa.github_client_id = 'github_client_id'
13
+ raa.github_client_secret = 'github_client_secret'
14
+ raa.github_redirect_uri = 'github_redirect_uri'
15
+
12
16
  raa.edx_client_id = 'edx_client_id'
13
17
  raa.edx_client_secret = 'edx_client_secret'
14
18
  raa.edx_domain = 'edxdomain.org'
@@ -0,0 +1,12 @@
1
+ describe GithubAuthenticator do
2
+ let(:uid_mapped_field) { 'id' }
3
+
4
+ let(:authenticated_user_data) do
5
+ {
6
+ email: 'user@gmail.com',
7
+ id: '789789789789'
8
+ }
9
+ end
10
+ include_context 'stubbed github requests'
11
+ it_behaves_like 'a authenticator'
12
+ end
@@ -8,7 +8,7 @@ SimpleCov.start do
8
8
  end
9
9
  end
10
10
 
11
- require File.expand_path('../dummy/config/environment.rb', __FILE__)
11
+ require File.expand_path('dummy/config/environment.rb', __dir__)
12
12
  require 'rspec/rails'
13
13
  require 'factory_girl_rails'
14
14
  require 'faker'
@@ -0,0 +1,13 @@
1
+ shared_context 'stubbed github requests' do
2
+ let(:auth_code) { 'authcode' }
3
+ let(:auth_state) { 'abc123' }
4
+ let(:access_token) { 'UsQfLVVKUJmSjD6gtRk9UsrZqfpL9ajB' }
5
+ let(:response_with_gh_token) { { body: JSON.generate({ access_token: access_token, token_type: 'bearer', scope: 'user' }), headers: { 'Content-Type' => 'application/json' } } }
6
+ let(:response_with_gh_user) { { body: JSON.generate(authenticated_user_data), headers: { 'Content-Type' => 'application/json' } } }
7
+ let(:token_parameters) { { code: auth_code, client_id: 'app_id', client_secret: 'app_secret', redirect_uri: 'redirect_uri', state: auth_state } }
8
+
9
+ before do
10
+ stub_request(:post, GithubAuthenticator::TOKEN_URL % token_parameters).to_return(response_with_gh_token)
11
+ stub_request(:get, GithubAuthenticator::USER_URL % { access_token: access_token }).to_return(response_with_gh_user)
12
+ end
13
+ end
@@ -4,6 +4,8 @@ shared_examples 'a authenticator' do
4
4
 
5
5
  if described_class::PROVIDER.eql? 'edx'
6
6
  subject { described_class.new(username, auth_code).authenticate! }
7
+ elsif described_class::PROVIDER.eql? 'github'
8
+ subject { described_class.new(auth_state, auth_code).authenticate! }
7
9
  else
8
10
  subject { described_class.new(auth_code).authenticate! }
9
11
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_api_auth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marco Otte-Witte
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-02-13 00:00:00.000000000 Z
12
+ date: 2018-04-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bcrypt
@@ -77,6 +77,7 @@ files:
77
77
  - app/services/base_authenticator.rb
78
78
  - app/services/edx_authenticator.rb
79
79
  - app/services/facebook_authenticator.rb
80
+ - app/services/github_authenticator.rb
80
81
  - app/services/google_authenticator.rb
81
82
  - config/routes.rb
82
83
  - db/migrate/20150709221755_create_logins.rb
@@ -136,12 +137,14 @@ files:
136
137
  - spec/requests/oauth2_spec.rb
137
138
  - spec/services/edx_authenticator_spec.rb
138
139
  - spec/services/facebook_authenticator_spec.rb
140
+ - spec/services/github_authenticator_spec.rb
139
141
  - spec/services/google_authenticator_spec.rb
140
142
  - spec/spec_helper.rb
141
143
  - spec/support/factory_girl.rb
142
144
  - spec/support/shared_contexts/force_ssl.rb
143
145
  - spec/support/shared_contexts/stubbed_edx_requests.rb
144
146
  - spec/support/shared_contexts/stubbed_facebook_requests.rb
147
+ - spec/support/shared_contexts/stubbed_github_requests.rb
145
148
  - spec/support/shared_contexts/stubbed_google_requests.rb
146
149
  - spec/support/shared_examples/authenticator_shared_requests.rb
147
150
  - spec/support/shared_examples/oauth2_edx_shared_requests.rb
@@ -166,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
169
  version: '0'
167
170
  requirements: []
168
171
  rubyforge_project:
169
- rubygems_version: 2.5.2
172
+ rubygems_version: 2.4.5.1
170
173
  signing_key:
171
174
  specification_version: 4
172
175
  summary: Engine that implements OAuth 2.0 and Facebook authentication for API projects
@@ -218,6 +221,7 @@ test_files:
218
221
  - spec/requests/authenticated_spec.rb
219
222
  - spec/requests/access_once_spec.rb
220
223
  - spec/requests/custom_authenticated_spec.rb
224
+ - spec/support/shared_contexts/stubbed_github_requests.rb
221
225
  - spec/support/shared_contexts/force_ssl.rb
222
226
  - spec/support/shared_contexts/stubbed_facebook_requests.rb
223
227
  - spec/support/shared_contexts/stubbed_edx_requests.rb
@@ -228,6 +232,7 @@ test_files:
228
232
  - spec/support/factory_girl.rb
229
233
  - spec/factories/logins.rb
230
234
  - spec/factories/accounts.rb
235
+ - spec/services/github_authenticator_spec.rb
231
236
  - spec/services/google_authenticator_spec.rb
232
237
  - spec/services/edx_authenticator_spec.rb
233
238
  - spec/services/facebook_authenticator_spec.rb