proxy_authentication 0.0.4

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 (95) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +34 -0
  4. data/lib/proxy_authentication.rb +68 -0
  5. data/lib/proxy_authentication/authentication_cipher.rb +59 -0
  6. data/lib/proxy_authentication/cipher.rb +64 -0
  7. data/lib/proxy_authentication/helpers.rb +31 -0
  8. data/lib/proxy_authentication/test_helpers.rb +44 -0
  9. data/lib/proxy_authentication/version.rb +3 -0
  10. data/lib/tasks/proxy_authentication_tasks.rake +4 -0
  11. data/test/authentication_cipher_test.rb +83 -0
  12. data/test/authentication_controller_test.rb +72 -0
  13. data/test/cipher_test.rb +21 -0
  14. data/test/dummy/README.rdoc +28 -0
  15. data/test/dummy/Rakefile +6 -0
  16. data/test/dummy/app/assets/javascripts/application.js +13 -0
  17. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  18. data/test/dummy/app/controllers/application_controller.rb +10 -0
  19. data/test/dummy/app/controllers/home_controller.rb +6 -0
  20. data/test/dummy/app/helpers/application_helper.rb +2 -0
  21. data/test/dummy/app/models/user.rb +13 -0
  22. data/test/dummy/app/views/home/show.html.erb +3 -0
  23. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  24. data/test/dummy/bin/bundle +3 -0
  25. data/test/dummy/bin/rails +4 -0
  26. data/test/dummy/bin/rake +4 -0
  27. data/test/dummy/bin/setup +29 -0
  28. data/test/dummy/config.ru +4 -0
  29. data/test/dummy/config/application.rb +26 -0
  30. data/test/dummy/config/boot.rb +5 -0
  31. data/test/dummy/config/database.yml +25 -0
  32. data/test/dummy/config/environment.rb +5 -0
  33. data/test/dummy/config/environments/development.rb +41 -0
  34. data/test/dummy/config/environments/production.rb +79 -0
  35. data/test/dummy/config/environments/test.rb +42 -0
  36. data/test/dummy/config/initializers/assets.rb +11 -0
  37. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  38. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  39. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  40. data/test/dummy/config/initializers/inflections.rb +16 -0
  41. data/test/dummy/config/initializers/mime_types.rb +4 -0
  42. data/test/dummy/config/initializers/proxy_authentication.rb +6 -0
  43. data/test/dummy/config/initializers/session_store.rb +3 -0
  44. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  45. data/test/dummy/config/locales/en.yml +23 -0
  46. data/test/dummy/config/routes.rb +59 -0
  47. data/test/dummy/config/secrets.yml +22 -0
  48. data/test/dummy/db/development.sqlite3 +0 -0
  49. data/test/dummy/db/test.sqlite3 +0 -0
  50. data/test/dummy/log/development.log +360 -0
  51. data/test/dummy/log/production.log +0 -0
  52. data/test/dummy/log/test.log +4612 -0
  53. data/test/dummy/public/404.html +67 -0
  54. data/test/dummy/public/422.html +67 -0
  55. data/test/dummy/public/500.html +66 -0
  56. data/test/dummy/public/favicon.ico +0 -0
  57. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/0-zEvwlFHnH_Pe19oAQdm9AvqiKmpSxMkm4hkxwuO2Q.cache +0 -0
  58. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/0ieeKnMtadPClPcf7n4_-7f9dFAa5EKPn-nhh8g4E_I.cache +1 -0
  59. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/3PrmpHHPB63uKo_J8DA17m8A2ifRM2oQwV2ht-J0-is.cache +0 -0
  60. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/3fB7XY5WyPu8FySUeyC372vbXJ2Ix4iB1QaNHXbk_BY.cache +1 -0
  61. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/5Lly_CA8DZvPhQV2jDQx-Y6P_y3Ygra9t5jfSlGhHDA.cache +2 -0
  62. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/EHcymtlGKlOMMf7gOs-X2_jpvcBTW92Qeaxu2B5-Wbg.cache +1 -0
  63. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/KwafFPkbuDYTVqsISFs_yCHgXK4p07hzR6veAzDwuuc.cache +1 -0
  64. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/OI6uxGcnsKavdWTtwDAasU3wPx8QXhzBgV0X2n1KjMQ.cache +3 -0
  65. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/SGxtd6iKmB2TMwH-VOx-jVYXh5m_09UjNEOkifPHLL0.cache +1 -0
  66. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/UGriVNvoxX6203fJqmsTHnKUagkF3JBw6nn6mfw3w5g.cache +0 -0
  67. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/dOuzt3uIJxwUNVKI0daCeNk0PQDI8MYqLlfcMHzc6-E.cache +1 -0
  68. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/glnuwd6ozsfCCVdZ5uagYczBMDB0D-W-i6JAuDfKvoc.cache +0 -0
  69. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/hZi1k6tpxxCGYxRe7zY74ItcOI8gZrREOpGuA8JSpGg.cache +3 -0
  70. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/o1kR1PA3NiPrjlfxeTACSvO3YLlOPjUQi2YkxURHJCs.cache +0 -0
  71. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/pEhaat2KBd5SrT7szC_8R1_6hK17FTpvoRFkmCRSD3M.cache +2 -0
  72. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/zW42jTcqmsgkuFrYkna-BYD_J6kKuRW16OhweSyNss0.cache +1 -0
  73. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/4udH3Kvt3C2cCGuaQlNudmK4ORwSvcL3wly1cxYQSCI.cache +0 -0
  74. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/5Lly_CA8DZvPhQV2jDQx-Y6P_y3Ygra9t5jfSlGhHDA.cache +2 -0
  75. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/9jPCqzZvmeFf31Rz8y3OEo8OQXEHVcwmLgkx0tXs-o8.cache +1 -0
  76. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/CNAnhGuda7RU2cy1LoLZtgOXanVdsdgrZA6YLhYkfCg.cache +1 -0
  77. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Ct2bBJ2j5lnvWEsqMkvxgrBschDpIaLnrbFjNlNqkwQ.cache +1 -0
  78. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/GQgusgBOwVSgRbnk7ZD_byHBEGf5x8tB7KEmS_Nn7go.cache +0 -0
  79. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/IsR8qItXiIDT-adWpc8GqBPg7rG0qBqvCOj3K-VsoT8.cache +0 -0
  80. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/OI6uxGcnsKavdWTtwDAasU3wPx8QXhzBgV0X2n1KjMQ.cache +3 -0
  81. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/OwNOsob6Xcj4v6Rh7nE6il11_qI3Y1aZgQLbWcwpcAA.cache +1 -0
  82. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/Qx1JQQo3e3jJx9EX_SjE51tC9izB-kU-Dx3Lxs9pJog.cache +0 -0
  83. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/XLdrSXICyvmXq6FCVF8xNBTy0wtRmX087QMWRS5XGXA.cache +1 -0
  84. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/_Slb8psWEK6pgvtcS5M2j38q9zUh6Xl86eQqnw5yjWY.cache +0 -0
  85. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/h3E0XD4wRGR5pmdK_kHHGggBEU01INtD8LDnoR8Nt_w.cache +0 -0
  86. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/hZi1k6tpxxCGYxRe7zY74ItcOI8gZrREOpGuA8JSpGg.cache +3 -0
  87. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/ldn4mjNpwK-bJF0geft9TpHRidEVK2xKXMx4AqhIMWI.cache +1 -0
  88. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/o2kqwqoUQ3gkgncZO1IWdVRzFD0wCSQ-HyL62cINFOU.cache +1 -0
  89. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/pEhaat2KBd5SrT7szC_8R1_6hK17FTpvoRFkmCRSD3M.cache +2 -0
  90. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/pQIgTfLmEPykNamzxdqBww21SMT7YlZlZGy6hgQ6eVE.cache +1 -0
  91. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/td9wUl9SLRnSSgE2ZK_VqCzLxTkFiCW50KkOhE916Wo.cache +1 -0
  92. data/test/dummy/tmp/cache/assets/test/sprockets/v3.0/vvv17q90-DU3Hs_cfDWuupUuw9khOZXTqTOEMhCl3ek.cache +1 -0
  93. data/test/proxy_authentication_test.rb +7 -0
  94. data/test/test_helper.rb +26 -0
  95. metadata +272 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6b2be32c03d684e55f8f79667693aa29b49bc889
4
+ data.tar.gz: deac0c0703ba178036555364cab6d2c7a22cee1b
5
+ SHA512:
6
+ metadata.gz: e96d2557e4fee2f2817f2ab85944591456fff06b91835e5eb892463694805a11667834b4c79350e0ff0dfee04562f1f4f34d40f17ab76dd7a24ae8baea33fa85
7
+ data.tar.gz: 91867ff95fbd785c90da9d5415b615c4f2c3ee0113f2eb1d32585ce5195190e23428e516f56da42e2b0f887749d971cb25f50d729a94d21591045c099fa5a9a0
@@ -0,0 +1,20 @@
1
+ Copyright 2015 Jesús Dugarte
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,34 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'ProxyAuthentication'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task default: :test
@@ -0,0 +1,68 @@
1
+ require 'warden'
2
+ require 'proxy_authentication/helpers'
3
+ require 'proxy_authentication/authentication_cipher'
4
+
5
+ module ProxyAuthentication
6
+
7
+ mattr_accessor :user_class
8
+ @@user_class = 'User'
9
+
10
+ mattr_accessor :redirect_to_if_authentication_failed
11
+ @@redirect_to_if_authentication_failed = nil
12
+
13
+ mattr_accessor :secret_key
14
+ @@secret_key = nil
15
+
16
+ mattr_accessor :validate_with_block
17
+ @@validate_with_block = nil
18
+
19
+ class << self
20
+
21
+ def setup
22
+ setup_warden
23
+ include_helpers
24
+ yield self if block_given?
25
+ end
26
+
27
+ def validate_with &block
28
+ @@validate_with_block = block
29
+ end
30
+
31
+ private
32
+
33
+ def setup_warden
34
+ insert_warden_middleware
35
+ define_warden_strategy
36
+ end
37
+
38
+ def insert_warden_middleware
39
+ Rails.configuration.middleware.insert_before ActionDispatch::ParamsParser, Warden::Manager do |manager|
40
+ manager.default_strategies :proxy_authentication_via_token
41
+ manager.serialize_into_session { |user| ProxyAuthentication::AuthenticationCipher.encode user }
42
+ manager.serialize_from_session { |hash| ProxyAuthentication::AuthenticationCipher.decode hash }
43
+ end
44
+ end
45
+
46
+ def define_warden_strategy
47
+ Warden::Strategies.add(:proxy_authentication_via_token) do
48
+
49
+ def valid?
50
+ params['u'].present? && env['action_controller.instance'].present?
51
+ end
52
+
53
+ def authenticate!
54
+ rails_request = env['action_controller.instance'].request
55
+ user = ProxyAuthentication::AuthenticationCipher.decode params['u'].to_s, rails_request
56
+ user.present? ? success!(user) : fail
57
+ end
58
+
59
+ end
60
+ end
61
+
62
+ def include_helpers
63
+ ActionController::Base.send :include, ::ProxyAuthentication::Helpers
64
+ end
65
+
66
+ end
67
+
68
+ end
@@ -0,0 +1,59 @@
1
+ require 'proxy_authentication/cipher'
2
+
3
+ module ProxyAuthentication
4
+
5
+ module AuthenticationCipher
6
+
7
+ extend self
8
+
9
+ def encode user, request = nil
10
+ data = request_info(request) << user.to_authentication_hash.to_json
11
+ Cipher.encode_data_as_url_token data
12
+ end
13
+
14
+ def decode token, request = nil
15
+ data = Cipher.decode_data_from_url_token token
16
+ return nil if data.nil? || !valid_request?(data, request)
17
+ extract_user data.last
18
+ end
19
+
20
+ private
21
+
22
+ def request_info request
23
+ [
24
+ ip(request.try(:remote_ip)),
25
+ Time.now.to_i,
26
+ ]
27
+ end
28
+
29
+ # TODO: add validation for the time of the request
30
+ # e.g. only consider a request valid if it was generated in the last 15 minutes
31
+ def valid_request? data, request
32
+ return true if request.nil?
33
+ return validate_with_block(data, request) if ProxyAuthentication.validate_with_block.present?
34
+ ip(request.remote_ip) == ip(data.first)
35
+ end
36
+
37
+ def ip value
38
+ return 'localhost' if %w[ localhost 127.0.0.1 ::1 ].include?(value)
39
+ value
40
+ end
41
+
42
+ def extract_user data
43
+ hash = JSON.parse data
44
+ klass = ProxyAuthentication.user_class.to_s.classify.constantize
45
+ klass.from_authentication_hash hash
46
+ end
47
+
48
+ def validate_with_block data, request
49
+ arguments = {
50
+ ip: data.first,
51
+ time: Time.at(data.second.to_i),
52
+ user: extract_user(data.last),
53
+ }
54
+ ProxyAuthentication.validate_with_block.call ip(request.remote_ip), arguments
55
+ end
56
+
57
+ end
58
+
59
+ end
@@ -0,0 +1,64 @@
1
+ module ProxyAuthentication
2
+
3
+ module Cipher
4
+
5
+ extend self
6
+
7
+ def encode_data_as_url_token data, separator = "\n"
8
+ data = data.join separator
9
+ string = [ data, signature_for(data) ].join separator
10
+ Base64.urlsafe_encode64 string
11
+ end
12
+
13
+ def decode_data_from_url_token token_base64, separator = "\n"
14
+ raw_data = decode64 token_base64
15
+ return nil if raw_data.nil?
16
+
17
+ data = raw_data.split separator
18
+ actual_signature = data.pop
19
+ expected_signature = signature_for data.join(separator)
20
+ return nil if actual_signature != expected_signature
21
+
22
+ data
23
+ end
24
+
25
+ private
26
+
27
+ def signature_for string
28
+ OpenSSL::HMAC.hexdigest OpenSSL::Digest::SHA1.new, secret_key, string
29
+ end
30
+
31
+ def decode64 token_base64
32
+ Base64.urlsafe_decode64 token_base64
33
+ rescue ArgumentError => exception
34
+ return nil if exception.message =~ /invalid base64/
35
+ raise exception
36
+ end
37
+
38
+ def secret_key
39
+ ProxyAuthentication.secret_key || Rails.application.secrets.secret_key_base
40
+ end
41
+
42
+ end
43
+
44
+ end
45
+
46
+ # Backport Base64.urlsafe_[en|de]code64 methods to ruby 1.8
47
+ # https://gist.github.com/phallstrom/1397972
48
+ if RUBY_VERSION < '1.9'
49
+ begin
50
+ require 'base64'
51
+ rescue LoadError
52
+ end
53
+
54
+ if defined? ::Base64
55
+ module ::Base64
56
+ def self.urlsafe_encode64(bin)
57
+ [bin].pack("m0").tr("+/", "-_")
58
+ end
59
+ def self.urlsafe_decode64(str)
60
+ str.tr("-_", "+/").unpack("m0").first
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,31 @@
1
+ module ProxyAuthentication
2
+
3
+ module Helpers
4
+
5
+ def self.included mod
6
+ mod.helper_method :current_user, :user_signed_in?
7
+ end
8
+
9
+ def current_user
10
+ @current_user ||= warden.user
11
+ end
12
+
13
+ def user_signed_in?
14
+ !!current_user
15
+ end
16
+
17
+ private
18
+
19
+ def authenticate_user_from_token!
20
+ warden.logout if warden.authenticated? && params['u'].present?
21
+ warden.authenticate
22
+ redirect_to ProxyAuthentication.redirect_to_if_authentication_failed if warden.unauthenticated?
23
+ end
24
+
25
+ def warden
26
+ request.env['warden']
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,44 @@
1
+ # Based on Kentaro Imai's code:
2
+ # http://kentaroimai.com/articles/1-controller-test-helpers-for-warden
3
+
4
+ module ProxyAuthentication
5
+
6
+ module TestHelpers
7
+
8
+ def self.included base
9
+ base.class_eval do
10
+ setup :setup_controller_for_warden, :warden if respond_to? :setup
11
+ end
12
+ end
13
+
14
+ def sign_in user
15
+ warden.instance_variable_get(:@users).delete :default
16
+ warden.session_serializer.store user, :default
17
+ end
18
+
19
+ def sign_out
20
+ @controller.instance_variable_set :@current_user, nil
21
+ user = warden.instance_variable_get(:@users).delete :default
22
+ warden.session_serializer.delete :default, user
23
+ end
24
+
25
+ private
26
+
27
+ # We need to setup the environment variables and the response in the controller
28
+ def setup_controller_for_warden
29
+ @request.env['action_controller.instance'] = @controller
30
+ end
31
+
32
+ # Quick access to Warden::Proxy (memoized at setup)
33
+ def warden
34
+ @warden ||= new_warden_proxy
35
+ end
36
+
37
+ def new_warden_proxy
38
+ manager = Warden::Manager.new nil, &Rails.application.config.middleware.detect { |m| m.name == 'Warden::Manager'}.block
39
+ @request.env['warden'] = Warden::Proxy.new @request.env, manager
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,3 @@
1
+ module ProxyAuthentication
2
+ VERSION = "0.0.4"
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :proxy_authentication do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,83 @@
1
+ require 'test_helper'
2
+
3
+ class AuthenticationCipherTest < ActiveSupport::TestCase
4
+
5
+ test "user remains the same" do
6
+ token = ProxyAuthentication::AuthenticationCipher.encode user
7
+ assert_equal user, ProxyAuthentication::AuthenticationCipher.decode(token)
8
+ end
9
+
10
+ test "if no validation block is provided, returns something if the ip addresses are the same" do
11
+ request = ActionDispatch::Request.new 'REMOTE_ADDR' => '1.2.3.4'
12
+ token = ProxyAuthentication::AuthenticationCipher.encode user, request
13
+ decoded = ProxyAuthentication::AuthenticationCipher.decode token, request
14
+ assert_not_nil decoded
15
+ end
16
+
17
+ test "if no validation block is provided, returns nil if the ip addresses are different" do
18
+ token = ProxyAuthentication::AuthenticationCipher.encode user, ActionDispatch::Request.new('REMOTE_ADDR' => '1.2.3.4')
19
+ decoded = ProxyAuthentication::AuthenticationCipher.decode token, ActionDispatch::Request.new('REMOTE_ADDR' => '0.0.0.0')
20
+ assert_nil decoded
21
+ end
22
+
23
+ test "call the validation block, if provided" do
24
+ validation_block = -> {}
25
+ validation_block.expects :call
26
+ ProxyAuthentication.validate_with &validation_block
27
+
28
+ request = ActionDispatch::Request.new 'REMOTE_ADDR' => '1.2.3.4'
29
+ token = ProxyAuthentication::AuthenticationCipher.encode user, request
30
+ ProxyAuthentication::AuthenticationCipher.decode token, request
31
+ ProxyAuthentication.validate_with
32
+ end
33
+
34
+ test "call the validation block with the request information" do
35
+ validation_block = lambda {}
36
+ time = Time.now
37
+ ip = '1.2.3.4'
38
+ arguments = {
39
+ ip: ip,
40
+ time: Time.at(time.to_i),
41
+ user: user,
42
+ }
43
+ Time.stubs(:now).returns(time)
44
+ validation_block.expects(:call).with(ip, arguments)
45
+ ProxyAuthentication.validate_with &validation_block
46
+
47
+ request = ActionDispatch::Request.new 'REMOTE_ADDR' => ip
48
+ token = ProxyAuthentication::AuthenticationCipher.encode user, request
49
+ ProxyAuthentication::AuthenticationCipher.decode token, request
50
+ ProxyAuthentication.validate_with
51
+ end
52
+
53
+ test "returns nil if the validation block return false" do
54
+ validation_block = lambda { |*| false }
55
+ ProxyAuthentication.validate_with &validation_block
56
+
57
+ request = ActionDispatch::Request.new 'REMOTE_ADDR' => '1.2.3.4'
58
+ token = ProxyAuthentication::AuthenticationCipher.encode user, request
59
+ decoded = ProxyAuthentication::AuthenticationCipher.decode token, request
60
+ ProxyAuthentication.validate_with
61
+
62
+ assert_nil decoded
63
+ end
64
+
65
+ test "returns something if the validation block return true" do
66
+ validation_block = lambda { |*| true }
67
+ ProxyAuthentication.validate_with &validation_block
68
+
69
+ request = ActionDispatch::Request.new 'REMOTE_ADDR' => '1.2.3.4'
70
+ token = ProxyAuthentication::AuthenticationCipher.encode user, request
71
+ decoded = ProxyAuthentication::AuthenticationCipher.decode token, request
72
+ ProxyAuthentication.validate_with
73
+
74
+ assert_not_nil decoded
75
+ end
76
+
77
+ private
78
+
79
+ def user
80
+ @user = User.new 1, 'User', 'user@example.com'
81
+ end
82
+
83
+ end
@@ -0,0 +1,72 @@
1
+ require 'test_helper'
2
+
3
+ class AuthenticationControllerTest < ActionController::TestCase
4
+
5
+ tests HomeController
6
+
7
+ test "accesing root without authenticating a user redirects to sign in" do
8
+ get :show
9
+
10
+ assert_redirection_to_sign_in
11
+ end
12
+
13
+ test "accesing root with a valid authentication hash signs in the user" do
14
+ token = ProxyAuthentication::AuthenticationCipher.encode user, request
15
+
16
+ get :show, u: token
17
+
18
+ assert_successful_sign_in
19
+ end
20
+
21
+ test "accesing root with a authentication hash from a different ip address redirects to sign in" do
22
+ token = ProxyAuthentication::AuthenticationCipher.encode user, ActionDispatch::Request.new('REMOTE_ADDR' => '1.2.3.4')
23
+
24
+ get :show, u: token
25
+
26
+ assert_redirection_to_sign_in
27
+ end
28
+
29
+ test "accesing root with an invalid authentication hash redirects to sign in" do
30
+ get :show, u: 'not a valid hash'
31
+
32
+ assert_redirection_to_sign_in
33
+ end
34
+
35
+ test "accesing root after a valid session was created doesn't require sign in" do
36
+ sign_in user
37
+
38
+ get :show
39
+
40
+ assert_successful_sign_in
41
+ end
42
+
43
+ test "accesing root with a valid authentication hash after a valid session was created should change the current user" do
44
+ sign_in user
45
+ other_user = User.new 2, 'Other User', 'other_user@example.com'
46
+ token = ProxyAuthentication::AuthenticationCipher.encode other_user, request
47
+
48
+ get :show, u: token
49
+
50
+ assert_equal other_user.id, @controller.current_user.id
51
+ end
52
+
53
+ private
54
+
55
+ def user
56
+ @user = User.new 1, 'User', 'user@example.com'
57
+ end
58
+
59
+ def assert_redirection_to_sign_in
60
+ assert_response :redirect
61
+ assert_redirected_to ProxyAuthentication.redirect_to_if_authentication_failed
62
+ refute @controller.user_signed_in?
63
+ assert_nil @controller.current_user
64
+ end
65
+
66
+ def assert_successful_sign_in
67
+ assert_response :success
68
+ assert @controller.user_signed_in?
69
+ assert_not_nil @controller.current_user
70
+ end
71
+
72
+ end