zena 1.2.2 → 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +25 -0
- data/app/controllers/documents_controller.rb +3 -25
- data/app/controllers/nodes_controller.rb +34 -24
- data/app/controllers/user_sessions_controller.rb +5 -4
- data/app/controllers/versions_controller.rb +44 -17
- data/app/models/acl.rb +2 -7
- data/app/models/group.rb +6 -2
- data/app/models/link.rb +14 -0
- data/app/models/node.rb +2 -2
- data/app/models/site.rb +13 -4
- data/app/models/text_document.rb +1 -1
- data/app/models/user.rb +11 -2
- data/app/models/virtual_class.rb +1 -1
- data/app/views/groups/_form.rhtml +6 -6
- data/app/views/nodes/render_error.rhtml +15 -0
- data/app/views/templates/document_create_tabs/_file.rhtml +1 -1
- data/app/views/templates/document_create_tabs/_import.rhtml +1 -1
- data/app/views/templates/document_create_tabs/_template.rhtml +1 -1
- data/app/views/templates/document_create_tabs/_text_document.rhtml +1 -1
- data/app/views/templates/edit_tabs/_title.rhtml +1 -1
- data/app/views/zafu/default/Node-admin.zafu +1 -1
- data/bricks/acls/zena/test/integration/acl_integration_test.rb +2 -2
- data/bricks/acls/zena/test/unit/acl_test.rb +2 -1
- data/bricks/fs_skin/zena/migrate/20110702010330_add_fs_skin_to_idx_templates.rb +1 -0
- data/bricks/fs_skin/zena/skins/blog/img/style.css +4 -4
- data/bricks/grid/lib/bricks/grid.rb +9 -3
- data/bricks/passenger/zena/deploy.rb +2 -1
- data/bricks/pdf/lib/bricks/pdf.rb +1 -1
- data/bricks/tags/zena/test/zafu/tags.yml +5 -1
- data/bricks/zena/zena/migrate/20120904071601_change_link_status_to_float.rb +13 -0
- data/config/bricks.yml +10 -10
- data/config/deploy.rb +1 -5
- data/config/gems.yml +2 -2
- data/db/init/base/skins/default/Node.zafu +7 -3
- data/db/init/base/skins/default/notes.zafu +3 -1
- data/lib/zafu/all.rb +0 -9
- data/lib/zafu/compiler.rb +0 -4
- data/lib/zafu/controller_methods.rb +0 -2
- data/lib/zafu/handler.rb +0 -5
- data/lib/zafu/markup.rb +4 -6
- data/lib/zafu/ordered_hash.rb +3 -2
- data/lib/zafu/parsing_rules.rb +1 -3
- data/lib/zafu/process/ajax.rb +4 -2
- data/lib/zafu/process/context.rb +34 -4
- data/lib/zafu/process/forms.rb +2 -2
- data/lib/zafu/process/ruby_less_processing.rb +5 -10
- data/lib/zafu/template.rb +0 -2
- data/lib/zafu/test_helper.rb +0 -2
- data/lib/zafu/view_methods.rb +0 -1
- data/lib/zafu.rb +1 -1
- data/lib/zena/acts/secure_node.rb +5 -4
- data/lib/zena/console.rb +19 -17
- data/lib/zena/core_ext/string.rb +3 -2
- data/lib/zena/deploy/app_init.rhtml +6 -1
- data/lib/zena/deploy/httpd.rhtml +16 -13
- data/lib/zena/deploy/stats.vhost.rhtml +1 -1
- data/lib/zena/deploy/vhost.rhtml +31 -11
- data/lib/zena/deploy/vhost_ssl_redir.rhtml +12 -0
- data/lib/zena/deploy/vhost_www.rhtml +1 -1
- data/lib/zena/deploy.rb +55 -11
- data/lib/zena/info.rb +1 -1
- data/lib/zena/parser/zazen_rules.rb +18 -9
- data/lib/zena/routes.rb +1 -3
- data/lib/zena/site_worker.rb +8 -1
- data/lib/zena/use/ajax.rb +29 -3
- data/lib/zena/use/ancestry.rb +2 -1
- data/lib/zena/use/authlogic.rb +12 -18
- data/lib/zena/use/context.rb +1 -1
- data/lib/zena/use/dates.rb +28 -18
- data/lib/zena/use/display.rb +49 -7
- data/lib/zena/use/forms.rb +51 -18
- data/lib/zena/use/html_tags.rb +6 -6
- data/lib/zena/use/i18n.rb +13 -4
- data/lib/zena/use/image_builder.rb +2 -0
- data/lib/zena/use/query_builder.rb +39 -14
- data/lib/zena/use/query_link.rb +57 -0
- data/lib/zena/use/query_node.rb +68 -32
- data/lib/zena/use/relations.rb +25 -15
- data/lib/zena/use/rendering.rb +66 -15
- data/lib/zena/use/upload.rb +34 -5
- data/lib/zena/use/urls.rb +28 -25
- data/lib/zena/use/version_hash.rb +14 -2
- data/lib/zena/use/zafu_safe_definitions.rb +72 -3
- data/lib/zena/use/zazen.rb +16 -4
- data/lib/zena.rb +1 -0
- data/public/javascripts/grid.js +213 -64
- data/public/javascripts/raphael.js +10 -0
- data/public/javascripts/zena.js +146 -22
- data/public/stylesheets/reset.css +12 -12
- data/public/stylesheets/zena.css +1 -1
- data/test/custom_queries/complex.host.yml +19 -0
- data/test/fixtures/files/TestNode.zafu +40 -4
- data/test/functional/nodes_controller_test.rb +84 -39
- data/test/functional/versions_controller_test.rb +2 -2
- data/test/integration/navigation_test.rb +61 -35
- data/test/integration/query_node/basic.yml +7 -7
- data/test/integration/query_node/comments.yml +1 -1
- data/test/integration/query_node/complex.yml +3 -3
- data/test/integration/query_node/filters.yml +32 -8
- data/test/integration/query_node/idx_key_value.yml +10 -10
- data/test/integration/query_node/idx_scope.yml +7 -7
- data/test/integration/query_node/relations.yml +4 -4
- data/test/integration/zafu_compiler/ajax.yml +19 -11
- data/test/integration/zafu_compiler/apphelper.yml +1 -1
- data/test/integration/zafu_compiler/asset.yml +2 -2
- data/test/integration/zafu_compiler/comments.yml +1 -1
- data/test/integration/zafu_compiler/dates.yml +1 -1
- data/test/integration/zafu_compiler/display.yml +49 -21
- data/test/integration/zafu_compiler/eval.yml +4 -4
- data/test/integration/zafu_compiler/forms.yml +25 -11
- data/test/integration/zafu_compiler/i18n.yml +5 -0
- data/test/integration/zafu_compiler/meta.yml +3 -3
- data/test/integration/zafu_compiler/query.yml +27 -9
- data/test/integration/zafu_compiler/relations.yml +9 -9
- data/test/integration/zafu_compiler/roles.yml +6 -6
- data/test/integration/zafu_compiler/rubyless.yml +7 -2
- data/test/integration/zafu_compiler/safe_definitions.yml +33 -4
- data/test/integration/zafu_compiler/security.yml +46 -1
- data/test/integration/zafu_compiler/urls.yml +28 -13
- data/test/integration/zafu_compiler/user.yml +12 -7
- data/test/integration/zafu_compiler/zafu_attributes.yml +1 -1
- data/test/integration/zafu_compiler/zazen.yml +5 -5
- data/test/integration/zafu_compiler_test.rb +18 -0
- data/test/selenium/Filter/filter3.rsel +20 -0
- data/test/selenium/Filter/filter4.rsel +20 -0
- data/test/sites/zena/versions.yml +2 -0
- data/test/unit/exif_data_test.rb +6 -1
- data/test/unit/group_test.rb +18 -3
- data/test/unit/node_test.rb +0 -7
- data/test/unit/project_test.rb +4 -0
- data/test/unit/relation_proxy_test.rb +2 -2
- data/test/unit/remote_test.rb +0 -9
- data/test/unit/role_test.rb +1 -1
- data/test/unit/string_hash_test.rb +1 -1
- data/test/unit/text_document_test.rb +13 -13
- data/test/unit/zena/use/html_tags_test.rb +6 -6
- data/test/unit/zena/use/rendering_test.rb +20 -10
- data/test/unit/zena/use/urls_test.rb +21 -18
- data/test/unit/zena/use/zafu_template_test.rb +0 -5
- data/test/unit/zena/use/zazen_test.rb +25 -25
- data/zena.gemspec +63 -57
- metadata +136 -130
- data/test/functional/nodes_controller_commit_test.rb +0 -67
data/History.txt
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
+
== 1.2.3 2013-03-11
|
2
|
+
|
3
|
+
* Major changes
|
4
|
+
* Better support for Passenger (deploy receipt, asset host)
|
5
|
+
* Support for 'sortable' <== TODO: Document
|
6
|
+
* html_escape all properties by default
|
7
|
+
* Better support for Passenger (default deployment method now)
|
8
|
+
* Simplified caching (using cachestamp in filename)
|
9
|
+
* Added preview='dom_id' to [form]. (Use preview_node to show preview content.) <== TODO: Document
|
10
|
+
* Added "in_group" zafu method on visitor. <== TODO: Document
|
11
|
+
* Added [upload_field] method to zafu to allow custom upload forms. <== TODO: Document
|
12
|
+
* Added support for custom images on nodes with the "img_tag_{mode}" string attribute or the 'img_tag' hash attribute. <== TODO: Document
|
13
|
+
* Added support for tag clouds through sqliss (<r:void do='tag_cloud from nodes in site' do='each' join=', '><r:name/> (<r:link_count/>)</r:void>). <== TODO: Document
|
14
|
+
|
15
|
+
* Minor changes
|
16
|
+
* Support for 'lang_list' when creating vhost file <== TODO: Document
|
17
|
+
* Support for Range in zafu. <== TODO: Document
|
18
|
+
* Added options to query_parse to ignore unwanted parameters <== TODO: Document
|
19
|
+
* Added 'hparams' option to only return Hash parameters from params. <== TODO: Document
|
20
|
+
* Fixed query_parse to convert dates to UTC.
|
21
|
+
* Fixed form preview inside block.
|
22
|
+
* Added unique id to img_tag_{mode} code generated 'UUID'. <== TODO: Document
|
23
|
+
* Added PATH_mode.format and [JS] marker to img_tag_{mode}.
|
24
|
+
* Fixed form preview with long text (use POST).
|
25
|
+
|
1
26
|
== 1.2.2 2012-08-30
|
2
27
|
|
3
28
|
* Major changes
|
@@ -52,30 +52,8 @@ class DocumentsController < ApplicationController
|
|
52
52
|
# Create a document with upload progression (upload in mongrel)
|
53
53
|
def upload
|
54
54
|
create_document
|
55
|
-
|
56
|
-
|
57
|
-
render :update do |page|
|
58
|
-
if @node.new_record?
|
59
|
-
page.replace_html 'form_errors', error_messages_for(:node, :object => @node)
|
60
|
-
page.call 'UploadProgress.setAsError'
|
61
|
-
else
|
62
|
-
page.call 'UploadProgress.setAsFinished'
|
63
|
-
page.delay(1) do # allow the progress bar fade to complete
|
64
|
-
if params[:js]
|
65
|
-
page << params[:js]
|
66
|
-
end
|
67
|
-
if params[:reload]
|
68
|
-
page << "Zena.t().Zena.reload(#{params[:reload].inspect})"
|
69
|
-
end
|
70
|
-
if params[:redir]
|
71
|
-
page << "Zena.reload_and_close(#{params[:redir].inspect})"
|
72
|
-
else
|
73
|
-
page.redirect_to document_url(@node[:zip], :reload => params[:reload], :js => params[:js])
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
55
|
+
|
56
|
+
render_upload
|
79
57
|
end
|
80
58
|
|
81
59
|
def upload_progress
|
@@ -109,7 +87,7 @@ class DocumentsController < ApplicationController
|
|
109
87
|
raise ActiveRecord::RecordNotFound
|
110
88
|
end
|
111
89
|
end
|
112
|
-
|
90
|
+
|
113
91
|
def create_document
|
114
92
|
attrs = params['node']
|
115
93
|
file, error = get_attachment
|
@@ -20,9 +20,13 @@ Examples:
|
|
20
20
|
class NodesController < ApplicationController
|
21
21
|
before_filter :check_is_admin, :only => [:export]
|
22
22
|
before_filter :check_api_group
|
23
|
+
if Bricks.raw_config['passenger']
|
24
|
+
before_filter :escape_path, :only => [:index, :show]
|
25
|
+
end
|
23
26
|
before_filter :find_node, :except => [:index, :create, :not_found, :catch_all, :search]
|
24
27
|
before_filter :check_can_drive, :only => [:edit]
|
25
28
|
before_filter :check_path, :only => [:index, :show]
|
29
|
+
|
26
30
|
layout :popup_layout, :only => [:edit, :import]
|
27
31
|
|
28
32
|
def index
|
@@ -49,7 +53,7 @@ class NodesController < ApplicationController
|
|
49
53
|
query_params_list = []
|
50
54
|
query_params.each do |k,v|
|
51
55
|
next if v.kind_of?(Hash) # FIXME: we should support nested hashes. Can't we use something in rails here ?
|
52
|
-
query_params_list << "#{k}=#{CGI.escape(v)}"
|
56
|
+
query_params_list << "#{k}=#{CGI.escape(v.to_s)}"
|
53
57
|
end
|
54
58
|
redirect_to "/" + ([prefix]+params[:path]).flatten.join('/') + (query_params_list == [] ? '' : "?#{query_params_list.join('&')}")
|
55
59
|
end
|
@@ -170,7 +174,7 @@ class NodesController < ApplicationController
|
|
170
174
|
content_path = @node.asset_path(filename)
|
171
175
|
content_type = (Zena::EXT_TO_TYPE[params[:format]] || ['application/octet-stream'])[0]
|
172
176
|
send_file(content_path, :filename=>filename, :type => content_type, :disposition=>'inline', :x_sendfile => ENABLE_XSENDFILE)
|
173
|
-
cache_page(:content_path => content_path, :authenticated => @node.
|
177
|
+
cache_page(:content_path => content_path, :authenticated => @node.v_public?) # content_path is used to cache by creating a symlink
|
174
178
|
elsif @node.kind_of?(Document) && params[:format] == @node.ext
|
175
179
|
# Get document data (inline if possible)
|
176
180
|
content_path = nil
|
@@ -192,7 +196,8 @@ class NodesController < ApplicationController
|
|
192
196
|
send_file(content_path, :filename => @node.filename, :type => @node.content_type, :disposition => 'inline', :stream => false, :x_sendfile => ENABLE_XSENDFILE)
|
193
197
|
end
|
194
198
|
|
195
|
-
|
199
|
+
# content_path is used to cache by creating a symlink
|
200
|
+
cache_page(:content_path => content_path, :authenticated => @node.v_public?)
|
196
201
|
else
|
197
202
|
render_and_cache
|
198
203
|
# FIXME: redirect to document format should occur in render_and_cache
|
@@ -213,7 +218,7 @@ class NodesController < ApplicationController
|
|
213
218
|
file, file_error = get_attachment
|
214
219
|
if file
|
215
220
|
attrs['file'] = file
|
216
|
-
attrs['klass']
|
221
|
+
attrs['klass'] ||= 'Document'
|
217
222
|
end
|
218
223
|
|
219
224
|
attrs = secure(Node) { Node.transform_attributes(attrs) }
|
@@ -229,6 +234,11 @@ class NodesController < ApplicationController
|
|
229
234
|
end
|
230
235
|
@node.errors.add('file', file_error) if file_error
|
231
236
|
|
237
|
+
if params[Zena::Use::Upload::UPLOAD_KEY]
|
238
|
+
# Respond in parent from iframe.
|
239
|
+
return render_upload
|
240
|
+
end
|
241
|
+
|
232
242
|
respond_to do |format|
|
233
243
|
if @node.errors.empty?
|
234
244
|
flash.now[:notice] = 'Node was successfully created.'
|
@@ -574,6 +584,7 @@ class NodesController < ApplicationController
|
|
574
584
|
# archive-1 ---> fullpath
|
575
585
|
# archive ---> fullpath
|
576
586
|
def find_node
|
587
|
+
|
577
588
|
if path = params[:path]
|
578
589
|
# We do not use params[:path] because Rails does url unescape
|
579
590
|
# and we want to do this ourselves.
|
@@ -592,13 +603,14 @@ class NodesController < ApplicationController
|
|
592
603
|
if path.last =~ Zena::Use::Urls::ALLOWED_REGEXP
|
593
604
|
zip = $3
|
594
605
|
name = $4
|
595
|
-
params[:mode]
|
596
|
-
|
597
|
-
|
598
|
-
|
606
|
+
params[:mode] = $5 == '' ? nil : $5[1..-1]
|
607
|
+
params[:asset] = $6 == '' ? nil : $6[1..-1]
|
608
|
+
stamp_and_format = $7 == '' ? '' : $7[1..-1]
|
609
|
+
if stamp_and_format =~ /(\w+)\.(\w+)/
|
610
|
+
@cachestamp = $1
|
599
611
|
set_format($2)
|
600
612
|
else
|
601
|
-
set_format(
|
613
|
+
set_format(stamp_and_format)
|
602
614
|
end
|
603
615
|
|
604
616
|
# We use the visitor to find the node in order to ease implementation
|
@@ -618,6 +630,15 @@ class NodesController < ApplicationController
|
|
618
630
|
end
|
619
631
|
end
|
620
632
|
|
633
|
+
# Passenger unescapes url before passing it to Rails. We escape it back.
|
634
|
+
# FIXME: Performance: reverse this code (consider unescaped urls the norm and unescape if not using Passenger).
|
635
|
+
def escape_path
|
636
|
+
if params[:path]
|
637
|
+
params[:path].map! {|p| URI.escape(p) }
|
638
|
+
end
|
639
|
+
true
|
640
|
+
end
|
641
|
+
|
621
642
|
def set_format(format)
|
622
643
|
request.instance_eval do
|
623
644
|
parameters[:format] = format
|
@@ -647,37 +668,26 @@ class NodesController < ApplicationController
|
|
647
668
|
end
|
648
669
|
when 'show'
|
649
670
|
|
650
|
-
if params[:format] != 'html' && params[:cachestamp].nil?
|
651
|
-
# maybe not seen, try to find it
|
652
|
-
params.each do |k,v|
|
653
|
-
if k =~ /\A\d+\Z/ && v.nil?
|
654
|
-
params[:cachestamp] = k
|
655
|
-
params.delete(k)
|
656
|
-
break
|
657
|
-
end
|
658
|
-
end
|
659
|
-
end
|
660
|
-
|
661
671
|
if params[:prefix] != prefix && !avoid_prefix_redirect
|
662
672
|
# lang changed
|
663
673
|
set_visitor_lang(params[:prefix])
|
664
674
|
redirect_to zen_path(@node, path_params) and return false
|
665
675
|
end
|
666
676
|
|
667
|
-
current_url =
|
677
|
+
current_url = "/#{params[:prefix]}/#{params[:path].join('/')}"
|
668
678
|
base_url = zen_path(@node,
|
669
679
|
:prefix => params[:prefix],
|
670
680
|
:format => params[:format],
|
671
681
|
:mode => params[:mode],
|
672
682
|
:asset => params[:asset])
|
673
|
-
|
683
|
+
|
674
684
|
if current_url != base_url
|
675
685
|
# Badly formed url, redirect
|
676
686
|
redirect_to zen_path(@node, path_params) and return false
|
677
687
|
end
|
678
|
-
|
688
|
+
|
679
689
|
if should_cachestamp?(@node, params[:format], params[:asset]) &&
|
680
|
-
|
690
|
+
@cachestamp != make_cachestamp(@node, params[:mode])
|
681
691
|
# Invalid cachestamp, redirect
|
682
692
|
redirect_to zen_path(@node, path_params) and return false
|
683
693
|
end
|
@@ -3,7 +3,8 @@
|
|
3
3
|
Create, destroy sessions by letting users login and logout. When the user does not login, he/she is considered to be the anonymous user.
|
4
4
|
=end
|
5
5
|
class UserSessionsController < ApplicationController
|
6
|
-
skip_before_filter :set_after_login, :force_authentication
|
6
|
+
skip_before_filter :set_after_login, :force_authentication?, :redirect_to_https
|
7
|
+
before_filter :session_redirect_to_https
|
7
8
|
|
8
9
|
# /login
|
9
10
|
def new
|
@@ -33,9 +34,9 @@ class UserSessionsController < ApplicationController
|
|
33
34
|
@user_session.destroy
|
34
35
|
reset_session
|
35
36
|
#flash.now[:notice] = _("Successfully logged out.")
|
36
|
-
redirect_to "http://#{current_site.host}#{
|
37
|
+
redirect_to "http://#{current_site.host}#{params[:redirect] || home_path(:prefix => prefix)}"
|
37
38
|
else
|
38
|
-
redirect_to "http://#{current_site.host}#{
|
39
|
+
redirect_to "http://#{current_site.host}#{home_path(:prefix => prefix)}"
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
@@ -55,7 +56,7 @@ class UserSessionsController < ApplicationController
|
|
55
56
|
end
|
56
57
|
|
57
58
|
# Overwrite redirect on https rules for this controller
|
58
|
-
def
|
59
|
+
def session_redirect_to_https
|
59
60
|
if params[:action] == 'destroy'
|
60
61
|
# ignore
|
61
62
|
else
|
@@ -89,29 +89,56 @@ class VersionsController < ApplicationController
|
|
89
89
|
end
|
90
90
|
|
91
91
|
# TODO: test/improve or remove (experiments)
|
92
|
+
# https://github.com/samg/diffy
|
92
93
|
def diff
|
93
|
-
|
94
|
-
|
94
|
+
if false
|
95
|
+
# FULL PAGE DIFF
|
96
|
+
|
97
|
+
# Render with source
|
98
|
+
source_html = render_and_cache :as_string => true
|
99
|
+
|
100
|
+
# target
|
101
|
+
if params[:to].to_i > 0
|
102
|
+
version = secure!(Version) { Version.find(:first, :conditions => ['node_id = ? AND number = ?', @node.id, params[:to]])}
|
103
|
+
# Reload prop
|
104
|
+
@node.prop = version.prop
|
105
|
+
else
|
106
|
+
# default
|
107
|
+
@node.instance_variable_set(:@version, nil)
|
108
|
+
end
|
95
109
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
110
|
+
# Render with target
|
111
|
+
target_html = render_and_cache :as_string => true
|
112
|
+
|
113
|
+
result = Differ.diff_by_word(target_html, source_html).format_as(:html)
|
114
|
+
|
115
|
+
render :inline => result # Broken because Differ does not understand html...
|
100
116
|
else
|
101
|
-
#
|
102
|
-
@node.instance_variable_set(:@version, nil)
|
103
|
-
end
|
104
|
-
target = @node.prop
|
117
|
+
# PROP DIFF
|
105
118
|
|
106
|
-
|
119
|
+
# source
|
120
|
+
source = @node.version.prop
|
107
121
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
122
|
+
# target
|
123
|
+
if params[:to].to_i > 0
|
124
|
+
version = secure!(Version) { Version.find(:first, :conditions => ['node_id = ? AND number = ?', @node.id, params[:to]])}
|
125
|
+
@node.version = version
|
126
|
+
else
|
127
|
+
# default
|
128
|
+
@node.instance_variable_set(:@version, nil)
|
129
|
+
end
|
130
|
+
target = @node.prop
|
131
|
+
|
132
|
+
keys = (target.keys + source.keys).uniq
|
113
133
|
|
114
|
-
|
134
|
+
keys.each do |k|
|
135
|
+
target[k] = Differ.diff_by_word(
|
136
|
+
target[k] || '',
|
137
|
+
source[k] || '').format_as(:html).gsub(/(\s+)<\/del>/, '</del>\1')
|
138
|
+
end
|
139
|
+
|
140
|
+
show
|
141
|
+
end
|
115
142
|
end
|
116
143
|
|
117
144
|
# preview when editing node
|
data/app/models/acl.rb
CHANGED
@@ -15,7 +15,7 @@ class Acl < ActiveRecord::Base
|
|
15
15
|
include RubyLess
|
16
16
|
|
17
17
|
safe_method :params => Zena::Use::ZafuSafeDefinitions::ParamsDictionary
|
18
|
-
safe_method :asset_host?
|
18
|
+
safe_method :asset_host? => {:class => Boolean, :method => 'visitor.asset_host?'}
|
19
19
|
safe_method :visitor => User
|
20
20
|
|
21
21
|
def safe_method_type(signature, receiver = nil)
|
@@ -45,11 +45,6 @@ class Acl < ActiveRecord::Base
|
|
45
45
|
@exec_skin ||= secure(Skin) { Skin.find(exec_skin_id) }
|
46
46
|
end
|
47
47
|
|
48
|
-
# Returns true if we are on the asset host.
|
49
|
-
def asset_host?
|
50
|
-
@asset_host
|
51
|
-
end
|
52
|
-
|
53
48
|
# Make visitor public so that we can use 'visitor' in queries.
|
54
49
|
def visitor
|
55
50
|
super
|
@@ -76,7 +71,7 @@ class Acl < ActiveRecord::Base
|
|
76
71
|
def make_query(node, params = {}, request = nil)
|
77
72
|
@node = node
|
78
73
|
@params = params
|
79
|
-
|
74
|
+
|
80
75
|
query_str = safe_eval(self.query)
|
81
76
|
|
82
77
|
# We add a stupid order clause to avoid the 'order by title' thing.
|
data/app/models/group.rb
CHANGED
@@ -50,7 +50,11 @@ class Group < ActiveRecord::Base
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def user_ids=(list)
|
53
|
-
|
53
|
+
if public_group? || site_group?
|
54
|
+
# ignore
|
55
|
+
else
|
56
|
+
@defined_user_ids = list
|
57
|
+
end
|
54
58
|
end
|
55
59
|
|
56
60
|
alias o_users users
|
@@ -92,7 +96,7 @@ class Group < ActiveRecord::Base
|
|
92
96
|
# Public and admin groups are special. They cannot be destroyed.
|
93
97
|
def check_can_destroy
|
94
98
|
# do not destroy admin or public groups
|
95
|
-
raise Zena::AccessViolation.new("'admin', '
|
99
|
+
raise Zena::AccessViolation.new("'admin', 'logged-in' or 'public' groups cannot be destroyed") if visitor.site.protected_group_ids.include?( id )
|
96
100
|
return can_destroy?
|
97
101
|
end
|
98
102
|
|
data/app/models/link.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
class Link < ActiveRecord::Base
|
2
|
+
include Zena::Use::QueryLink::ModelMethods
|
3
|
+
|
2
4
|
include RubyLess
|
3
5
|
safe_attribute :status, :comment, :date
|
6
|
+
# Used in tag cloud
|
7
|
+
safe_method :name => String
|
8
|
+
safe_method :link_count => Number
|
4
9
|
|
5
10
|
attr_reader :relation
|
6
11
|
attr_accessor :start, :side
|
@@ -118,4 +123,13 @@ class Link < ActiveRecord::Base
|
|
118
123
|
def role
|
119
124
|
relation_proxy.other_role
|
120
125
|
end
|
126
|
+
|
127
|
+
# Used by tags
|
128
|
+
def name
|
129
|
+
comment
|
130
|
+
end
|
131
|
+
|
132
|
+
def link_count
|
133
|
+
read_attribute('link_count') || 0
|
134
|
+
end
|
121
135
|
end
|
data/app/models/node.rb
CHANGED
@@ -1487,8 +1487,8 @@ class Node < ActiveRecord::Base
|
|
1487
1487
|
export_keys[:dates].each do |k, v|
|
1488
1488
|
hash[k] = visitor.tz.utc_to_local(v).strftime("%Y-%m-%d %H:%M:%S")
|
1489
1489
|
end
|
1490
|
-
|
1491
|
-
hash.merge!('class' => self.klass)
|
1490
|
+
|
1491
|
+
hash.merge!('class' => self.klass, 'position' => self.position)
|
1492
1492
|
hash.to_yaml
|
1493
1493
|
end
|
1494
1494
|
|
data/app/models/site.rb
CHANGED
@@ -50,6 +50,9 @@ class Site < ActiveRecord::Base
|
|
50
50
|
['nodes' , 'site_id = ?'],
|
51
51
|
]
|
52
52
|
ACTIONS = %w{clear_cache rebuild_index}
|
53
|
+
PUBLIC_PATH = Bricks.raw_config['public_path'] || '/public'
|
54
|
+
CACHE_PATH = Bricks.raw_config['cache_path'] || '/public'
|
55
|
+
|
53
56
|
include RubyLess
|
54
57
|
safe_method :host => String, :lang_list => [String], :default_lang => String
|
55
58
|
safe_method :root => Proc.new {|h, r, s| {:method => 'root_node', :class => VirtualClass['Project'], :nil => true}}
|
@@ -136,8 +139,8 @@ class Site < ActiveRecord::Base
|
|
136
139
|
editors.users << admin_user
|
137
140
|
|
138
141
|
# create site group
|
139
|
-
sgroup = site.send(:secure,Group) { Group.create( :name => '
|
140
|
-
raise Exception.new("Could not create
|
142
|
+
sgroup = site.send(:secure,Group) { Group.create( :name => 'logged-in') }
|
143
|
+
raise Exception.new("Could not create logged-in group for site [#{host}] (site#{site[:id]})\n#{sgroup.errors.map{|k,v| "[#{k}] #{v}"}.join("\n")}") if sgroup.new_record?
|
141
144
|
|
142
145
|
site.public_group_id = pub[:id]
|
143
146
|
site.site_group_id = sgroup[:id]
|
@@ -231,7 +234,13 @@ class Site < ActiveRecord::Base
|
|
231
234
|
# If you need to serve from another directory, we do not store the path into the sites table
|
232
235
|
# for security reasons. The easiest way around this limitation is to symlink the 'public' directory.
|
233
236
|
def public_path
|
234
|
-
"/#{self[:host]}
|
237
|
+
"/#{self[:host]}#{PUBLIC_PATH}"
|
238
|
+
end
|
239
|
+
|
240
|
+
# This is the place where cached files should be stored in case we do not want
|
241
|
+
# to store the cached file inside the public directory.
|
242
|
+
def cache_path
|
243
|
+
"/#{self[:host]}#{CACHE_PATH}"
|
235
244
|
end
|
236
245
|
|
237
246
|
# Return path for documents data: RAILS_ROOT/sites/_host_/data
|
@@ -374,7 +383,7 @@ class Site < ActiveRecord::Base
|
|
374
383
|
end
|
375
384
|
|
376
385
|
def clear_cache(clear_zafu = true)
|
377
|
-
path = "#{SITES_ROOT}#{self.
|
386
|
+
path = "#{SITES_ROOT}#{self.cache_path}"
|
378
387
|
Site.logger.error("\n-----------------\nCLEAR CACHE FOR SITE #{host}\n-----------------\n")
|
379
388
|
|
380
389
|
if File.exist?(path)
|
data/app/models/text_document.rb
CHANGED
@@ -15,7 +15,7 @@ class TextDocument < Document
|
|
15
15
|
class << self
|
16
16
|
# Return true if a new text document can be created with the content_type. Used by the superclass Document to choose the corret subclass when creating a new object.
|
17
17
|
def accept_content_type?(content_type)
|
18
|
-
(content_type =~ /(^text|^image\/svg\+xml|
|
18
|
+
(content_type =~ /(^text|^image\/svg\+xml|javascript)/) &&
|
19
19
|
(Zena::TYPE_TO_EXT[content_type.chomp] != ['rtf'])
|
20
20
|
end
|
21
21
|
|
data/app/models/user.rb
CHANGED
@@ -24,7 +24,7 @@ things they can/cannot do :
|
|
24
24
|
TODO: when a user is 'destroyed', pass everything he owns to another user or just mark the user as 'deleted'...
|
25
25
|
=end
|
26
26
|
class User < ActiveRecord::Base
|
27
|
-
attr_accessor :zafu_cache
|
27
|
+
attr_accessor :zafu_cache, :asset_host
|
28
28
|
|
29
29
|
include Property
|
30
30
|
RESCUE_SKIN_ID = -1
|
@@ -66,7 +66,7 @@ class User < ActiveRecord::Base
|
|
66
66
|
safe_attribute :login, :time_zone, :created_at, :updated_at, :lang, :id
|
67
67
|
safe_method :initials => String, :status => Number, :status_name => String,
|
68
68
|
:is_anon? => Boolean, :is_admin? => Boolean, :user? => Boolean, :commentator? => Boolean,
|
69
|
-
:moderated? => Boolean
|
69
|
+
:moderated? => Boolean, :asset_host? => Boolean, [:in_group?, String] => Boolean
|
70
70
|
|
71
71
|
safe_context :node => node_user_proc,
|
72
72
|
:to_publish => ['Version'], :redactions => ['Version'], :proposed => ['Version'],
|
@@ -215,6 +215,15 @@ class User < ActiveRecord::Base
|
|
215
215
|
# tested in site_test
|
216
216
|
user_site.anon_id == self[:id] && (!new_record? || self[:login].nil?) # (when creating a new site, anon_id == nil)
|
217
217
|
end
|
218
|
+
|
219
|
+
# This is set on the user during login.
|
220
|
+
alias asset_host? asset_host
|
221
|
+
|
222
|
+
def in_group?(name)
|
223
|
+
@group_names ||= begin
|
224
|
+
groups.all(:order=>'name').map(&:name)
|
225
|
+
end.include?(name)
|
226
|
+
end
|
218
227
|
|
219
228
|
# Return true if the user's status is high enough to start editing nodes.
|
220
229
|
def user?
|
data/app/models/virtual_class.rb
CHANGED
@@ -597,7 +597,7 @@ class VirtualClass < Role
|
|
597
597
|
Zena::Db.execute "UPDATE roles SET kpath = '#{new_kpath}' WHERE kpath = '#{old_kpath}' AND site_id = #{current_site.id} AND (type = 'Role' or type IS NULL)"
|
598
598
|
# ========================================= Update templates
|
599
599
|
idx_templates = IdxTemplate.all(
|
600
|
-
:conditions => ['tkpath = ? AND site_id = ?', old_kpath, site_id]
|
600
|
+
:conditions => ['tkpath = ? AND site_id = ? AND node_id IS NOT NULL', old_kpath, site_id]
|
601
601
|
)
|
602
602
|
|
603
603
|
if !idx_templates.empty?
|
@@ -33,12 +33,12 @@
|
|
33
33
|
<tr><td class='label'><%= _('replace by') %></td><td><%= select('group', 'replace_by', @groups.map{|g| [g[:name], g[:id]]} , {:include_blank => true}) %></td></tr>
|
34
34
|
<% end -%>
|
35
35
|
<tr>
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
36
|
+
<td class='label'><%= _('auto_publish') %></td>
|
37
|
+
<td>
|
38
|
+
<input type='hidden' name='group[auto_publish]' value=''/>
|
39
|
+
<input type='checkbox' name='group[auto_publish]' value='1'<%= @group.auto_publish? ? " checked='checked'" : '' %>/> <%= _('auto_publish') %>
|
40
|
+
</td>
|
41
|
+
</tr>
|
42
42
|
<tr><td colspan='2'><input type='submit' class='btn_validate' value='<%= _('validate') %>'/></td></tr>
|
43
43
|
</table>
|
44
44
|
</form>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
|
4
|
+
<html lang='en' xmlns='http://www.w3.org/1999/xhtml'>
|
5
|
+
<head>
|
6
|
+
<title>500 Error</title>
|
7
|
+
</head>
|
8
|
+
|
9
|
+
<body style='font-family:Helvetica, Arial, sans-serif; background:#eee;'>
|
10
|
+
<!-- The zena_error500 is used we running automated tests. Do not change -->
|
11
|
+
<div id='zena_error500' style='display:table; margin:50px auto; background:#aaa; height:200px; width:600px; border:1px solid black; border-radius:8px;'>
|
12
|
+
<%= @render_error %>
|
13
|
+
</div>
|
14
|
+
</body>
|
15
|
+
</html>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<%= upload_form_tag(:action => 'upload') %>
|
2
2
|
<%= hidden_field 'node', 'parent_id', :value=>@node.parent_zip %>
|
3
3
|
<% [:redir, :js, :reload].each do |p|; next unless params[p] %>
|
4
|
-
<input type='hidden' name='<%= p %>' value='<%=
|
4
|
+
<input type='hidden' name='<%= p %>' value='<%=h params[p] %>'/>
|
5
5
|
<% end %>
|
6
6
|
<p class="btn_validate"><input type="submit" value='<%= _('validate') %>'/></p>
|
7
7
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<%= upload_form_tag( :controller => 'nodes', :action => 'import', :id => @node.parent_zip ) %>
|
2
2
|
<p class="btn_validate"><input type="submit" value='<%= _('validate') %>'/></p>
|
3
3
|
<% [:redir, :js, :reload].each do |p|; next unless params[p] %>
|
4
|
-
<input type='hidden' name='<%= p %>' value='<%=
|
4
|
+
<input type='hidden' name='<%= p %>' value='<%=h params[p] %>'/>
|
5
5
|
<% end %>
|
6
6
|
|
7
7
|
<%= upload_field %>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<%= hidden_field 'node', 'parent_id', :value => @node.parent_zip %>
|
3
3
|
<p class="btn_validate"><input type="submit" onclick="$('loader').style.visibility = 'visible';" value='<%= _('validate') %>'/></p>
|
4
4
|
<% [:redir, :js, :reload].each do |p|; next unless params[p] %>
|
5
|
-
<input type='hidden' name='<%= p %>' value='<%=
|
5
|
+
<input type='hidden' name='<%= p %>' value='<%=h params[p] %>'/>
|
6
6
|
<% end %>
|
7
7
|
|
8
8
|
<input type='hidden' name='node[klass]' value='Template'/>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<%= hidden_field 'node', 'parent_id', :value=>@node.parent_zip %>
|
3
3
|
<p class="btn_validate"><input type="submit" onclick="$('loader').style.visibility = 'visible';" value='<%= _('validate') %>'/></p>
|
4
4
|
<% [:redir, :js, :reload].each do |p|; next unless params[p] %>
|
5
|
-
<input type='hidden' name='<%= p %>' value='<%=
|
5
|
+
<input type='hidden' name='<%= p %>' value='<%=h params[p] %>'/>
|
6
6
|
<% end %>
|
7
7
|
|
8
8
|
<label for='node_content_type'><%= _('content type') %></label>
|
@@ -7,7 +7,7 @@
|
|
7
7
|
<label for='v_lang'><%= _("language") %></label>
|
8
8
|
<% if @node.vclass.monolingual?
|
9
9
|
if @node.new_record?
|
10
|
-
|
10
|
+
selected = current_site.default_lang
|
11
11
|
else
|
12
12
|
selected = @node.v_lang == visitor.lang ? @node.v_lang : current_site.default_lang
|
13
13
|
end
|
@@ -88,7 +88,7 @@
|
|
88
88
|
<div id='form' do='form'>
|
89
89
|
<r:if test='can_edit?' do='default' label='t'>
|
90
90
|
<r:input type='submit'/>
|
91
|
-
<input type='hidden' name='redir' value='#{path(this, :mode
|
91
|
+
<input type='hidden' name='redir' value='#{path(this, :mode => "admin")}'/>
|
92
92
|
<div do='vclass' do='roles'>
|
93
93
|
<fieldset do='each'>
|
94
94
|
<legend do='name'/>
|
@@ -16,7 +16,7 @@ class AclIntegrationTest < Zena::Integration::TestCase
|
|
16
16
|
should 'find nodes' do
|
17
17
|
get "http://erebus.host/oo/project#{nodes_zip(:over_zeus)}.html"
|
18
18
|
assert_response :success
|
19
|
-
assert_match %r{there is
|
19
|
+
assert_match %r{there is "A plan to overrule Zeus"}, response.body
|
20
20
|
end
|
21
21
|
end # with normal access
|
22
22
|
|
@@ -48,7 +48,7 @@ class AclIntegrationTest < Zena::Integration::TestCase
|
|
48
48
|
|
49
49
|
should 'render with forced skin' do
|
50
50
|
get "http://erebus.host/oo/project#{nodes_zip(:queen)}.html"
|
51
|
-
assert_match %r{you can see
|
51
|
+
assert_match %r{you can see "My Queen"}, response.body
|
52
52
|
end
|
53
53
|
|
54
54
|
should 'find items in view with exec_group' do
|
@@ -61,7 +61,8 @@ class AclTest < Zena::Unit::TestCase
|
|
61
61
|
end
|
62
62
|
assert subject.update_attributes(:query => "'nodes where 1 = \#{asset_host? ? 1 : 0} in site'")
|
63
63
|
assert_nil subject.authorize?(base_node, {:id => nodes_zip(:over_zeus)}, mock_request)
|
64
|
-
|
64
|
+
visitor.asset_host = true
|
65
|
+
assert_equal 'A plan to overrule Zeus', subject.authorize?(base_node, {:id => nodes_zip(:over_zeus)}, mock_request).title
|
65
66
|
end
|
66
67
|
end # saving an acl with asset_host in query
|
67
68
|
|