mack 0.7.0.1 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +34 -0
- data/README +6 -13
- data/bin/env_handler.rb +10 -0
- data/bin/gem_load_path.rb +25 -0
- data/bin/mack +1 -0
- data/bin/mackery +22 -0
- data/bin/mackery-console +16 -0
- data/bin/mackery-server +41 -0
- data/lib/mack.rb +7 -1
- data/lib/mack/controller/controller.rb +5 -4
- data/lib/mack/controller/request.rb +19 -1
- data/lib/mack/errors/errors.rb +8 -8
- data/lib/mack/generators/controller_generator/controller_generator.rb +1 -1
- data/lib/mack/generators/mack_application_generator/templates/app/views/layouts/application.html.erb.template +1 -2
- data/lib/mack/generators/mack_application_generator/templates/config/app_config/default.yml.template +2 -0
- data/lib/mack/generators/mack_application_generator/templates/config/database.yml.template +6 -6
- data/lib/mack/generators/passenger_generator/passenger_generator.rb +2 -0
- data/lib/mack/generators/passenger_generator/templates/config.ru.template +5 -0
- data/lib/mack/generators/passenger_generator/templates/tmp/README.template +2 -0
- data/lib/mack/initialization/application.rb +39 -36
- data/lib/mack/initialization/boot_loader.rb +174 -0
- data/lib/mack/initialization/configuration.rb +83 -95
- data/lib/mack/initialization/console.rb +11 -0
- data/lib/mack/initialization/environment.rb +16 -0
- data/lib/mack/initialization/helpers.rb +26 -24
- data/lib/mack/initialization/logging.rb +81 -81
- data/lib/mack/initialization/plugins.rb +14 -11
- data/lib/mack/initialization/server/simple_server.rb +3 -3
- data/lib/mack/rendering/type/base.rb +1 -1
- data/lib/mack/rendering/type/layout.rb +1 -1
- data/lib/mack/rendering/type/partial.rb +1 -1
- data/lib/mack/rendering/type/public.rb +1 -1
- data/lib/mack/rendering/type/template.rb +1 -1
- data/lib/mack/runner.rb +2 -2
- data/lib/mack/runner_helpers/session.rb +3 -3
- data/lib/mack/sessions/cookie_session_store.rb +44 -0
- data/lib/mack/{controller → sessions}/session.rb +0 -0
- data/lib/mack/sessions/session_store_base.rb +62 -0
- data/lib/mack/sessions/test_session_store.rb +38 -0
- data/lib/mack/tasks/mack_server_tasks.rake +8 -21
- data/lib/mack/tasks/mack_tasks.rake +33 -6
- data/lib/mack/tasks/rake_rules.rake +8 -0
- data/lib/mack/tasks/test_tasks.rake +39 -15
- data/lib/mack/testing/helpers.rb +6 -39
- data/lib/mack/utils/content_length_handler.rb +45 -0
- data/lib/mack/utils/forgery_detector.rb +152 -0
- data/lib/mack/utils/gem_manager.rb +22 -1
- data/lib/mack/utils/paths.rb +154 -0
- data/lib/mack/utils/server.rb +8 -6
- data/lib/mack/version.rb +1 -1
- data/lib/mack/view_helpers/asset_helpers.rb +50 -0
- data/lib/mack/view_helpers/form_helpers.rb +52 -6
- data/lib/mack/view_helpers/link_helpers.rb +6 -3
- data/lib/mack_app.rb +12 -14
- data/lib/mack_core.rb +35 -14
- data/lib/mack_tasks.rb +35 -20
- metadata +23 -27
- data/lib/mack/tasks/cachetastic_tasks.rake +0 -58
@@ -4,30 +4,17 @@ namespace :mack do
|
|
4
4
|
|
5
5
|
desc "Starts the webserver."
|
6
6
|
task :start do |t|
|
7
|
+
puts %{
|
8
|
+
This task has been removed. Please use the 'mackery' command to start/stop the server:
|
7
9
|
|
8
|
-
|
9
|
-
require 'optparse'
|
10
|
-
require 'optparse/time'
|
11
|
-
require 'ostruct'
|
12
|
-
require 'fileutils'
|
10
|
+
$ mackery server
|
13
11
|
|
14
|
-
|
12
|
+
The environment can be set like this:
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
# require File.join(Mack.root, "config", "boot.rb")
|
22
|
-
require 'mack'
|
23
|
-
|
24
|
-
if options.handler == "thin"
|
25
|
-
# thin_opts = ["start", "-r", "config/thin.ru"]
|
26
|
-
thin_opts = ["start"]
|
27
|
-
Thin::Runner.new(thin_opts.flatten).run!
|
28
|
-
else
|
29
|
-
Mack::SimpleServer.run(options)
|
30
|
-
end
|
14
|
+
$ mackery server -e test
|
15
|
+
|
16
|
+
$ mackery server -p 8080 -e production # etc...
|
17
|
+
}
|
31
18
|
end # start
|
32
19
|
|
33
20
|
end # server
|
@@ -1,18 +1,45 @@
|
|
1
|
+
require 'fileutils'
|
1
2
|
namespace :mack do
|
2
3
|
|
3
4
|
desc "Loads the Mack environment. Default is development."
|
4
5
|
task :environment do
|
5
|
-
require File.join(File.dirname(__FILE__), '..',
|
6
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'mack')
|
7
|
+
Mack::Environment.load
|
6
8
|
end # environment
|
7
9
|
|
8
|
-
desc "Loads an irb console allow you full access to the application w/o a browser."
|
10
|
+
# desc "Loads an irb console allow you full access to the application w/o a browser."
|
9
11
|
task :console do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
puts %{
|
13
|
+
This task has been removed. Please use the 'mackery' command to access the console:
|
14
|
+
|
15
|
+
$ mackery console
|
16
|
+
|
17
|
+
The environment can be set like this:
|
18
|
+
|
19
|
+
$ mackery console -e test
|
20
|
+
}
|
14
21
|
end # console
|
15
22
|
|
23
|
+
namespace :freeze do
|
24
|
+
|
25
|
+
desc "Freezes the Edge Mack code into your vendor/framework folder"
|
26
|
+
task :edge do
|
27
|
+
f_dir = File.join(FileUtils.pwd, 'vendor', 'framework')
|
28
|
+
FileUtils.mkdir_p(f_dir)
|
29
|
+
%w{mack mack-more}.each do |proj|
|
30
|
+
proj_dir = File.join(f_dir, proj)
|
31
|
+
if File.exists?(proj_dir)
|
32
|
+
FileUtils.cd proj_dir
|
33
|
+
system 'git pull'
|
34
|
+
else
|
35
|
+
FileUtils.cd f_dir
|
36
|
+
system "git clone git://github.com/#{ENV["USERNAME"] || 'markbates'}/#{proj}.git"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
16
43
|
end # mack
|
17
44
|
|
18
45
|
alias_task :console, "mack:console"
|
@@ -17,6 +17,14 @@ rule /^cachetastic:/ do |t|
|
|
17
17
|
Rake::Task["cachetastic:manipulate_caches"].invoke
|
18
18
|
end
|
19
19
|
|
20
|
+
rule /^generate:.+:desc/ do |t|
|
21
|
+
klass = t.name.gsub("generate:", '')
|
22
|
+
klass.gsub!(":desc", '')
|
23
|
+
Rake::Task["environment"].invoke
|
24
|
+
klass = "#{klass.camelcase}Generator"
|
25
|
+
puts klass.constantize.describe
|
26
|
+
end
|
27
|
+
|
20
28
|
rule /^generate:/ do |t|
|
21
29
|
klass = t.name.gsub("generate:", '')
|
22
30
|
Rake::Task["environment"].invoke
|
@@ -10,24 +10,25 @@ namespace :test do
|
|
10
10
|
|
11
11
|
desc "Run test code."
|
12
12
|
Rake::TestTask.new(:test_case) do |t|
|
13
|
+
require File.join(File.dirname(__FILE__), '..', 'initialization', 'configuration')
|
14
|
+
Mack::BootLoader.run(:configuration)
|
13
15
|
t.libs << "test"
|
14
|
-
t.pattern =
|
16
|
+
t.pattern = app_config.mack.send("#{app_config.mack.testing_framework}_file_pattern")
|
15
17
|
t.verbose = true
|
16
18
|
end
|
17
19
|
|
18
20
|
desc 'Run specifications'
|
19
21
|
Spec::Rake::SpecTask.new(:rspec) do |t|
|
22
|
+
require File.join(File.dirname(__FILE__), '..', 'initialization', 'configuration')
|
23
|
+
Mack::BootLoader.run(:configuration)
|
20
24
|
t.spec_opts << '--options' << 'test/spec.opts' if File.exists?('test/spec.opts')
|
21
|
-
t.spec_files = Dir.glob(
|
25
|
+
t.spec_files = Dir.glob(app_config.mack.send("#{app_config.mack.testing_framework}_file_pattern"))
|
22
26
|
end
|
23
27
|
|
24
28
|
desc "Report code statistics (KLOCs, etc) from the application. Requires the rcov gem."
|
25
29
|
task :stats do |t|
|
26
|
-
|
27
|
-
|
28
|
-
Rake::Task["test:setup"].invoke
|
29
|
-
x = `rcov test/**/*_#{app_config.mack.testing_framework == "rspec" ? "spec" : "test"}.rb -T --no-html -x Rakefile,config\/,tasks\/`
|
30
|
-
x.each do |line|
|
30
|
+
res = common_coverage
|
31
|
+
res.each do |line|
|
31
32
|
case line
|
32
33
|
when /^\+[\+\-]*\+$/, /^\|.*\|$/, /\d+\sLines\s+\d+\sLOC/
|
33
34
|
puts line
|
@@ -37,11 +38,14 @@ namespace :test do
|
|
37
38
|
|
38
39
|
desc "Generates test coverage from the application. Requires the rcov gem."
|
39
40
|
task :coverage do |t|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
common_coverage
|
42
|
+
|
43
|
+
unless PLATFORM['i386-mswin32']
|
44
|
+
system("open coverage/index.html") if PLATFORM['darwin']
|
45
|
+
else
|
46
|
+
system("\"C:/Program Files/Mozilla Firefox/firefox.exe\" " +
|
47
|
+
"coverage/index.html")
|
48
|
+
end
|
45
49
|
end
|
46
50
|
|
47
51
|
task :empty do |t|
|
@@ -52,12 +56,32 @@ namespace :test do
|
|
52
56
|
raise "Oh No!"
|
53
57
|
end
|
54
58
|
|
59
|
+
private
|
60
|
+
def common_coverage
|
61
|
+
ENV["MACK_ENV"] = "test"
|
62
|
+
Rake::Task["mack:environment"].invoke
|
63
|
+
Rake::Task["test:setup"].invoke
|
64
|
+
|
65
|
+
rm_f Mack::Paths.root("coverage")
|
66
|
+
rm_f Mack::Paths.root("coverage.data")
|
67
|
+
unless PLATFORM['i386-mswin32']
|
68
|
+
rcov = "rcov --sort coverage --rails --aggregate coverage.data " +
|
69
|
+
"--text-summary -Ilib -T -x gems/*,rcov*,lib/tasks/*,Rakefile"
|
70
|
+
else
|
71
|
+
rcov = "rcov.cmd --sort coverage --rails --aggregate coverage.data " +
|
72
|
+
"--text-summary -Ilib -T"
|
73
|
+
end
|
74
|
+
|
75
|
+
puts "Generating... please wait..."
|
76
|
+
res = `#{rcov} --html #{app_config.mack.send("#{app_config.mack.testing_framework}_file_pattern")}`
|
77
|
+
res
|
78
|
+
end
|
79
|
+
|
55
80
|
end
|
56
81
|
|
57
82
|
task :default do
|
58
|
-
require '
|
59
|
-
|
60
|
-
app_config.load_file(File.join(FileUtils.pwd, "config", "app_config", "test.yml"))
|
83
|
+
require File.join(File.dirname(__FILE__), '..', 'initialization', 'configuration')
|
84
|
+
Mack::BootLoader.run(:configuration)
|
61
85
|
tf = "rspec"
|
62
86
|
begin
|
63
87
|
tf = app_config.mack.testing_framework
|
data/lib/mack/testing/helpers.rb
CHANGED
@@ -19,41 +19,6 @@ module Mack
|
|
19
19
|
module Testing # :nodoc:
|
20
20
|
module Helpers
|
21
21
|
|
22
|
-
# Runs the given rake task. Takes an optional hash that mimics command line parameters.
|
23
|
-
def rake_task(name, env = {}, tasks = [])
|
24
|
-
# set up the Rake application
|
25
|
-
rake = Rake::Application.new
|
26
|
-
Rake.application = rake
|
27
|
-
|
28
|
-
[File.join(File.dirname(__FILE__), "..", "..", "mack_tasks.rb"), tasks].flatten.each do |task|
|
29
|
-
load(task)
|
30
|
-
end
|
31
|
-
|
32
|
-
# save the old ENV so we can revert it
|
33
|
-
old_env = ENV.to_hash
|
34
|
-
# add in the new ENV stuff
|
35
|
-
env.each_pair {|k,v| ENV[k.to_s] = v}
|
36
|
-
|
37
|
-
begin
|
38
|
-
# run the rake task
|
39
|
-
rake[name].invoke
|
40
|
-
|
41
|
-
# yield for the tests
|
42
|
-
yield if block_given?
|
43
|
-
|
44
|
-
rescue Exception => e
|
45
|
-
raise e
|
46
|
-
ensure
|
47
|
-
# empty out the ENV
|
48
|
-
ENV.clear
|
49
|
-
# revert to the ENV before the test started
|
50
|
-
old_env.to_hash.each_pair {|k,v| ENV[k] = v}
|
51
|
-
|
52
|
-
# get rid of the Rake application
|
53
|
-
Rake.application = nil
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
22
|
# Temporarily changes the application configuration. Changes are reverted after
|
58
23
|
# the yield returns.
|
59
24
|
def temp_app_config(options = {})
|
@@ -125,14 +90,16 @@ module Mack
|
|
125
90
|
|
126
91
|
# Returns a Mack::Session from the request.
|
127
92
|
def session # :nodoc:
|
128
|
-
|
93
|
+
sess = Mack::SessionStore.get($current_session_id, nil, nil, nil)
|
94
|
+
if sess.nil?
|
129
95
|
id = String.randomize(40).downcase
|
130
96
|
set_cookie(app_config.mack.session_id, id)
|
131
97
|
sess = Mack::Session.new(id)
|
132
|
-
|
98
|
+
Mack::SessionStore.store.direct_set(id, sess)
|
133
99
|
$current_session_id = id
|
134
|
-
sess
|
100
|
+
sess
|
135
101
|
end
|
102
|
+
sess
|
136
103
|
end
|
137
104
|
|
138
105
|
# Used to create a 'session' around a block of code. This is great of 'integration' tests.
|
@@ -148,7 +115,7 @@ module Mack
|
|
148
115
|
|
149
116
|
# Clears all the sessions.
|
150
117
|
def clear_session
|
151
|
-
|
118
|
+
Mack::SessionStore.expire_all
|
152
119
|
end
|
153
120
|
|
154
121
|
# Returns a Hash of cookies from the response.
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Mack
|
2
|
+
module Utils
|
3
|
+
#
|
4
|
+
# The whole purpose of this handler is to intercept the rack application process,
|
5
|
+
# calculate the size of the response body, and set the 'Content-Length' header if necessary.
|
6
|
+
#
|
7
|
+
# From: http://thin.lighthouseapp.com/projects/7212/tickets/74
|
8
|
+
# Content-Length should not be automatically added:
|
9
|
+
# * When the Status code is 1xx, 204 or 304
|
10
|
+
# * When the Transfer-Encoding header is set to chunked
|
11
|
+
# * When the body is neither a String or an Array
|
12
|
+
#
|
13
|
+
class ContentLengthHandler
|
14
|
+
attr_reader :response
|
15
|
+
|
16
|
+
def initialize(app) # :nodoc:
|
17
|
+
@app = app
|
18
|
+
end
|
19
|
+
|
20
|
+
def call(env) # :nodoc:
|
21
|
+
ret = @app.call(env)
|
22
|
+
|
23
|
+
status = ret[0]
|
24
|
+
hdr = ret[1]
|
25
|
+
@response = ret[2]
|
26
|
+
|
27
|
+
unless self.response.is_a?(Rack::File) or
|
28
|
+
(!self.response.body.kind_of?Array and !self.response.body.kind_of?String) or
|
29
|
+
hdr["Transfer-Encoding"] == "chunked" or
|
30
|
+
(status == 204 or status == 304 or (status >= 100 and status < 200))
|
31
|
+
size = 0
|
32
|
+
|
33
|
+
if self.response.body.respond_to?(:to_str)
|
34
|
+
size = self.response.body.to_str.size
|
35
|
+
elsif self.response.body.respond_to?(:each)
|
36
|
+
self.response.body.each { |part| size += part.to_s.size }
|
37
|
+
end
|
38
|
+
|
39
|
+
hdr["Content-Length"] = size.to_s
|
40
|
+
end
|
41
|
+
return ret
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
module Mack
|
2
|
+
module Utils
|
3
|
+
|
4
|
+
module ForgeryDetector # :nodoc:
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
|
8
|
+
#
|
9
|
+
# By default the framework will try to validate incoming
|
10
|
+
# HTTP request (other than GET) by validating a secret token
|
11
|
+
# stored as hidden field in the posted form.
|
12
|
+
#
|
13
|
+
# There are 2 ways of disabling this feature:
|
14
|
+
# 1. Globally disabling this feature by setting mack::disable_forgery_detector to true in app_config
|
15
|
+
# 2. In a controller, call this method (disable_forgery_detector) to disable the detection
|
16
|
+
# for a specified set of methods.
|
17
|
+
#
|
18
|
+
# Supported options:
|
19
|
+
# :only => list_of_methods.
|
20
|
+
# This directive will tell the framework only disable the detection for the specified list of methods.
|
21
|
+
# :except => list_of_methods
|
22
|
+
# This directive will tell the framework to disable the detection for all methods except the ones specified.
|
23
|
+
#
|
24
|
+
# Example:
|
25
|
+
# class MyController
|
26
|
+
# include Mack::Controller
|
27
|
+
# disable_forgery_detector :only => [:test1, :test2]
|
28
|
+
#
|
29
|
+
# def test1
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# def test2
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# Notes:
|
36
|
+
# - This method will not work properly if both :only and :except options are passed in
|
37
|
+
# - In inherited case, the following behavior is to be expected:
|
38
|
+
# * If the super class declare that it wants to disable detection for all methods, and the
|
39
|
+
# subclass declare that it wants to disable detection for only a set of methods, then
|
40
|
+
# when the subclass is run, the "disable all detection" from the parent class will be overwritten
|
41
|
+
# * On the other hand, if the super class declare that it wants to disable a set of methods,
|
42
|
+
# and the subclass also declare it wants to disable a set of methods from its own set. Then
|
43
|
+
# the "only" list will be the combination of both
|
44
|
+
# * The first rule apply in inheritance; this method will not work properly if superclass declear
|
45
|
+
# "except" list, and subclass declare "only" list
|
46
|
+
#
|
47
|
+
def disable_forgery_detector(options = {})
|
48
|
+
hash = self.ignored_actions
|
49
|
+
hash[:all] = true and return if options.empty?
|
50
|
+
|
51
|
+
# TODO: should raise error if type is invalid
|
52
|
+
type = options[:only] ? :only : (options[:except] ? :except : :unknown)
|
53
|
+
list = options[:only] ? [options[:only]].flatten : (options[:except] ? [options[:except]].flatten : [])
|
54
|
+
if !list.empty?
|
55
|
+
hash[type] ||= []
|
56
|
+
hash[type] << list
|
57
|
+
hash[type].flatten!
|
58
|
+
hash[type].uniq!
|
59
|
+
hash[:all] = false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def ignored_actions # :nodoc:
|
64
|
+
unless @ignored_actions
|
65
|
+
@ignored_actions = {}
|
66
|
+
sc = self.superclass
|
67
|
+
if sc.class_is_a?(Mack::Controller)
|
68
|
+
sc_hash = sc.ignored_actions
|
69
|
+
if sc_hash[:only]
|
70
|
+
@ignored_actions[:only] ||= []
|
71
|
+
@ignored_actions[:only] << sc_hash[:only]
|
72
|
+
@ignored_actions[:only].flatten!
|
73
|
+
elsif sc_hash[:except]
|
74
|
+
@ignored_actions[:except] ||= []
|
75
|
+
@ignored_actions[:except] << sc_hash[:except]
|
76
|
+
@ignored_actions[:except].flatten!
|
77
|
+
elsif sc_hash[:all]
|
78
|
+
@ignored_actions[:all] = sc_hash[:all]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
return @ignored_actions
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
# This method will be added as "before-filter" for all controllers.
|
88
|
+
#
|
89
|
+
# This method will filter the incoming request, and raise an exception
|
90
|
+
# if it thinks that the incoming request is a forged request.
|
91
|
+
#
|
92
|
+
# The requirement for a request to be considered a forged:
|
93
|
+
# - It must not be a GET request
|
94
|
+
# - The forgery detection is not disabled globally
|
95
|
+
# - The current action is not part of the "disabled" list
|
96
|
+
# - The authenticity token in the request param is valid
|
97
|
+
# - All of the above must be true
|
98
|
+
#
|
99
|
+
def detect_forgery
|
100
|
+
valid_request? || raise(Mack::Errors::InvalidAuthenticityToken.new(request.params[:__authenticity_token] || "unknown token"))
|
101
|
+
end
|
102
|
+
|
103
|
+
protected
|
104
|
+
|
105
|
+
def symbolize_list_elements(list = []) # :nodoc:
|
106
|
+
list.collect { |x| x.to_sym }
|
107
|
+
end
|
108
|
+
|
109
|
+
def skip_action? # :nodoc:
|
110
|
+
return true if self.class.ignored_actions[:all] and self.class.ignored_actions.empty?
|
111
|
+
return false if !self.class.ignored_actions[:all] and self.class.ignored_actions.empty?
|
112
|
+
|
113
|
+
skip = true
|
114
|
+
action = request.params[:action]
|
115
|
+
hash = self.class.ignored_actions
|
116
|
+
if hash[:only]
|
117
|
+
list = [hash[:only]].flatten
|
118
|
+
list = symbolize_list_elements(list)
|
119
|
+
skip = false if !list.include?action.to_sym
|
120
|
+
elsif hash[:except]
|
121
|
+
list = [hash[:except]].flatten
|
122
|
+
list = symbolize_list_elements(list)
|
123
|
+
skip = false if list.include?action.to_sym
|
124
|
+
end
|
125
|
+
return skip
|
126
|
+
end
|
127
|
+
|
128
|
+
def valid_request? # :nodoc:
|
129
|
+
return true if !self.class.ignored_actions.empty? and self.skip_action?
|
130
|
+
return app_config.mack.disable_forgery_detector ||
|
131
|
+
self.skip_action? ||
|
132
|
+
request.params[:method] == "get" ||
|
133
|
+
(request.params[:__authenticity_token] == authenticity_token)
|
134
|
+
end
|
135
|
+
|
136
|
+
def authenticity_token # :nodoc:
|
137
|
+
Mack::Utils::AuthenticityTokenDispenser.instance.dispense_token(request.session.id)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
class AuthenticityTokenDispenser # :nodoc:
|
142
|
+
include Singleton
|
143
|
+
|
144
|
+
def dispense_token(key) # :nodoc:
|
145
|
+
salt = app_config.request_authenticity_token_salt || "shh, it's a secret"
|
146
|
+
salt = "shh, it's a secret" if salt.empty?
|
147
|
+
string_to_hash = key.to_s + salt.to_s
|
148
|
+
Digest::SHA1.hexdigest(string_to_hash)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|