proxy_authentication 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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