zena 1.2.3 → 1.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +29 -1
- data/Rakefile +0 -1
- data/app/controllers/documents_controller.rb +1 -1
- data/app/controllers/nodes_controller.rb +34 -8
- data/app/controllers/sites_controller.rb +8 -1
- data/app/controllers/user_sessions_controller.rb +13 -3
- data/app/models/acl.rb +16 -0
- data/app/models/document.rb +33 -14
- data/app/models/idx_nodes_integer.rb +5 -0
- data/app/models/image.rb +16 -4
- data/app/models/node.rb +16 -3
- data/app/models/relation_proxy.rb +3 -3
- data/app/models/site.rb +11 -1
- data/app/models/string_hash.rb +1 -1
- data/app/models/template.rb +1 -1
- data/app/models/user.rb +6 -1
- data/app/models/virtual_class.rb +36 -1
- data/app/views/acls/_form.rhtml +5 -1
- data/app/views/acls/_li.rhtml +1 -1
- data/app/views/templates/document_create_tabs/_file.rhtml +1 -0
- data/app/views/templates/document_create_tabs/_template.rhtml +1 -1
- data/app/views/users/_form.rhtml +1 -0
- data/app/views/virtual_classes/_form.erb +8 -7
- data/bricks/acls/lib/bricks/acls.rb +43 -15
- data/bricks/acls/zena/migrate/20130313110443_add_create_kpath_to_acl.rb +13 -0
- data/bricks/acls/zena/migrate/20130429073432_fix_create_kpath_default.rb +8 -0
- data/bricks/acls/zena/test/integration/acl_integration_test.rb +53 -1
- data/bricks/acls/zena/test/sites/erebus/acls.yml +21 -0
- data/bricks/acls/zena/test/unit/acl_test.rb +35 -2
- data/bricks/math/lib/bricks/math.rb +1 -1
- data/bricks/sphinx/zena/tasks.rb +1 -1
- data/bricks/spreadsheet/lib/bricks/spreadsheet.rb +1 -1
- data/bricks/worker/zena/worker +25 -0
- data/config/environment.rb +1 -1
- data/config/environments/production.rb +1 -1
- data/config/gems.yml +6 -5
- data/lib/bricks/requirements_validation.rb +1 -1
- data/lib/log_recorder/lib/log_recorder.rb +1 -1
- data/lib/tasks/zena.rake +10 -2
- data/lib/zena.rb +4 -3
- data/lib/zena/app.rb +1 -0
- data/lib/zena/deploy/httpd.rhtml +2 -2
- data/lib/zena/deploy/template.rb +15 -5
- data/lib/zena/info.rb +1 -1
- data/lib/zena/parser/zazen_rules.rb +9 -2
- data/lib/zena/remote/connection.rb +2 -2
- data/lib/zena/remote/interface.rb +8 -2
- data/lib/zena/remote/node.rb +1 -1
- data/lib/zena/routes.rb +2 -1
- data/lib/zena/use/action.rb +8 -2
- data/lib/zena/use/ajax.rb +31 -20
- data/lib/zena/use/calendar.rb +2 -0
- data/lib/zena/use/conditional.rb +15 -14
- data/lib/zena/use/dates.rb +5 -2
- data/lib/zena/use/display.rb +3 -2
- data/lib/zena/use/forms.rb +36 -9
- data/lib/zena/use/i18n.rb +8 -2
- data/lib/zena/use/image_builder.rb +7 -0
- data/lib/zena/use/query_node.rb +24 -8
- data/lib/zena/use/relations.rb +2 -6
- data/lib/zena/use/rendering.rb +10 -6
- data/lib/zena/use/upload.rb +6 -4
- data/lib/zena/use/urls.rb +13 -5
- data/lib/zena/use/zafu_safe_definitions.rb +1 -1
- data/public/javascripts/grid.js +11 -2
- data/public/javascripts/upload-progress.js +5 -3
- data/public/javascripts/zena.js +6 -2
- data/public/stylesheets/upload-progress.css +1 -0
- data/test/fixtures/files/TestNode.zafu +2 -2
- data/test/fixtures/files/translations_fr.yml +2 -1
- data/test/functional/acls_controller_test.rb +6 -0
- data/test/functional/nodes_controller_test.rb +1 -1
- data/test/functional/sites_controller_test.rb +19 -0
- data/test/integration/navigation_test.rb +7 -0
- data/test/integration/query_node/filters.yml +10 -0
- data/test/integration/zafu_compiler/action.yml +8 -4
- data/test/integration/zafu_compiler/ajax.yml +4 -4
- data/test/integration/zafu_compiler/calendar.yml +8 -15
- data/test/integration/zafu_compiler/context.yml +1 -1
- data/test/integration/zafu_compiler/dates.yml +5 -1
- data/test/integration/zafu_compiler/display.yml +1 -2
- data/test/integration/zafu_compiler/forms.yml +37 -10
- data/test/integration/zafu_compiler/query.yml +5 -5
- data/test/integration/zafu_compiler/relations.yml +8 -8
- data/test/integration/zafu_compiler/safe_definitions.yml +7 -2
- data/test/integration/zafu_compiler/urls.yml +24 -3
- data/test/integration/zafu_compiler/zazen.yml +9 -1
- data/test/selenium/Destroy/destroy1.rsel +2 -1
- data/test/selenium/Destroy/destroy2.rsel +17 -0
- data/test/unit/document_test.rb +17 -4
- data/test/unit/relation_proxy_test.rb +19 -8
- data/test/unit/string_hash_test.rb +1 -1
- data/test/unit/template_test.rb +3 -3
- data/test/unit/virtual_class_test.rb +77 -0
- data/test/unit/zena/use/urls_test.rb +9 -1
- data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails_config.rb +1 -1
- data/zena.gemspec +60 -53
- metadata +145 -125
@@ -70,7 +70,7 @@ class RelationProxy < Relation
|
|
70
70
|
# get
|
71
71
|
|
72
72
|
def other_link
|
73
|
-
other_links ? other_links
|
73
|
+
other_links ? other_links.first : nil
|
74
74
|
end
|
75
75
|
|
76
76
|
def other_id
|
@@ -100,9 +100,9 @@ class RelationProxy < Relation
|
|
100
100
|
}.merge(opts)
|
101
101
|
@records = secure(Node) { Node.find(:all, options) }
|
102
102
|
end
|
103
|
-
|
103
|
+
|
104
104
|
LINK_ATTRIBUTES.each do |sym|
|
105
|
-
define_method(sym) do
|
105
|
+
define_method(:"other_#{sym}") do
|
106
106
|
other_link ? other_link[sym] : nil
|
107
107
|
end
|
108
108
|
end
|
data/app/models/site.rb
CHANGED
@@ -470,9 +470,19 @@ class Site < ActiveRecord::Base
|
|
470
470
|
# unpublished templates).
|
471
471
|
def rebuild_index(nodes = nil, page = nil, page_count = nil)
|
472
472
|
if !page
|
473
|
-
Site.logger.error("\n----------------- REBUILD INDEX FOR SITE #{host} -----------------\n")
|
474
473
|
Zena::SiteWorker.perform(self, :rebuild_index)
|
475
474
|
else
|
475
|
+
if page == 1
|
476
|
+
Site.logger.error("\n----------------- REBUILD INDEX FOR SITE #{host} -----------------\n")
|
477
|
+
# Reset reference to cache origin to make sure it is always overwritten
|
478
|
+
Zena::Use::ScopeIndex::AVAILABLE_MODELS.each do |klass|
|
479
|
+
changes = klass.column_names.select{|n| n =~ %r{(.*)_id}}.reject {|n| %w{node_id site_id}.include?(n)}.map do |c|
|
480
|
+
"#{c} = NULL"
|
481
|
+
end.join(', ')
|
482
|
+
Site.logger.error("#{klass.name}: reset #{changes}\n")
|
483
|
+
Zena::Db.execute "UPDATE #{klass.table_name} SET #{changes} WHERE site_id = #{id}"
|
484
|
+
end
|
485
|
+
end
|
476
486
|
# do things
|
477
487
|
nodes.each do |node|
|
478
488
|
node.rebuild_index!
|
data/app/models/string_hash.rb
CHANGED
data/app/models/template.rb
CHANGED
data/app/models/user.rb
CHANGED
@@ -340,7 +340,7 @@ class User < ActiveRecord::Base
|
|
340
340
|
end
|
341
341
|
end
|
342
342
|
|
343
|
-
def find_node(path, zip, name, request)
|
343
|
+
def find_node(path, zip, name, request, need_write = false)
|
344
344
|
secure!(Node) do
|
345
345
|
if name =~ /^\d+$/
|
346
346
|
Node.find_by_zip(name)
|
@@ -397,6 +397,11 @@ class User < ActiveRecord::Base
|
|
397
397
|
if login.blank? && !is_anon?
|
398
398
|
self.login = name
|
399
399
|
end
|
400
|
+
|
401
|
+
if !is_admin?
|
402
|
+
# Make sure we remove dev_skin settings if user is not an admin.
|
403
|
+
self[:dev_skin_id] = nil
|
404
|
+
end
|
400
405
|
end
|
401
406
|
|
402
407
|
# Validates that anon user does not have a login, that other users have a password
|
data/app/models/virtual_class.rb
CHANGED
@@ -34,7 +34,7 @@ class VirtualClass < Role
|
|
34
34
|
attr_accessor :export_attributes
|
35
35
|
end
|
36
36
|
|
37
|
-
self.export_attributes = %w{auto_create_discussion icon monolingual}
|
37
|
+
self.export_attributes = %w{auto_create_discussion icon monolingual content_type}
|
38
38
|
|
39
39
|
attr_accessor :import_result
|
40
40
|
belongs_to :create_group, :class_name => 'Group', :foreign_key => 'create_group_id'
|
@@ -52,7 +52,10 @@ class VirtualClass < Role
|
|
52
52
|
include Zena::Use::ScopeIndex::VirtualClassMethods
|
53
53
|
|
54
54
|
property.boolean 'monolingual'
|
55
|
+
property.text 'content_type'
|
56
|
+
|
55
57
|
safe_method :monolingual? => Boolean
|
58
|
+
safe_method :content_type => String
|
56
59
|
safe_method :roles => {:class => ['Role'], :method => 'sorted_roles'}
|
57
60
|
safe_method :relations => {:class => ['RelationProxy'], :method => 'all_relations'}
|
58
61
|
safe_method [:relations, String] => {:class => ['RelationProxy'], :method => 'filtered_relations'}
|
@@ -68,6 +71,17 @@ class VirtualClass < Role
|
|
68
71
|
end
|
69
72
|
end
|
70
73
|
|
74
|
+
# Class path hierarchy. Example for (Post) : N, NN, NNP
|
75
|
+
def self.split_kpath(kpath)
|
76
|
+
parts = []
|
77
|
+
kpath.split(//).each_index { |i| parts << kpath[0..i] }
|
78
|
+
parts
|
79
|
+
end
|
80
|
+
|
81
|
+
def split_kpath
|
82
|
+
@split_kpath ||= VirtualClass.split_kpath(kpath)
|
83
|
+
end
|
84
|
+
|
71
85
|
class Cache
|
72
86
|
def initialize
|
73
87
|
clear_cache!
|
@@ -240,6 +254,7 @@ class VirtualClass < Role
|
|
240
254
|
attribute = opts[:class_attr] || 'name'
|
241
255
|
|
242
256
|
VirtualClass.all_classes(base_kpath, opts[:without]).map do |vclass|
|
257
|
+
# Only insert allowed classes.
|
243
258
|
if vclass.create_group_id.nil? || group_ids.include?(vclass.create_group_id)
|
244
259
|
# white spaces are insecable spaces (not ' ')
|
245
260
|
a, b = vclass.kpath, vclass.name
|
@@ -249,6 +264,15 @@ class VirtualClass < Role
|
|
249
264
|
end
|
250
265
|
end.compact
|
251
266
|
end
|
267
|
+
|
268
|
+
def sub_classes
|
269
|
+
@sub_classes ||= VirtualClass.all_classes(self.kpath).sort {|a,b| a.name <=> b.name}
|
270
|
+
end
|
271
|
+
|
272
|
+
def content_type_re
|
273
|
+
# if content_type is empty => match all
|
274
|
+
@content_type_re ||= %r{^#{content_type || ".*"}$}
|
275
|
+
end
|
252
276
|
|
253
277
|
# Include all roles into the this schema. By including the superclass
|
254
278
|
# and all roles related to this class.
|
@@ -579,6 +603,17 @@ class VirtualClass < Role
|
|
579
603
|
unless self[:real_class]
|
580
604
|
errors.add('superclass', 'invalid')
|
581
605
|
end
|
606
|
+
|
607
|
+
if content_type =~ /[^a-zA-Z\.\-\/\*\|\\]/
|
608
|
+
errors.add('content_type', 'invalid characters')
|
609
|
+
else
|
610
|
+
begin
|
611
|
+
re = %r{^#{content_type}$}
|
612
|
+
rescue RegexpError => err
|
613
|
+
errors.add('content_type', err.message)
|
614
|
+
end
|
615
|
+
end
|
616
|
+
|
582
617
|
end
|
583
618
|
|
584
619
|
def get_real_class(klass)
|
data/app/views/acls/_form.rhtml
CHANGED
@@ -21,7 +21,11 @@
|
|
21
21
|
</tr>
|
22
22
|
<tr>
|
23
23
|
<td class='label'><%= _('action')%> <%= help(_('acl_action_help')) %></td>
|
24
|
-
<td
|
24
|
+
<td>
|
25
|
+
<%= select('acl', 'action', Acl::ACTIONS ) %>
|
26
|
+
|
27
|
+
<%= _('create only: allow') %> <%= select('acl', 'create_kpath', Node.kpaths_for_form ) %>
|
28
|
+
</td>
|
25
29
|
</tr>
|
26
30
|
<tr class='priority'>
|
27
31
|
<td class='label'><%= _('priority')%> <%= help(_('acl_priority_help')) %></td>
|
data/app/views/acls/_li.rhtml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
<tr id='acl<%= li[:id] %>'>
|
2
2
|
<td class="adm_icon"><%= link_to_remote( _("img_acl"), :update=>"acl#{li[:id]}", :url=>edit_acl_path(li), :method=>:get) %></td>
|
3
3
|
<td class='group'><%= li.group.name %></td>
|
4
|
-
<td class='act'><%= li.action %></td>
|
4
|
+
<td class='act'><%= li.action %><% if li.action == 'create' %> <span class='constant'><%= li.create_vclass_name %></span><% end %></td>
|
5
5
|
<td class='name'><%= li.name %></td>
|
6
6
|
<td class='mode'><%= li.mode %></td>
|
7
7
|
<td class='format'><%= li.format %></td>
|
@@ -11,7 +11,7 @@
|
|
11
11
|
<input id='title' type='text' name='node[title]'/><br/>
|
12
12
|
|
13
13
|
<label for='node_target_klass'><%= _('class scope') %></label>
|
14
|
-
<%= select('node', 'target_klass', Node.classes_for_form, {:include_blank => true} ) %><br/>
|
14
|
+
<%= select('node', 'target_klass', Node.classes_for_form, {:include_blank => true}, {} ) %><br/>
|
15
15
|
|
16
16
|
<label for='node_mode'><%= _('mode') %></label>
|
17
17
|
<input id='node_mode' type='text' name='node[mode]'/><br/>
|
data/app/views/users/_form.rhtml
CHANGED
@@ -23,6 +23,7 @@
|
|
23
23
|
<% end -%>
|
24
24
|
<% end -%>
|
25
25
|
<tr><td class='label'><%= _("status")%> </td><td><%= select('user', 'status', User::Status.reject {|k,v| v > User::Status[:admin]}.map{|k,v| [_(k.to_s),v]}.sort{|a,b| b[1] <=> a[1]}) %></td></tr>
|
26
|
+
<tr><td class='label'><%= _("single_access_token")%> </td><td><%= @user.single_access_token %></td></tr>
|
26
27
|
<tr><td class='label'><%= _('language')%> </td><td><%= select('user', 'lang', visitor.site.lang_list.map {|l| [_(l),l]}) %></td></tr>
|
27
28
|
<tr><td class='label'><%= _("time zone")%> </td><td><select name='user[time_zone]'><%= options_for_select([''] + TZInfo::Timezone.all_identifiers, @user[:time_zone] || '') %></select></td></tr>
|
28
29
|
<% unless @user.is_anon? -%>
|
@@ -32,16 +32,17 @@
|
|
32
32
|
|
33
33
|
<% if @virtual_class.kind_of?(VirtualClass) -%>
|
34
34
|
<% Zena::Use::Fulltext::FULLTEXT_FIELDS.reverse_each do |fld| -%>
|
35
|
-
<tr><td class='label'><%= _(fld)%></td><td><%= text_area('virtual_class', fld, :rows => 2, :cols => 30) %></td></tr>
|
35
|
+
<tr><td class='label'><%= _(fld) %></td><td><%= text_area('virtual_class', fld, :rows => 2, :cols => 30) %></td></tr>
|
36
36
|
<% end -%>
|
37
|
-
<tr><td class='label'><%= _('idx_class')%></td><td><%= select('virtual_class', 'idx_class', Zena::Use::ScopeIndex.models_for_form) %></td></tr>
|
38
|
-
<tr><td class='label'><%= _('idx_scope')%></td><td><%= text_area('virtual_class', 'idx_scope', :rows => 2, :cols => 30) %></td></tr>
|
39
|
-
<tr><td class='label'><%= _('idx_reverse_scope')%></td><td><%= text_area('virtual_class', 'idx_reverse_scope', :rows => 2, :cols => 30) %></td></tr>
|
40
|
-
<tr><td class='label'><%= _('prop eval')%></td><td><%= text_area('virtual_class', 'prop_eval', :rows => 2, :cols => 30) %></td></tr>
|
37
|
+
<tr><td class='label'><%= _('idx_class') %></td><td><%= select('virtual_class', 'idx_class', Zena::Use::ScopeIndex.models_for_form) %></td></tr>
|
38
|
+
<tr><td class='label'><%= _('idx_scope') %></td><td><%= text_area('virtual_class', 'idx_scope', :rows => 2, :cols => 30) %></td></tr>
|
39
|
+
<tr><td class='label'><%= _('idx_reverse_scope') %></td><td><%= text_area('virtual_class', 'idx_reverse_scope', :rows => 2, :cols => 30) %></td></tr>
|
40
|
+
<tr><td class='label'><%= _('prop eval') %></td><td><%= text_area('virtual_class', 'prop_eval', :rows => 2, :cols => 30) %></td></tr>
|
41
41
|
|
42
|
-
<tr><td class='label'><%= _('
|
42
|
+
<tr><td class='label'><%= _('edit group') %></td><td><%= select('virtual_class', 'create_group_id', visitor.all_groups.map{|g| [g.name, g.id]} ) %></td></tr>
|
43
43
|
<tr><td class='label'><%= _('auto create discussion')%></td><td><%= check_box('virtual_class', 'auto_create_discussion') %></td></tr>
|
44
|
-
<tr><td class='label'><%= _('monolingual')%></td><td><%= check_box('virtual_class', 'monolingual') %></td></tr>
|
44
|
+
<tr><td class='label'><%= _('monolingual') %></td><td><%= check_box('virtual_class', 'monolingual') %></td></tr>
|
45
|
+
<tr><td class='label'><%= _('content_type')%></td><td><%= text_field('virtual_class', 'content_type') %></td></tr>
|
45
46
|
<% end -%>
|
46
47
|
<tr><td class='label'><%= _('icon')%> </td><td><%= text_field('virtual_class', 'icon', :size=>15 ) %></td></tr>
|
47
48
|
<tr><td colspan='2'><p class='btn_validate'><input type='submit' value='<%= _('validate') %>'/></p></td></tr>
|
@@ -34,7 +34,11 @@ module Bricks
|
|
34
34
|
def acl_authorized?(action, params, request)
|
35
35
|
node = nil
|
36
36
|
group_ids_bak = group_ids.dup
|
37
|
-
|
37
|
+
if action == 'create'
|
38
|
+
klass = (params['node'] || {})['klass']
|
39
|
+
end
|
40
|
+
|
41
|
+
acls(action, params[:mode], params[:format], klass).each do |acl|
|
38
42
|
# Load exec_group to execute query
|
39
43
|
if acl.exec_group_id
|
40
44
|
@group_ids = group_ids_bak + [acl.exec_group_id]
|
@@ -56,27 +60,46 @@ module Bricks
|
|
56
60
|
|
57
61
|
# Find all acls for the visitor for a given action. The action should
|
58
62
|
# be one of the following: 'create', 'read', 'update', 'delete'. See
|
59
|
-
# Acl::ACTIONS.
|
60
|
-
|
63
|
+
# Acl::ACTIONS. If the action is 'create', we should also pass the class
|
64
|
+
# of the object to create.
|
65
|
+
def acls(action, mode, format, klass = nil)
|
61
66
|
mode = '' if mode.blank?
|
62
67
|
# Can the format be blank ?
|
63
68
|
format = 'html' if format.blank?
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
69
|
+
if action == 'create'
|
70
|
+
return [] unless klass = VirtualClass[klass || 'Node']
|
71
|
+
# Can the format be blank ?
|
72
|
+
format = 'html' if format.blank?
|
73
|
+
secure(Acl) { Acl.find(:all,
|
74
|
+
:conditions => [
|
75
|
+
'group_id IN (?) AND action = ? AND (mode = ? OR mode = ?) AND (format = ? OR format = ?) AND create_kpath IN (?)',
|
76
|
+
group_ids, action, '*', mode, '*', format, klass.split_kpath],
|
77
|
+
:order => 'priority DESC'
|
78
|
+
)}
|
79
|
+
else
|
80
|
+
secure(Acl) { Acl.find(:all,
|
81
|
+
:conditions => [
|
82
|
+
'group_id IN (?) AND action = ? AND (mode = ? OR mode = ?) AND (format = ? OR format = ?)',
|
83
|
+
group_ids, action, '*', mode, '*', format],
|
84
|
+
:order => 'priority DESC'
|
85
|
+
)}
|
86
|
+
end || []
|
70
87
|
end
|
71
88
|
|
72
89
|
def get_skin_with_acls(node)
|
73
90
|
exec_acl ? exec_acl.exec_skin : get_skin_without_acls(node)
|
74
91
|
end
|
75
92
|
|
76
|
-
def find_node_with_acls(path, zip, name, request)
|
77
|
-
find_node_without_acls(path, zip, name, request)
|
78
|
-
|
79
|
-
|
93
|
+
def find_node_with_acls(path, zip, name, request, need_write = false)
|
94
|
+
n = find_node_without_acls(path, zip, name, request, need_write) rescue nil
|
95
|
+
if !n || (!n.can_write? && need_write)
|
96
|
+
n = find_node_force_acls(path, zip, name, request) || n
|
97
|
+
end
|
98
|
+
n
|
99
|
+
end
|
100
|
+
|
101
|
+
def find_node_force_acls(path, zip, name, request)
|
102
|
+
raise ActiveRecord::RecordNotFound unless visitor.use_acls?
|
80
103
|
acl_params = request.params.dup
|
81
104
|
if name =~ /^\d+$/
|
82
105
|
acl_params[:id] = name
|
@@ -86,8 +109,13 @@ module Bricks
|
|
86
109
|
else
|
87
110
|
acl_params[:id] = zip
|
88
111
|
end
|
89
|
-
|
90
|
-
|
112
|
+
if request.path =~ %r{^/nodes/\d+/zafu$}
|
113
|
+
# This is to allow preview by using POST requests (long text in js).
|
114
|
+
action = 'read'
|
115
|
+
else
|
116
|
+
action = ::Acl::ACTION_FROM_METHOD[request.method]
|
117
|
+
end
|
118
|
+
visitor.acl_authorized?(action, acl_params, request)
|
91
119
|
end
|
92
120
|
end # UserMethods
|
93
121
|
end # Acls
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class AddCreateKpathToAcl < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :acls, :create_kpath, :string, :limit => 200
|
4
|
+
add_index :acls, ["create_kpath", "group_id", "action", "site_id"]
|
5
|
+
rescue
|
6
|
+
# Could be run twice (was in zena brick by mistake in zena 1.2.4pre)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.down
|
10
|
+
remove_column :groups, :auto_publish
|
11
|
+
remove_index :acls, :column => ["create_kpath", "group_id", "action", "site_id"]
|
12
|
+
end
|
13
|
+
end
|
@@ -145,7 +145,8 @@ class AclIntegrationTest < Zena::Integration::TestCase
|
|
145
145
|
setup do
|
146
146
|
# The visitor can create objects in assigned_project as direct parent
|
147
147
|
Zena::Db.execute "UPDATE acls SET query = '%q{assigned_project}', action = 'create' WHERE id = #{acls_id(:rap)}"
|
148
|
-
@create_url = "http://erebus.host/nodes?node[parent_id]=#{nodes_zip(:queen)}&node[klass]=
|
148
|
+
@create_url = "http://erebus.host/nodes?node[parent_id]=#{nodes_zip(:queen)}&node[klass]=Contact&node[title]=foobar"
|
149
|
+
@create_bad = "http://erebus.host/nodes?node[parent_id]=#{nodes_zip(:queen)}&node[klass]=Page&node[title]=foobar"
|
149
150
|
end
|
150
151
|
|
151
152
|
context 'with wrong user status' do
|
@@ -170,6 +171,14 @@ class AclIntegrationTest < Zena::Integration::TestCase
|
|
170
171
|
assert_equal nodes_id(:queen), node.parent_id
|
171
172
|
assert_equal 'foobar', node.title
|
172
173
|
end
|
174
|
+
|
175
|
+
context 'with wrong klass type' do
|
176
|
+
should 'create item' do
|
177
|
+
assert_difference('Node.count', 0) do
|
178
|
+
post @create_bad
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
173
182
|
|
174
183
|
should 'not create item out of acl scope' do
|
175
184
|
assert_difference('Node.count', 0) do
|
@@ -177,6 +186,30 @@ class AclIntegrationTest < Zena::Integration::TestCase
|
|
177
186
|
end
|
178
187
|
assert_response :missing
|
179
188
|
end
|
189
|
+
|
190
|
+
context 'with read access' do
|
191
|
+
setup do
|
192
|
+
# We must grant read access on visitor node to avoid errors in page rendering
|
193
|
+
Zena::Db.execute "UPDATE nodes SET rgroup_id = #{groups_id(:site)} WHERE id IN (#{nodes_id(:queen)},#{nodes_id(:demeter)})"
|
194
|
+
end
|
195
|
+
|
196
|
+
should 'read without acl' do
|
197
|
+
get "http://erebus.host/oo/project#{nodes_zip(:queen)}.html"
|
198
|
+
assert_response :success
|
199
|
+
assert_nil visitor.exec_acl
|
200
|
+
end
|
201
|
+
|
202
|
+
should 'load acl' do
|
203
|
+
assert_difference('Node.count', 1) do
|
204
|
+
post @create_url
|
205
|
+
end
|
206
|
+
node = assigns(:node)
|
207
|
+
assert visitor.exec_acl
|
208
|
+
assert_equal visitor.id, node.user_id
|
209
|
+
assert_equal nodes_id(:queen), node.parent_id
|
210
|
+
assert_equal 'foobar', node.title
|
211
|
+
end
|
212
|
+
end
|
180
213
|
|
181
214
|
context 'without use acl' do
|
182
215
|
setup do
|
@@ -223,6 +256,25 @@ class AclIntegrationTest < Zena::Integration::TestCase
|
|
223
256
|
put "http://erebus.host/nodes/#{nodes_zip(:queen)}?node[title]=foobar"
|
224
257
|
assert_response :missing
|
225
258
|
end
|
259
|
+
|
260
|
+
context 'with read access' do
|
261
|
+
setup do
|
262
|
+
# We must grant read access on visitor node to avoid errors in page rendering
|
263
|
+
Zena::Db.execute "UPDATE nodes SET rgroup_id = #{groups_id(:site)} WHERE id IN (#{nodes_id(:persephone)},#{nodes_id(:demeter)})"
|
264
|
+
end
|
265
|
+
|
266
|
+
should 'read without acl' do
|
267
|
+
get "http://erebus.host/oo/contact#{nodes_zip(:persephone)}.html"
|
268
|
+
assert_response :success
|
269
|
+
assert_nil visitor.exec_acl
|
270
|
+
end
|
271
|
+
|
272
|
+
should 'load acl' do
|
273
|
+
put @update_url
|
274
|
+
assert_equal 'foobar', nodes(:persephone).title
|
275
|
+
assert visitor.exec_acl
|
276
|
+
end
|
277
|
+
end
|
226
278
|
|
227
279
|
context 'without use acl' do
|
228
280
|
setup do
|
@@ -17,6 +17,27 @@ rap:
|
|
17
17
|
# allow any format
|
18
18
|
format: '*'
|
19
19
|
|
20
|
+
# Create Posts in assigned projects
|
21
|
+
create_rap:
|
22
|
+
name: create posts in assigned projects
|
23
|
+
# Anyone in the 'sky' group
|
24
|
+
group: sky
|
25
|
+
# can create
|
26
|
+
action: create
|
27
|
+
# in 'assigned_projects'
|
28
|
+
query: "%q{assigned_projects}"
|
29
|
+
# objects with kpath
|
30
|
+
create_kpath: NRC
|
31
|
+
# by receiving the 'erebus' access group
|
32
|
+
exec_group: erebus
|
33
|
+
# and viewing it through the 'sky' Skin.
|
34
|
+
exec_skin: sky
|
35
|
+
priority: 10
|
36
|
+
# allow any mode
|
37
|
+
mode: '*'
|
38
|
+
# allow any format
|
39
|
+
format: '*'
|
40
|
+
|
20
41
|
# Read self (this never matches)
|
21
42
|
self:
|
22
43
|
name: read assigned projects
|