[Git][noosfero/noosfero][master] 4 commits: debian-package: run setup on postinst

Antonio Terceiro gitlab at mg.gitlab.com
Thu Feb 25 13:05:20 BRT 2016


Antonio Terceiro pushed to branch master at Noosfero / noosfero


Commits:
aaa0ee68 by Rodrigo Souto at 2016-02-23T12:38:09-03:00
debian-package: run setup on postinst

- - - - -
523b40fc by Rodrigo Souto at 2016-02-23T12:38:09-03:00
chat: move apache config to virtualhosts file

- - - - -
3af4b045 by Rodrigo Souto at 2016-02-23T12:38:09-03:00
private-articles: creating dbm files do filter private files access thorugh web server

Also rewriting the file visualization to work consistently with every
file type. Here is the overall basic behavior now:

  * If the request is passed with view=true, content is displayed
    as an article content.
    * If the file has an inline visualization (like images) it's already
      displayed.
    * If not, a download link is displayed.
  * If the request is passed with view=false, the file is provided
    straight, without any noosfero layout being loaded.

  * If the file is private:
    * And the user accesses its public filesystem path, apache (this is
      done by noosfero-apache) will redirect the request to rails
      path so that the rails server will provide it considering
      appropriate permissions.
    * And the user accesses its rails path, rails server will provide as
      well.
  * If the file is public:
    * And the user accesses its public filesystem path, apache will
      provide the file.
    * And the user accesses its rails path, rails server will redirect
      to its public filesystem path so that apache provides the file.

- - - - -
1c3dc68d by Antonio Terceiro at 2016-02-25T16:05:02+00:00
Merge branch 'dbm-private-files' into 'master'

Dbm private files

Also rewriting the file visualization to work consistently with every
file type. Here is the overall basic behavior now:

  * If the request is passed with view=true, content is displayed
    as an article content.
    * If the file has an inline visualization (like images) it's already
      displayed.
    * If not, a download link is displayed.
  * If the request is passed with view=false, the file is provided
    straight, without any noosfero layout being loaded.

  * If the file is private:
    * And the user accesses its public filesystem path, apache (this is
      done by noosfero-apache) will redirect the request to rails
      path so that the rails server will provide it considering
      appropriate permissions.
    * And the user accesses its rails path, rails server will provide as
      well.
  * If the file is public:
    * And the user accesses its public filesystem path, apache will
      provide the file.
    * And the user accesses its rails path, rails server will redirect
      to its public filesystem path so that apache provides the file.

The feature and debian package were tested and are still available for testing on: http://private-files.dev.colivre.net

See merge request !797
- - - - -


21 changed files:

- app/controllers/public/content_viewer_controller.rb
- app/models/article.rb
- app/models/rss_feed.rb
- app/models/uploaded_file.rb
- app/views/file_presenter/_generic.html.erb
- debian/apache2/virtualhost.conf
- debian/dbinstall
- debian/dbupgrade
- debian/noosfero.links
- debian/noosfero.postinst
- debian/update-noosfero-apache
- etc/init.d/noosfero
- lib/file_presenter.rb
- + lib/tasks/cache.rake
- script/apacheconf
- test/functional/content_viewer_controller_test.rb
- test/unit/article_block_test.rb
- test/unit/article_test.rb
- test/unit/blog_helper_test.rb
- test/unit/uploaded_file_test.rb
- − util/chat/apache/xmpp.conf


Changes:

=====================================
app/controllers/public/content_viewer_controller.rb
=====================================
--- a/app/controllers/public/content_viewer_controller.rb
+++ b/app/controllers/public/content_viewer_controller.rb
@@ -205,8 +205,6 @@ class ContentViewerController < ApplicationController
 
   def rendered_file_download(view = nil)
     if @page.download? view
-      headers['Content-Type'] = @page.mime_type
-      headers.merge! @page.download_headers
       data = @page.data
 
       # TODO test the condition
@@ -214,7 +212,12 @@ class ContentViewerController < ApplicationController
         raise "No data for file"
       end
 
-      render :text => data, :layout => false
+      if @page.published && @page.uploaded_file?
+        redirect_to @page.public_filename
+      else
+        send_data data, @page.download_headers
+      end
+
       return true
     end
 


=====================================
app/models/article.rb
=====================================
--- a/app/models/article.rb
+++ b/app/models/article.rb
@@ -383,6 +383,10 @@ class Article < ActiveRecord::Base
     end
   end
 
+  def full_path
+    profile.hostname.blank? ? "/#{profile.identifier}/#{path}" : "/#{path}"
+  end
+
   def url
     @url ||= self.profile.url.merge(:page => path.split('/'))
   end
@@ -408,17 +412,19 @@ class Article < ActiveRecord::Base
   end
 
   def download? view = nil
-    (self.uploaded_file? and not self.image?) or
-      (self.image? and view.blank?) or
-      (not self.uploaded_file? and self.mime_type != 'text/html')
+    false
   end
 
   def is_followed_by?(user)
     self.person_followers.include? user
   end
 
+  def download_disposition
+    'inline'
+  end
+
   def download_headers
-    {}
+    { :filename => filename, :type => mime_type, :disposition => download_disposition}
   end
 
   def alternate_languages


=====================================
app/models/rss_feed.rb
=====================================
--- a/app/models/rss_feed.rb
+++ b/app/models/rss_feed.rb
@@ -65,6 +65,10 @@ class RssFeed < Article
     'text/xml'
   end
 
+  def download?(view = nil)
+    true
+  end
+
   include Rails.application.routes.url_helpers
   def fetch_articles
     if parent && parent.has_posts?


=====================================
app/models/uploaded_file.rb
=====================================
--- a/app/models/uploaded_file.rb
+++ b/app/models/uploaded_file.rb
@@ -2,6 +2,9 @@
 #
 # Limitation: only file metadata are versioned. Only the latest version
 # of the file itself is kept. (FIXME?)
+
+require 'sdbm'
+
 class UploadedFile < Article
 
   attr_accessible :uploaded_data, :title
@@ -10,6 +13,19 @@ class UploadedFile < Article
     _('File')
   end
 
+  DBM_PRIVATE_FILE = 'cache/private_files'
+  after_save do |uploaded_file|
+    if uploaded_file.published_changed?
+      dbm = SDBM.open(DBM_PRIVATE_FILE)
+      if uploaded_file.published
+        dbm.delete(uploaded_file.public_filename)
+      else
+        dbm.store(uploaded_file.public_filename, uploaded_file.full_path)
+      end
+      dbm.close
+    end
+  end
+
   track_actions :upload_image, :after_create, :keep_params => ["view_url", "thumbnail_path", "parent.url", "parent.name"], :if => Proc.new { |a| a.published? && a.image? && !a.parent.nil? && a.parent.gallery? }, :custom_target => :parent
 
   def title
@@ -106,10 +122,13 @@ class UploadedFile < Article
     self.name ||= self.filename
   end
 
-  def download_headers
-    {
-      'Content-Disposition' => "attachment; filename=\"#{self.filename}\"",
-    }
+  def download_disposition
+    case content_type
+    when 'application/pdf'
+      'inline'
+    else
+      'attachment'
+    end
   end
 
   def data


=====================================
app/views/file_presenter/_generic.html.erb
=====================================
--- a/app/views/file_presenter/_generic.html.erb
+++ b/app/views/file_presenter/_generic.html.erb
@@ -2,4 +2,4 @@
   <%= generic.abstract %>
 </div>
 
-<%= button(:download, _('Download'), [Noosfero.root, generic.public_filename].join, class:'download-link', option:'primary', size:'lg') %>
+<%= button(:download, _('Download'), generic.url, class:'download-link', option:'primary', size:'lg', :target => "_blank") %>


=====================================
debian/apache2/virtualhost.conf
=====================================
--- a/debian/apache2/virtualhost.conf
+++ b/debian/apache2/virtualhost.conf
@@ -8,6 +8,19 @@ DocumentRoot "/usr/share/noosfero/public"
 
 RewriteEngine On
 
+# If your XMPP XMPP/BOSH isn't in localhost, change the config below to correct
+# point to address
+RewriteRule /http-bind http://localhost:5280/http-bind [P,QSA,L]
+<Proxy http://localhost:5280/http-bind>
+  Order Allow,Deny
+  Allow from All
+</Proxy>
+
+# Pass access to private files to backend
+RewriteMap private_files "dbm=sdbm:/usr/share/noosfero/cache/private_files"
+RewriteCond ${private_files:$1|NOT_FOUND} !NOT_FOUND
+RewriteRule ^(/articles/.*) ${private_files:$1} [P,QSA,L]
+
 # Rewrite index to check for static index.html
 RewriteRule ^/$ /index.html [QSA]
 


=====================================
debian/dbinstall
=====================================
--- a/debian/dbinstall
+++ b/debian/dbinstall
@@ -5,8 +5,6 @@ set -e
 # dbconfig-common uses "pgsql", but we want "postgresql"
 sed -i -e 's/adapter: pgsql/adapter: postgresql/' /etc/noosfero/database.yml
 
-/etc/init.d/noosfero setup
-
 cd /usr/share/noosfero && su noosfero -c "rake db:schema:load RAILS_ENV=production"
 cd /usr/share/noosfero && su noosfero -c "rake db:migrate RAILS_ENV=production SCHEMA=/dev/null"
 cd /usr/share/noosfero && su noosfero -c "rake db:data:minimal RAILS_ENV=production"


=====================================
debian/dbupgrade
=====================================
--- a/debian/dbupgrade
+++ b/debian/dbupgrade
@@ -2,7 +2,5 @@
 
 set -e
 
-/etc/init.d/noosfero setup
-
 cd /usr/share/noosfero && su noosfero -c "rake db:migrate RAILS_ENV=production SCHEMA=/dev/null"
 


=====================================
debian/noosfero.links
=====================================
--- a/debian/noosfero.links
+++ b/debian/noosfero.links
@@ -1,5 +1,6 @@
 var/tmp/noosfero                                    usr/share/noosfero/tmp
 var/log/noosfero                                    usr/share/noosfero/log
+var/cache/noosfero                                  usr/share/noosfero/cache
 etc/noosfero/database.yml                           usr/share/noosfero/config/database.yml
 etc/noosfero/unicorn.rb                             usr/share/noosfero/config/unicorn.rb
 etc/noosfero/plugins                                usr/share/noosfero/config/plugins


=====================================
debian/noosfero.postinst
=====================================
--- a/debian/noosfero.postinst
+++ b/debian/noosfero.postinst
@@ -68,10 +68,17 @@ if [ ! -z "$RET" ]; then
   export NOOSFERO_DOMAIN="$RET"
 fi
 
+/etc/init.d/noosfero setup
+
 # dbconfig-common magic
 . /usr/share/dbconfig-common/dpkg/postinst
 dbc_go noosfero $@
 
+if [ ! -f /usr/share/noosfero/cache/private_files.pag ] && [ $1 = "configure" ] && [ -n  $2 ]; then
+  echo "Creating private files dbm map..."
+  cd /usr/share/noosfero && su noosfero -c "rake cache:private_files RAILS_ENV=production"
+fi
+
 # stop debconf to avoid the problem with infinite hanging, cfe
 # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=295477
 db_stop


=====================================
debian/update-noosfero-apache
=====================================
--- a/debian/update-noosfero-apache
+++ b/debian/update-noosfero-apache
@@ -17,13 +17,13 @@ if test -x /usr/share/noosfero/script/apacheconf; then
   if ! test -e "$apache_site"; then
     echo "Generating apache virtual host ..."
     cd /usr/share/noosfero && su noosfero -c "RAILS_ENV=production ./script/apacheconf virtualhosts" > "$apache_site"
-  else
-    pattern="Include \/etc\/noosfero\/apache\/virtualhost.conf"
-    include="Include \/usr\/share\/noosfero\/util\/chat\/apache\/xmpp.conf"
-    if ! cat $apache_site | grep "^ *$include" > /dev/null ; then
-      echo "Updating apache virtual host ..."
-      sed -i "s/.*$pattern.*/  $include\n&/" $apache_site
-    fi
+  fi
+
+  # remove old way to include chat config
+  pattern="Include \/usr\/share\/noosfero\/util\/chat\/apache\/xmpp.conf"
+  if cat $apache_site | grep "^ *$pattern" > /dev/null ; then
+    echo "Removing obsolete chat configuration ..."
+    sed -i "/.*$pattern.*/d" $apache_site
   fi
 
   echo 'Noosfero Apache configuration updated.'


=====================================
etc/init.d/noosfero
=====================================
--- a/etc/init.d/noosfero
+++ b/etc/init.d/noosfero
@@ -86,6 +86,13 @@ do_setup() {
     chmod 750 /var/tmp/noosfero
   fi
 
+  # Noosfero cache directory
+  if [ ! -d /var/cache/noosfero ]; then
+    mkdir /var/cache/noosfero
+    chown $NOOSFERO_USER:root /var/cache/noosfero
+    chmod 755 /var/cache/noosfero
+  fi
+
   # symlink the directories into Noosfero directory
   if [ ! -e $NOOSFERO_DIR/tmp ]; then
     ln -s /var/tmp/noosfero $NOOSFERO_DIR/tmp
@@ -96,6 +103,9 @@ do_setup() {
   if [ ! -e $NOOSFERO_DIR/log ]; then
     ln -s /var/log/noosfero $NOOSFERO_DIR/log
   fi
+  if [ ! -e $NOOSFERO_DIR/cache ]; then
+    ln -s /var/cache/noosfero $NOOSFERO_DIR/cache
+  fi
 }
 
 do_start() {


=====================================
lib/file_presenter.rb
=====================================
--- a/lib/file_presenter.rb
+++ b/lib/file_presenter.rb
@@ -52,8 +52,8 @@ class FilePresenter
     nil
   end
 
-  def download?(view=nil)
-    false
+  def download? view = nil
+    view.blank?
   end
 
   def short_description


=====================================
lib/tasks/cache.rake
=====================================
--- /dev/null
+++ b/lib/tasks/cache.rake
@@ -0,0 +1,14 @@
+namespace :cache do
+  task :private_files => :environment do
+    require 'sdbm'
+
+    hash = {}
+    UploadedFile.where(:published => false).find_each do |uploaded_file|
+      hash[uploaded_file.public_filename] = uploaded_file.full_path
+    end
+
+    dbm = SDBM.open(UploadedFile::DBM_PRIVATE_FILE)
+    dbm.update(hash)
+    dbm.close
+  end
+end


=====================================
script/apacheconf
=====================================
--- a/script/apacheconf
+++ b/script/apacheconf
@@ -17,7 +17,6 @@ when 'virtualhosts'
       puts "  #{server_directive} #{domain.name}"
       server_directive = 'ServerAlias'
     end
-    puts "  Include /usr/share/noosfero/util/chat/apache/xmpp.conf"
     puts "  Include /etc/noosfero/apache/virtualhost.conf"
     puts "</VirtualHost>"
   end


=====================================
test/functional/content_viewer_controller_test.rb
=====================================
--- a/test/functional/content_viewer_controller_test.rb
+++ b/test/functional/content_viewer_controller_test.rb
@@ -51,27 +51,26 @@ class ContentViewerControllerTest < ActionController::TestCase
     assert_response :missing
   end
 
-  should 'produce a download-link when article is a uploaded file' do
+  should 'produce a download-link when view page is true' do
     profile = create_user('someone').person
     html = UploadedFile.create! :uploaded_data => fixture_file_upload('/files/500.html', 'text/html'), :profile => profile
     html.save!
 
-    get :view_page, :profile => 'someone', :page => [ '500.html' ]
+    get :view_page, :profile => 'someone', :page => [ '500.html' ], :view => true
 
     assert_response :success
-    assert_match /#{html.public_filename}/, @response.body
+    assert_select "a[href=#{html.full_path}]"
   end
 
-  should 'download file when article is image' do
+  should 'download file when view page is blank' do
     profile = create_user('someone').person
     image = UploadedFile.create! :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :profile => profile
     image.save!
 
     get :view_page, :profile => 'someone', :page => [ 'rails.png' ]
 
-    assert_response :success
-    assert_not_nil assigns(:page).data
-    assert_match /image\/png/, @response.headers['Content-Type']
+    assert_response :redirect
+    assert_redirected_to image.public_filename
   end
 
   should 'display image on a page when article is image and has a view param' do


=====================================
test/unit/article_block_test.rb
=====================================
--- a/test/unit/article_block_test.rb
+++ b/test/unit/article_block_test.rb
@@ -140,6 +140,8 @@ class ArticleBlockTest < ActiveSupport::TestCase
     block.article = file
     block.save!
 
+    UploadedFile.any_instance.stubs(:url).returns('myhost.mydomain/path/to/file')
+
     assert_tag_in_string instance_eval(&block.content), :tag => 'a', :content => _('Download')
   end
 


=====================================
test/unit/article_test.rb
=====================================
--- a/test/unit/article_test.rb
+++ b/test/unit/article_test.rb
@@ -2241,4 +2241,15 @@ class ArticleTest < ActiveSupport::TestCase
     assert !a.display_preview?
   end
 
+  should 'return full_path' do
+    p1 = fast_create(Profile)
+    p2 = fast_create(Profile)
+    p2.domains << Domain.create!(:name => 'p2.domain')
+    a1 = fast_create(Article, :profile_id => p1.id)
+    a2 = fast_create(Article, :profile_id => p2.id)
+
+    assert_equal "/#{p1.identifier}/#{a1.path}", a1.full_path
+    assert_equal "/#{a2.path}", a2.full_path
+  end
+
 end


=====================================
test/unit/blog_helper_test.rb
=====================================
--- a/test/unit/blog_helper_test.rb
+++ b/test/unit/blog_helper_test.rb
@@ -101,11 +101,9 @@ class BlogHelperTest < ActionView::TestCase
 
   should 'display link to file if post is an uploaded_file' do
     file = create(UploadedFile, :uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain'), :profile => profile, :published => true, :parent => blog)
-
     result = display_post(file)
-    assert_tag_in_string result, :tag => 'a',
-                                 :attributes => { :href => file.public_filename },
-                                 :content => _('Download')
+
+    assert_tag_in_string result, :tag => 'a', :content => _('Download')
   end
 
   should 'display image if post is an image' do


=====================================
test/unit/uploaded_file_test.rb
=====================================
--- a/test/unit/uploaded_file_test.rb
+++ b/test/unit/uploaded_file_test.rb
@@ -357,4 +357,25 @@ class UploadedFileTest < ActiveSupport::TestCase
     assert_instance_of Fixnum, UploadedFile.max_size
   end
 
+  should 'add file to dbm if it becomes private' do
+    require 'sdbm'
+    public_file = create(UploadedFile, :uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain'), :profile => profile, :published => true)
+    private_file = create(UploadedFile, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :profile => profile, :published => false)
+
+    dbm = SDBM.open(UploadedFile::DBM_PRIVATE_FILE)
+    assert !dbm.has_key?(public_file.public_filename)
+    assert dbm.has_key?(private_file.public_filename)
+    dbm.close
+
+    public_file.published = false
+    public_file.save!
+    private_file.published = true
+    private_file.save!
+
+    dbm = SDBM.open(UploadedFile::DBM_PRIVATE_FILE)
+    assert dbm.has_key?(public_file.public_filename)
+    assert !dbm.has_key?(private_file.public_filename)
+    dbm.close
+  end
+
 end


=====================================
util/chat/apache/xmpp.conf deleted
=====================================
--- a/util/chat/apache/xmpp.conf
+++ /dev/null
@@ -1,11 +0,0 @@
-# If your XMPP XMPP/BOSH isn't in localhost, change the config below to correct
-# point to address
-
-  RewriteEngine On
-  RewriteRule /http-bind http://localhost:5280/http-bind [P,QSA,L]
-  <Proxy http://localhost:5280/http-bind>
-    Order Allow,Deny
-    Allow from All
-  </Proxy>
-
-# vim: ft=apache



View it on GitLab: https://gitlab.com/noosfero/noosfero/compare/2a0453241dc9bd4de32b9595d8020cc206063ffa...1c3dc68da731f78b61f2923c4c022137475eab19
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listas.softwarelivre.org/pipermail/noosfero-dev/attachments/20160225/09320214/attachment-0001.html>


More information about the Noosfero-dev mailing list