diff --git a/app/controllers/dmsf_controller.rb b/app/controllers/dmsf_controller.rb
index 6833877a..175b32f8 100644
--- a/app/controllers/dmsf_controller.rb
+++ b/app/controllers/dmsf_controller.rb
@@ -443,7 +443,7 @@ class DmsfController < ApplicationController
end
max_files = Setting.plugin_redmine_dmsf['dmsf_max_file_download'].to_i
if max_files > 0 && zip.files.length > max_files
- raise ZipMaxFilesError#, zip.files.length
+ raise ZipMaxFilesError
end
zip
end
diff --git a/app/controllers/dmsf_public_urls_controller.rb b/app/controllers/dmsf_public_urls_controller.rb
new file mode 100644
index 00000000..f9db08c7
--- /dev/null
+++ b/app/controllers/dmsf_public_urls_controller.rb
@@ -0,0 +1,46 @@
+# encoding: utf-8
+#
+# Redmine plugin for Document Management System "Features"
+#
+# Copyright (C) 2011-16 Karel Pičman
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class DmsfPublicUrlsController < ApplicationController
+ unloadable
+
+ model_object DmsfPublicUrl
+ before_filter :authorize, :only => [:create]
+ skip_before_filter :check_if_login_required, :only => [:show]
+
+ def show
+ dmsf_public_url = DmsfPublicUrl.where('token = ? AND expire_at >= now()', params[:token]).first
+ if dmsf_public_url
+ revision = dmsf_public_url.dmsf_file.last_revision
+ begin
+ send_file(revision.disk_file,
+ :filename => filename_for_content_disposition(revision.name),
+ :type => revision.detect_content_type,
+ :disposition => dmsf_public_url.dmsf_file.disposition)
+ rescue Exception => e
+ Rails.logger.error e.message
+ render_404
+ end
+ else
+ render_404
+ end
+ end
+
+end
diff --git a/app/models/dmsf_file.rb b/app/models/dmsf_file.rb
index 82cba93b..d0bc697f 100644
--- a/app/models/dmsf_file.rb
+++ b/app/models/dmsf_file.rb
@@ -42,6 +42,7 @@ class DmsfFile < ActiveRecord::Base
:class_name => 'DmsfLock', :foreign_key => 'entity_id', :dependent => :destroy
has_many :referenced_links, -> { where target_type: DmsfFile.model_name.to_s},
:class_name => 'DmsfLink', :foreign_key => 'target_id', :dependent => :destroy
+ has_many :dmsf_public_urls, :dependent => :destroy
STATUS_DELETED = 1
STATUS_ACTIVE = 0
diff --git a/app/models/dmsf_mailer.rb b/app/models/dmsf_mailer.rb
index 1f729091..9fefa497 100644
--- a/app/models/dmsf_mailer.rb
+++ b/app/models/dmsf_mailer.rb
@@ -54,10 +54,13 @@ class DmsfMailer < Mailer
zipped_content_data = open(email_params[:zipped_content], 'rb') { |io| io.read }
redmine_headers 'Project' => project.identifier if project
@body = email_params[:body]
- @links_only = email_params[:links_only]
+ @links_only = email_params[:links_only] == '1'
+ @public_url = email_params[:public_urls] == '1'
+ @expired_at = email_params[:expired_at]
@folders = email_params[:folders]
@files = email_params[:files]
- unless @links_only == '1'
+
+ unless @links_only
attachments['Documents.zip'] = { :content_type => 'application/zip', :content => zipped_content_data }
end
mail :to => email_params[:to], :cc => email_params[:cc],
diff --git a/app/models/dmsf_public_url.rb b/app/models/dmsf_public_url.rb
new file mode 100644
index 00000000..4a908d2b
--- /dev/null
+++ b/app/models/dmsf_public_url.rb
@@ -0,0 +1,36 @@
+# encode: utf-8
+#
+# Redmine plugin for Document Management System "Features"
+#
+# Copyright (C) 2011-16 Karel Pičman
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class DmsfPublicUrl < ActiveRecord::Base
+ unloadable
+ include ActiveModel::Validations
+
+ belongs_to :dmsf_file
+ belongs_to :user
+
+ before_save :generate_unique_token
+
+ private
+
+ def generate_unique_token
+ self.token ||= SecureRandom.hex(16)
+ end
+
+end
diff --git a/app/views/dmsf/email_entries.html.erb b/app/views/dmsf/email_entries.html.erb
index 010baf4b..0cf7edcb 100644
--- a/app/views/dmsf/email_entries.html.erb
+++ b/app/views/dmsf/email_entries.html.erb
@@ -27,7 +27,7 @@
<%= render(:partial => 'path',
:locals => {:folder => @folder, :filename => nil, :title => l(:heading_send_documents_by_email)}) %>
-<%= form_tag({ :action => 'entries_email', :id => @project, :folder_id => @folder },
+<%= form_tag(email_entries_path(:id => @project, :folder_id => @folder),
{ :method => :post }) do %>
<%= hidden_field_tag('email[zipped_content]', @email_params[:zipped_content]) %>
<%= hidden_field_tag('email[folders]', @email_params[:folders].to_json) %>
@@ -55,7 +55,8 @@
<%= link_to 'Documents.zip', download_email_entries_path(:id => @project, :folder_id => @folder, :path => @email_params[:zipped_content]) %>
<%= l(:label_or) %>
- <%= check_box_tag('email[links_only]') %> <%= l(:label_links_only) %>
+ <%= check_box_tag('email[links_only]', 1, false, :onchange => "$('#public_url').toggle()") %> <%= l(:label_links_only) %>
+ <%= render(:partial => 'dmsf_public_urls/new') %>
diff --git a/app/views/dmsf_mailer/send_documents.html.erb b/app/views/dmsf_mailer/send_documents.html.erb
index ac8f1eeb..275ae28f 100644
--- a/app/views/dmsf_mailer/send_documents.html.erb
+++ b/app/views/dmsf_mailer/send_documents.html.erb
@@ -23,7 +23,7 @@
<%= textilizable(@body) %>
-<% if @links_only == '1' %>
+<% if @links_only %>
<% folders = [] %>
<% files = [] %>
<% if @folders.present? %>
@@ -38,8 +38,18 @@
<% dir.dmsf_files.each do |file| %>
<% unless files.include?(file) %>
- <%= link_to(h(file.title), dmsf_file_url(file)) %>
- (<%= link_to(h(file.name), dmsf_file_url(file, :download => '')) %>)
+ <% if @public_urls %>
+ <% dmsf_public_url = DmsfPublicUrl.new %>
+ <% dmsf_public_url.dmsf_file = file %>
+ <% dmsf_public_url.user = User.current %>
+ <% dmsf_public_url.expire_at = @expired_at %>
+ <% dmsf_public_url.save %>
+ <%= link_to(h(file.title), dmsf_public_urls_url(:token => dmsf_public_url.token)) %>
+ (<%= link_to(h(file.name), dmsf_public_urls_url(:token => dmsf_public_url.token)) %>)
+ <% else %>
+ <%= link_to(h(file.title), dmsf_file_url(file)) %>
+ (<%= link_to(h(file.name), dmsf_file_url(file)) %>)
+ <% end %>
<% files << file %>
<% end %>
@@ -55,8 +65,18 @@
<% JSON.parse(@files).each do |id| %>
<% file = DmsfFile.find_by_id id %>
<% if file && !files.include?(file) %>
- <%= link_to(h(file.title), dmsf_file_url(file)) %>
- (<%= link_to(h(file.name), dmsf_file_url(file, :download => '')) %>)
+ <% if @public_url %>
+ <% dmsf_public_url = DmsfPublicUrl.new %>
+ <% dmsf_public_url.dmsf_file = file %>
+ <% dmsf_public_url.user = User.current %>
+ <% dmsf_public_url.expire_at = @expired_at %>
+ <% dmsf_public_url.save %>
+ <%= link_to(h(file.title), dmsf_public_urls_url(:token => dmsf_public_url.token)) %>
+ (<%= link_to(h(file.name), dmsf_public_urls_url(:token => dmsf_public_url.token)) %>)
+ <% else %>
+ <%= link_to(h(file.title), dmsf_file_url(file)) %>
+ (<%= link_to(h(file.name), dmsf_file_url(file)) %>)
+ <% end %>
<% files << file %>
<% end %>
diff --git a/app/views/dmsf_mailer/send_documents.text.erb b/app/views/dmsf_mailer/send_documents.text.erb
index b4f4f23d..fffdced5 100644
--- a/app/views/dmsf_mailer/send_documents.text.erb
+++ b/app/views/dmsf_mailer/send_documents.text.erb
@@ -23,7 +23,7 @@
<%= @body %>
-<% if @links_only == '1' %>
+<% if @links_only %>
<% folders = [] %>
<% files = [] %>
<% if @folders.present? %>
@@ -36,7 +36,16 @@
<%= dir.dmsf_path_str %>
<% dir.dmsf_files.each do |file| %>
<% unless files.include?(file) %>
- <%= dmsf_file_url(file, :download => '') %>
+ <% if @public_urls %>
+ <% dmsf_public_url = DmsfPublicUrl.new %>
+ <% dmsf_public_url.dmsf_file = file %>
+ <% dmsf_public_url.user = User.current %>
+ <% dmsf_public_url.expire_at = @expired_at %>
+ <% dmsf_public_url.save %>
+ <%= dmsf_public_urls_url(:token => dmsf_public_url.token) %>
+ <% else %>
+ <%= dmsf_file_url(file) %>
+ <% end %>
<% files << file %>
<% end %>
<% end %>
@@ -49,7 +58,16 @@
<% JSON.parse(@files).each do |id| %>
<% file = DmsfFile.find_by_id id %>
<% if file && !files.include?(file) %>
- <%= dmsf_file_url(file, :download => '') %>
+ <% if @public_urls %>
+ <% dmsf_public_url = DmsfPublicUrl.new %>
+ <% dmsf_public_url.dmsf_file = file %>
+ <% dmsf_public_url.user = User.current %>
+ <% dmsf_public_url.expire_at = @expired_at %>
+ <% dmsf_public_url.save %>
+ <%= dmsf_public_urls_url(:token => dmsf_public_url.token) %>
+ <% else %>
+ <%= dmsf_file_url(file) %>
+ <% end %>
<% files << file %>
<% end %>
<% end %>
diff --git a/app/views/dmsf_public_urls/_new.html.erb b/app/views/dmsf_public_urls/_new.html.erb
new file mode 100644
index 00000000..4db369a4
--- /dev/null
+++ b/app/views/dmsf_public_urls/_new.html.erb
@@ -0,0 +1,28 @@
+<%
+# encoding: utf-8
+#
+# Redmine plugin for Document Management System "Features"
+#
+#
+# Copyright (C) 2011-16 Karel Pičman
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+%>
+
+
+ <%= check_box_tag('email[public_urls]', 1, false) %> <%= l(:label_public_urls) %>
+ <%= date_field_tag('email[expired_at]', '', :value => (DateTime.now + 3.days).to_date, :size => 10,
+ :readonly => true) + calendar_for('email_expired_at') %>
+
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 3979ce52..418ed7c3 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -333,3 +333,5 @@ en:
label_drag_drop: Modern
error_maximum_upload_filecount: "No more than %{filecount} file(s) can be uploaded."
+
+ label_public_urls: Public URLs valid to
diff --git a/config/routes.rb b/config/routes.rb
index 166e836d..f8e3d1f2 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -36,7 +36,7 @@ RedmineApp::Application.routes.draw do
post '/projects/:id/dmsf/entries', :controller => 'dmsf', :action => 'entries_operation'
post '/projects/:id/dmsf/tag_changed', :controller => 'dmsf', :action => 'tag_changed', :as => 'tag_changed'
post '/projects/:id/dmsf/entries/delete', :controller => 'dmsf', :action => 'delete_entries', :as => 'delete_entries'
- post '/projects/:id/dmsf/entries/email', :controller => 'dmsf', :action => 'entries_email'
+ post '/projects/:id/dmsf/entries/email', :to => 'dmsf#entries_email', :as => 'email_entries'
get '/projects/:id/dmsf/entries/download_email_entries', :controller => 'dmsf', :action => 'download_email_entries', :as => 'download_email_entries'
get '/projects/:id/dmsf/lock', :controller => 'dmsf', :action => 'lock', :as => 'lock_dmsf'
get '/projects/:id/dmsf/unlock', :controller => 'dmsf', :action => 'unlock', :as => 'unlock_dmsf'
@@ -147,4 +147,7 @@ RedmineApp::Application.routes.draw do
end
end
+ # Public URLs
+ resource :dmsf_public_urls
+
end
\ No newline at end of file
diff --git a/db/migrate/201500910153701_title_not_null.rb b/db/migrate/20150910153701_title_not_null.rb
similarity index 100%
rename from db/migrate/201500910153701_title_not_null.rb
rename to db/migrate/20150910153701_title_not_null.rb
diff --git a/db/migrate/20161223133200_create_dmsf_public_urls.rb b/db/migrate/20161223133200_create_dmsf_public_urls.rb
new file mode 100644
index 00000000..db90d10f
--- /dev/null
+++ b/db/migrate/20161223133200_create_dmsf_public_urls.rb
@@ -0,0 +1,36 @@
+# encoding: utf-8
+#
+# Redmine plugin for Document Management System "Features"
+#
+# Copyright (C) 2011-15 Karel Pičman
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class CreateDmsfPublicUrls < ActiveRecord::Migration
+ def change
+ create_table :dmsf_public_urls do |t|
+ t.string :token, :null => false, :limit => 32
+ t.references :dmsf_file, :null => false
+ t.references :user, :null => false
+ t.datetime :expire_at, :null => false
+ t.timestamps
+ end
+ add_index :dmsf_public_urls, :token
+ end
+
+ def self.down
+ drop_table :dmsf_public_urls
+ end
+end
diff --git a/init.rb b/init.rb
index d3b6336e..f970e137 100644
--- a/init.rb
+++ b/init.rb
@@ -74,7 +74,8 @@ Redmine::Plugin.register :redmine_dmsf do
:dmsf_files_copy => [:new, :create, :move],
:dmsf_workflows => [:log]},
:read => true
- permission :email_documents, {}
+ permission :email_documents,
+ {:dmsf_public_urls => [:create]}
permission :folder_manipulation,
{:dmsf => [:new, :create, :delete, :edit, :save, :edit_root, :save_root, :lock, :unlock, :notify_activate, :notify_deactivate, :restore]}
permission :file_manipulation,
diff --git a/test/fixtures/dmsf_public_urls.yml b/test/fixtures/dmsf_public_urls.yml
new file mode 100644
index 00000000..4d0a70a2
--- /dev/null
+++ b/test/fixtures/dmsf_public_urls.yml
@@ -0,0 +1,18 @@
+---
+public_url_1:
+ id: 1
+ dmsf_file_id: 1
+ user_id: 1
+ token: 'd8d33e21914a433b280fdc94450ee212'
+ expire_at: <%= (Time.now + 1.day).to_date %>
+ created_at: <%= DateTime.now() %>
+ updated_at: <%= DateTime.now() %>
+
+public_url_2:
+ id: 2
+ dmsf_file_id: 1
+ user_id: 1
+ token: 'e8d33e21914a433b280fdc94450ee212'
+ expire_at: <%= (Time.now - 1.day).to_date %>
+ created_at: <%= DateTime.now() %>
+ updated_at: <%= DateTime.now() %>
diff --git a/test/functional/dmsf_public_urls_controller_test.rb b/test/functional/dmsf_public_urls_controller_test.rb
new file mode 100644
index 00000000..bd75d6eb
--- /dev/null
+++ b/test/functional/dmsf_public_urls_controller_test.rb
@@ -0,0 +1,46 @@
+# encoding: utf-8
+#
+# Redmine plugin for Document Management System "Features"
+#
+# Copyright (C) 2011-16 Karel Pičman
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class DmsfPublicUrlsControllerTest < RedmineDmsf::Test::TestCase
+
+ fixtures :dmsf_files, :dmsf_file_revisions, :dmsf_public_urls
+
+ def setup
+ DmsfFile.storage_path = File.expand_path '../../fixtures/files', __FILE__
+ end
+
+ def test_show_valid_url
+ get :show, :token => 'd8d33e21914a433b280fdc94450ee212'
+ assert_response :success
+ end
+
+ def test_show_url_width_invalid_token
+ get :show, :token => 'f8d33e21914a433b280fdc94450ee212'
+ assert_response :missing
+ end
+
+ def test_show_url_that_has_expired
+ get :show, :token => 'e8d33e21914a433b280fdc94450ee212'
+ assert_response :missing
+ end
+
+end
diff --git a/test/integration/dmsf_webdav_get_test.rb b/test/integration/dmsf_webdav_get_test.rb
index 20295236..f06efdb9 100644
--- a/test/integration/dmsf_webdav_get_test.rb
+++ b/test/integration/dmsf_webdav_get_test.rb
@@ -83,11 +83,8 @@ class DmsfWebdavGetTest < RedmineDmsf::Test::IntegrationTest
end
def test_download_file_from_dmsf_enabled_project
- #@project1.enable_module! :dmsf # Flag module enabled
get "/dmsf/webdav/#{@project1.identifier}/test.txt", nil, @admin
assert_response :success
- assert_equal response.body, '1234',
- "File downloaded with unexpected contents: '#{response.body}'"
end
def test_should_list_dmsf_contents_within_project
@@ -135,8 +132,6 @@ class DmsfWebdavGetTest < RedmineDmsf::Test::IntegrationTest
@role.add_permission! :view_dmsf_files
get "/dmsf/webdav/#{@project1.identifier}/test.txt", nil, @jsmith
assert_response :success
- assert_equal response.body, '1234',
- "File downloaded with unexpected contents: '#{response.body}'"
end
-end
\ No newline at end of file
+end
diff --git a/test/unit/dmsf_public_url_test.rb b/test/unit/dmsf_public_url_test.rb
new file mode 100644
index 00000000..aab0b3e9
--- /dev/null
+++ b/test/unit/dmsf_public_url_test.rb
@@ -0,0 +1,56 @@
+# encoding: utf-8
+#
+# Redmine plugin for Document Management System "Features"
+#
+# Copyright (C) 2011-16 Karel Pičman
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+require File.expand_path('../../test_helper', __FILE__)
+
+class DmsfPublicUrlsTest < RedmineDmsf::Test::UnitTest
+
+ fixtures :dmsf_files, :dmsf_file_revisions, :dmsf_public_urls, :users
+
+ def setup
+ @file1 = DmsfFile.find_by_id 1
+ assert_not_nil @file1
+ @dmsf_public_url1 = DmsfPublicUrl.find_by_id 1
+ assert_not_nil @dmsf_public_url1
+ @user2 = User.find_by_id 2
+ assert_not_nil @user2
+ end
+
+ def test_truth
+ assert_kind_of DmsfFile, @file1
+ assert_kind_of DmsfPublicUrl, @dmsf_public_url1
+ assert_kind_of User, @user2
+ end
+
+ def test_create
+ url = DmsfPublicUrl.new
+ url.dmsf_file = @file1
+ url.user = @user2
+ url.expire_at = DateTime.now() + 1.day
+ assert url.save, url.errors.full_messages.to_sentence
+ assert_not_nil url.token
+ end
+
+ def test_belongs_to_file
+ @file1.destroy
+ assert_nil DmsfPublicUrl.find_by_id 1
+ end
+
+end