Changeset 1125

Show
Ignore:
Timestamp:
2008-07-25 15:22:23 (6 months ago)
Author:
gaspard
Message:

Added 'mode' parameter to [form] to redirect after update in a specific mode.
[security] fixed multiversion (added a 'safe_attribute?' method before calling send).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/app/controllers/nodes_controller.rb

    r1094 r1125  
    224224          redirect_to edit_version_url(:node_id => @node[:zip], :id=>(@node.v_number || 0))  
    225225        else 
    226           redirect_to zen_path(@node
     226          redirect_to zen_path(@node, :mode => params[:mode]
    227227        end 
    228228      end 
  • trunk/app/models/document_content.rb

    r1094 r1125  
    1414 
    1515  zafu_readable         :size, :name, :content_type, :ext 
     16  safe_attribute        :file 
    1617 
    1718  belongs_to            :site 
  • trunk/app/models/image.rb

    r957 r1125  
    5454=end 
    5555class Image < Document 
    56    
    5756  class << self 
    5857    def accept_content_type?(content_type) 
  • trunk/app/models/image_content.rb

    r1094 r1125  
    1818   
    1919  zafu_readable    :width, :height 
     20  safe_attribute   :crop 
    2021   
    2122  # Return a cropped image using the 'crop' hash with the top left corner position (:x, :y) and the width and height (:width, :heigt). 
  • trunk/app/models/node.rb

    r1122 r1125  
    132132                     :section_zip, :skin, :ref_lang, :fullpath, :rootpath, :position, :publish_from, :max_status, :rgroup_id,  
    133133                     :wgroup_id, :pgroup_id, :basepath, :custom_base, :klass, :zip, :score, :comments_count, :l_status, :l_comment, 
    134                      :custom_a, :custom_b, :title, :text                  
     134                     :custom_a, :custom_b, :title, :text 
     135  safe_attribute     :m_text, :m_title, :m_author           
    135136  zafu_context       :author => "Contact", :parent => "Node",  
    136137                     :project => "Project", :section => "Section",  
     
    728729    return @visitor if @visitor 
    729730    raise Zena::RecordNotSecured.new("Visitor not set, record not secured.") 
     731  end 
     732   
     733  # Return true if the attribute can be read (is zafu_readable) 
     734  def safe_attribute?(att) 
     735    # FIXME: SECURITY: is there any risk here ? (k can be anything) 
     736    attribute = att.to_s 
     737    case attribute[0..1] 
     738    when 'v_' 
     739      version.class.safe_attribute?(attribute[2..-1]) 
     740    when 'c_' 
     741      c = version.content 
     742      c ? c.class.safe_attribute?(attribute[2..-1]) : false 
     743    when 'd_' 
     744      true 
     745    else 
     746      if attribute =~ /_(id|zip|status|comment)s?\Z/ 
     747        true 
     748      else 
     749        self.class.safe_attribute?(attribute) 
     750      end 
     751    end 
    730752  end 
    731753   
     
    11291151  end 
    11301152   
     1153  # attributes are set only but we need dummy values for multiversion's remove_attributes_with_same_value 
     1154  def m_text; nil end 
     1155  def m_title; nil end 
     1156  def m_author; nil end 
     1157   
    11311158  def m_title=(str) 
    11321159    @add_comment ||= {} 
  • trunk/app/models/template_content.rb

    r1094 r1125  
    11class TemplateContent < ActiveRecord::Base 
    22  zafu_readable   :tkpath, :ext, :format, :content_type, :filename, :mode, :klass, :skin_name 
     3  safe_attribute  :file 
    34   
    45  attr_protected :tkpath 
  • trunk/lib/multiversion.rb

    r1114 r1125  
    335335              next 
    336336            end 
    337             current_value = self.send(k) rescue nil 
     337            if safe_attribute?(k) 
     338              current_value = self.send(k) rescue nil 
     339            else 
     340              # ignore 
     341              next 
     342            end 
     343             
    338344            case current_value.class.to_s 
    339345            when 'NilClass' 
  • trunk/lib/parser/lib/rules/zena.rb

    r1124 r1125  
    4242  # FIXME: zafu_readable should belong to core_ext. 
    4343  class ActiveRecord::Base 
    44     @@_zafu_readable ||= {} # defined for each class 
    45     @@_zafu_context  ||= {} # defined for each class (list of methods to change contexts) 
     44    @@_zafu_readable  ||= {} # defined for each class 
     45    @@_safe_attribute ||= {} # defined for each class 
     46    @@_zafu_context   ||= {} # defined for each class (list of methods to change contexts) 
    4647    @@_zafu_readable_attributes ||= {} # full list with inherited attributes 
     48    @@_safe_attribute_list      ||= {} # full list with inherited attributes 
    4749    @@_zafu_known_contexts      ||= {} # full list with inherited attributes 
    4850   
     
    5254    end 
    5355     
     56    def self.safe_attribute(*list) 
     57      @@_safe_attribute[self] ||= [] 
     58      @@_safe_attribute[self] = (@@_safe_attribute[self] + list.map{|l| l.to_s}).uniq 
     59    end 
     60     
    5461    def self.zafu_context(hash) 
    5562      @@_zafu_context[self] ||= {} 
     
    6269      else 
    6370        (superclass.zafu_readable_attributes + (@@_zafu_readable[self] || [])).uniq.sort 
     71      end 
     72    end 
     73     
     74    def self.safe_attribute_list 
     75      @@_safe_attribute_list[self] ||= if superclass == ActiveRecord::Base 
     76        @@_safe_attribute[self] || [] 
     77      else 
     78        (superclass.safe_attribute_list + (@@_safe_attribute[self] || [])).uniq.sort 
    6479      end 
    6580    end 
     
    98113      end 
    99114    end 
    100    
     115     
     116    def self.safe_attribute?(sym) 
     117      column_names.include?(sym) || zafu_readable?(sym) || safe_attribute_list.include?(sym.to_s) 
     118    end 
     119     
    101120    def self.zafu_readable?(sym) 
    102121      if sym.to_s =~ /(.*)_zips?$/ 
     
    10031022        form = "<form method='post' action='/nodes/#{erb_node_id}'><div style='margin:0;padding:0'><input name='_method' type='hidden' value='put' /></div>" 
    10041023      end 
    1005       hidden_fields['node[klass]']    = @params[:klass] || @context[:klass] || 'Page' if node_kind_of?(Node) 
     1024       
     1025      if node_kind_of?(Node) && (@params[:klass] || @context[:klass]) 
     1026        hidden_fields['node[klass]']    = @params[:klass] || @context[:klass] 
     1027      end 
     1028       
     1029      if node_kind_of?(Node) && @params[:mode] 
     1030        hidden_fields['mode'] = @params[:mode] 
     1031      end 
     1032       
    10061033      hidden_fields['node[v_status]'] = Zena::Status[:pub] if @context[:publish_after_save] || (@params[:publish] == 'true') 
    10071034       
     
    10531080    # TODO: implement checkbox in the same spirit as 'r_select' 
    10541081    def r_checkbox 
    1055       return parser_error("missing 'values'") unless values = @params[:values] 
     1082      return parser_error("missing 'nodes'") unless values = @params[:values] || @params[:nodes] 
    10561083      return parser_error("missing 'role'")   unless   role = (@params[:role] || @params[:name]) 
     1084      attribute = @params[:attr] || 'name' 
     1085      if role =~ /(.*)_ids?\Z/ 
     1086        role = $1 
     1087      end 
    10571088      meth = role.singularize 
    1058       attribute = @params[:attr] || 'name' 
     1089 
    10591090      if values =~ /^\d+\s*($|,)/ 
    10601091        # ids 
     
    10831114      out "<span><input type='checkbox' name='node[#{meth}_ids][]' value='#{erb_node_id(var)}'<%= #{list_var}_ids.include?(#{var}[:id]) ? \" checked='checked'\" : '' %>/> <%= #{node_attribute(attribute, :node=>var)} %></span> " 
    10841115      out "<% end -%></div>" 
    1085       out "<input type='hidden' name='node[#{meth}_ids]' value=''/>" 
     1116      out "<input type='hidden' name='node[#{meth}_ids][]' value=''/>" 
    10861117 
    10871118      out "<% end -%><% end -%>" 
  • trunk/test/helpers/zena_parser/basic.yml

    r1124 r1125  
    886886    node: 'opening' 
    887887  src: "<r:checkbox role='calendar' values='11'/>" 
    888   res: "/input type='checkbox' name='node\[calendar_ids\]\[\]' value='11' checked='checked'.*zena.*hidden.*node\[calendar_ids\]' value=''/" 
     888  res: "/input type='checkbox' name='node\[calendar_ids\]\[\]' value='11' checked='checked'.*zena.*hidden.*node\[calendar_ids\]\[\]' value=''/" 
    889889 
    890890input_set_value: 
  • trunk/test/unit/multiversion_test.rb

    r1114 r1125  
    8282    assert_equal Hash[:v_title=>'hey', :d_what=>'ever', :v_publish_from=>nil], node.remove_attributes_with_same_value(current.merge(:v_title=>'hey', :d_what=>'ever', :v_publish_from=>nil))   
    8383    assert_equal Hash[:v_title=>'hey', :d_what=>'ever', :v_publish_from=>''], node.remove_attributes_with_same_value(current.merge(:v_title=>'hey', :d_what=>'ever', :v_publish_from=>'')) 
     84  end 
     85   
     86  def test_remove_attributes_with_same_value_bad_attribute 
     87    # should not call the method if unsafe ! 
     88    login(:ant) 
     89    node = secure!(Node) { nodes(:status) } 
     90    current = { :name => "status", 
     91      :position => "0", 
     92      :v_publish_from => "2006-03-10", 
     93      :v_summary => "status summary", 
     94      :v_text => "status text", 
     95      :v_title => "Etat des travaux"} 
     96    res = {} 
     97    assert_nothing_raised { res = node.remove_attributes_with_same_value(current.merge(:raise=>'mean idea')) } 
     98    assert_equal Hash[], res 
    8499  end 
    85100   
  • trunk/test/unit/node_test.rb

    r1103 r1125  
    13131313  end 
    13141314   
     1315  def test_safe_attribute 
     1316    login(:ant) 
     1317    node = secure(Node) { nodes(:ant) } 
     1318    ['v_puts', 'c_file', :raise, :blah, 'c_blah', 'c_system', 'system', 'v_system'].each do |k| 
     1319      assert ! node.safe_attribute?(k), "#{k} should not be readable" 
     1320    end 
     1321     
     1322    ['v_status', 'id', :c_first_name, :c_name, 'parent_id', :m_text, :inherit, :v_title, 'd_blah', 'l_status', 'l_comment', 'hot_status', 'blah_comment', 'blah_zips', 'blah_id', 'blah_ids'].each do |k| 
     1323      assert node.safe_attribute?(k), "#{k} should be safe" 
     1324    end 
     1325     
     1326    node = secure(Node) { nodes(:bird_jpg)} 
     1327     
     1328    ['c_file'].each do |k| 
     1329      assert node.safe_attribute?(k), "#{k} should be safe" 
     1330    end 
     1331  end 
     1332   
    13151333  # FIXME: write test 
    13161334  def test_assets 
  • trunk/test/unit/relation_proxy_test.rb

    r1103 r1125  
    106106    assert_nothing_raised (NoMethodError) { node.update_attributes( 'tralala_ids' => ['33'])} 
    107107    assert node.errors['tralala'] 
    108     assert_raise (NoMethodError) { node.update_attributes( 'some_bad_method_name' => ['33'])} 
    109     assert_raise (NoMethodError) { node.some_bad_method_name } 
     108    assert_equal Hash[], node.remove_attributes_with_same_value( 'some_bad_method_name' => ['33']) 
    110109  end 
    111110