zena 1.2.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. data/History.txt +25 -0
  2. data/app/controllers/documents_controller.rb +3 -25
  3. data/app/controllers/nodes_controller.rb +34 -24
  4. data/app/controllers/user_sessions_controller.rb +5 -4
  5. data/app/controllers/versions_controller.rb +44 -17
  6. data/app/models/acl.rb +2 -7
  7. data/app/models/group.rb +6 -2
  8. data/app/models/link.rb +14 -0
  9. data/app/models/node.rb +2 -2
  10. data/app/models/site.rb +13 -4
  11. data/app/models/text_document.rb +1 -1
  12. data/app/models/user.rb +11 -2
  13. data/app/models/virtual_class.rb +1 -1
  14. data/app/views/groups/_form.rhtml +6 -6
  15. data/app/views/nodes/render_error.rhtml +15 -0
  16. data/app/views/templates/document_create_tabs/_file.rhtml +1 -1
  17. data/app/views/templates/document_create_tabs/_import.rhtml +1 -1
  18. data/app/views/templates/document_create_tabs/_template.rhtml +1 -1
  19. data/app/views/templates/document_create_tabs/_text_document.rhtml +1 -1
  20. data/app/views/templates/edit_tabs/_title.rhtml +1 -1
  21. data/app/views/zafu/default/Node-admin.zafu +1 -1
  22. data/bricks/acls/zena/test/integration/acl_integration_test.rb +2 -2
  23. data/bricks/acls/zena/test/unit/acl_test.rb +2 -1
  24. data/bricks/fs_skin/zena/migrate/20110702010330_add_fs_skin_to_idx_templates.rb +1 -0
  25. data/bricks/fs_skin/zena/skins/blog/img/style.css +4 -4
  26. data/bricks/grid/lib/bricks/grid.rb +9 -3
  27. data/bricks/passenger/zena/deploy.rb +2 -1
  28. data/bricks/pdf/lib/bricks/pdf.rb +1 -1
  29. data/bricks/tags/zena/test/zafu/tags.yml +5 -1
  30. data/bricks/zena/zena/migrate/20120904071601_change_link_status_to_float.rb +13 -0
  31. data/config/bricks.yml +10 -10
  32. data/config/deploy.rb +1 -5
  33. data/config/gems.yml +2 -2
  34. data/db/init/base/skins/default/Node.zafu +7 -3
  35. data/db/init/base/skins/default/notes.zafu +3 -1
  36. data/lib/zafu/all.rb +0 -9
  37. data/lib/zafu/compiler.rb +0 -4
  38. data/lib/zafu/controller_methods.rb +0 -2
  39. data/lib/zafu/handler.rb +0 -5
  40. data/lib/zafu/markup.rb +4 -6
  41. data/lib/zafu/ordered_hash.rb +3 -2
  42. data/lib/zafu/parsing_rules.rb +1 -3
  43. data/lib/zafu/process/ajax.rb +4 -2
  44. data/lib/zafu/process/context.rb +34 -4
  45. data/lib/zafu/process/forms.rb +2 -2
  46. data/lib/zafu/process/ruby_less_processing.rb +5 -10
  47. data/lib/zafu/template.rb +0 -2
  48. data/lib/zafu/test_helper.rb +0 -2
  49. data/lib/zafu/view_methods.rb +0 -1
  50. data/lib/zafu.rb +1 -1
  51. data/lib/zena/acts/secure_node.rb +5 -4
  52. data/lib/zena/console.rb +19 -17
  53. data/lib/zena/core_ext/string.rb +3 -2
  54. data/lib/zena/deploy/app_init.rhtml +6 -1
  55. data/lib/zena/deploy/httpd.rhtml +16 -13
  56. data/lib/zena/deploy/stats.vhost.rhtml +1 -1
  57. data/lib/zena/deploy/vhost.rhtml +31 -11
  58. data/lib/zena/deploy/vhost_ssl_redir.rhtml +12 -0
  59. data/lib/zena/deploy/vhost_www.rhtml +1 -1
  60. data/lib/zena/deploy.rb +55 -11
  61. data/lib/zena/info.rb +1 -1
  62. data/lib/zena/parser/zazen_rules.rb +18 -9
  63. data/lib/zena/routes.rb +1 -3
  64. data/lib/zena/site_worker.rb +8 -1
  65. data/lib/zena/use/ajax.rb +29 -3
  66. data/lib/zena/use/ancestry.rb +2 -1
  67. data/lib/zena/use/authlogic.rb +12 -18
  68. data/lib/zena/use/context.rb +1 -1
  69. data/lib/zena/use/dates.rb +28 -18
  70. data/lib/zena/use/display.rb +49 -7
  71. data/lib/zena/use/forms.rb +51 -18
  72. data/lib/zena/use/html_tags.rb +6 -6
  73. data/lib/zena/use/i18n.rb +13 -4
  74. data/lib/zena/use/image_builder.rb +2 -0
  75. data/lib/zena/use/query_builder.rb +39 -14
  76. data/lib/zena/use/query_link.rb +57 -0
  77. data/lib/zena/use/query_node.rb +68 -32
  78. data/lib/zena/use/relations.rb +25 -15
  79. data/lib/zena/use/rendering.rb +66 -15
  80. data/lib/zena/use/upload.rb +34 -5
  81. data/lib/zena/use/urls.rb +28 -25
  82. data/lib/zena/use/version_hash.rb +14 -2
  83. data/lib/zena/use/zafu_safe_definitions.rb +72 -3
  84. data/lib/zena/use/zazen.rb +16 -4
  85. data/lib/zena.rb +1 -0
  86. data/public/javascripts/grid.js +213 -64
  87. data/public/javascripts/raphael.js +10 -0
  88. data/public/javascripts/zena.js +146 -22
  89. data/public/stylesheets/reset.css +12 -12
  90. data/public/stylesheets/zena.css +1 -1
  91. data/test/custom_queries/complex.host.yml +19 -0
  92. data/test/fixtures/files/TestNode.zafu +40 -4
  93. data/test/functional/nodes_controller_test.rb +84 -39
  94. data/test/functional/versions_controller_test.rb +2 -2
  95. data/test/integration/navigation_test.rb +61 -35
  96. data/test/integration/query_node/basic.yml +7 -7
  97. data/test/integration/query_node/comments.yml +1 -1
  98. data/test/integration/query_node/complex.yml +3 -3
  99. data/test/integration/query_node/filters.yml +32 -8
  100. data/test/integration/query_node/idx_key_value.yml +10 -10
  101. data/test/integration/query_node/idx_scope.yml +7 -7
  102. data/test/integration/query_node/relations.yml +4 -4
  103. data/test/integration/zafu_compiler/ajax.yml +19 -11
  104. data/test/integration/zafu_compiler/apphelper.yml +1 -1
  105. data/test/integration/zafu_compiler/asset.yml +2 -2
  106. data/test/integration/zafu_compiler/comments.yml +1 -1
  107. data/test/integration/zafu_compiler/dates.yml +1 -1
  108. data/test/integration/zafu_compiler/display.yml +49 -21
  109. data/test/integration/zafu_compiler/eval.yml +4 -4
  110. data/test/integration/zafu_compiler/forms.yml +25 -11
  111. data/test/integration/zafu_compiler/i18n.yml +5 -0
  112. data/test/integration/zafu_compiler/meta.yml +3 -3
  113. data/test/integration/zafu_compiler/query.yml +27 -9
  114. data/test/integration/zafu_compiler/relations.yml +9 -9
  115. data/test/integration/zafu_compiler/roles.yml +6 -6
  116. data/test/integration/zafu_compiler/rubyless.yml +7 -2
  117. data/test/integration/zafu_compiler/safe_definitions.yml +33 -4
  118. data/test/integration/zafu_compiler/security.yml +46 -1
  119. data/test/integration/zafu_compiler/urls.yml +28 -13
  120. data/test/integration/zafu_compiler/user.yml +12 -7
  121. data/test/integration/zafu_compiler/zafu_attributes.yml +1 -1
  122. data/test/integration/zafu_compiler/zazen.yml +5 -5
  123. data/test/integration/zafu_compiler_test.rb +18 -0
  124. data/test/selenium/Filter/filter3.rsel +20 -0
  125. data/test/selenium/Filter/filter4.rsel +20 -0
  126. data/test/sites/zena/versions.yml +2 -0
  127. data/test/unit/exif_data_test.rb +6 -1
  128. data/test/unit/group_test.rb +18 -3
  129. data/test/unit/node_test.rb +0 -7
  130. data/test/unit/project_test.rb +4 -0
  131. data/test/unit/relation_proxy_test.rb +2 -2
  132. data/test/unit/remote_test.rb +0 -9
  133. data/test/unit/role_test.rb +1 -1
  134. data/test/unit/string_hash_test.rb +1 -1
  135. data/test/unit/text_document_test.rb +13 -13
  136. data/test/unit/zena/use/html_tags_test.rb +6 -6
  137. data/test/unit/zena/use/rendering_test.rb +20 -10
  138. data/test/unit/zena/use/urls_test.rb +21 -18
  139. data/test/unit/zena/use/zafu_template_test.rb +0 -5
  140. data/test/unit/zena/use/zazen_test.rb +25 -25
  141. data/zena.gemspec +63 -57
  142. metadata +136 -130
  143. data/test/functional/nodes_controller_commit_test.rb +0 -67
@@ -1,9 +1,20 @@
1
1
  # zena apache2 setup for <%= config[:balancer] %>
2
2
  # automatically generated file
3
3
 
4
+ <% if config[:ssl] %>
5
+ NameVirtualHost *:80
6
+ NameVirtualHost *:443
7
+
8
+ SSLProtocol all
9
+ SSLCipherSuite HIGH:MEDIUM
10
+ <% else %>
4
11
  NameVirtualHost *
12
+ <% end %>
13
+
5
14
  <% if config[:app_type] == :passenger %>
6
- LoadModule upload_progress_module /usr/lib/apache2/modules/mod_upload_progress.so
15
+ LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/<%= config[:passenger_version] || 'passenger-3.0.17' %>/ext/apache2/mod_passenger.so
16
+ PassengerRoot /usr/lib/ruby/gems/1.8/gems/<%= config[:passenger_version] || 'passenger-3.0.17' %>
17
+ PassengerRuby /usr/bin/ruby1.8
7
18
  PassengerDefaultUser www-data
8
19
  <% elsif config[:app_type] == :mongrel %>
9
20
  <Proxy *>
@@ -22,16 +33,8 @@ PassengerDefaultUser www-data
22
33
  <% end %>
23
34
 
24
35
  <IfModule mod_expires.c>
25
- ExpiresActive on
26
- ExpiresDefault A0
27
- ExpiresByType image/jpeg "access plus 1 year"
28
- ExpiresByType image/gif "access plus 1 year"
29
- ExpiresByType image/png "access plus 1 year"
30
- ExpiresByType text/css "access plus 1 year"
31
- ExpiresByType application/javascript "access plus 1 year"
36
+ <FilesMatch "\.(ico|flv|jpe?g|png|gif|js|css|swf)">
37
+ ExpiresActive On
38
+ ExpiresDefault "access plus 1 year"
39
+ </FilesMatch>
32
40
  </IfModule>
33
-
34
- <% if config[:ssl] %>
35
- SSLProtocol all
36
- SSLCipherSuite HIGH:MEDIUM
37
- <% end %>
@@ -1,7 +1,7 @@
1
1
  # zena awstats vhost for <%= config[:host] %>
2
2
  # automatically generated file
3
3
 
4
- <VirtualHost *>
4
+ <VirtualHost *<%= vhost_port %>>
5
5
  ServerName stats.<%= config[:host] %>
6
6
 
7
7
  DocumentRoot /usr/share/doc/awstats/examples
@@ -1,7 +1,7 @@
1
1
  # zena apache2 vhost for <%= config[:host] %>
2
2
  # automatically generated file
3
3
 
4
- <VirtualHost *<%= config[:ssl] ? ':443' : '' %>>
4
+ <VirtualHost *<%= vhost_port %>>
5
5
  ServerName <%= config[:host] %>
6
6
 
7
7
  DocumentRoot <%= config[:sites_root] %>/<%= config[:host] %>/public
@@ -13,6 +13,8 @@
13
13
  AllowOverride None
14
14
  Order allow,deny
15
15
  Allow from all
16
+ # Passenger does not support MultiViews and we do not need it.
17
+ Options -MultiViews
16
18
  </Directory>
17
19
 
18
20
  <% if config[:static].include?('cgi-bin') %>
@@ -42,7 +44,6 @@
42
44
  Satisfy All
43
45
  </DirectoryMatch>
44
46
 
45
- <% if config[:app_type] == :mongrel %>
46
47
  RewriteEngine On
47
48
  <% if config[:debug_rewrite] %>
48
49
  # rewrite debugging
@@ -56,28 +57,46 @@
56
57
  RewriteCond %{SCRIPT_FILENAME} !maintenance.html
57
58
  RewriteRule ^.*$ /system/maintenance.html [L]
58
59
 
60
+ <% list = (config[:lang_list] || 'en').split(',').map(&:strip)
61
+ default = list.first
62
+ list.reverse_each do |l|
63
+ if l != default %>
64
+ # Browser wants "<%= l %>" as favorite language
65
+ RewriteCond %{REQUEST_URI} ^/$
66
+ RewriteCond %{HTTP:Accept-Language} ^<%= l %>
67
+ RewriteRule ^.*$ /<%= l %> [R,L]
68
+ <% else %>
69
+ # Default language for website is "<%= l %>"
70
+ RewriteCond %{REQUEST_URI} ^/$
71
+ RewriteRule ^.*$ /<%= l %> [R,L]
72
+ <% end
73
+ end %>
74
+
59
75
  # Rewrite index to check for static
60
76
  RewriteRule ^/$ /index.html [QSA]
61
77
 
62
- # Rewrite to check for Rails cached page
63
- RewriteRule ^([^.]+)$ $1.html [QSA]
64
-
65
78
  # Serve static (cached) assets
66
79
  RewriteCond %{QUERY_STRING} ^[0-9]+$
67
- RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME}.%{QUERY_STRING} -f
68
- # We have to use '.'. If we use '?' apache won't find the file.
69
- RewriteRule ^/(.*)$ %{REQUEST_FILENAME}.%{QUERY_STRING} [L]
80
+ RewriteCond %{DOCUMENT_ROOT}<%= config[:cache_path] %>%{REQUEST_FILENAME}.%{QUERY_STRING} -f
81
+ RewriteRule ^/(.*)$ <%= config[:cache_path] %>%{REQUEST_FILENAME}.%{QUERY_STRING} [L]
70
82
 
71
- # Rails assets (static CSS, JS).
83
+ # Static CSS, JS
72
84
  RewriteCond %{QUERY_STRING} ^[0-9]+$
73
85
  RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} -f
74
86
  RewriteRule ^/(.*)$ %{REQUEST_FILENAME} [L]
75
87
 
88
+ # Zena dynamic cache
89
+ RewriteCond %{DOCUMENT_ROOT}<%= config[:cache_path] %>%{REQUEST_FILENAME}%{QUERY_STRING} -f
90
+ RewriteRule ^/(.*)$ <%= config[:cache_path] %>%{REQUEST_FILENAME}%{QUERY_STRING} [L]
91
+ RewriteCond %{DOCUMENT_ROOT}<%= config[:cache_path] %>%{REQUEST_FILENAME}%{QUERY_STRING}.html -f
92
+ RewriteRule ^/(.*)$ <%= config[:cache_path] %>%{REQUEST_FILENAME}%{QUERY_STRING}.html [L]
93
+
94
+ <% if config[:app_type] == :mongrel %>
76
95
  # else
77
96
  # Request with query string (if some page is cached, the same page with a query should not be served as static)
78
97
  RewriteCond %{QUERY_STRING} ^.+$ [OR]
79
98
  # All non-static
80
- RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
99
+ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
81
100
  RewriteRule ^/(.*)$ balancer://<%= config[:balancer] %>%{REQUEST_URI} [P,QSA,L]
82
101
  <% elsif config[:app_type] == :passenger %>
83
102
  PassengerAppRoot <%= config[:app_root] %>
@@ -110,11 +129,12 @@
110
129
  CustomLog <%= config[:sites_root] %>/<%= config[:host] %>/log/deflate.log deflate
111
130
  <% end %>
112
131
 
113
- <% if config[:ssl] %>
132
+ <% if ssl %>
114
133
  SSLEngine on
115
134
  SSLCertificateFile /etc/ssl/<%= config[:host] %>.crt
116
135
  SSLCertificateKeyFile /etc/ssl/<%= config[:host] %>.key
117
136
  SSLCACertificateFile /etc/ssl/<%= config[:ssl_pem] %>
118
137
  SSLVerifyClient None
138
+ RequestHeader set X_FORWARDED_PROTO 'https'
119
139
  <% end %>
120
140
  </VirtualHost>
@@ -0,0 +1,12 @@
1
+ # Zena apache2 vhost for <%= config[:host] %>
2
+ # Automatically generated file.
3
+
4
+ <VirtualHost *:80>
5
+ ServerName <%= config[:host] %>
6
+
7
+ # Redirect all requests to ssl
8
+
9
+ RewriteEngine On
10
+ RewriteCond %{HTTPS} off
11
+ RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [NE]
12
+ </VirtualHost>
@@ -1,7 +1,7 @@
1
1
  # zena apache2 vhost for <%= config[:host] %>
2
2
  # automatically generated file
3
3
 
4
- <VirtualHost *>
4
+ <VirtualHost *<%= vhost_port %>>
5
5
  ServerName www.<%= config[:host] %>
6
6
 
7
7
  RewriteEngine On
data/lib/zena/deploy.rb CHANGED
@@ -93,9 +93,11 @@ Capistrano::Configuration.instance(:must_exist).load do
93
93
  'current/tmp',
94
94
  'current/log',
95
95
  'shared/log',
96
+ # Passenger uses the owner of environment.rb as worker
97
+ 'current/config/environment.rb',
96
98
  ].map {|dir| "#{deploy_to}/#{dir}"}
97
99
 
98
- # make sure production.log is created before so that it gets the correct permissionsong
100
+ # make sure production.log is created before so that it gets the correct permission
99
101
  run "touch #{deploy_to}/shared/log/production.log"
100
102
  run "chown -R www-data:www-data #{directories.join(' ')}"
101
103
  end
@@ -150,13 +152,20 @@ Capistrano::Configuration.instance(:must_exist).load do
150
152
  #========================== MANAGE HOST =========================#
151
153
  desc "create a new site [-s host='...' -s pass='...' -s lang='...']"
152
154
  task :mksite, :roles => :app do
153
- run "#{in_current} rake zena:mksite HOST='#{self[:host]}' PASSWORD='#{self[:pass]}' RAILS_ENV='production' HOST_LANG='#{self[:lang] || 'en'}'"
155
+ lang = self[:lang] ||= (self[:lang_list] || 'en').split(',').map(&:strip).first
156
+ self[:lang_list] ||= lang
157
+ run "#{in_current} rake zena:mksite HOST='#{self[:host]}' PASSWORD='#{self[:pass]}' RAILS_ENV='production' HOST_LANG='#{lang}' LANG_LIST='#{self[:lang_list] || lang}'"
154
158
  run "test -e #{sites_root}/#{self[:host]} || mkdir #{sites_root}/#{self[:host]}"
155
159
  create_vhost
156
160
  create_awstats
157
161
  logrotate
158
162
  run "chown -R www-data:www-data #{sites_root}/#{self[:host]}"
159
163
  end
164
+
165
+ task :mksymlinks, :roles => :app do
166
+ run "#{in_current} rake zena:mksymlinks HOST='#{self[:host]}'"
167
+ run "chown -R www-data:www-data #{sites_root}/#{self[:host]}"
168
+ end
160
169
 
161
170
  desc "update code in the current version"
162
171
  task :up, :roles => :app do
@@ -195,17 +204,49 @@ Capistrano::Configuration.instance(:must_exist).load do
195
204
  unless self[:host]
196
205
  puts "HOST not set (use -s host=...)"
197
206
  else
198
- vhost = render("#{templates}/vhost.rhtml", :config => self)
199
- put(vhost, "#{vhost_root}/#{self[:host]}")
207
+ vhost_files = []
208
+ if self[:ssl] == :all
209
+
210
+ public_path = Bricks.raw_config['public_path'] || '/public'
211
+ cache_path = Bricks.raw_config['cache_path'] || '/public'
212
+
213
+ self[:cache_path] = cache_path.sub(%r{^#{public_path}},'')
214
+ vhost = render("#{templates}/vhost.rhtml", :config => self, :ssl => true, :vhost_port => ':443')
215
+ put(vhost, "#{vhost_root}/#{self[:host]}.ssl")
216
+ vhost_files << "#{self[:host]}.ssl"
217
+
218
+ # Redirect if not ssl
219
+ vhost = render("#{templates}/vhost_ssl_redir.rhtml", :config => self)
220
+ put(vhost, "#{vhost_root}/#{self[:host]}")
221
+ vhost_files << "#{self[:host]}"
222
+ elsif self[:ssl] == :logged_in
223
+ # Redirect only if logged in
224
+ vhost = render("#{templates}/vhost.rhtml", :config => self, :ssl => true, :vhost_port => ':443')
225
+ put(vhost, "#{vhost_root}/#{self[:host]}.ssl")
226
+ vhost_files << "#{self[:host]}.ssl"
227
+
228
+ # Redirect to ssl if logged in (this redirect is triggered by Zena).
229
+ vhost = render("#{templates}/vhost.rhtml", :config => self, :ssl => false, :vhost_port => ':80')
230
+ put(vhost, "#{vhost_root}/#{self[:host]}")
231
+ vhost_files << "#{self[:host]}"
232
+ else
233
+ vhost = render("#{templates}/vhost.rhtml", :config => self, :ssl => false, :vhost_port => '')
234
+ put(vhost, "#{vhost_root}/#{self[:host]}")
235
+ vhost_files << "#{self[:host]}"
236
+ end
200
237
 
201
238
  # directory setup for log
202
239
  run "test -e #{sites_root}/#{self[:host]}/log || mkdir #{sites_root}/#{self[:host]}/log"
203
240
  run "chown www-data:www-data #{sites_root}/#{self[:host]}/log"
204
-
205
- run "test -e /etc/apache2/sites-enabled/#{self[:host]} || a2ensite #{self[:host]}" if debian_host
241
+
242
+ if debian_host
243
+ vhost_files.each do |host|
244
+ run "test -e /etc/apache2/sites-enabled/#{host} || a2ensite #{host}"
245
+ end
246
+ end
206
247
 
207
248
  unless self[:host] =~ /^www/
208
- vhost_www = render("#{templates}/vhost_www.rhtml", :config => self)
249
+ vhost_www = render("#{templates}/vhost_www.rhtml", :config => self, :vhost_port => (self[:ssl] ? ':80' : ''))
209
250
  put(vhost_www, "#{vhost_root}/www.#{self[:host]}")
210
251
  run "test -e /etc/apache2/sites-enabled/www.#{self[:host]} || a2ensite www.#{self[:host]}" if debian_host
211
252
  end
@@ -229,7 +270,7 @@ Capistrano::Configuration.instance(:must_exist).load do
229
270
  run "chmod 640 /etc/awstats/awstats.#{self[:host]}.conf"
230
271
 
231
272
  # create stats vhost
232
- stats_vhost = render("#{templates}/stats.vhost.rhtml", :config => self)
273
+ stats_vhost = render("#{templates}/stats.vhost.rhtml", :config => self, :vhost_port => (self[:ssl] ? ':80' : ''))
233
274
  put(stats_vhost, "#{vhost_root}/stats.#{self[:host]}")
234
275
  run "test -e /etc/apache2/sites-enabled/stats.#{self[:host]} || a2ensite stats.#{self[:host]}"
235
276
 
@@ -262,7 +303,7 @@ Capistrano::Configuration.instance(:must_exist).load do
262
303
  else
263
304
  # create logrotate config file
264
305
  logrotate_conf = render("#{templates}/logrotate_host.rhtml", :config => self )
265
- put(logrotate_conf, "/etc/logrotate.d/#{self[:host]}")
306
+ put(logrotate_conf, "/etc/logrotate.d/#{db_name}-#{self[:host]}")
266
307
  end
267
308
  end
268
309
  end
@@ -275,7 +316,8 @@ Capistrano::Configuration.instance(:must_exist).load do
275
316
  run "#{in_current} rake zena:rename_site OLD_HOST='#{self[:old_host]}' HOST='#{self[:host]}' RAILS_ENV='production'"
276
317
  old_vhosts = ["#{self[:old_host]}",
277
318
  "stats.#{self[:old_host]}",
278
- "www.#{self[:old_host]}"]
319
+ "www.#{self[:old_host]}",
320
+ "#{self[:old_host]}.ssl"]
279
321
  old_vhosts.each do |vhost|
280
322
  run "test -e /etc/apache2/sites-enabled/#{vhost} && a2dissite #{vhost} || true"
281
323
  vhost_path = "#{vhost_root}/#{vhost}"
@@ -314,10 +356,12 @@ Capistrano::Configuration.instance(:must_exist).load do
314
356
 
315
357
  run "test -e /etc/apache2/sites-enabled/000-default && a2dissite default || echo 'default already disabled'"
316
358
 
317
- modules = %w{rewrite deflate proxy_balancer proxy proxy_http expires}
359
+ modules = %w{rewrite headers deflate proxy_balancer proxy proxy_http expires}
318
360
  if self[:ssl]
319
361
  modules << 'ssl'
362
+ modules << 'headers'
320
363
  # Default in debian: no need to change ports.
364
+ # Remove NameVirtualHost directives in ports.conf (avoids warnings).
321
365
  # /etc/apache2/ports.conf:
322
366
  # Listen 443
323
367
  end
data/lib/zena/info.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Zena
2
- VERSION = '1.2.2'
2
+ VERSION = '1.2.3'
3
3
  ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
4
4
  end
@@ -7,7 +7,14 @@ module Zena
7
7
  include Zena::Acts::Secure
8
8
 
9
9
  PSEUDO_ID_REGEXP = ":[0-9a-zA-Z-]+\\+*|\\([^\\)]*\\)"
10
-
10
+
11
+ def raw_content(txt)
12
+ txt = [:raw, txt] if txt.kind_of?(String)
13
+ @escaped_code << txt
14
+ @block_counter += 1
15
+ return "<pre>\\ZAZENBLOCKCODE#{@block_counter}ZAZENBLOCKCODE\\</pre>"
16
+ end
17
+
11
18
  def start(mode)
12
19
  @helper = @options[:helper]
13
20
  # we do nothing, everything is done when 'render' is called
@@ -326,12 +333,10 @@ module Zena
326
333
 
327
334
  def extract_code(fulltext)
328
335
  @escaped_code = []
329
- block_counter = -1
336
+ @block_counter = -1
330
337
  fulltext.gsub!( /<code([^>]*)>(.*?)<\/code>/m ) do
331
338
  if @translate_ids
332
- @escaped_code << $&
333
- block_counter += 1
334
- "<pre>\\ZAZENBLOCKCODE#{block_counter}ZAZENBLOCKCODE\\</pre>"
339
+ raw_content([nil, $&])
335
340
  else
336
341
  params, text = $1, $2
337
342
  pre_params = []
@@ -345,9 +350,7 @@ module Zena
345
350
  end
346
351
  #pre_params << "class='code'" unless params =~ /class\s*=/
347
352
  pre_params = pre_params.blank? ? nil : pre_params.join(' ')
348
- @escaped_code << [lang, text, pre_params]
349
- block_counter += 1
350
- "<pre>\\ZAZENBLOCKCODE#{block_counter}ZAZENBLOCKCODE\\</pre>"
353
+ raw_content([lang, text, pre_params])
351
354
  end
352
355
  end
353
356
 
@@ -366,7 +369,13 @@ module Zena
366
369
  @escaped_code[$1.to_i]
367
370
  else
368
371
  code_lang, code, pre_params = @escaped_code[$1.to_i]
369
- Zena::CodeSyntax.new(code, @context[:pretty_code] ? code_lang : nil).to_html(@context.merge(:pre_params => pre_params))
372
+ # FIXME: How to not parse with Textile ?
373
+ if code_lang == :raw then
374
+ # SECURITY: symbol cannot be set from zazen.
375
+ code
376
+ else
377
+ Zena::CodeSyntax.new(code, @context[:pretty_code] ? code_lang : nil).to_html(@context.merge(:pre_params => pre_params))
378
+ end
370
379
  end
371
380
  end
372
381
 
data/lib/zena/routes.rb CHANGED
@@ -17,8 +17,6 @@ module Zena
17
17
  resources :acls
18
18
  resources :iformats
19
19
 
20
-
21
- connect ':prefix/*path?:cachestamp', :controller => 'nodes', :action => 'show', :prefix => /\w\w/, :cachestamp => /\d+/
22
20
  connect ':prefix/*path', :controller => 'nodes', :action => 'show', :prefix => /\w\w/
23
21
  connect 'dav/*path_info', :controller => 'nodes', :action => 'webdav'
24
22
 
@@ -26,7 +24,7 @@ module Zena
26
24
  :collection => { :asearch => :get, :search => :get },
27
25
  :member => { :import => :post, :export => :get, :save_text => :put,
28
26
  :order => :any, :clear_order => :any,
29
- :zafu => :get, :drop => :put, :attribute => :get,
27
+ :zafu => :any, :drop => :put, :attribute => :get,
30
28
  :find => :get # same as search but starting on current node instead of root
31
29
  }.merge(Zena::Use.routes('nodes')) do |nodes|
32
30
  nodes.resources :versions,
@@ -30,7 +30,14 @@ module Zena
30
30
  Zena::SiteWorker.perform(site, action, page + 1)
31
31
 
32
32
  # do action on nodes
33
- site.send(action, nodes, page, page_count)
33
+ begin
34
+ site.send(action, nodes, page, page_count)
35
+ rescue => err
36
+ # If we let the action fail, it will rerun and we will recreate an action for page + 1 !
37
+ Site.logger.warn "[JOB] Failed: '#{action}'"
38
+ Site.logger.warn err.message
39
+ end
40
+
34
41
  end
35
42
  end
36
43
  end
data/lib/zena/use/ajax.rb CHANGED
@@ -187,10 +187,27 @@ module Zena
187
187
  else
188
188
  loading = ''
189
189
  end
190
+ # Disable 'redir' parameter during preview or filter.
190
191
  js_data << %Q{new Form.Observer('#{dom_id}', 0.3, function(element, value) {#{loading}
191
- new Ajax.Request('#{zafu_node_path(node)}', {asynchronous:true, evalScripts:true, method:'get', parameters:Form.serialize('#{dom_id}')})
192
+ var data = Form.serialize('#{dom_id}').gsub(/&redir=/,'&no_redir=')
193
+ new Ajax.Request('#{zafu_node_path(node)}', {asynchronous:true, evalScripts:true, method:'post', parameters:data})
192
194
  });}
193
195
  end
196
+
197
+ # Load parameters in node before rendering.
198
+ # SECURITY: There may be a security threat here if the node attributes are used for queries or relations.
199
+ def preview_node(node)
200
+ return nil if !node.kind_of?(Node)
201
+ if attrs = params[:node]
202
+ # Return a copy
203
+ new_node = node.dup
204
+ new_node.version = node.version.dup
205
+ new_node.attributes = Node.transform_attributes(params[:node], node, true)
206
+ return new_node
207
+ else
208
+ return node
209
+ end
210
+ end
194
211
 
195
212
  # Include draggable ids in bottom of page Javascript.
196
213
  def render_js(in_html = true)
@@ -284,7 +301,11 @@ module Zena
284
301
  end
285
302
  end
286
303
 
287
- # Display an input field to filter a remote block
304
+ def r_preview_node
305
+ expand_if("#{var} = preview_node(#{node})", node.move_to(var, node.klass))
306
+ end
307
+
308
+ # Display an input field to filter a remote block.
288
309
  def r_filter
289
310
  if upd = @params[:update]
290
311
  return unless block = find_target(upd)
@@ -516,7 +537,12 @@ module Zena
516
537
  def r_ajax?
517
538
  r_if(RubyLess.translate(self, 'ajax?'))
518
539
  end
519
-
540
+
541
+ def r_reset_sort
542
+ text = text_for_link(trans('reset_sort'))
543
+ out "<a href='javascript:void()' onclick='Zena.resetSort(this)'>#{text}</a>"
544
+ end
545
+
520
546
  protected
521
547
 
522
548
  def need_ajax?(each_block)
@@ -65,7 +65,8 @@ module Zena
65
65
 
66
66
  module ModelMethods
67
67
  include RubyLess
68
- safe_context :ancestors => {:class => ['Node'], :method => 'z_ancestors'}
68
+ # This is used to defer :class type resolution to compilation time
69
+ safe_method :ancestors => Proc.new {|h, r, s| {:method => 'z_ancestors', :class => [VirtualClass['Node']], :nil => true}}
69
70
  safe_method :fullpath => String, :short_path => [String]
70
71
 
71
72
  def self.included(base)
@@ -39,7 +39,8 @@ module Zena
39
39
  end
40
40
 
41
41
  def set_visitor
42
- unless site = forge_cookie_with_http_auth || Site.find_by_host(request.host)
42
+ forge_cookie_with_http_auth
43
+ unless site = Site.find_by_host(request.host)
43
44
  raise ActiveRecord::RecordNotFound.new("host not found #{request.host}")
44
45
  end
45
46
 
@@ -47,7 +48,10 @@ module Zena
47
48
  ::I18n.locale = site.default_lang
48
49
 
49
50
  User.send(:with_scope, :find => {:conditions => ['site_id = ?', site.id]}) do
50
- Thread.current[:visitor] = token_visitor || registered_visitor || anonymous_visitor(site)
51
+ if user = token_visitor || registered_visitor || anonymous_visitor(site)
52
+ user.asset_host = @asset_host
53
+ Thread.current[:visitor] = user
54
+ end
51
55
  end
52
56
  end
53
57
 
@@ -83,27 +87,17 @@ module Zena
83
87
  end
84
88
 
85
89
  # Create a fake cookie based on HTTP_AUTH using session_id and render_token. This is
86
- # only used for requests to localhost.
90
+ # only used for requests from localhost (asset host).
87
91
  def forge_cookie_with_http_auth
88
- if (request.host == '127.0.0.1' || request.host == 'localhost') && request.port == Zena::ASSET_PORT
92
+ if (request.headers['REMOTE_ADDR'] == '127.0.0.1' || request.headers['REMOTE_ADDR'] == '::1') &&
93
+ (Zena::ASSET_PORT.to_i == 0 || request.port.to_i == Zena::ASSET_PORT)
89
94
  authenticate_with_http_basic do |login, password|
90
95
  # login = visitor.id
91
96
  # password = persistence_token
92
-
93
- # Temporary user to find site
94
- user = User.find(login)
95
- if user && site = user.site
96
- # OK, we can set host
97
- request.env['HTTP_HOST'] = "#{site.host}:#{Zena::ASSET_PORT}"
98
- # forge cookie
99
- cookies['user_credentials'] = "#{password}::#{login}"
100
- site
101
- else
102
- raise ActiveRecord::RecordNotFound
103
- end
97
+ @asset_host = true
98
+ # forge cookie
99
+ cookies['user_credentials'] = "#{password}::#{login}"
104
100
  end
105
- else
106
- nil
107
101
  end
108
102
  end
109
103
 
@@ -248,7 +248,7 @@ module Zena
248
248
  method = "group_array(#{node}) {|e| #{key}}"
249
249
  out "<% if #{var} = #{method} %>"
250
250
  open_node_context({:method => method}, :node => node.move_to(var, [node.klass], :query => node.opts[:query])) do
251
- if child['each_group']
251
+ if descendant('each_group')
252
252
  out expand_with
253
253
  else
254
254
  @var = nil
@@ -119,21 +119,21 @@ module Zena
119
119
  module FormTags
120
120
  # Date selection tool.
121
121
  # TODO: make it work with form_helper: <%= f.date_box(:event_at) %>
122
- def date_box(obj, name, opts = {})
123
- rnd_id = rand(100000000000)
124
- defaults = { :id=>"datef#{rnd_id}", :button=>"dateb#{rnd_id}", :display=>"dated#{rnd_id}" }
125
- opts = defaults.merge(opts)
126
- date = opts[:value] || obj.safe_send(name)
127
- showsTime = opts[:time] || 'true'
128
- # TODO: could we pass the format from the view so that it is
129
- # translated with the view's dictionary during compilation ?
130
- dateFormat = showsTime == 'true' ? _('datetime') : _('long_date')
131
- value = format_date(date, :format => dateFormat)
132
-
133
- # TODO: migrate code to Zafu::Markup (needs Zafu 0.7.7)
134
- # fld = Zafu::Markup.new('input')
135
- # fld.params = (opts[:html] || {}).merge(:name => "node[#{name}]", :id => opts[:id], :type => 'text', :value => value)
136
- if opts[:size]
122
+ def date_box(obj, name, opts = {})
123
+ rnd_id = rand(100000000000)
124
+ defaults = { :id=>"datef#{rnd_id}", :button=>"dateb#{rnd_id}", :display=>"dated#{rnd_id}" }
125
+ opts = defaults.merge(opts)
126
+ date = opts[:value] || obj.safe_send(name)
127
+ showsTime = opts[:time] || 'true'
128
+ # TODO: could we pass the format from the view so that it is
129
+ # translated with the view's dictionary during compilation ?
130
+ dateFormat = showsTime == 'true' ? _('datetime') : _('long_date')
131
+ value = format_date(date, :format => dateFormat)
132
+
133
+ # TODO: migrate code to Zafu::Markup (needs Zafu 0.7.7)
134
+ # fld = Zafu::Markup.new('input')
135
+ # fld.params = (opts[:html] || {}).merge(:name => "node[#{name}]", :id => opts[:id], :type => 'text', :value => value)
136
+ if opts[:size]
137
137
  fld = "<input id='#{opts[:id]}' name='#{name}' type='text' size='#{opts[:size]}' value='#{value}' class='#{opts[:class]}'/>"
138
138
  else
139
139
  fld = "<input id='#{opts[:id]}' name='#{name}' type='text' value='#{value}' class='#{opts[:class]}'/>"
@@ -147,11 +147,11 @@ module Zena
147
147
  ifFormat : '#{dateFormat}'
148
148
  });}
149
149
 
150
- <<-EOL
150
+ <<-EOL
151
151
  <span class="date_box"><img src="/calendar/iconCalendar.gif" id="#{opts[:button]}" alt='#{_('date selection')}'/>
152
152
  #{fld}</span>
153
- EOL
154
- end
153
+ EOL
154
+ end
155
155
  end
156
156
 
157
157
  module ModelMethods
@@ -288,6 +288,8 @@ module Zena
288
288
  def strftime_tz(format, tz = nil)
289
289
  if tz.blank?
290
290
  tz = visitor.tz
291
+ elsif tz == 'UTC'
292
+ return self.strftime(format.to_s)
291
293
  elsif tz.kind_of?(String)
292
294
  tz = TZInfo::Timezone.get(tz)
293
295
  end
@@ -301,6 +303,8 @@ module Zena
301
303
  def year_tz(tz = nil)
302
304
  if tz.blank?
303
305
  tz = visitor.tz
306
+ elsif tz == 'UTC'
307
+ return self.year
304
308
  elsif tz.kind_of?(String)
305
309
  tz = TZInfo::Timezone.get(tz)
306
310
  end
@@ -314,6 +318,8 @@ module Zena
314
318
  def advance_tz(opts, tz = nil)
315
319
  if tz.blank?
316
320
  tz = visitor.tz
321
+ elsif tz == 'UTC'
322
+ return self.advance(opts)
317
323
  elsif tz.kind_of?(String)
318
324
  tz = TZInfo::Timezone.get(tz)
319
325
  end
@@ -327,6 +333,8 @@ module Zena
327
333
  def wday_tz(tz = nil)
328
334
  if tz.blank?
329
335
  tz = visitor.tz
336
+ elsif tz == 'UTC'
337
+ return self.wday
330
338
  elsif tz.kind_of?(String)
331
339
  tz = TZInfo::Timezone.get(tz)
332
340
  end
@@ -340,6 +348,8 @@ module Zena
340
348
  def to_date_tz(tz = nil)
341
349
  if tz.blank?
342
350
  tz = visitor.tz
351
+ elsif tz == 'UTC'
352
+ return self.to_date
343
353
  elsif tz.kind_of?(String)
344
354
  tz = TZInfo::Timezone.get(tz)
345
355
  end