zena 1.2.2 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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