Commit 0111638e4bf10b3bb08876c8df5622b424d11f35

Authored by Rodrigo Souto
2 parents d606d2a1 0db12ddd

Merge branch 'stable'

app/helpers/application_helper.rb
@@ -1121,7 +1121,7 @@ module ApplicationHelper @@ -1121,7 +1121,7 @@ module ApplicationHelper
1121 1121
1122 (_('Welcome, %s') % link_to('<i></i><strong>{login}</strong>', @environment.top_url + '/{login}', :id => "homepage-link", :title => _('Go to your homepage'))) + 1122 (_('Welcome, %s') % link_to('<i></i><strong>{login}</strong>', @environment.top_url + '/{login}', :id => "homepage-link", :title => _('Go to your homepage'))) +
1123 render_environment_features(:usermenu) + 1123 render_environment_features(:usermenu) +
1124 - link_to('<i class="icon-menu-admin"></i><strong>' + _('Administration') + '</strong>', { :host => @environment.default_hostname, :controller => 'admin_panel', :action => 'index' }, :id => "controlpanel", :title => _("Configure the environment"), :class => 'admin-link', :style => 'display: none') + 1124 + link_to('<i class="icon-menu-admin"></i><strong>' + _('Administration') + '</strong>', @environment.top_url + '/admin', :id => "controlpanel", :title => _("Configure the environment"), :class => 'admin-link', :style => 'display: none') +
1125 manage_enterprises.to_s + 1125 manage_enterprises.to_s +
1126 link_to('<i class="icon-menu-ctrl-panel"></i><strong>' + _('Control panel') + '</strong>', @environment.top_url + '/myprofile/{login}', :id => "controlpanel", :title => _("Configure your personal account and content")) + 1126 link_to('<i class="icon-menu-ctrl-panel"></i><strong>' + _('Control panel') + '</strong>', @environment.top_url + '/myprofile/{login}', :id => "controlpanel", :title => _("Configure your personal account and content")) +
1127 pending_tasks_count + 1127 pending_tasks_count +
app/models/approve_article.rb
@@ -77,6 +77,10 @@ class ApproveArticle &lt; Task @@ -77,6 +77,10 @@ class ApproveArticle &lt; Task
77 true 77 true
78 end 78 end
79 79
  80 + def reject_details
  81 + true
  82 + end
  83 +
80 def default_decision 84 def default_decision
81 if article 85 if article
82 'skip' 86 'skip'
@@ -107,4 +111,11 @@ class ApproveArticle &lt; Task @@ -107,4 +111,11 @@ class ApproveArticle &lt; Task
107 end 111 end
108 end 112 end
109 113
  114 + def task_cancelled_message
  115 + message = _('Your request for publishing the article "{article}" was rejected.')
  116 + if !reject_explanation.blank?
  117 + message += " " + _("Here is the reject explanation left by the administrator who rejected your article: \n\n%{reject_explanation}") % {:reject_explanation => reject_explanation}
  118 + end
  119 + end
  120 +
110 end 121 end
app/models/environment.rb
@@ -9,6 +9,13 @@ class Environment &lt; ActiveRecord::Base @@ -9,6 +9,13 @@ class Environment &lt; ActiveRecord::Base
9 9
10 has_many :tasks, :dependent => :destroy, :as => 'target' 10 has_many :tasks, :dependent => :destroy, :as => 'target'
11 11
  12 + IDENTIFY_SCRIPTS = /(?:php[0-9s]?(\..*)?|[sp]htm[l]?(\..*)?|pl|py|cgi|rb)/
  13 +
  14 + def self.verify_filename(filename)
  15 + filename += '.txt' if filename =~ IDENTIFY_SCRIPTS
  16 + filename
  17 + end
  18 +
12 PERMISSIONS['Environment'] = { 19 PERMISSIONS['Environment'] = {
13 'view_environment_admin_panel' => N_('View environment admin panel'), 20 'view_environment_admin_panel' => N_('View environment admin panel'),
14 'edit_environment_features' => N_('Edit environment features'), 21 'edit_environment_features' => N_('Edit environment features'),
@@ -523,9 +530,6 @@ class Environment &lt; ActiveRecord::Base @@ -523,9 +530,6 @@ class Environment &lt; ActiveRecord::Base
523 domain = (self.domains.find_by_is_default(true) || self.domains.find(:first, :order => 'id')).name 530 domain = (self.domains.find_by_is_default(true) || self.domains.find(:first, :order => 'id')).name
524 domain = email_hostname ? domain : (force_www ? ('www.' + domain) : domain) 531 domain = email_hostname ? domain : (force_www ? ('www.' + domain) : domain)
525 end 532 end
526 - if Noosfero.url_options.has_key?(:port)  
527 - domain += ":#{Noosfero.url_options[:port]}"  
528 - end  
529 domain 533 domain
530 end 534 end
531 535
app/models/image.rb
@@ -4,6 +4,8 @@ class Image &lt; ActiveRecord::Base @@ -4,6 +4,8 @@ class Image &lt; ActiveRecord::Base
4 Image.attachment_options[:max_size] 4 Image.attachment_options[:max_size]
5 end 5 end
6 6
  7 + sanitize_filename
  8 +
7 has_attachment :content_type => :image, 9 has_attachment :content_type => :image,
8 :storage => :file_system, 10 :storage => :file_system,
9 :path_prefix => 'public/image_uploads', 11 :path_prefix => 'public/image_uploads',
app/models/thumbnail.rb
@@ -3,5 +3,7 @@ class Thumbnail &lt; ActiveRecord::Base @@ -3,5 +3,7 @@ class Thumbnail &lt; ActiveRecord::Base
3 :content_type => :image, :max_size => 5.megabytes 3 :content_type => :image, :max_size => 5.megabytes
4 validates_as_attachment 4 validates_as_attachment
5 5
  6 + sanitize_filename
  7 +
6 postgresql_attachment_fu 8 postgresql_attachment_fu
7 end 9 end
app/models/uploaded_file.rb
@@ -18,6 +18,8 @@ class UploadedFile &lt; Article @@ -18,6 +18,8 @@ class UploadedFile &lt; Article
18 18
19 validates_size_of :title, :maximum => 60, :if => (lambda { |file| !file.title.blank? }) 19 validates_size_of :title, :maximum => 60, :if => (lambda { |file| !file.title.blank? })
20 20
  21 + sanitize_filename
  22 +
21 before_create do |uploaded_file| 23 before_create do |uploaded_file|
22 uploaded_file.is_image = true if uploaded_file.image? 24 uploaded_file.is_image = true if uploaded_file.image?
23 end 25 end
config/initializers/active_record_extensions.rb 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +require 'upload_sanitizer'
debian/changelog
1 -noosfero (0.31.2) lucid; urgency=low 1 +noosfero (0.31.3) unstable; urgency=low
  2 +
  3 + * Bugfix Version release.
  4 +
  5 + -- Rodrigo <rodrigo@colivre.coop.br> Thu, 16 Jun 2011 11:13:42 -0300
  6 +
  7 +noosfero (0.31.2) unstable; urgency=low
2 8
3 * Bugfix Version release. 9 * Bugfix Version release.
4 10
features/approve_article.feature
@@ -5,9 +5,9 @@ Feature: approve article @@ -5,9 +5,9 @@ Feature: approve article
5 5
6 Background: 6 Background:
7 Given the following users 7 Given the following users
8 - | login | name |  
9 - | joaosilva | Joao Silva |  
10 - | mariasilva | Maria Silva | 8 + | login | name | email |
  9 + | joaosilva | Joao Silva | joaosilva@example.com |
  10 + | mariasilva | Maria Silva | mariasilva@example.com |
11 And the following articles 11 And the following articles
12 | owner | name | body | homepage | 12 | owner | name | body | homepage |
13 | mariasilva | Sample Article | This is an article | true | 13 | mariasilva | Sample Article | This is an article | true |
@@ -34,3 +34,20 @@ Feature: approve article @@ -34,3 +34,20 @@ Feature: approve article
34 And I go to Sample Community's sitemap 34 And I go to Sample Community's sitemap
35 And I follow "Sample Article" 35 And I follow "Sample Article"
36 Then I should see "This is an article edited" 36 Then I should see "This is an article edited"
  37 +
  38 + @selenium
  39 + Scenario: reject an article with explanation
  40 + Given I am logged in as "mariasilva"
  41 + And I go to Maria Silva's cms
  42 + And I follow "Sample Article"
  43 + And I follow "Spread" and wait
  44 + And I check "Sample Community"
  45 + And I press "Spread this"
  46 + And I am logged in as "joaosilva"
  47 + And I go to Sample Community's control panel
  48 + And I follow "Process requests" and wait
  49 + And I choose "Reject"
  50 + And I fill in "Rejection explanation" with "This is not an appropriate article for this community."
  51 + And I press "Apply!"
  52 + When I go to Sample Community's sitemap
  53 + Then I should not see "Sample Article"
features/profile_domain.feature
@@ -69,4 +69,4 @@ Feature: domain for profile @@ -69,4 +69,4 @@ Feature: domain for profile
69 Scenario: Compose link to administration with environment domain 69 Scenario: Compose link to administration with environment domain
70 Given I am logged in as "joaosilva" 70 Given I am logged in as "joaosilva"
71 When I visit "/" and wait 71 When I visit "/" and wait
72 - Then I should see "Administration" linking to "http://127.0.0.1:3001/admin" 72 + Then I should see "Administration" linking to "http://127.0.0.1/admin"
lib/feed_handler.rb
@@ -65,7 +65,12 @@ class FeedHandler @@ -65,7 +65,12 @@ class FeedHandler
65 if container.update_errors > FeedHandler.max_errors 65 if container.update_errors > FeedHandler.max_errors
66 container.enabled = false 66 container.enabled = false
67 end 67 end
68 - container.finish_fetch 68 + begin
  69 + container.finish_fetch
  70 + rescue Exception => finish_fetch_exception
  71 + RAILS_DEFAULT_LOGGER.warn("Unable to finish fetch from %s ID %d\n%s" % [container.class.name, container.id, finish_fetch_exception.to_s])
  72 + RAILS_DEFAULT_LOGGER.warn("Backtrace:\n%s" % finish_fetch_exception.backtrace.join("\n"))
  73 + end
69 end 74 end
70 end 75 end
71 76
lib/noosfero.rb
1 module Noosfero 1 module Noosfero
2 PROJECT = 'noosfero' 2 PROJECT = 'noosfero'
3 - VERSION = '0.31.2' 3 + VERSION = '0.31.3'
4 4
5 def self.pattern_for_controllers_in_directory(dir) 5 def self.pattern_for_controllers_in_directory(dir)
6 disjunction = controllers_in_directory(dir).join('|') 6 disjunction = controllers_in_directory(dir).join('|')
lib/upload_sanitizer.rb 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +module UploadSanitizer
  2 + def self.included(base)
  3 + base.extend(ClassMethods)
  4 + end
  5 +
  6 + module ClassMethods
  7 + def sanitize_filename
  8 + before_create { |file| file.filename = Environment.verify_filename(file.filename) }
  9 + end
  10 + end
  11 +end
  12 +
  13 +ActiveRecord::Base.send(:include, UploadSanitizer)
test/fixtures/files/hello_world.php 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<? print("Hello World"); ?>
test/unit/environment_test.rb
@@ -234,11 +234,9 @@ class EnvironmentTest &lt; Test::Unit::TestCase @@ -234,11 +234,9 @@ class EnvironmentTest &lt; Test::Unit::TestCase
234 234
235 should 'include port in default top URL for development environment' do 235 should 'include port in default top URL for development environment' do
236 env = Environment.new 236 env = Environment.new
237 - env.expects(:default_hostname).returns('www.lalala.net')  
238 -  
239 Noosfero.expects(:url_options).returns({ :port => 9999 }).at_least_once 237 Noosfero.expects(:url_options).returns({ :port => 9999 }).at_least_once
240 238
241 - assert_equal 'http://www.lalala.net:9999', env.top_url 239 + assert_equal 'http://localhost:9999', env.top_url
242 end 240 end
243 241
244 should 'use https when asked for a ssl url' do 242 should 'use https when asked for a ssl url' do
@@ -1119,10 +1117,27 @@ class EnvironmentTest &lt; Test::Unit::TestCase @@ -1119,10 +1117,27 @@ class EnvironmentTest &lt; Test::Unit::TestCase
1119 assert_equal ["Meter", "Kilo", "Litre"], Environment.default.units.map(&:singular) 1117 assert_equal ["Meter", "Kilo", "Litre"], Environment.default.units.map(&:singular)
1120 end 1118 end
1121 1119
1122 - should 'include port in default hostname for development environment' do 1120 + should 'not include port in default hostname' do
1123 env = Environment.new 1121 env = Environment.new
1124 - Noosfero.expects(:url_options).returns({ :port => 9999 }).at_least_once  
1125 - assert_equal 'localhost:9999', env.default_hostname 1122 + Noosfero.stubs(:url_options).returns({ :port => 9999 })
  1123 + assert_no_match /9999/, env.default_hostname
  1124 + end
  1125 +
  1126 + should 'identify scripts with regex' do
  1127 + scripts_extensions = %w[php php1 php4 phps php.bli cgi shtm phtm shtml phtml pl py rb]
  1128 + name = 'uploaded_file'
  1129 + scripts_extensions.each do |extension|
  1130 + assert_not_nil name+'.'+extension =~ Environment::IDENTIFY_SCRIPTS
  1131 + end
  1132 + end
  1133 +
  1134 + should 'verify filename and append .txt if script' do
  1135 + scripts_extensions = %w[php php1 php4 phps php.bli cgi shtm phtm shtml phtml pl py rb]
  1136 + name = 'uploaded_file'
  1137 + scripts_extensions.each do |extension|
  1138 + filename = name+'.'+extension
  1139 + assert_equal filename+'.txt', Environment.verify_filename(filename)
  1140 + end
1126 end 1141 end
1127 1142
1128 end 1143 end
test/unit/feed_handler_test.rb
@@ -114,4 +114,11 @@ class FeedHandlerTest &lt; Test::Unit::TestCase @@ -114,4 +114,11 @@ class FeedHandlerTest &lt; Test::Unit::TestCase
114 end 114 end
115 end 115 end
116 116
  117 + should 'not crash even when finish fetch fails' do
  118 + container.stubs(:finish_fetch).raises(Exception.new("crash"))
  119 + assert_nothing_raised do
  120 + handler.process(container)
  121 + end
  122 + end
  123 +
117 end 124 end
test/unit/image_test.rb
@@ -118,4 +118,9 @@ class ImageTest &lt; Test::Unit::TestCase @@ -118,4 +118,9 @@ class ImageTest &lt; Test::Unit::TestCase
118 file.destroy 118 file.destroy
119 end 119 end
120 120
  121 + should 'not allow script files to be uploaded without append .txt in the end' do
  122 + file = Image.create!(:uploaded_data => fixture_file_upload('files/hello_world.php', 'image/png'))
  123 + assert_equal 'hello_world.php.txt', file.filename
  124 + end
  125 +
121 end 126 end
test/unit/thumbnail_test.rb
@@ -9,5 +9,10 @@ class ThumbnailTest &lt; Test::Unit::TestCase @@ -9,5 +9,10 @@ class ThumbnailTest &lt; Test::Unit::TestCase
9 assert_match 'image/', item 9 assert_match 'image/', item
10 end 10 end
11 end 11 end
  12 +
  13 + should 'not allow script files to be uploaded without append .txt in the end' do
  14 + file = Thumbnail.create!(:uploaded_data => fixture_file_upload('files/hello_world.php', 'image/png'))
  15 + assert_equal 'hello_world.php.txt', file.filename
  16 + end
12 17
13 end 18 end
test/unit/uploaded_file_test.rb
@@ -325,4 +325,9 @@ class UploadedFileTest &lt; Test::Unit::TestCase @@ -325,4 +325,9 @@ class UploadedFileTest &lt; Test::Unit::TestCase
325 uses_sqlite 325 uses_sqlite
326 end 326 end
327 327
  328 + should 'not allow script files to be uploaded without append .txt in the end' do
  329 + file = UploadedFile.create!(:uploaded_data => fixture_file_upload('files/hello_world.php', 'application/x-php'), :profile => @profile)
  330 + assert_equal 'hello_world.php.txt', file.filename
  331 + end
  332 +
328 end 333 end