Module: Panmind::SSLHelper::Routing

Defined in:
lib/panmind/ssl_helper.rb

Constant Summary collapse

Classes =
[
  ActionController::Base,
  ActionController::Integration::Session,
  ActionController::TestCase,

  ActionView::Base
]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



24
25
26
27
28
# File 'lib/panmind/ssl_helper.rb', line 24

def self.included(base)
  base.instance_eval do
    alias_method_chain :finalize!, :ssl
  end
end

Instance Method Details

#create_ssl_helpersObject

Populates the @ssl_helpers module with ssl_ and plain_ helper counterparts for all defined named route helpers.

Tries to use the ActionController::Routing::Routes private Rails API, falls back to regexp filtering if it is not available.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/panmind/ssl_helper.rb', line 65

def create_ssl_helpers
  @ssl_helpers ||= Module.new
  return @ssl_helpers if @ssl_helpers.frozen?

  route_helpers =
    if defined? Rails.application.routes.named_routes.helpers
      # This is a Private Rails API, so we check whether it's defined
      # and reject all the hash_for_*() and the *_path() helpers.
      #
      Rails.application.routes.named_routes.helpers.
        reject { |h| h =~ /^hash_for|path$/ }
    else
      # Warn the developer and fall back.
      #
      Rails.logger.warn "SSLHelper: Rails.application.routes.named_routes.helpers disappeared"
      Rails.logger.warn "SSLHelper: falling back to filtering controller methods"

      ac   = ActionController::Base
      skip = /(^hash_for_|^formatted_|polymorphic_|^redirect_)/
      ac.instance_methods.grep(/_url$/) - ac.instance_methods.grep(skip)
    end

  return if route_helpers.empty?

  # Create a Module containing all the ssl_ and plain_ helpers
  # that: [1] alter the args they receive with the SSL options
  # and [2] forward the altered args to the Rails' helper.
  #
  @ssl_helpers.module_eval do
    route_helpers.each do |helper|
      ssl, plain = "ssl_#{helper}", "plain_#{helper}"

      define_method(ssl)   { |*args| send(helper, *ssl_alter(args, WITH_SSL))    }
      define_method(plain) { |*args| send(helper, *ssl_alter(args, WITHOUT_SSL)) }

      protected ssl, plain
    end

    private
      def ssl_alter(args, with) #:nodoc:
        return args if Rails.env.development?

        options = args.last.kind_of?(Hash) ? args.pop : {}
        args.push(options.update(with))
      end
  end

  # No further modification allowed.
  #
  @ssl_helpers.freeze
end

#finalize_with_ssl!Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/panmind/ssl_helper.rb', line 38

def finalize_with_ssl!
  helpers = create_ssl_helpers
  return unless helpers # Not ready yet.

  return if Classes.first.included_modules.include? helpers

  # Include the helper_module into each class to patch.
  #
  Classes.each {|k| k.instance_eval { include helpers } }

  # Set the helpers as public in the AC::Integration::Session class
  # for easy testing in the console.
  #
  ActionController::Integration::Session.module_eval do
    public *helpers.instance_methods
  end

ensure
  finalize_without_ssl!
end