Commit 0111638e4bf10b3bb08876c8df5622b424d11f35
Exists in
master
and in
29 other branches
Merge branch 'stable'
Showing
19 changed files
with
118 additions
and
17 deletions
Show diff stats
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 < Task | @@ -77,6 +77,10 @@ class ApproveArticle < 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 < Task | @@ -107,4 +111,11 @@ class ApproveArticle < 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 < ActiveRecord::Base | @@ -9,6 +9,13 @@ class Environment < 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 < ActiveRecord::Base | @@ -523,9 +530,6 @@ class Environment < 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 < ActiveRecord::Base | @@ -4,6 +4,8 @@ class Image < 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 < ActiveRecord::Base | @@ -3,5 +3,7 @@ class Thumbnail < 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 < Article | @@ -18,6 +18,8 @@ class UploadedFile < 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 |
@@ -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('|') |
@@ -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) |
@@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
1 | +<? print("Hello World"); ?> |
test/unit/environment_test.rb
@@ -234,11 +234,9 @@ class EnvironmentTest < Test::Unit::TestCase | @@ -234,11 +234,9 @@ class EnvironmentTest < 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 < Test::Unit::TestCase | @@ -1119,10 +1117,27 @@ class EnvironmentTest < 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 < Test::Unit::TestCase | @@ -114,4 +114,11 @@ class FeedHandlerTest < 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 < Test::Unit::TestCase | @@ -118,4 +118,9 @@ class ImageTest < 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 < Test::Unit::TestCase | @@ -9,5 +9,10 @@ class ThumbnailTest < 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 < Test::Unit::TestCase | @@ -325,4 +325,9 @@ class UploadedFileTest < 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 |