capcoauth 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -35
  3. data/.rspec +1 -0
  4. data/.travis.yml +11 -0
  5. data/Gemfile +10 -0
  6. data/Gemfile.lock +171 -0
  7. data/README.md +3 -1
  8. data/Rakefile +7 -7
  9. data/app/controllers/capcoauth/application_controller.rb +8 -1
  10. data/app/controllers/capcoauth/login_controller.rb +5 -1
  11. data/app/controllers/capcoauth/logout_controller.rb +2 -6
  12. data/capcoauth.gemspec +13 -6
  13. data/lib/capcoauth/config.rb +52 -58
  14. data/lib/capcoauth/errors.rb +3 -0
  15. data/lib/capcoauth/notifications.rb +11 -9
  16. data/lib/capcoauth/oauth/access_token.rb +0 -1
  17. data/lib/capcoauth/oauth/token_verifier.rb +15 -10
  18. data/lib/capcoauth/rails/helpers.rb +45 -44
  19. data/lib/capcoauth/version.rb +11 -1
  20. data/lib/capcoauth.rb +1 -9
  21. data/lib/generators/capcoauth/templates/initializer.rb +23 -12
  22. data/spec/dummy/Rakefile +7 -0
  23. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  24. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +12 -0
  25. data/spec/dummy/app/controllers/home_controller.rb +17 -0
  26. data/spec/dummy/app/controllers/metal_controller.rb +11 -0
  27. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +11 -0
  28. data/spec/dummy/app/models/user.rb +3 -0
  29. data/spec/dummy/app/views/home/index.html.erb +0 -0
  30. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  31. data/spec/dummy/config/application.rb +16 -0
  32. data/spec/dummy/config/boot.rb +6 -0
  33. data/spec/dummy/config/database.yml +15 -0
  34. data/spec/dummy/config/environment.rb +5 -0
  35. data/spec/dummy/config/environments/development.rb +29 -0
  36. data/spec/dummy/config/environments/production.rb +62 -0
  37. data/spec/dummy/config/environments/test.rb +42 -0
  38. data/spec/dummy/config/initializers/active_record_belongs_to_required_by_default.rb +6 -0
  39. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  40. data/spec/dummy/config/initializers/capcoauth.rb +41 -0
  41. data/spec/dummy/config/initializers/secret_token.rb +9 -0
  42. data/spec/dummy/config/initializers/session_store.rb +8 -0
  43. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  44. data/spec/dummy/config/routes.rb +50 -0
  45. data/spec/dummy/config.ru +4 -0
  46. data/spec/dummy/db/migrate/20111122132257_create_users.rb +9 -0
  47. data/spec/dummy/db/schema.rb +22 -0
  48. data/spec/dummy/public/404.html +26 -0
  49. data/spec/dummy/public/422.html +26 -0
  50. data/spec/dummy/public/500.html +26 -0
  51. data/spec/dummy/public/favicon.ico +0 -0
  52. data/spec/dummy/script/rails +6 -0
  53. data/spec/generators/install_generator_spec.rb +27 -0
  54. data/spec/generators/templates/routes.rb +3 -0
  55. data/spec/lib/capcoauth/oauth/access_token_spec.rb +31 -0
  56. data/spec/lib/capcoauth/oauth/token_verifier_spec.rb +121 -0
  57. data/spec/lib/capcoauth/oauth/ttl_cache_spec.rb +88 -0
  58. data/spec/lib/capcoauth_spec.rb +3 -0
  59. data/spec/lib/config_spec.rb +215 -0
  60. data/spec/lib/version_spec.rb +25 -0
  61. data/spec/spec_helper.rb +8 -0
  62. data/spec/spec_helper_integration.rb +50 -0
  63. data/spec/support/http_method_shim.rb +38 -0
  64. data/spec/support/orm/active_record.rb +3 -0
  65. metadata +172 -12
  66. data/lib/capcoauth/helpers/controller.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f3219f2f066b3f768660b18dc93573735aae8597
4
- data.tar.gz: 3c1915a11faccc0dabedea935d1ff6652f62d16b
3
+ metadata.gz: 034c46acdc3cd67430792c484dccaffa490190b0
4
+ data.tar.gz: 9334e9e08a061613dd2d5a93efae5cb7f13d832f
5
5
  SHA512:
6
- metadata.gz: 540cbf8a0ea52e8e98474065f57432de4db5c7533746ca6fdc538fcfcf61a6aa875d6a58b4998eeb727226d571de7b249e102349eaa3e515387903487250de26
7
- data.tar.gz: ac54859312f5f47b2fb05a2ca8fe006317c73dffb630c77274727cfb897111ebe4c08e0ac8d8aae8882c34e61d8d376d8c96ac21b1ffbe89dd17ad1fb2883c46
6
+ metadata.gz: 24802981fe766eaf8c08f99fa141f2228b005eb47491706ba40eadbbd1bad81ee2ff0d9de22e86a934893aab2ef7be2207dad21c7576b215ab85cafc273efa6a
7
+ data.tar.gz: e0ab260d5a042d7c6e90e489a33411d3b2c090182eb3b2b60341d525dcc1ac0c1e0c523cd3bee634f4e3573b45a624a8d4ee73de70c9649cfb7eb1fbb9b58920
data/.gitignore CHANGED
@@ -1,40 +1,20 @@
1
- *.gem
1
+ .bundle/
2
+ .rbx
2
3
  *.rbc
3
- /.config
4
- /coverage/
5
- /InstalledFiles
6
- /pkg/
7
- /spec/reports/
8
- /spec/examples.txt
9
- /test/tmp/
10
- /test/version_tmp/
11
- /tmp/
12
-
13
- ## Specific to RubyMotion:
14
- .dat*
15
- .repl_history
16
- build/
17
-
18
- ## Documentation cache and generated files:
4
+ log/*.log
5
+ pkg/
6
+ spec/dummy/db/*.sqlite3
7
+ spec/dummy/log/*.log
8
+ spec/dummy/tmp/
9
+ spec/generators/tmp
10
+ Gemfile.lock
11
+ gemfiles/*.lock
12
+ .rvmrc
13
+ *.swp
14
+ .idea
19
15
  /.yardoc/
20
16
  /_yardoc/
21
17
  /doc/
22
18
  /rdoc/
23
-
24
- ## Environment normalization:
25
- /.bundle/
26
- /vendor/bundle
27
- /lib/bundler/man/
28
-
29
- # for a library or gem, you might want to ignore these files since the code is
30
- # intended to run in multiple environments; otherwise, check them in:
31
- # Gemfile.lock
32
- # .ruby-version
33
- # .ruby-gemset
34
-
35
- # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
36
- .rvmrc
37
-
38
- # IDE
39
- .idea
40
- .editorconfig
19
+ coverage
20
+ *.gem
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ cache: bundler
2
+ language: ruby
3
+ sudo: false
4
+
5
+ rvm:
6
+ - 2.2.7
7
+ - 2.3.4
8
+ - 2.4.1
9
+
10
+ before_install:
11
+ - gem install bundler -v '~> 1.10'
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rails', '~> 4.2.0'
4
+
5
+ gem 'simplecov', require: false, group: :test
6
+
7
+ gem 'activerecord-jdbcsqlite3-adapter', platform: :jruby
8
+ gem 'sqlite3', platform: [:ruby, :mswin, :mingw, :x64_mingw]
9
+ gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw]
10
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,171 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ capcoauth (0.4.0)
5
+ activesupport (>= 3.0)
6
+ httparty (~> 0.14)
7
+ railties (>= 4.2, < 6.0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ actionmailer (4.2.8)
13
+ actionpack (= 4.2.8)
14
+ actionview (= 4.2.8)
15
+ activejob (= 4.2.8)
16
+ mail (~> 2.5, >= 2.5.4)
17
+ rails-dom-testing (~> 1.0, >= 1.0.5)
18
+ actionpack (4.2.8)
19
+ actionview (= 4.2.8)
20
+ activesupport (= 4.2.8)
21
+ rack (~> 1.6)
22
+ rack-test (~> 0.6.2)
23
+ rails-dom-testing (~> 1.0, >= 1.0.5)
24
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
25
+ actionview (4.2.8)
26
+ activesupport (= 4.2.8)
27
+ builder (~> 3.1)
28
+ erubis (~> 2.7.0)
29
+ rails-dom-testing (~> 1.0, >= 1.0.5)
30
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
31
+ activejob (4.2.8)
32
+ activesupport (= 4.2.8)
33
+ globalid (>= 0.3.0)
34
+ activemodel (4.2.8)
35
+ activesupport (= 4.2.8)
36
+ builder (~> 3.1)
37
+ activerecord (4.2.8)
38
+ activemodel (= 4.2.8)
39
+ activesupport (= 4.2.8)
40
+ arel (~> 6.0)
41
+ activesupport (4.2.8)
42
+ i18n (~> 0.7)
43
+ minitest (~> 5.1)
44
+ thread_safe (~> 0.3, >= 0.3.4)
45
+ tzinfo (~> 1.1)
46
+ addressable (2.5.1)
47
+ public_suffix (~> 2.0, >= 2.0.2)
48
+ arel (6.0.4)
49
+ builder (3.2.3)
50
+ capybara (2.14.0)
51
+ addressable
52
+ mime-types (>= 1.16)
53
+ nokogiri (>= 1.3.3)
54
+ rack (>= 1.0.0)
55
+ rack-test (>= 0.5.4)
56
+ xpath (~> 2.0)
57
+ concurrent-ruby (1.0.5)
58
+ database_cleaner (1.5.3)
59
+ diff-lcs (1.3)
60
+ docile (1.1.5)
61
+ erubis (2.7.0)
62
+ factory_girl (4.7.0)
63
+ activesupport (>= 3.0.0)
64
+ generator_spec (0.9.3)
65
+ activesupport (>= 3.0.0)
66
+ railties (>= 3.0.0)
67
+ globalid (0.4.0)
68
+ activesupport (>= 4.2.0)
69
+ httparty (0.15.2)
70
+ multi_xml (>= 0.5.2)
71
+ i18n (0.8.1)
72
+ json (2.1.0)
73
+ loofah (2.0.3)
74
+ nokogiri (>= 1.5.9)
75
+ mail (2.6.5)
76
+ mime-types (>= 1.16, < 4)
77
+ mime-types (3.1)
78
+ mime-types-data (~> 3.2015)
79
+ mime-types-data (3.2016.0521)
80
+ mini_portile2 (2.1.0)
81
+ minitest (5.10.2)
82
+ multi_xml (0.6.0)
83
+ nokogiri (1.7.2)
84
+ mini_portile2 (~> 2.1.0)
85
+ public_suffix (2.0.5)
86
+ rack (1.6.6)
87
+ rack-test (0.6.3)
88
+ rack (>= 1.0)
89
+ rails (4.2.8)
90
+ actionmailer (= 4.2.8)
91
+ actionpack (= 4.2.8)
92
+ actionview (= 4.2.8)
93
+ activejob (= 4.2.8)
94
+ activemodel (= 4.2.8)
95
+ activerecord (= 4.2.8)
96
+ activesupport (= 4.2.8)
97
+ bundler (>= 1.3.0, < 2.0)
98
+ railties (= 4.2.8)
99
+ sprockets-rails
100
+ rails-deprecated_sanitizer (1.0.3)
101
+ activesupport (>= 4.2.0.alpha)
102
+ rails-dom-testing (1.0.8)
103
+ activesupport (>= 4.2.0.beta, < 5.0)
104
+ nokogiri (~> 1.6)
105
+ rails-deprecated_sanitizer (>= 1.0.1)
106
+ rails-html-sanitizer (1.0.3)
107
+ loofah (~> 2.0)
108
+ railties (4.2.8)
109
+ actionpack (= 4.2.8)
110
+ activesupport (= 4.2.8)
111
+ rake (>= 0.8.7)
112
+ thor (>= 0.18.1, < 2.0)
113
+ rake (12.0.0)
114
+ rspec-core (3.6.0)
115
+ rspec-support (~> 3.6.0)
116
+ rspec-expectations (3.6.0)
117
+ diff-lcs (>= 1.2.0, < 2.0)
118
+ rspec-support (~> 3.6.0)
119
+ rspec-mocks (3.6.0)
120
+ diff-lcs (>= 1.2.0, < 2.0)
121
+ rspec-support (~> 3.6.0)
122
+ rspec-rails (3.6.0)
123
+ actionpack (>= 3.0)
124
+ activesupport (>= 3.0)
125
+ railties (>= 3.0)
126
+ rspec-core (~> 3.6.0)
127
+ rspec-expectations (~> 3.6.0)
128
+ rspec-mocks (~> 3.6.0)
129
+ rspec-support (~> 3.6.0)
130
+ rspec-support (3.6.0)
131
+ simplecov (0.14.1)
132
+ docile (~> 1.1.0)
133
+ json (>= 1.8, < 3)
134
+ simplecov-html (~> 0.10.0)
135
+ simplecov-html (0.10.0)
136
+ sprockets (3.7.1)
137
+ concurrent-ruby (~> 1.0)
138
+ rack (> 1, < 3)
139
+ sprockets-rails (3.2.0)
140
+ actionpack (>= 4.0)
141
+ activesupport (>= 4.0)
142
+ sprockets (>= 3.0.0)
143
+ sqlite3 (1.3.13)
144
+ thor (0.19.4)
145
+ thread_safe (0.3.6)
146
+ timecop (0.8.1)
147
+ tzinfo (1.2.3)
148
+ thread_safe (~> 0.1)
149
+ xpath (2.0.0)
150
+ nokogiri (~> 1.3)
151
+
152
+ PLATFORMS
153
+ ruby
154
+
155
+ DEPENDENCIES
156
+ activerecord-jdbcsqlite3-adapter
157
+ capcoauth!
158
+ capybara
159
+ database_cleaner (~> 1.5.3)
160
+ factory_girl (~> 4.7.0)
161
+ generator_spec (~> 0.9.3)
162
+ rails (~> 4.2.0)
163
+ rake (>= 11.3.0)
164
+ rspec-rails
165
+ simplecov
166
+ sqlite3
167
+ timecop (~> 0.8.1)
168
+ tzinfo-data
169
+
170
+ BUNDLED WITH
171
+ 1.13.5
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # capcoauth-gem
2
2
 
3
+ ![Travis Build status](https://travis-ci.org/arcreative/capcoauth-gem.svg?branch=master)
4
+
3
5
  Ruby Gem for integrating a Rails project with CapcOAuth
4
6
 
5
7
  Currently, this only supports session-based authentication, but can easily be adapted to accept bearer tokens if needed.
@@ -50,7 +52,7 @@ class ApplicationController < ActionController::Base
50
52
  end
51
53
  ```
52
54
 
53
- Or even skip it entirely for specific actions:
55
+ Or even skip it entirely for specific controllers:
54
56
 
55
57
  ```ruby
56
58
  class PublicStuffController < ApplicationController
data/Rakefile CHANGED
@@ -2,19 +2,19 @@ require 'bundler/setup'
2
2
  require 'rspec/core/rake_task'
3
3
 
4
4
  desc 'Default: run specs.'
5
- task :default => :spec
5
+ task :default => :spec_example
6
6
 
7
7
  desc 'Run all specs'
8
- RSpec::Core::RakeTask.new(:spec) do |config|
8
+ RSpec::Core::RakeTask.new(:spec_example) do |config|
9
9
  config.verbose = false
10
10
  end
11
11
 
12
12
  namespace :capcoauth do
13
- # desc 'Install Capcoauth in dummy app'
14
- # task :install do
15
- # cd 'spec/dummy'
16
- # system 'bundle exec rails g capcoauth:install --force'
17
- # end
13
+ desc 'Install Capcoauth in dummy app'
14
+ task :install do
15
+ cd 'spec/dummy'
16
+ system 'bundle exec rails g capcoauth:install --force'
17
+ end
18
18
  end
19
19
 
20
20
  Bundler::GemHelper.install_tasks
@@ -1,11 +1,18 @@
1
1
  module Capcoauth
2
2
  class ApplicationController < ActionController::Base
3
- include Helpers::Controller
4
3
 
5
4
  if ::Rails.version.to_i < 4
6
5
  protect_from_forgery
7
6
  else
8
7
  protect_from_forgery with: :exception
9
8
  end
9
+
10
+ def capcoauth_token
11
+ @capcoauth_token ||= OAuth::AccessToken.new(session[:capcoauth_access_token])
12
+ end
13
+
14
+ def oauth_callback_url
15
+ "#{root_url}auth/callback"
16
+ end
10
17
  end
11
18
  end
@@ -10,7 +10,11 @@ module Capcoauth
10
10
  # Attempt to verify
11
11
  begin
12
12
  capcoauth_token.verify
13
- redirect_to session.delete(:previous_url) || root_url, notice: 'You are already logged in'
13
+ if Capcoauth.configuration.perform_login_redirects
14
+ redirect_to session.delete(:previous_url) || root_url, notice: 'You are already logged in'
15
+ else
16
+ redirect_to root_url, notice: 'You are already logged in'
17
+ end
14
18
  return
15
19
  rescue; end
16
20
  end
@@ -3,12 +3,8 @@ module Capcoauth
3
3
  def show
4
4
  session.delete(:capcoauth_user_id)
5
5
  token = session.delete(:capcoauth_access_token)
6
- if token
7
- OAuth::TTLCache.remove(token)
8
- redirect_to root_url, notice: 'You have been logged out'
9
- else
10
- redirect_to root_url
11
- end
6
+ OAuth::TTLCache.remove(token) if token.present?
7
+ redirect_to root_url, notice: 'You have been logged out'
12
8
  end
13
9
  end
14
10
  end
data/capcoauth.gemspec CHANGED
@@ -1,10 +1,10 @@
1
- $:.push File.expand_path("../lib", __FILE__)
1
+ $:.push File.expand_path('../lib', __FILE__)
2
2
 
3
3
  require 'capcoauth/version'
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'capcoauth'
7
- s.version = Capcoauth::VERSION
7
+ s.version = Capcoauth.gem_version.to_s
8
8
  s.authors = ['Adam Robertson']
9
9
  s.email = %w'adam.robertson@capco.com'
10
10
  s.homepage = 'https://github.com/arcreative/capcoauth-gem'
@@ -13,13 +13,20 @@ Gem::Specification.new do |s|
13
13
  s.license = 'MIT'
14
14
 
15
15
  s.files = `git ls-files`.split("\n")
16
- # s.test_files = `git ls-files -- spec/*`.split("\n")
16
+ s.test_files = `git ls-files -- spec/*`.split("\n")
17
17
  s.require_paths = ['lib']
18
+
19
+ s.required_ruby_version = '>= 2.1'
18
20
 
19
21
  s.add_dependency 'railties', ['>= 4.2', '< 6.0']
20
22
  s.add_dependency 'activesupport', '>= 3.0'
21
- s.add_dependency 'httparty', '~> 0.13'
23
+ s.add_dependency 'httparty', '~> 0.14'
22
24
 
23
- s.add_development_dependency 'rake', '~> 10.5'
24
- s.add_development_dependency 'rspec-rails', '~> 3.4'
25
+ s.add_development_dependency 'capybara'
26
+ s.add_development_dependency 'database_cleaner', '~> 1.5.3'
27
+ s.add_development_dependency 'factory_girl', '~> 4.7.0'
28
+ s.add_development_dependency 'generator_spec', '~> 0.9.3'
29
+ s.add_development_dependency 'rake', '>= 11.3.0'
30
+ s.add_development_dependency 'rspec-rails'
31
+ s.add_development_dependency 'timecop', '~> 0.8.1'
25
32
  end
@@ -1,86 +1,80 @@
1
1
  require 'active_support/cache'
2
2
 
3
3
  module Capcoauth
4
- class MissingConfiguration < StandardError
5
- def initialize
6
- super 'Capcoauth configuration is missing. Please ensure you have an initializer in config/initializers/capcoauth.rb'
4
+ class MissingConfigurationError < StandardError
5
+ def message
6
+ # :nocov:
7
+ 'Capcoauth configuration is missing. Please ensure you have an initializer in config/initializers/capcoauth.rb'
8
+ # :nocov:
7
9
  end
8
10
  end
11
+ class MissingRequiredOptionError < StandardError; end
9
12
 
10
13
  def self.configure(&block)
11
14
  @config = Config::Builder.new(&block).build
12
15
  end
13
16
 
14
17
  def self.configuration
15
- @config || (fail MissingConfiguration.new)
18
+ @config || (fail MissingConfigurationError.new)
16
19
  end
17
20
 
18
21
  class Config
19
- attr_reader :client_id
20
- attr_reader :client_secret
21
- attr_reader :logger
22
- attr_accessor :using_routes
22
+ CAPCOAUTH_URL_DEFAULT = 'https://capcoauth.capco.com'.freeze
23
+ TOKEN_VERIFY_TTL_DEFAULT = 10.freeze
23
24
 
24
25
  class Builder
25
26
  def initialize(&block)
26
27
  @config = Config.new
27
- instance_eval(&block)
28
+
29
+ # Set defaults
30
+ @config.logger = ::Rails.logger
31
+ @config.using_routes = false
32
+ @config.perform_login_redirects = true
33
+ @config.token_verify_ttl = TOKEN_VERIFY_TTL_DEFAULT
34
+ @config.capcoauth_url = CAPCOAUTH_URL_DEFAULT
35
+ @config.user_id_field = :capcoauth
36
+ @config.cache_store = ::ActiveSupport::Cache::MemoryStore.new
37
+ @config.require_user = true
38
+
39
+ # Evaluate configuration block
40
+ @config.instance_eval(&block)
28
41
  end
29
42
 
30
43
  def build
31
44
  @config
32
45
  end
33
-
34
- def client_id(client_id)
35
- @config.instance_variable_set('@client_id', client_id)
36
- end
37
-
38
- def client_secret(client_secret)
39
- @config.instance_variable_set('@client_secret', client_secret)
40
- end
41
-
42
- def logger(logger)
43
- @config.instance_variable_set('@logger', logger)
44
- end
45
46
  end
46
47
 
47
- module Option
48
- def option(name, options = {})
49
- attribute = options[:as] || name
50
-
51
- Builder.instance_eval do
52
- define_method name do |*args, &block|
53
- value = block ? block : args.first
54
-
55
- @config.instance_variable_set(:"@#{attribute}", value)
56
- end
57
- end
58
-
59
- define_method attribute do |*args|
60
- if instance_variable_defined?(:"@#{attribute}")
61
- instance_variable_get(:"@#{attribute}")
62
- else
63
- options[:default]
64
- end
65
- end
66
-
67
- public attribute
68
- end
69
-
70
- def extended(base)
71
- base.send(:private, :option)
72
- end
48
+ attr_accessor :logger,
49
+ :using_routes,
50
+ :perform_login_redirects,
51
+ :token_verify_ttl,
52
+ :capcoauth_url,
53
+ :user_id_field,
54
+ :cache_store,
55
+ :user_resolver,
56
+ :require_user
57
+
58
+ def client_id
59
+ @client_id || raise(MissingRequiredOptionError, 'Missing required option `client_id`')
60
+ end
61
+ def client_id= (val=nil)
62
+ raise(MissingRequiredOptionError, '`client_id` cannot be set to nil') if val.nil?
63
+ @client_id = val
64
+ end
65
+ def client_secret
66
+ @client_secret || raise(MissingRequiredOptionError, 'Missing required option `client_secret`')
67
+ end
68
+ def client_secret= (val=nil)
69
+ raise(MissingRequiredOptionError, '`client_secret` cannot be set to nil') if val.nil?
70
+ @client_secret = val
71
+ end
72
+ def user_resolver
73
+ @user_resolver || raise(MissingRequiredOptionError, 'Missing required option/lambda `user_resolver`')
74
+ end
75
+ def user_resolver= (val=nil)
76
+ raise(MissingRequiredOptionError, '`user_resolver` cannot be set to nil') if val.nil?
77
+ @user_resolver = val
73
78
  end
74
-
75
- extend Option
76
-
77
- option :token_verify_ttl, default: 10
78
- option :capcoauth_url, default: 'https://capcoauth.capco.com'
79
- option :user_id_field, default: :capcoauth
80
- option :cache_store, default: ::ActiveSupport::Cache::MemoryStore.new
81
- option :user_resolver, default: (lambda do |capcoauth_user_id|
82
- Capcoauth.configuration.logger.warn('[CapcOAuth] User resolver is not configured. Please specify a block in configuration to resolve the proper user')
83
- nil
84
- end)
85
79
  end
86
80
  end
@@ -0,0 +1,3 @@
1
+ module Capcoauth
2
+ class AuthorizationError < StandardError; end
3
+ end
@@ -6,10 +6,12 @@ module Capcoauth
6
6
 
7
7
  class << self
8
8
 
9
- @@bearer_token = nil
9
+ def store
10
+ Capcoauth.configuration.cache_store
11
+ end
10
12
 
11
13
  def bearer_token
12
- return @@bearer_token if @@bearer_token.present?
14
+ return store.fetch('application_token') if store.fetch('application_token').present?
13
15
 
14
16
  res = self.post(
15
17
  "#{Capcoauth.configuration.capcoauth_url}/oauth/token",
@@ -24,15 +26,15 @@ module Capcoauth
24
26
  }
25
27
  )
26
28
  if res.ok? and res.parsed_response['access_token']
27
- @@bearer_token = res.parsed_response['access_token']
29
+ store.write('application_token', res.parsed_response['access_token'], expires_in: res.parsed_response['expires_in'])
28
30
  end
29
- @@bearer_token
31
+ store.fetch('application_token')
30
32
  end
31
33
 
32
34
  def default_headers
33
35
  {
34
- 'Authorization' => "Bearer #{bearer_token}",
35
- 'Content-Type' => 'application/vnd.api+json'
36
+ 'Authorization': "Bearer #{bearer_token}",
37
+ 'Content-Type': 'application/vnd.api+json'
36
38
  }
37
39
  end
38
40
 
@@ -62,7 +64,7 @@ module Capcoauth
62
64
  headers: default_headers
63
65
  }
64
66
  )
65
- @@bearer_token = nil if res.code == 401
67
+ store.delete('application_token') if res.code == 401
66
68
  return true if res.created?
67
69
  return true if res.body.include? 'has already been registered'
68
70
  false
@@ -70,7 +72,7 @@ module Capcoauth
70
72
 
71
73
  def remove_device_token(device_token)
72
74
  res = self.delete("#{Capcoauth.configuration.capcoauth_url}/api/v1/user_devices/#{device_token}", headers: default_headers)
73
- @@bearer_token = nil if res.code == 401
75
+ store.delete('application_token') if res.code == 401
74
76
  res.code == 204
75
77
  end
76
78
 
@@ -100,7 +102,7 @@ module Capcoauth
100
102
  headers: default_headers
101
103
  }
102
104
  )
103
- @@bearer_token = nil if res.code == 401
105
+ store.delete('application_token') if res.code == 401
104
106
  return true if res.created?
105
107
  false
106
108
  end
@@ -10,7 +10,6 @@ module Capcoauth
10
10
  end
11
11
 
12
12
  def verify
13
- nil unless @token
14
13
  TokenVerifier.verify(self)
15
14
  end
16
15
  end
@@ -8,15 +8,20 @@ module Capcoauth
8
8
  class OtherError < StandardError; end
9
9
 
10
10
  def self.verify(access_token)
11
- raise UnauthorizedError if access_token.blank? or access_token.token.blank?
11
+ raise UnauthorizedError, 'Please log in to continue' if access_token.blank? or access_token.token.blank?
12
12
  return access_token if TTLCache.user_id_for(access_token.token)
13
13
 
14
14
  # Call Capcoauth
15
- response = ::HTTParty.get("#{Capcoauth.configuration.capcoauth_url}/oauth/token/info", {
16
- headers: {
17
- :'Authorization' => "Bearer #{access_token.token}"
18
- }
19
- })
15
+ begin
16
+ response = ::HTTParty.get("#{Capcoauth.configuration.capcoauth_url}/oauth/token/info", {
17
+ timeout: 5,
18
+ headers: {
19
+ :'Authorization' => "Bearer #{access_token.token}"
20
+ }
21
+ })
22
+ rescue Net::OpenTimeout
23
+ raise OtherError, 'An error occurred while verifying your credentials (server not available)'
24
+ end
20
25
 
21
26
  # Set the user_id from the token response
22
27
  if response.code == 200
@@ -35,7 +40,7 @@ module Capcoauth
35
40
  # Throw unauthorized if ID of specified type doesn't exist
36
41
  if access_token.user_id.blank? and !application_credentials
37
42
  logger.info("CapcOAuth: The access token for #{user_id_field} user ##{access_token.user_id} did not have an ID for type `#{user_id_field}`") unless logger.nil?
38
- raise UnauthorizedError
43
+ raise UnauthorizedError, 'The system cannot recognize you by that ID type'
39
44
  end
40
45
 
41
46
  # Verify token is for correct application/client
@@ -45,16 +50,16 @@ module Capcoauth
45
50
  access_token
46
51
  else
47
52
  logger.info("CapcOAuth: The access token for #{user_id_field} user ##{access_token.user_id} was valid, but for a different OAuth client ID") unless logger.nil?
48
- raise UnauthorizedError
53
+ raise UnauthorizedError, 'Your credentials are valid, but are not for use with this system'
49
54
  end
50
55
  elsif response.code == 401
51
56
  TTLCache.remove(access_token.token)
52
57
  logger.info("CapcOAuth: The access token was invalid, expired, or revoked") unless logger.nil?
53
- raise UnauthorizedError
58
+ raise UnauthorizedError, 'Please log in to continue'
54
59
  else
55
60
  logger.info("CapcOAuth: Received unknown response") unless logger.nil?
56
61
  logger.info(JSON.pretty_generate(response)) unless logger.nil?
57
- raise OtherError
62
+ raise OtherError, 'An error occurred while verifying your credentials (unknown response)'
58
63
  end
59
64
  end
60
65