capcoauth 0.1.4 → 0.2.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 +4 -4
- data/README.md +9 -0
- data/app/controllers/capcoauth/callback_controller.rb +2 -1
- data/app/controllers/capcoauth/login_controller.rb +12 -4
- data/app/controllers/capcoauth/logout_controller.rb +3 -3
- data/capcoauth.gemspec +1 -1
- data/lib/capcoauth/config.rb +7 -0
- data/lib/capcoauth/helpers/controller.rb +1 -3
- data/lib/capcoauth/oauth/token_verifier.rb +30 -7
- data/lib/capcoauth/rails/helpers.rb +57 -8
- data/lib/capcoauth/rails/routes.rb +1 -0
- data/lib/capcoauth/version.rb +1 -1
- data/lib/generators/capcoauth/templates/initializer.rb +12 -2
- metadata +11 -6
- data/app/controllers/capcoauth/application_metal_controller.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 413293494a485db6a7d32e5f7ebb599b0a140dd1
|
4
|
+
data.tar.gz: f37a26cb400e3c5092b2958799551e13ee433af0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6401723ff07e5dc867d4fbbac9a2142c5bba2139d34b0c5969ff1737cb83f5d90fa261103e689eb289b23dce44ba0b046a488f1845496d1554d277ec1878162
|
7
|
+
data.tar.gz: 2d591b42756602ac29116859f224a0780408ddefaf303f53ce3b41d5340504d61fbc49a84242bcb32c655f2b9f5f39830749ca4bf43f5d62753f677e5452e606
|
data/README.md
CHANGED
@@ -79,6 +79,15 @@ whatever TTL value you set in your initializer. This saves time by preventing e
|
|
79
79
|
CapcOAuth for approval. This can be increased or decreased at your discretion, but should be kept to a relatively low
|
80
80
|
value.
|
81
81
|
|
82
|
+
## API-only applications
|
83
|
+
|
84
|
+
Simply remove `use_capcoauth` from `routes.rb`, or don't add it if you created your own initializer.
|
85
|
+
|
86
|
+
By default, this gem assumes you're using a normal Rails application, and thus adds `use_capcoauth` to your `routes.rb`
|
87
|
+
file. When `use_capcoauth` is used, it signals the gem to allow redirects and session variables whenever an HTML
|
88
|
+
request type is detected. For API-only applications, it will only parse the `access_token` query param and
|
89
|
+
`Authorization` headers.
|
90
|
+
|
82
91
|
## Bugs? Feature requests? Pull requests?
|
83
92
|
|
84
93
|
Email me or submit via issue/pull request.
|
@@ -3,10 +3,11 @@ require 'httparty'
|
|
3
3
|
module Capcoauth
|
4
4
|
class CallbackController < Capcoauth::ApplicationController
|
5
5
|
def show
|
6
|
+
|
6
7
|
# Abort if code not found
|
7
8
|
return redirect_to root_url, alert: 'Authorization was canceled' unless params[:code].present?
|
8
9
|
|
9
|
-
response = HTTParty.post(
|
10
|
+
response = ::HTTParty.post("#{Capcoauth.configuration.capcoauth_url}/oauth/token", {
|
10
11
|
body: {
|
11
12
|
client_id: Capcoauth.configuration.client_id,
|
12
13
|
client_secret: Capcoauth.configuration.client_secret,
|
@@ -3,12 +3,20 @@ require 'uri'
|
|
3
3
|
module Capcoauth
|
4
4
|
class LoginController < Capcoauth::ApplicationController
|
5
5
|
def show
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
|
7
|
+
# If set in session
|
8
|
+
if session[:capcoauth_access_token]
|
9
|
+
|
10
|
+
# Attempt to verify
|
11
|
+
begin
|
12
|
+
capcoauth_token.verify
|
13
|
+
redirect_to session.delete(:previous_url) || root_url, notice: 'You are already logged in'
|
14
|
+
return
|
15
|
+
rescue; end
|
9
16
|
end
|
10
17
|
|
11
|
-
|
18
|
+
# Otherwise, redirect
|
19
|
+
redirect_to "#{Capcoauth.configuration.capcoauth_url}/oauth/authorize?client_id=#{Capcoauth.configuration.client_id}&redirect_uri=#{URI.encode(oauth_callback_url)}&response_type=code"
|
12
20
|
end
|
13
21
|
end
|
14
22
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module Capcoauth
|
2
2
|
class LogoutController < Capcoauth::ApplicationController
|
3
|
-
|
4
3
|
def show
|
5
4
|
session.delete(:capcoauth_user_id)
|
6
|
-
|
7
|
-
|
5
|
+
token = session.delete(:capcoauth_access_token)
|
6
|
+
if token
|
7
|
+
OAuth::TTLCache.remove(token)
|
8
8
|
redirect_to root_url, notice: 'You have been logged out'
|
9
9
|
else
|
10
10
|
redirect_to root_url
|
data/capcoauth.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
|
|
16
16
|
# s.test_files = `git ls-files -- spec/*`.split("\n")
|
17
17
|
s.require_paths = ['lib']
|
18
18
|
|
19
|
-
s.add_dependency 'railties', '
|
19
|
+
s.add_dependency 'railties', ['>= 4.2', '< 6.0']
|
20
20
|
s.add_dependency 'httparty', '~> 0.13'
|
21
21
|
|
22
22
|
s.add_development_dependency 'rake', '~> 10.5'
|
data/lib/capcoauth/config.rb
CHANGED
@@ -16,6 +16,8 @@ module Capcoauth
|
|
16
16
|
class Config
|
17
17
|
attr_reader :client_id
|
18
18
|
attr_reader :client_secret
|
19
|
+
attr_reader :logger
|
20
|
+
attr_accessor :using_routes
|
19
21
|
|
20
22
|
class Builder
|
21
23
|
def initialize(&block)
|
@@ -34,6 +36,10 @@ module Capcoauth
|
|
34
36
|
def client_secret(client_secret)
|
35
37
|
@config.instance_variable_set('@client_secret', client_secret)
|
36
38
|
end
|
39
|
+
|
40
|
+
def logger(logger)
|
41
|
+
@config.instance_variable_set('@logger', logger)
|
42
|
+
end
|
37
43
|
end
|
38
44
|
|
39
45
|
module Option
|
@@ -67,5 +73,6 @@ module Capcoauth
|
|
67
73
|
extend Option
|
68
74
|
|
69
75
|
option :token_verify_ttl, default: 10
|
76
|
+
option :capcoauth_url, default: 'https://capcoauth.capco.com'
|
70
77
|
end
|
71
78
|
end
|
@@ -3,10 +3,8 @@ module Capcoauth
|
|
3
3
|
module Controller
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
|
-
private
|
7
|
-
|
8
6
|
def capcoauth_token
|
9
|
-
@
|
7
|
+
@capcoauth_token ||= OAuth::AccessToken.new(session[:capcoauth_access_token])
|
10
8
|
end
|
11
9
|
|
12
10
|
def oauth_callback_url
|
@@ -1,27 +1,50 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
1
3
|
module Capcoauth
|
2
4
|
module OAuth
|
3
5
|
class TokenVerifier
|
6
|
+
|
7
|
+
class UnauthorizedError < StandardError; end
|
8
|
+
class OtherError < StandardError; end
|
9
|
+
|
4
10
|
def self.verify(access_token)
|
5
|
-
|
11
|
+
raise UnauthorizedError if access_token.blank? or access_token.token.blank?
|
6
12
|
return access_token if TTLCache.valid?(access_token.token)
|
7
13
|
|
8
14
|
# Call Capcoauth
|
9
|
-
response = HTTParty.get(
|
15
|
+
response = ::HTTParty.get("#{Capcoauth.configuration.capcoauth_url}/oauth/token/info", {
|
10
16
|
headers: {
|
11
|
-
'Authorization' => "Bearer #{access_token.token}"
|
17
|
+
:'Authorization' => "Bearer #{access_token.token}"
|
12
18
|
}
|
13
19
|
})
|
14
20
|
|
15
21
|
# Set the user_id from the token response
|
16
22
|
if response.code == 200
|
17
|
-
TTLCache.update(access_token.token)
|
18
23
|
access_token.user_id = response.parsed_response['resource_owner_id']
|
19
|
-
|
20
|
-
|
24
|
+
if response.parsed_response.fetch('application', {}).fetch('uid', nil) === Capcoauth.configuration.client_id
|
25
|
+
logger.info("CapcOAuth: The access token for user ##{access_token.user_id} was verified successfully") unless logger.nil?
|
26
|
+
TTLCache.update(access_token.token)
|
27
|
+
access_token
|
28
|
+
else
|
29
|
+
logger.info("CapcOAuth: The access token for user ##{access_token.user_id} was valid, but for a different OAuth client ID") unless logger.nil?
|
30
|
+
raise UnauthorizedError
|
31
|
+
end
|
32
|
+
elsif response.code == 401
|
21
33
|
TTLCache.remove(access_token.token)
|
22
|
-
nil
|
34
|
+
logger.info("CapcOAuth: The access token was invalid, expired, or revoked") unless logger.nil?
|
35
|
+
raise UnauthorizedError
|
36
|
+
else
|
37
|
+
logger.info("CapcOAuth: Received unknown response") unless logger.nil?
|
38
|
+
logger.info(JSON.pretty_generate(response)) unless logger.nil?
|
39
|
+
raise OtherError
|
23
40
|
end
|
24
41
|
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def self.logger
|
46
|
+
Capcoauth.configuration.logger
|
47
|
+
end
|
25
48
|
end
|
26
49
|
end
|
27
50
|
end
|
@@ -4,25 +4,74 @@ module Capcoauth
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
def verify_authorized!
|
7
|
-
if
|
7
|
+
return if request.method_symbol == :options
|
8
|
+
capcoauth_token.verify
|
9
|
+
|
10
|
+
# Browser client
|
11
|
+
if handle_sessions?
|
8
12
|
session.delete(:previous_url)
|
9
|
-
|
13
|
+
end
|
14
|
+
|
15
|
+
@current_user_id ||= capcoauth_token.user_id
|
16
|
+
rescue OAuth::TokenVerifier::UnauthorizedError
|
17
|
+
if handle_sessions?
|
18
|
+
session[:previous_url] = request.url
|
10
19
|
session.delete(:capcoauth_access_token)
|
11
20
|
session.delete(:capcoauth_user_id)
|
12
|
-
session[:previous_url] = request.url
|
13
|
-
redirect_to :auth_login
|
14
21
|
end
|
22
|
+
handle_unauthorized
|
23
|
+
rescue OAuth::TokenVerifier::OtherError
|
24
|
+
if handle_sessions?
|
25
|
+
session.delete(:capcoauth_access_token)
|
26
|
+
session.delete(:capcoauth_user_id)
|
27
|
+
end
|
28
|
+
handle_internal_server_error
|
15
29
|
end
|
16
30
|
|
17
31
|
def current_user
|
18
|
-
User.
|
32
|
+
@user ||= User.find_by_id verify_authorized!
|
19
33
|
end
|
20
34
|
|
35
|
+
protected
|
36
|
+
|
37
|
+
def handle_unauthorized
|
38
|
+
if handle_sessions?
|
39
|
+
redirect_to :auth_login
|
40
|
+
else
|
41
|
+
render plain: 'Unauthorized', status: :unauthorized
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def handle_internal_server_error
|
46
|
+
render plain: 'Internal server error', status: :internal_server_error
|
47
|
+
end
|
48
|
+
|
21
49
|
private
|
22
50
|
|
23
|
-
|
24
|
-
|
25
|
-
|
51
|
+
def capcoauth_token
|
52
|
+
@_capcoauth_token ||= OAuth::AccessToken.new(token_from_request)
|
53
|
+
end
|
54
|
+
|
55
|
+
def token_from_request
|
56
|
+
token_from_param || token_from_session || token_from_headers
|
57
|
+
end
|
58
|
+
|
59
|
+
def token_from_param
|
60
|
+
params[:access_token]
|
61
|
+
end
|
62
|
+
|
63
|
+
def token_from_session
|
64
|
+
session[:capcoauth_access_token]
|
65
|
+
end
|
66
|
+
|
67
|
+
def token_from_headers
|
68
|
+
header_parts = (request.headers['AUTHORIZATION'] || '').split(' ')
|
69
|
+
(header_parts.length == 2 and header_parts[0].downcase == 'bearer') ? header_parts[1] : header_parts[0]
|
70
|
+
end
|
71
|
+
|
72
|
+
def handle_sessions?
|
73
|
+
request.format.html? and Capcoauth.configuration.using_routes
|
74
|
+
end
|
26
75
|
end
|
27
76
|
end
|
28
77
|
end
|
data/lib/capcoauth/version.rb
CHANGED
@@ -1,11 +1,21 @@
|
|
1
1
|
Capcoauth.configure do |config|
|
2
|
+
|
3
|
+
raise 'CapcOAuth Client ID not found' if ENV['CAPCOAUTH_CLIENT_ID'].nil?
|
4
|
+
raise 'CapcOAuth Client secret not found' if ENV['CAPCOAUTH_CLIENT_SECRET'].nil?
|
5
|
+
|
2
6
|
# CapcOAuth Client ID
|
3
|
-
config.client_id '
|
7
|
+
config.client_id ENV['CAPCOAUTH_CLIENT_ID']
|
4
8
|
|
5
9
|
# CapcOAuth Client Secret
|
6
|
-
config.client_secret '
|
10
|
+
config.client_secret ENV['CAPCOAUTH_CLIENT_SECRET']
|
7
11
|
|
8
12
|
# Configures how often to check CapcOAuth for access token validity, in seconds. If this value is too high,
|
9
13
|
# application will continue to serve requests to users even after the token is revoked
|
10
14
|
# config.token_verify_ttl 10
|
15
|
+
|
16
|
+
# Configure CapcOAuth service URL
|
17
|
+
# config.capcoauth_url ENV['CAPCOAUTH_URL']
|
18
|
+
|
19
|
+
# Configure the logger to use for OAuth events
|
20
|
+
config.logger Rails.logger
|
11
21
|
end
|
metadata
CHANGED
@@ -1,29 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capcoauth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Robertson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '4.2'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '6.0'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: '4.2'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '6.0'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: httparty
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -79,7 +85,6 @@ files:
|
|
79
85
|
- README.md
|
80
86
|
- Rakefile
|
81
87
|
- app/controllers/capcoauth/application_controller.rb
|
82
|
-
- app/controllers/capcoauth/application_metal_controller.rb
|
83
88
|
- app/controllers/capcoauth/callback_controller.rb
|
84
89
|
- app/controllers/capcoauth/login_controller.rb
|
85
90
|
- app/controllers/capcoauth/logout_controller.rb
|
@@ -119,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
119
124
|
version: '0'
|
120
125
|
requirements: []
|
121
126
|
rubyforge_project:
|
122
|
-
rubygems_version: 2.
|
127
|
+
rubygems_version: 2.5.1
|
123
128
|
signing_key:
|
124
129
|
specification_version: 4
|
125
130
|
summary: Integration with Capcoauth authentication service
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module Capcoauth
|
2
|
-
class ApplicationMetalController < ActionController::Metal
|
3
|
-
MODULES = [
|
4
|
-
ActionController::Instrumentation,
|
5
|
-
AbstractController::Rendering,
|
6
|
-
ActionController::Rendering,
|
7
|
-
ActionController::Renderers::All,
|
8
|
-
Helpers::Controller
|
9
|
-
]
|
10
|
-
|
11
|
-
MODULES.each do |mod|
|
12
|
-
include mod
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|