radiant 0.6.7 → 0.6.8

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of radiant might be problematic. Click here for more details.

Files changed (96) hide show
  1. data/CHANGELOG +35 -3
  2. data/CONTRIBUTORS +11 -1
  3. data/README +5 -3
  4. data/app/controllers/admin/welcome_controller.rb +7 -0
  5. data/app/migrate/020_add_session_info_to_users.rb +11 -0
  6. data/app/models/page.rb +22 -9
  7. data/app/models/standard_tags.rb +133 -10
  8. data/app/models/user.rb +9 -1
  9. data/app/views/admin/page/edit.html.haml +5 -4
  10. data/app/views/admin/welcome/login.html.haml +42 -24
  11. data/app/views/layouts/application.html.haml +1 -1
  12. data/config/environment.rb +4 -2
  13. data/db/migrate/020_add_session_info_to_users.rb +11 -0
  14. data/db/migrate/021_remove_session_expire_from_users.rb +9 -0
  15. data/db/schema.rb +3 -2
  16. data/lib/generators/instance/instance_generator.rb +2 -1
  17. data/lib/generators/instance/templates/instance_environment.rb +5 -3
  18. data/lib/login_system.rb +13 -0
  19. data/lib/radiant.rb +1 -1
  20. data/lib/radiant/admin_ui.rb +21 -21
  21. data/lib/radiant/extension/script.rb +251 -0
  22. data/lib/radiant/extension_loader.rb +22 -20
  23. data/lib/radiant/initializer.rb +1 -1
  24. data/lib/radiant/setup.rb +2 -0
  25. data/lib/tasks/framework.rake +39 -29
  26. data/public/500.html +1 -1
  27. data/public/javascripts/admin/admin.js +11 -9
  28. data/script/extension +5 -0
  29. data/spec/controllers/admin/user_controller_spec.rb +1 -1
  30. data/spec/controllers/admin/welcome_controller_spec.rb +31 -5
  31. data/spec/controllers/site_controller_spec.rb +15 -2
  32. data/spec/lib/login_system_spec.rb +106 -60
  33. data/spec/lib/radiant/extension/script_spec.rb +349 -0
  34. data/spec/lib/radiant/extension_loader_spec.rb +3 -0
  35. data/spec/models/page_spec.rb +62 -2
  36. data/spec/models/standard_tags_spec.rb +150 -3
  37. data/spec/models/user_spec.rb +28 -0
  38. data/spec/scenarios/file_not_found_scenario.rb +5 -0
  39. data/spec/scenarios/pages_scenario.rb +6 -0
  40. data/spec/scenarios/snippets_scenario.rb +4 -0
  41. data/test/fixtures/users.yml +11 -6
  42. data/vendor/plugins/haml/FAQ +138 -0
  43. data/vendor/plugins/haml/REVISION +1 -0
  44. data/vendor/plugins/haml/Rakefile +54 -62
  45. data/vendor/plugins/haml/VERSION +1 -1
  46. data/vendor/plugins/haml/init.rb +6 -1
  47. data/vendor/plugins/haml/lib/haml.rb +72 -12
  48. data/vendor/plugins/haml/lib/haml/buffer.rb +47 -40
  49. data/vendor/plugins/haml/lib/haml/engine.rb +20 -30
  50. data/vendor/plugins/haml/lib/haml/error.rb +4 -5
  51. data/vendor/plugins/haml/lib/haml/exec.rb +4 -2
  52. data/vendor/plugins/haml/lib/haml/filters.rb +30 -15
  53. data/vendor/plugins/haml/lib/haml/helpers.rb +47 -28
  54. data/vendor/plugins/haml/lib/haml/helpers/action_view_mods.rb +74 -25
  55. data/vendor/plugins/haml/lib/haml/precompiler.rb +92 -51
  56. data/vendor/plugins/haml/lib/haml/template.rb +11 -3
  57. data/vendor/plugins/haml/lib/haml/template/patch.rb +1 -1
  58. data/vendor/plugins/haml/lib/sass.rb +26 -3
  59. data/vendor/plugins/haml/lib/sass/constant.rb +26 -57
  60. data/vendor/plugins/haml/lib/sass/constant/literal.rb +1 -0
  61. data/vendor/plugins/haml/lib/sass/constant/nil.rb +9 -0
  62. data/vendor/plugins/haml/lib/sass/css.rb +17 -2
  63. data/vendor/plugins/haml/lib/sass/engine.rb +11 -5
  64. data/vendor/plugins/haml/test/haml/engine_test.rb +57 -39
  65. data/vendor/plugins/haml/test/haml/helper_test.rb +20 -4
  66. data/vendor/plugins/haml/test/haml/html2haml_test.rb +1 -3
  67. data/vendor/plugins/haml/test/haml/results/content_for_layout.xhtml +1 -2
  68. data/vendor/plugins/haml/test/haml/results/eval_suppressed.xhtml +2 -4
  69. data/vendor/plugins/haml/test/haml/results/filters.xhtml +12 -8
  70. data/vendor/plugins/haml/test/haml/results/helpers.xhtml +2 -5
  71. data/vendor/plugins/haml/test/haml/results/just_stuff.xhtml +1 -3
  72. data/vendor/plugins/haml/test/haml/results/nuke_inner_whitespace.xhtml +40 -0
  73. data/vendor/plugins/haml/test/haml/results/nuke_outer_whitespace.xhtml +148 -0
  74. data/vendor/plugins/haml/test/haml/results/original_engine.xhtml +2 -4
  75. data/vendor/plugins/haml/test/haml/results/tag_parsing.xhtml +1 -6
  76. data/vendor/plugins/haml/test/haml/results/very_basic.xhtml +2 -4
  77. data/vendor/plugins/haml/test/haml/results/whitespace_handling.xhtml +13 -21
  78. data/vendor/plugins/haml/test/haml/template_test.rb +31 -48
  79. data/vendor/plugins/haml/test/haml/templates/filters.haml +13 -0
  80. data/vendor/plugins/haml/test/haml/templates/helpers.haml +1 -1
  81. data/vendor/plugins/haml/test/haml/templates/just_stuff.haml +0 -1
  82. data/vendor/plugins/haml/test/haml/templates/nuke_inner_whitespace.haml +32 -0
  83. data/vendor/plugins/haml/test/haml/templates/nuke_outer_whitespace.haml +144 -0
  84. data/vendor/plugins/haml/test/haml/templates/partials.haml +1 -1
  85. data/vendor/plugins/haml/test/haml/templates/tag_parsing.haml +0 -3
  86. data/vendor/plugins/haml/test/haml/templates/whitespace_handling.haml +10 -10
  87. data/vendor/plugins/haml/test/sass/engine_test.rb +11 -5
  88. data/vendor/plugins/haml/test/sass/plugin_test.rb +2 -6
  89. data/vendor/plugins/haml/test/sass/results/constants.css +2 -0
  90. data/vendor/plugins/haml/test/sass/templates/constants.sass +3 -0
  91. data/vendor/plugins/haml/test/{haml/test_helper.rb → test_helper.rb} +4 -3
  92. metadata +21 -11
  93. data/vendor/plugins/haml/TODO +0 -9
  94. data/vendor/plugins/haml/extra/haml-mode.el +0 -328
  95. data/vendor/plugins/haml/extra/sass-mode.el +0 -88
  96. data/vendor/plugins/haml/test/profile.rb +0 -65
@@ -29,7 +29,7 @@
29
29
  #error
30
30
  %p= flash[:error]
31
31
  #content
32
- = yield
32
+ = find_and_preserve(yield)
33
33
  %hr{:class=>"hidden"}/
34
34
  #footer
35
35
  %p
@@ -45,7 +45,7 @@ Radiant::Initializer.run do |config|
45
45
  # Use the database for sessions instead of the cookie-based default,
46
46
  # which shouldn't be used to store highly confidential information
47
47
  # (create the session table with 'rake db:sessions:create')
48
- config.action_controller.session_store = :active_record_store
48
+ config.action_controller.session_store = :cookie_store
49
49
 
50
50
  # Use SQL instead of Active Record's schema dumper when creating the test database.
51
51
  # This is necessary if your schema can't be completely dumped by the schema dumper,
@@ -84,4 +84,6 @@ Radiant::Initializer.run do |config|
84
84
  ResponseCache.defaults[:directory] = ActionController::Base.page_cache_directory
85
85
  ResponseCache.defaults[:logger] = ActionController::Base.logger
86
86
  end
87
- end
87
+ end
88
+
89
+ Page.load_subclasses
@@ -0,0 +1,11 @@
1
+ class AddSessionInfoToUsers < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :users, :session_token, :string
4
+ add_column :users, :session_expire, :datetime
5
+ end
6
+
7
+ def self.down
8
+ remove_column :users, :session_token
9
+ remove_column :users, :session_expire
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ class RemoveSessionExpireFromUsers < ActiveRecord::Migration
2
+ def self.up
3
+ remove_column :users, :session_expire
4
+ end
5
+
6
+ def self.down
7
+ add_column :users, :session_expire, :datetime
8
+ end
9
+ end
data/db/schema.rb CHANGED
@@ -9,7 +9,7 @@
9
9
  #
10
10
  # It's strongly recommended to check this file into your version control system.
11
11
 
12
- ActiveRecord::Schema.define(:version => 19) do
12
+ ActiveRecord::Schema.define(:version => 21) do
13
13
 
14
14
  create_table "config", :force => true do |t|
15
15
  t.string "key", :limit => 40, :default => "", :null => false
@@ -67,8 +67,8 @@ ActiveRecord::Schema.define(:version => 19) do
67
67
  t.datetime "updated_at"
68
68
  end
69
69
 
70
- add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
71
70
  add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
71
+ add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
72
72
 
73
73
  create_table "snippets", :force => true do |t|
74
74
  t.string "name", :limit => 100, :default => "", :null => false
@@ -97,6 +97,7 @@ ActiveRecord::Schema.define(:version => 19) do
97
97
  t.text "notes"
98
98
  t.integer "lock_version", :default => 0
99
99
  t.string "salt"
100
+ t.string "session_token"
100
101
  end
101
102
 
102
103
  add_index "users", ["login"], :name => "login", :unique => true
@@ -77,7 +77,8 @@ class InstanceGenerator < Rails::Generator::Base
77
77
  # Instance Configurations
78
78
  m.file "instance_routes.rb", "config/routes.rb"
79
79
  m.template "instance_environment.rb", "config/environment.rb", :assigns => {
80
- :radiant_environment => File.join(File.dirname(__FILE__), 'templates', radiant_root("config/environment.rb"))
80
+ :radiant_environment => File.join(File.dirname(__FILE__), 'templates', radiant_root("config/environment.rb")),
81
+ :app_name => File.basename(File.expand_path(@destination_root))
81
82
  }
82
83
  m.template "instance_boot.rb", "config/boot.rb"
83
84
 
@@ -39,13 +39,13 @@ Radiant::Initializer.run do |config|
39
39
  # no regular words or you'll be exposed to dictionary attacks.
40
40
  config.action_controller.session = {
41
41
  :session_key => '_radiant_session',
42
- :secret => 'asdfqwerfxcoivswqenadfasdfqewpfioutyqwel'
42
+ :secret => <% require 'digest/sha1' %>'<%= Digest::SHA1.hexdigest("--#{app_name}--#{Time.now.to_s}--#{rand(10000000)}--") %>'
43
43
  }
44
44
 
45
45
  # Use the database for sessions instead of the cookie-based default,
46
46
  # which shouldn't be used to store highly confidential information
47
47
  # (create the session table with 'rake db:sessions:create')
48
- config.action_controller.session_store = :active_record_store
48
+ config.action_controller.session_store = :cookie_store
49
49
 
50
50
  # Use SQL instead of Active Record's schema dumper when creating the test database.
51
51
  # This is necessary if your schema can't be completely dumped by the schema dumper,
@@ -84,4 +84,6 @@ Radiant::Initializer.run do |config|
84
84
  ResponseCache.defaults[:directory] = ActionController::Base.page_cache_directory
85
85
  ResponseCache.defaults[:logger] = ActionController::Base.logger
86
86
  end
87
- end
87
+ end
88
+
89
+ Page.load_subclasses
data/lib/login_system.rb CHANGED
@@ -30,6 +30,7 @@ module LoginSystem
30
30
 
31
31
  def authenticate
32
32
  action = params['action'].to_s.intern
33
+ login_from_cookie
33
34
  if no_login_required? or (current_user and user_has_access_to_action?(action))
34
35
  true
35
36
  else
@@ -69,6 +70,18 @@ module LoginSystem
69
70
  true
70
71
  end
71
72
  end
73
+
74
+ def login_from_cookie
75
+ if !cookies[:session_token].blank? && user = User.find_by_session_token(cookies[:session_token]) # don't find by empty value
76
+ user.remember_me
77
+ self.current_user = user
78
+ set_session_cookie
79
+ end
80
+ end
81
+
82
+ def set_session_cookie
83
+ cookies[:session_token] = { :value => current_user.session_token , :expires => Radiant::Config['session_timeout'].to_i.from_now.utc }
84
+ end
72
85
 
73
86
  module ClassMethods
74
87
  def no_login_required
data/lib/radiant.rb CHANGED
@@ -5,7 +5,7 @@ unless defined? Radiant::Version
5
5
  module Version
6
6
  Major = '0'
7
7
  Minor = '6'
8
- Tiny = '7'
8
+ Tiny = '8'
9
9
 
10
10
  class << self
11
11
  def to_s
@@ -5,29 +5,29 @@ module Radiant
5
5
  class AdminUI
6
6
  # This may be loaded before ActiveSupport, so do an explicit require
7
7
  require 'radiant/admin_ui/region_set'
8
-
8
+
9
9
  class DuplicateTabNameError < StandardError; end
10
-
10
+
11
11
  class Tab
12
12
  attr_accessor :name, :url, :visibility
13
-
13
+
14
14
  def initialize(name, url, options = {})
15
15
  @name, @url = name, url
16
16
  @visibility = [options[:for], options[:visibility]].flatten.compact
17
17
  @visibility = [:all] if @visibility.empty?
18
18
  end
19
-
19
+
20
20
  def shown_for?(user)
21
21
  visibility.include?(:all) or
22
22
  visibility.any? { |role| user.send("#{role}?") }
23
- end
23
+ end
24
24
  end
25
-
25
+
26
26
  class TabSet
27
27
  def initialize
28
28
  @tabs = []
29
29
  end
30
-
30
+
31
31
  def add(name, url, options = {})
32
32
  options.symbolize_keys!
33
33
  before = options.delete(:before)
@@ -45,15 +45,15 @@ module Radiant
45
45
  end
46
46
  end
47
47
  end
48
-
48
+
49
49
  def remove(name)
50
50
  @tabs.delete(self[name])
51
51
  end
52
-
52
+
53
53
  def size
54
54
  @tabs.size
55
55
  end
56
-
56
+
57
57
  def [](index)
58
58
  if index.kind_of? Integer
59
59
  @tabs[index]
@@ -61,31 +61,29 @@ module Radiant
61
61
  @tabs.find { |tab| tab.name == index }
62
62
  end
63
63
  end
64
-
64
+
65
65
  def each
66
66
  @tabs.each { |t| yield t }
67
67
  end
68
-
68
+
69
69
  def clear
70
70
  @tabs.clear
71
71
  end
72
-
72
+
73
73
  include Enumerable
74
74
  end
75
-
75
+
76
76
  include Simpleton
77
-
77
+
78
78
  attr_accessor :tabs
79
-
79
+
80
80
  # Region sets
81
81
  attr_accessor :page, :snippet, :layout, :user
82
-
82
+
83
83
  def initialize
84
84
  @tabs = TabSet.new
85
85
  load_default_regions
86
86
  end
87
-
88
- private
89
87
 
90
88
  def load_default_regions
91
89
  @page = load_default_page_regions
@@ -93,7 +91,9 @@ module Radiant
93
91
  @layout = load_default_layout_regions
94
92
  @user = load_default_user_regions
95
93
  end
96
-
94
+
95
+ private
96
+
97
97
  def load_default_page_regions
98
98
  returning OpenStruct.new do |page|
99
99
  page.edit = RegionSet.new do |edit|
@@ -117,7 +117,7 @@ module Radiant
117
117
  returning OpenStruct.new do |user|
118
118
  user.edit = RegionSet.new do |edit|
119
119
  edit.main.concat %w{edit_header edit_form}
120
- edit.form.concat %w{edit_name edit_email edit_username edit_password
120
+ edit.form.concat %w{edit_name edit_email edit_username edit_password
121
121
  edit_roles edit_notes}
122
122
  edit.form_bottom.concat %w{edit_timestamp edit_buttons}
123
123
  end
@@ -0,0 +1,251 @@
1
+ require 'active_resource'
2
+ require 'tmpdir'
3
+ require 'fileutils'
4
+
5
+ module Registry
6
+ class Extension < ActiveResource::Base
7
+ self.site = ENV['REGISTRY_URL'] || "http://ext.radiantcms.org/"
8
+
9
+ def install
10
+ Registry.const_get(install_type).new(self).install
11
+ end
12
+
13
+ def uninstall
14
+ Uninstaller.new(self).uninstall
15
+ end
16
+ end
17
+
18
+ class Action
19
+ def rake(command)
20
+ `rake #{command} RAILS_ENV=#{RAILS_ENV}`
21
+ end
22
+ end
23
+
24
+ class Installer < Action
25
+ attr_accessor :url, :path, :name
26
+ def initialize(url, name)
27
+ self.url, self.name = url, name
28
+ end
29
+
30
+ def install
31
+ copy_to_vendor_extensions
32
+ migrate
33
+ update
34
+ end
35
+
36
+ def copy_to_vendor_extensions
37
+ FileUtils.cp_r(self.path, File.expand_path(File.join(RAILS_ROOT, 'vendor', 'extensions', name)))
38
+ FileUtils.rm_r(self.path)
39
+ end
40
+
41
+ def migrate
42
+ rake "radiant:extensions:#{name}:migrate"
43
+ end
44
+
45
+ def update
46
+ rake "radiant:extensions:#{name}:update"
47
+ end
48
+ end
49
+
50
+ class Uninstaller < Action
51
+ attr_accessor :name
52
+ def initialize(extension)
53
+ self.name = extension.name
54
+ end
55
+
56
+ def uninstall
57
+ migrate_down
58
+ remove_extension_directory
59
+ end
60
+
61
+ def migrate_down
62
+ rake "radiant:extensions:#{name}:migrate VERSION=0"
63
+ end
64
+
65
+ def remove_extension_directory
66
+ FileUtils.rm_r(File.join(RAILS_ROOT, 'vendor', 'extensions', name))
67
+ end
68
+ end
69
+
70
+ class Checkout < Installer
71
+ def initialize(extension)
72
+ super(extension.repository_url, extension.name)
73
+ end
74
+
75
+ def checkout_command
76
+ raise "Not Implemented!"
77
+ end
78
+
79
+ def install
80
+ checkout
81
+ super
82
+ end
83
+
84
+ def checkout
85
+ self.path = File.join(Dir.tmpdir, name)
86
+ system "cd #{Dir.tmpdir}; #{checkout_command}"
87
+ end
88
+ end
89
+
90
+ class Download < Installer
91
+ def initialize(extension)
92
+ super(extension.download_url, extension.name)
93
+ end
94
+
95
+ def install
96
+ download
97
+ unpack
98
+ super
99
+ end
100
+
101
+ def unpack
102
+ raise "Not Implemented!"
103
+ end
104
+
105
+ def filename
106
+ File.basename(self.url)
107
+ end
108
+
109
+ def download
110
+ require 'open-uri'
111
+ File.open(File.join(Dir.tmpdir, self.filename), 'w') {|f| f.write open(self.url).read }
112
+ end
113
+ end
114
+
115
+ class Git < Checkout
116
+ def checkout_command
117
+ "git clone #{url} #{name}"
118
+ end
119
+ end
120
+
121
+ class Subversion < Checkout
122
+ def checkout_command
123
+ "svn checkout #{url} #{name}"
124
+ end
125
+ end
126
+
127
+ class Gem < Download
128
+ def download
129
+ # Don't download the gem if it's already installed
130
+ begin
131
+ gem filename.split('-').first
132
+ rescue ::Gem::LoadError
133
+ super
134
+ `gem install #{filename}`
135
+ end
136
+ end
137
+
138
+ def unpack
139
+ output = `cd #{Dir.tmpdir}; gem unpack #{filename.split('-').first}`
140
+ self.path = output.match(/'(.*)'/)[1]
141
+ end
142
+ end
143
+
144
+ class Tarball < Download
145
+ def filename
146
+ "#{self.name}.tar"
147
+ end
148
+
149
+ def unpack
150
+ output = `cd #{Dir.tmpdir}; tar xvf #{filename}`
151
+ self.path = File.join(Dir.tmpdir, output.split(/\n/).first.split('/').first)
152
+ end
153
+ end
154
+
155
+ class Gzip < Tarball
156
+ def filename
157
+ @unpacked ? super : "#{self.name}.tar.gz"
158
+ end
159
+
160
+ def unpack
161
+ system "cd #{Dir.tmpdir}; gunzip #{self.filename}"
162
+ @unpacked = true
163
+ super
164
+ end
165
+ end
166
+
167
+ class Bzip2 < Tarball
168
+ def filename
169
+ @unpacked ? super : "#{self.name}.tar.bz2"
170
+ end
171
+
172
+ def unpack
173
+ system "cd #{Dir.tmpdir}; bunzip2 #{self.filename}"
174
+ @unpacked = true
175
+ super
176
+ end
177
+ end
178
+
179
+ class Zip < Download
180
+ def unpack
181
+ output = `cd #{Dir.tmpdir}; unzip #{filename} -d #{name}`
182
+ self.path = File.join(Dir.tmpdir, name)
183
+ end
184
+ end
185
+ end
186
+
187
+ module Radiant
188
+ class Extension
189
+ module Script
190
+ class << self
191
+ def execute(args)
192
+ command = args.shift
193
+ const_get(command.camelize).new(args)
194
+ end
195
+ end
196
+
197
+ module Util
198
+ attr_accessor :extension_name, :extension
199
+
200
+ def to_extension_name(string)
201
+ string.to_s.underscore
202
+ end
203
+
204
+ def installed?
205
+ path_match = Regexp.compile("#{extension_name}$")
206
+ extension_paths.any? {|p| p =~ path_match }
207
+ end
208
+
209
+ def extension_paths
210
+ [RAILS_ROOT, RADIANT_ROOT].uniq.map { |p| Dir["#{p}/vendor/extensions/*"] }.flatten
211
+ end
212
+
213
+ def load_extensions
214
+ Registry::Extension.find(:all)
215
+ end
216
+
217
+ def find_extension
218
+ self.extension = load_extensions.find{|e| e.name == self.extension_name }
219
+ end
220
+ end
221
+
222
+ class Install
223
+ include Util
224
+
225
+ def initialize(args=[])
226
+ raise ArgumentError, "You must specify an extension to install." if args.blank?
227
+ self.extension_name = to_extension_name(args.shift)
228
+ if installed?
229
+ puts "#{extension_name} is already installed."
230
+ else
231
+ find_extension && extension.install
232
+ end
233
+ end
234
+ end
235
+
236
+ class Uninstall
237
+ include Util
238
+
239
+ def initialize(args=[])
240
+ raise ArgumentError, "You must specify an extension to uninstall." if args.blank?
241
+ self.extension_name = to_extension_name(args.shift)
242
+ if installed?
243
+ find_extension && extension.uninstall
244
+ else
245
+ puts "#{extension} is not installed."
246
+ end
247
+ end
248
+ end
249
+ end
250
+ end
251
+ end