capcoauth 0.4.0 → 0.5.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.
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