#1464 Digest authentication
This commit is contained in:
parent
d9b9cb05f5
commit
8f7157ca19
@ -22,11 +22,12 @@
|
|||||||
class DmsfController < ApplicationController
|
class DmsfController < ApplicationController
|
||||||
include RedmineDmsf::DmsfZip
|
include RedmineDmsf::DmsfZip
|
||||||
|
|
||||||
before_action :find_project, except: %i[expand_folder index]
|
before_action :find_project, except: %i[expand_folder index digest reset_digest]
|
||||||
before_action :authorize, except: %i[expand_folder index]
|
before_action :authorize, except: %i[expand_folder index digest reset_digest]
|
||||||
before_action :authorize_global, only: [:index]
|
before_action :authorize_global, only: [:index]
|
||||||
before_action :find_folder,
|
before_action :find_folder,
|
||||||
except: %i[new create edit_root save_root add_email append_email autocomplete_for_user]
|
except: %i[new create edit_root save_root add_email append_email autocomplete_for_user digest
|
||||||
|
reset_digest]
|
||||||
before_action :find_parent, only: %i[new create delete]
|
before_action :find_parent, only: %i[new create delete]
|
||||||
before_action :permissions
|
before_action :permissions
|
||||||
# Also try to lookup folder by title if this is an API call
|
# Also try to lookup folder by title if this is an API call
|
||||||
@ -35,6 +36,7 @@ class DmsfController < ApplicationController
|
|||||||
before_action :project_roles, only: %i[new edit create save]
|
before_action :project_roles, only: %i[new edit create save]
|
||||||
before_action :find_target_folder, only: %i[copymove entries_operation]
|
before_action :find_target_folder, only: %i[copymove entries_operation]
|
||||||
before_action :check_target_folder, only: [:entries_operation]
|
before_action :check_target_folder, only: [:entries_operation]
|
||||||
|
before_action :require_login, only: %i[digest reset_digest]
|
||||||
|
|
||||||
accept_api_auth :show, :create, :save, :delete, :entries_operation
|
accept_api_auth :show, :create, :save, :delete, :entries_operation
|
||||||
|
|
||||||
@ -465,6 +467,27 @@ class DmsfController < ApplicationController
|
|||||||
redirect_back_or_default trash_dmsf_path id: @project
|
redirect_back_or_default trash_dmsf_path id: @project
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Reset WebDAV digest
|
||||||
|
def digest; end
|
||||||
|
|
||||||
|
def reset_digest
|
||||||
|
if request.post?
|
||||||
|
raise StandardError, l(:notice_account_wrong_password) unless User.current.check_password?(params[:password])
|
||||||
|
|
||||||
|
# We have to create a token first to prevent an autogenerated token's value
|
||||||
|
token = Token.create!(user_id: User.current.id, action: 'dmsf-webdav-digest')
|
||||||
|
token.value = Digest::MD5.hexdigest(
|
||||||
|
"#{User.current.login}:#{RedmineDmsf::Webdav::AUTHENTICATION_REALM}:#{params[:password]}"
|
||||||
|
)
|
||||||
|
token.save
|
||||||
|
flash[:notice] = l(:notice_webdav_digest_reset)
|
||||||
|
end
|
||||||
|
rescue StandardError => e
|
||||||
|
flash[:error] = e.message
|
||||||
|
ensure
|
||||||
|
redirect_to my_account_path
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def users_for_new_users
|
def users_for_new_users
|
||||||
|
|||||||
30
app/views/dmsf/_digest.html.erb
Normal file
30
app/views/dmsf/_digest.html.erb
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<%
|
||||||
|
# Redmine plugin for Document Management System "Features"
|
||||||
|
#
|
||||||
|
# Karel Pičman <karel.picman@kontron.com>
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
%>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= l(:text_dmsf_webdav_digest_reset) %>
|
||||||
|
</p>
|
||||||
|
<%= form_tag(dmsf_reset_digest_path) do %>
|
||||||
|
<label for="password">
|
||||||
|
<%= l(:field_password) %>
|
||||||
|
</label>
|
||||||
|
<%= password_field_tag 'password', nil, autofocus: true %>
|
||||||
|
<input type="submit" name="reset" value="<%= l(:button_reset) %>" onclick="hideModal(this);">
|
||||||
|
<% end %>
|
||||||
22
app/views/dmsf/digest.js.erb
Normal file
22
app/views/dmsf/digest.js.erb
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<%
|
||||||
|
# Redmine plugin for Document Management System "Features"
|
||||||
|
#
|
||||||
|
# Karel Pičman <karel.picman@kontron.com>
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
%>
|
||||||
|
|
||||||
|
$('#ajax-modal').html('<%= escape_javascript render partial: 'digest' %>');
|
||||||
|
showModal('ajax-modal', '30%', '<%= l(:label_dmsf_webdav_digest) %>');
|
||||||
38
app/views/my/_sidebar.html.erb
Normal file
38
app/views/my/_sidebar.html.erb
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<%
|
||||||
|
# encoding: utf-8
|
||||||
|
#
|
||||||
|
# Redmine plugin for Document Management System "Features"
|
||||||
|
#
|
||||||
|
# Karel Pičman <karel.picman@kontron.com>
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
%>
|
||||||
|
|
||||||
|
<%= render partial: "/#{File.dirname(__FILE__)}/../../../../../app/views/my/sidebar.html.erb" %>
|
||||||
|
|
||||||
|
<%# DMSF extension do %>
|
||||||
|
<% if Setting.plugin_redmine_dmsf['dmsf_webdav_authentication'] == 'Digest' %>
|
||||||
|
<h4><%= l(:label_dmsf_webdav_digest) %></h4>
|
||||||
|
<p>
|
||||||
|
<% token = Token.find_by(user_id: @user.id, action: 'dmsf-webdav-digest') %>
|
||||||
|
<% if token %>
|
||||||
|
<%= l(:label_dmsf_webdav_digest_created_on, distance_of_time_in_words(Time.now, token.created_on)) %>
|
||||||
|
<% else %>
|
||||||
|
<%= l(:label_missing_dmsf_webdav_digest) %>
|
||||||
|
<% end %>
|
||||||
|
(<%= link_to l(:button_reset), dmsf_digest_path, remote: true %>)
|
||||||
|
</p>
|
||||||
|
<% end %>
|
||||||
|
<%# end %>
|
||||||
@ -277,6 +277,17 @@
|
|||||||
<% visible_class = @settings['dmsf_webdav'].blank? ? 'dmsf-hidden' : '' %>
|
<% visible_class = @settings['dmsf_webdav'].blank? ? 'dmsf-hidden' : '' %>
|
||||||
|
|
||||||
<div id="dmsf_webdav_block" class="<%= visible_class %>">
|
<div id="dmsf_webdav_block" class="<%= visible_class %>">
|
||||||
|
<p>
|
||||||
|
<%= content_tag :label, l(:label_webdav_authentication) %>
|
||||||
|
<% auth_types = [%w[Basic Basic], %w[Digest Digest]] %>
|
||||||
|
<% @settings['dmsf_webdav_authentication'] = 'Basic' if @settings['dmsf_webdav_authentication'].blank? %>
|
||||||
|
<%= select_tag 'settings[dmsf_webdav_authentication]',
|
||||||
|
options_for_select(auth_types, @settings['dmsf_webdav_authentication']) %>
|
||||||
|
<em class="<%= klass %>">
|
||||||
|
<%= l(:note_webdav_authentication) %> <br>
|
||||||
|
<%= l(:label_default)%>: <%= auth_types[0][0] %>
|
||||||
|
</em>
|
||||||
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<%= content_tag :label, l(:label_webdav_strategy) %>
|
<%= content_tag :label, l(:label_webdav_strategy) %>
|
||||||
<%= select_tag'settings[dmsf_webdav_strategy]',
|
<%= select_tag'settings[dmsf_webdav_strategy]',
|
||||||
@ -316,13 +327,12 @@
|
|||||||
<%= l(:label_default) %>: ^\~\$|\.tmp$
|
<%= l(:label_default) %>: ^\~\$|\.tmp$
|
||||||
</em>
|
</em>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<%= content_tag :label, l(:label_webdav_use_project_names) %>
|
<%= content_tag :label, l(:label_webdav_use_project_names) %>
|
||||||
<%= check_box_tag 'settings[dmsf_webdav_use_project_names]', true, @settings['dmsf_webdav_use_project_names'] %>
|
<%= check_box_tag 'settings[dmsf_webdav_use_project_names]', true, @settings['dmsf_webdav_use_project_names'] %>
|
||||||
<em class="<%= klass %>">
|
<em class="<%= klass %>">
|
||||||
<%= l(:note_webdav_use_project_names) %> <br>
|
<%= l(:note_webdav_use_project_names) %> <br>
|
||||||
<%= l(:label_default)%>: <%= l(:general_text_No)%>
|
<%= l(:label_default)%>: <%= l(:general_text_No) %>
|
||||||
</em>
|
</em>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -479,6 +479,16 @@ cs:
|
|||||||
error_not_supported_image_format: Nepodporovaný formát obrázku
|
error_not_supported_image_format: Nepodporovaný formát obrázku
|
||||||
error_not_supported_video_format: Nepodporovaný formát videa
|
error_not_supported_video_format: Nepodporovaný formát videa
|
||||||
|
|
||||||
|
label_webdav_authentication: WebDAV autentifikace
|
||||||
|
note_webdav_authentication: Autentifikační metoda Basic není považována za bezpečnou a z toho důvodu je blokována
|
||||||
|
některými klienty. Metoda Digest, na druhou stranu, vyžaduje od uživatelů vytvoření DMSF WebDAV digestu v jejich
|
||||||
|
profilu za použití hesla, které se pak používá při autentifikaci z WebDAV klienta.
|
||||||
|
label_dmsf_webdav_digest_created_on: "Dmsf WebDAV digest created %{value} ago"
|
||||||
|
label_missing_dmsf_webdav_digest: Chybějící Dmsf WebDAV digest
|
||||||
|
label_dmsf_webdav_digest: DMSF WebDAV digest
|
||||||
|
text_dmsf_webdav_digest_reset: Je vyžadováno vaše heslo pro vygenerování nového DMSF WebDAV digestu.
|
||||||
|
notice_webdav_digest_reset: Váš DMSF WebDAV digest byl resetován.
|
||||||
|
|
||||||
easy_pages:
|
easy_pages:
|
||||||
modules:
|
modules:
|
||||||
dmsf_locked_documents: My locked documents
|
dmsf_locked_documents: My locked documents
|
||||||
|
|||||||
@ -474,6 +474,16 @@ de:
|
|||||||
error_not_supported_image_format: Nicht unterstütztes Bildformat
|
error_not_supported_image_format: Nicht unterstütztes Bildformat
|
||||||
error_not_supported_video_format: Nicht unterstütztes Videoformat
|
error_not_supported_video_format: Nicht unterstütztes Videoformat
|
||||||
|
|
||||||
|
label_webdav_authentication: WebDAV Authentication
|
||||||
|
note_webdav_authentication: Basic authentication method is considered as unsecure and therefore blocked by some
|
||||||
|
clients. Digest authentication, on the other hand, requires users to create a DMSF WebDAV digest in their profiles
|
||||||
|
using a password that must by used for authentication in their WebDAV clients after that.
|
||||||
|
label_dmsf_webdav_digest_created_on: "Dmsf WebDAV digest created %{value} ago"
|
||||||
|
label_missing_dmsf_webdav_digest: Missing a Dmsf WebDAV digest
|
||||||
|
label_dmsf_webdav_digest: DMSF WebDAV digest
|
||||||
|
text_dmsf_webdav_digest_reset: You are supposed to enter your password to generate a new DMSF WebDAV digest.
|
||||||
|
notice_webdav_digest_reset: Your DMSF WebDAV digest was reset.
|
||||||
|
|
||||||
easy_pages:
|
easy_pages:
|
||||||
modules:
|
modules:
|
||||||
dmsf_locked_documents: Von mir gesperrte Dokumente
|
dmsf_locked_documents: Von mir gesperrte Dokumente
|
||||||
|
|||||||
@ -478,6 +478,16 @@ en:
|
|||||||
error_not_supported_image_format: Not supported image format
|
error_not_supported_image_format: Not supported image format
|
||||||
error_not_supported_video_format: Not supported video format
|
error_not_supported_video_format: Not supported video format
|
||||||
|
|
||||||
|
label_webdav_authentication: WebDAV Authentication
|
||||||
|
note_webdav_authentication: Basic authentication method is considered as unsecure and therefore blocked by some
|
||||||
|
clients. Digest authentication, on the other hand, requires users to create a DMSF WebDAV digest in their profiles
|
||||||
|
using a password that must by used for authentication in their WebDAV clients after that.
|
||||||
|
label_dmsf_webdav_digest_created_on: "Dmsf WebDAV digest created %{value} ago"
|
||||||
|
label_missing_dmsf_webdav_digest: Missing a Dmsf WebDAV digest
|
||||||
|
label_dmsf_webdav_digest: DMSF WebDAV digest
|
||||||
|
text_dmsf_webdav_digest_reset: You are supposed to enter your password to generate a new DMSF WebDAV digest.
|
||||||
|
notice_webdav_digest_reset: Your DMSF WebDAV digest was reset.
|
||||||
|
|
||||||
easy_pages:
|
easy_pages:
|
||||||
modules:
|
modules:
|
||||||
dmsf_locked_documents: My locked documents
|
dmsf_locked_documents: My locked documents
|
||||||
|
|||||||
@ -478,6 +478,16 @@ es:
|
|||||||
error_not_supported_image_format: Not supported image format
|
error_not_supported_image_format: Not supported image format
|
||||||
error_not_supported_video_format: Not supported video format
|
error_not_supported_video_format: Not supported video format
|
||||||
|
|
||||||
|
label_webdav_authentication: WebDAV Authentication
|
||||||
|
note_webdav_authentication: Basic authentication method is considered as unsecure and therefore blocked by some
|
||||||
|
clients. Digest authentication, on the other hand, requires users to create a DMSF WebDAV digest in their profiles
|
||||||
|
using a password that must by used for authentication in their WebDAV clients after that.
|
||||||
|
label_dmsf_webdav_digest_created_on: "Dmsf WebDAV digest created %{value} ago"
|
||||||
|
label_missing_dmsf_webdav_digest: Missing a Dmsf WebDAV digest
|
||||||
|
label_dmsf_webdav_digest: DMSF WebDAV digest
|
||||||
|
text_dmsf_webdav_digest_reset: You are supposed to enter your password to generate a new DMSF WebDAV digest.
|
||||||
|
notice_webdav_digest_reset: Your DMSF WebDAV digest was reset.
|
||||||
|
|
||||||
easy_pages:
|
easy_pages:
|
||||||
modules:
|
modules:
|
||||||
dmsf_locked_documents: My locked documents
|
dmsf_locked_documents: My locked documents
|
||||||
|
|||||||
@ -457,6 +457,16 @@ fa:
|
|||||||
error_not_supported_image_format: Not supported image format
|
error_not_supported_image_format: Not supported image format
|
||||||
error_not_supported_video_format: Not supported video format
|
error_not_supported_video_format: Not supported video format
|
||||||
|
|
||||||
|
label_webdav_authentication: WebDAV Authentication
|
||||||
|
note_webdav_authentication: Basic authentication method is considered as unsecure and therefore blocked by some
|
||||||
|
clients. Digest authentication, on the other hand, requires users to create a DMSF WebDAV digest in their profiles
|
||||||
|
using a password that must by used for authentication in their WebDAV clients after that.
|
||||||
|
label_dmsf_webdav_digest_created_on: "Dmsf WebDAV digest created %{value} ago"
|
||||||
|
label_missing_dmsf_webdav_digest: Missing a Dmsf WebDAV digest
|
||||||
|
label_dmsf_webdav_digest: DMSF WebDAV digest
|
||||||
|
text_dmsf_webdav_digest_reset: You are supposed to enter your password to generate a new DMSF WebDAV digest.
|
||||||
|
notice_webdav_digest_reset: Your DMSF WebDAV digest was reset.
|
||||||
|
|
||||||
easy_pages:
|
easy_pages:
|
||||||
modules:
|
modules:
|
||||||
dmsf_locked_documents: اسناد قفل شدهی من
|
dmsf_locked_documents: اسناد قفل شدهی من
|
||||||
|
|||||||
@ -479,6 +479,16 @@ fr:
|
|||||||
error_not_supported_image_format: Not supported image format
|
error_not_supported_image_format: Not supported image format
|
||||||
error_not_supported_video_format: Not supported video format
|
error_not_supported_video_format: Not supported video format
|
||||||
|
|
||||||
|
label_webdav_authentication: WebDAV Authentication
|
||||||
|
note_webdav_authentication: Basic authentication method is considered as unsecure and therefore blocked by some
|
||||||
|
clients. Digest authentication, on the other hand, requires users to create a DMSF WebDAV digest in their profiles
|
||||||
|
using a password that must by used for authentication in their WebDAV clients after that.
|
||||||
|
label_dmsf_webdav_digest_created_on: "Dmsf WebDAV digest created %{value} ago"
|
||||||
|
label_missing_dmsf_webdav_digest: Missing a Dmsf WebDAV digest
|
||||||
|
label_dmsf_webdav_digest: DMSF WebDAV digest
|
||||||
|
text_dmsf_webdav_digest_reset: You are supposed to enter your password to generate a new DMSF WebDAV digest.
|
||||||
|
notice_webdav_digest_reset: Your DMSF WebDAV digest was reset.
|
||||||
|
|
||||||
easy_pages:
|
easy_pages:
|
||||||
modules:
|
modules:
|
||||||
dmsf_locked_documents: My locked documents
|
dmsf_locked_documents: My locked documents
|
||||||
|
|||||||
@ -479,6 +479,16 @@ hu:
|
|||||||
error_not_supported_image_format: Not supported image format
|
error_not_supported_image_format: Not supported image format
|
||||||
error_not_supported_video_format: Not supported video format
|
error_not_supported_video_format: Not supported video format
|
||||||
|
|
||||||
|
label_webdav_authentication: WebDAV Authentication
|
||||||
|
note_webdav_authentication: Basic authentication method is considered as unsecure and therefore blocked by some
|
||||||
|
clients. Digest authentication, on the other hand, requires users to create a DMSF WebDAV digest in their profiles
|
||||||
|
using a password that must by used for authentication in their WebDAV clients after that.
|
||||||
|
label_dmsf_webdav_digest_created_on: "Dmsf WebDAV digest created %{value} ago"
|
||||||
|
label_missing_dmsf_webdav_digest: Missing a Dmsf WebDAV digest
|
||||||
|
label_dmsf_webdav_digest: DMSF WebDAV digest
|
||||||
|
text_dmsf_webdav_digest_reset: You are supposed to enter your password to generate a new DMSF WebDAV digest.
|
||||||
|
notice_webdav_digest_reset: Your DMSF WebDAV digest was reset.
|
||||||
|
|
||||||
easy_pages:
|
easy_pages:
|
||||||
modules:
|
modules:
|
||||||
dmsf_locked_documents: My locked documents
|
dmsf_locked_documents: My locked documents
|
||||||
|
|||||||
@ -478,6 +478,16 @@ it: # Italian strings thx 2 Matteo Arceci!
|
|||||||
error_not_supported_image_format: Not supported image format
|
error_not_supported_image_format: Not supported image format
|
||||||
error_not_supported_video_format: Not supported video format
|
error_not_supported_video_format: Not supported video format
|
||||||
|
|
||||||
|
label_webdav_authentication: WebDAV Authentication
|
||||||
|
note_webdav_authentication: Basic authentication method is considered as unsecure and therefore blocked by some
|
||||||
|
clients. Digest authentication, on the other hand, requires users to create a DMSF WebDAV digest in their profiles
|
||||||
|
using a password that must by used for authentication in their WebDAV clients after that.
|
||||||
|
label_dmsf_webdav_digest_created_on: "Dmsf WebDAV digest created %{value} ago"
|
||||||
|
label_missing_dmsf_webdav_digest: Missing a Dmsf WebDAV digest
|
||||||
|
label_dmsf_webdav_digest: DMSF WebDAV digest
|
||||||
|
text_dmsf_webdav_digest_reset: You are supposed to enter your password to generate a new DMSF WebDAV digest.
|
||||||
|
notice_webdav_digest_reset: Your DMSF WebDAV digest was reset.
|
||||||
|
|
||||||
easy_pages:
|
easy_pages:
|
||||||
modules:
|
modules:
|
||||||
dmsf_locked_documents: My locked documents
|
dmsf_locked_documents: My locked documents
|
||||||
|
|||||||
@ -480,6 +480,16 @@ ja:
|
|||||||
error_not_supported_image_format: Not supported image format
|
error_not_supported_image_format: Not supported image format
|
||||||
error_not_supported_video_format: Not supported video format
|
error_not_supported_video_format: Not supported video format
|
||||||
|
|
||||||
|
label_webdav_authentication: WebDAV Authentication
|
||||||
|
note_webdav_authentication: Basic authentication method is considered as unsecure and therefore blocked by some
|
||||||
|
clients. Digest authentication, on the other hand, requires users to create a DMSF WebDAV digest in their profiles
|
||||||
|
using a password that must by used for authentication in their WebDAV clients after that.
|
||||||
|
label_dmsf_webdav_digest_created_on: "Dmsf WebDAV digest created %{value} ago"
|
||||||
|
label_missing_dmsf_webdav_digest: Missing a Dmsf WebDAV digest
|
||||||
|
label_dmsf_webdav_digest: DMSF WebDAV digest
|
||||||
|
text_dmsf_webdav_digest_reset: You are supposed to enter your password to generate a new DMSF WebDAV digest.
|
||||||
|
notice_webdav_digest_reset: Your DMSF WebDAV digest was reset.
|
||||||
|
|
||||||
easy_pages:
|
easy_pages:
|
||||||
modules:
|
modules:
|
||||||
dmsf_locked_documents: 自分がロック中の文書
|
dmsf_locked_documents: 自分がロック中の文書
|
||||||
|
|||||||
@ -478,6 +478,16 @@ ko:
|
|||||||
error_not_supported_image_format: Not supported image format
|
error_not_supported_image_format: Not supported image format
|
||||||
error_not_supported_video_format: Not supported video format
|
error_not_supported_video_format: Not supported video format
|
||||||
|
|
||||||
|
label_webdav_authentication: WebDAV Authentication
|
||||||
|
note_webdav_authentication: Basic authentication method is considered as unsecure and therefore blocked by some
|
||||||
|
clients. Digest authentication, on the other hand, requires users to create a DMSF WebDAV digest in their profiles
|
||||||
|
using a password that must by used for authentication in their WebDAV clients after that.
|
||||||
|
label_dmsf_webdav_digest_created_on: "Dmsf WebDAV digest created %{value} ago"
|
||||||
|
label_missing_dmsf_webdav_digest: Missing a Dmsf WebDAV digest
|
||||||
|
label_dmsf_webdav_digest: DMSF WebDAV digest
|
||||||
|
text_dmsf_webdav_digest_reset: You are supposed to enter your password to generate a new DMSF WebDAV digest.
|
||||||
|
notice_webdav_digest_reset: Your DMSF WebDAV digest was reset.
|
||||||
|
|
||||||
easy_pages:
|
easy_pages:
|
||||||
modules:
|
modules:
|
||||||
dmsf_locked_documents: 내 잠긴 파일
|
dmsf_locked_documents: 내 잠긴 파일
|
||||||
|
|||||||
@ -478,6 +478,16 @@ nl:
|
|||||||
error_not_supported_image_format: Not supported image format
|
error_not_supported_image_format: Not supported image format
|
||||||
error_not_supported_video_format: Not supported video format
|
error_not_supported_video_format: Not supported video format
|
||||||
|
|
||||||
|
label_webdav_authentication: WebDAV Authentication
|
||||||
|
note_webdav_authentication: Basic authentication method is considered as unsecure and therefore blocked by some
|
||||||
|
clients. Digest authentication, on the other hand, requires users to create a DMSF WebDAV digest in their profiles
|
||||||
|
using a password that must by used for authentication in their WebDAV clients after that.
|
||||||
|
label_dmsf_webdav_digest_created_on: "Dmsf WebDAV digest created %{value} ago"
|
||||||
|
label_missing_dmsf_webdav_digest: Missing a Dmsf WebDAV digest
|
||||||
|
label_dmsf_webdav_digest: DMSF WebDAV digest
|
||||||
|
text_dmsf_webdav_digest_reset: You are supposed to enter your password to generate a new DMSF WebDAV digest.
|
||||||
|
notice_webdav_digest_reset: Your DMSF WebDAV digest was reset.
|
||||||
|
|
||||||
easy_pages:
|
easy_pages:
|
||||||
modules:
|
modules:
|
||||||
dmsf_locked_documents: My locked documents
|
dmsf_locked_documents: My locked documents
|
||||||
|
|||||||
@ -477,6 +477,16 @@ pl:
|
|||||||
error_not_supported_image_format: Not supported image format
|
error_not_supported_image_format: Not supported image format
|
||||||
error_not_supported_video_format: Not supported video format
|
error_not_supported_video_format: Not supported video format
|
||||||
|
|
||||||
|
label_webdav_authentication: WebDAV Authentication
|
||||||
|
note_webdav_authentication: Basic authentication method is considered as unsecure and therefore blocked by some
|
||||||
|
clients. Digest authentication, on the other hand, requires users to create a DMSF WebDAV digest in their profiles
|
||||||
|
using a password that must by used for authentication in their WebDAV clients after that.
|
||||||
|
label_dmsf_webdav_digest_created_on: "Dmsf WebDAV digest created %{value} ago"
|
||||||
|
label_missing_dmsf_webdav_digest: Missing a Dmsf WebDAV digest
|
||||||
|
label_dmsf_webdav_digest: DMSF WebDAV digest
|
||||||
|
text_dmsf_webdav_digest_reset: You are supposed to enter your password to generate a new DMSF WebDAV digest.
|
||||||
|
notice_webdav_digest_reset: Your DMSF WebDAV digest was reset.
|
||||||
|
|
||||||
easy_pages:
|
easy_pages:
|
||||||
modules:
|
modules:
|
||||||
dmsf_locked_documents: My locked documents
|
dmsf_locked_documents: My locked documents
|
||||||
|
|||||||
@ -478,6 +478,16 @@ pt-BR:
|
|||||||
error_not_supported_image_format: Not supported image format
|
error_not_supported_image_format: Not supported image format
|
||||||
error_not_supported_video_format: Not supported video format
|
error_not_supported_video_format: Not supported video format
|
||||||
|
|
||||||
|
label_webdav_authentication: WebDAV Authentication
|
||||||
|
note_webdav_authentication: Basic authentication method is considered as unsecure and therefore blocked by some
|
||||||
|
clients. Digest authentication, on the other hand, requires users to create a DMSF WebDAV digest in their profiles
|
||||||
|
using a password that must by used for authentication in their WebDAV clients after that.
|
||||||
|
label_dmsf_webdav_digest_created_on: "Dmsf WebDAV digest created %{value} ago"
|
||||||
|
label_missing_dmsf_webdav_digest: Missing a Dmsf WebDAV digest
|
||||||
|
label_dmsf_webdav_digest: DMSF WebDAV digest
|
||||||
|
text_dmsf_webdav_digest_reset: You are supposed to enter your password to generate a new DMSF WebDAV digest.
|
||||||
|
notice_webdav_digest_reset: Your DMSF WebDAV digest was reset.
|
||||||
|
|
||||||
easy_pages:
|
easy_pages:
|
||||||
modules:
|
modules:
|
||||||
dmsf_locked_documents: My locked documents
|
dmsf_locked_documents: My locked documents
|
||||||
|
|||||||
@ -479,6 +479,16 @@ sl:
|
|||||||
error_not_supported_image_format: Not supported image format
|
error_not_supported_image_format: Not supported image format
|
||||||
error_not_supported_video_format: Not supported video format
|
error_not_supported_video_format: Not supported video format
|
||||||
|
|
||||||
|
label_webdav_authentication: WebDAV Authentication
|
||||||
|
note_webdav_authentication: Basic authentication method is considered as unsecure and therefore blocked by some
|
||||||
|
clients. Digest authentication, on the other hand, requires users to create a DMSF WebDAV digest in their profiles
|
||||||
|
using a password that must by used for authentication in their WebDAV clients after that.
|
||||||
|
label_dmsf_webdav_digest_created_on: "Dmsf WebDAV digest created %{value} ago"
|
||||||
|
label_missing_dmsf_webdav_digest: Missing a Dmsf WebDAV digest
|
||||||
|
label_dmsf_webdav_digest: DMSF WebDAV digest
|
||||||
|
text_dmsf_webdav_digest_reset: You are supposed to enter your password to generate a new DMSF WebDAV digest.
|
||||||
|
notice_webdav_digest_reset: Your DMSF WebDAV digest was reset.
|
||||||
|
|
||||||
easy_pages:
|
easy_pages:
|
||||||
modules:
|
modules:
|
||||||
dmsf_locked_documents: My locked documents
|
dmsf_locked_documents: My locked documents
|
||||||
|
|||||||
@ -480,6 +480,16 @@ uk:
|
|||||||
error_not_supported_image_format: Not supported image format
|
error_not_supported_image_format: Not supported image format
|
||||||
error_not_supported_video_format: Not supported video format
|
error_not_supported_video_format: Not supported video format
|
||||||
|
|
||||||
|
label_webdav_authentication: WebDAV Authentication
|
||||||
|
note_webdav_authentication: Basic authentication method is considered as unsecure and therefore blocked by some
|
||||||
|
clients. Digest authentication, on the other hand, requires users to create a DMSF WebDAV digest in their profiles
|
||||||
|
using a password that must by used for authentication in their WebDAV clients after that.
|
||||||
|
label_dmsf_webdav_digest_created_on: "Dmsf WebDAV digest created %{value} ago"
|
||||||
|
label_missing_dmsf_webdav_digest: Missing a Dmsf WebDAV digest
|
||||||
|
label_dmsf_webdav_digest: DMSF WebDAV digest
|
||||||
|
text_dmsf_webdav_digest_reset: You are supposed to enter your password to generate a new DMSF WebDAV digest.
|
||||||
|
notice_webdav_digest_reset: Your DMSF WebDAV digest was reset.
|
||||||
|
|
||||||
easy_pages:
|
easy_pages:
|
||||||
modules:
|
modules:
|
||||||
dmsf_locked_documents: Мої заблоковані документи
|
dmsf_locked_documents: Мої заблоковані документи
|
||||||
|
|||||||
@ -477,6 +477,16 @@ zh-TW:
|
|||||||
error_not_supported_image_format: Not supported image format
|
error_not_supported_image_format: Not supported image format
|
||||||
error_not_supported_video_format: Not supported video format
|
error_not_supported_video_format: Not supported video format
|
||||||
|
|
||||||
|
label_webdav_authentication: WebDAV Authentication
|
||||||
|
note_webdav_authentication: Basic authentication method is considered as unsecure and therefore blocked by some
|
||||||
|
clients. Digest authentication, on the other hand, requires users to create a DMSF WebDAV digest in their profiles
|
||||||
|
using a password that must by used for authentication in their WebDAV clients after that.
|
||||||
|
label_dmsf_webdav_digest_created_on: "Dmsf WebDAV digest created %{value} ago"
|
||||||
|
label_missing_dmsf_webdav_digest: Missing a Dmsf WebDAV digest
|
||||||
|
label_dmsf_webdav_digest: DMSF WebDAV digest
|
||||||
|
text_dmsf_webdav_digest_reset: You are supposed to enter your password to generate a new DMSF WebDAV digest.
|
||||||
|
notice_webdav_digest_reset: Your DMSF WebDAV digest was reset.
|
||||||
|
|
||||||
easy_pages:
|
easy_pages:
|
||||||
modules:
|
modules:
|
||||||
dmsf_locked_documents: My locked documents
|
dmsf_locked_documents: My locked documents
|
||||||
|
|||||||
@ -479,6 +479,16 @@ zh:
|
|||||||
error_not_supported_image_format: Not supported image format
|
error_not_supported_image_format: Not supported image format
|
||||||
error_not_supported_video_format: Not supported video format
|
error_not_supported_video_format: Not supported video format
|
||||||
|
|
||||||
|
label_webdav_authentication: WebDAV Authentication
|
||||||
|
note_webdav_authentication: Basic authentication method is considered as unsecure and therefore blocked by some
|
||||||
|
clients. Digest authentication, on the other hand, requires users to create a DMSF WebDAV digest in their profiles
|
||||||
|
using a password that must by used for authentication in their WebDAV clients after that.
|
||||||
|
label_dmsf_webdav_digest_created_on: "Dmsf WebDAV digest created %{value} ago"
|
||||||
|
label_missing_dmsf_webdav_digest: Missing a Dmsf WebDAV digest
|
||||||
|
label_dmsf_webdav_digest: DMSF WebDAV digest
|
||||||
|
text_dmsf_webdav_digest_reset: You are supposed to enter your password to generate a new DMSF WebDAV digest.
|
||||||
|
notice_webdav_digest_reset: Your DMSF WebDAV digest was reset.
|
||||||
|
|
||||||
easy_pages:
|
easy_pages:
|
||||||
modules:
|
modules:
|
||||||
dmsf_locked_documents: My locked documents
|
dmsf_locked_documents: My locked documents
|
||||||
|
|||||||
@ -56,6 +56,8 @@ if Redmine::Plugin.installed? 'redmine_dmsf'
|
|||||||
put '/projects/:id/dmsf', controller: 'dmsf', action: 'drop'
|
put '/projects/:id/dmsf', controller: 'dmsf', action: 'drop'
|
||||||
get '/projects/:id/dmsf/empty_trash', to: 'dmsf#empty_trash', as: 'empty_trash'
|
get '/projects/:id/dmsf/empty_trash', to: 'dmsf#empty_trash', as: 'empty_trash'
|
||||||
get '/dmsf', to: 'dmsf#index', as: 'dmsf_index'
|
get '/dmsf', to: 'dmsf#index', as: 'dmsf_index'
|
||||||
|
get '/dmsf/digest', to: 'dmsf#digest', as: 'dmsf_digest'
|
||||||
|
post '/dmsf/digest', to: 'dmsf#reset_digest', as: 'dmsf_reset_digest'
|
||||||
|
|
||||||
# dmsf_context_menu_controller
|
# dmsf_context_menu_controller
|
||||||
match '/projects/dmsf/context_menu', to: 'dmsf_context_menus#dmsf', as: 'dmsf_context_menu', via: %i[get post]
|
match '/projects/dmsf/context_menu', to: 'dmsf_context_menus#dmsf', as: 'dmsf_context_menu', via: %i[get post]
|
||||||
@ -98,22 +100,6 @@ if Redmine::Plugin.installed? 'redmine_dmsf'
|
|||||||
get '/dmsf_files/:id', controller: 'dmsf_files', action: 'show'
|
get '/dmsf_files/:id', controller: 'dmsf_files', action: 'show'
|
||||||
get '/dmsf_files/:id/download', controller: 'dmsf_files', action: 'show', download: ''
|
get '/dmsf_files/:id/download', controller: 'dmsf_files', action: 'show', download: ''
|
||||||
|
|
||||||
#
|
|
||||||
# files_copy controller
|
|
||||||
# /dmsf/files/<file id>/copy
|
|
||||||
##
|
|
||||||
post '/dmsf/files/:id/copy/copy', controller: 'dmsf_files_copy', action: 'copy'
|
|
||||||
post '/dmsf/files/:id/copy/move', controller: 'dmsf_files_copy', action: 'move'
|
|
||||||
get '/dmsf/files/:id/copy', controller: 'dmsf_files_copy', action: 'new', as: 'copy_file'
|
|
||||||
|
|
||||||
#
|
|
||||||
# folders_copy controller
|
|
||||||
# /dmsf/folders/<folder id>/copy
|
|
||||||
##
|
|
||||||
post '/dmsf/folders/:id/copy/copy', controller: 'dmsf_folders_copy', action: 'copy'
|
|
||||||
post '/dmsf/folders/:id/copy/move', controller: 'dmsf_folders_copy', action: 'move'
|
|
||||||
get '/dmsf/folders/:id/copy', controller: 'dmsf_folders_copy', action: 'new', as: 'copy_folder'
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# dmsf_files controller
|
# dmsf_files controller
|
||||||
# /dmsf/files/<file id>
|
# /dmsf/files/<file id>
|
||||||
|
|||||||
3
init.rb
3
init.rb
@ -62,7 +62,8 @@ Redmine::Plugin.register :redmine_dmsf do
|
|||||||
'dmsf_global_menu_disabled' => nil,
|
'dmsf_global_menu_disabled' => nil,
|
||||||
'dmsf_default_query' => nil,
|
'dmsf_default_query' => nil,
|
||||||
'empty_minor_version_by_default' => nil,
|
'empty_minor_version_by_default' => nil,
|
||||||
'remove_original_documents_module' => nil
|
'remove_original_documents_module' => nil,
|
||||||
|
'dmsf_webdav_authentication' => 'Basic'
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,10 @@ module Dav4rack
|
|||||||
end
|
end
|
||||||
|
|
||||||
def authorization
|
def authorization
|
||||||
get_header 'HTTP_AUTHORIZATION'
|
get_header('HTTP_AUTHORIZATION') ||
|
||||||
|
get_header('X-HTTP_AUTHORIZATION') ||
|
||||||
|
get_header('X_HTTP_AUTHORIZATION') ||
|
||||||
|
get_header('REDIRECT_X_HTTP_AUTHORIZATION')
|
||||||
end
|
end
|
||||||
|
|
||||||
# path relative to root uri
|
# path relative to root uri
|
||||||
|
|||||||
@ -505,7 +505,7 @@ module Dav4rack
|
|||||||
def propnames_xml
|
def propnames_xml
|
||||||
response = Ox::Element.new(D_RESPONSE)
|
response = Ox::Element.new(D_RESPONSE)
|
||||||
response << ox_element(D_HREF, href)
|
response << ox_element(D_HREF, href)
|
||||||
propstats response, { OK => [propname_properties.map { |p| [p, nil] }].to_h }
|
propstats response, { OK => propname_properties.index_with { |p| [p, nil] } }
|
||||||
response
|
response
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -23,6 +23,7 @@ require "#{File.dirname(__FILE__)}/resource_proxy"
|
|||||||
|
|
||||||
module RedmineDmsf
|
module RedmineDmsf
|
||||||
module Webdav
|
module Webdav
|
||||||
|
AUTHENTICATION_REALM = 'DMSF content'
|
||||||
# Custom middleware
|
# Custom middleware
|
||||||
class CustomMiddleware
|
class CustomMiddleware
|
||||||
def initialize(app)
|
def initialize(app)
|
||||||
|
|||||||
@ -31,6 +31,78 @@ module RedmineDmsf
|
|||||||
# Switch the locale to English for WebDAV requests in order to have log messages in English
|
# Switch the locale to English for WebDAV requests in order to have log messages in English
|
||||||
I18n.with_locale(:en, &action)
|
I18n.with_locale(:en, &action)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def process
|
||||||
|
return super unless Setting.plugin_redmine_dmsf['dmsf_webdav_authentication'] == 'Digest'
|
||||||
|
|
||||||
|
status = skip_authorization? || authenticate ? process_action || OK : Dav4rack::HttpStatus::Unauthorized
|
||||||
|
rescue Dav4rack::HttpStatus::Status => e
|
||||||
|
status = e
|
||||||
|
ensure
|
||||||
|
if status
|
||||||
|
response.status = status.code
|
||||||
|
if status.code == 401
|
||||||
|
time_stamp = Time.now.to_i
|
||||||
|
h_once = Digest::MD5.hexdigest("#{time_stamp}:#{SecureRandom.hex(32)}")
|
||||||
|
nonce = Base64.strict_encode64("#{time_stamp}#{h_once}")
|
||||||
|
response['WWW-Authenticate'] =
|
||||||
|
%(Digest realm="#{authentication_realm}", nonce="#{nonce}", algorithm="MD5", qop="auth")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def authenticate
|
||||||
|
return super unless Setting.plugin_redmine_dmsf['dmsf_webdav_authentication'] == 'Digest'
|
||||||
|
|
||||||
|
auth_header = request.authorization.to_s
|
||||||
|
scheme = auth_header.split(' ', 2).first&.downcase
|
||||||
|
if scheme == 'digest'
|
||||||
|
Rails.logger.info 'Authentication: digest'
|
||||||
|
auth = Rack::Auth::Digest::Request.new(request.env)
|
||||||
|
params = auth.params
|
||||||
|
username = params['username']
|
||||||
|
response = params['response']
|
||||||
|
cnonce = params['cnonce']
|
||||||
|
nonce = params['nonce']
|
||||||
|
uri = params['uri']
|
||||||
|
qop = params['qop']
|
||||||
|
nc = params['nc']
|
||||||
|
user = User.find_by(login: username)
|
||||||
|
unless user
|
||||||
|
log_error('Digest authentication: provided user name has no match in the DB')
|
||||||
|
raise Unauthorized
|
||||||
|
end
|
||||||
|
token = Token.find_by(user_id: user.id, action: 'dmsf-webdav-digest')
|
||||||
|
if token.nil? && defined?(EasyExtensions)
|
||||||
|
if user.easy_digest_token_expired?
|
||||||
|
log_error('Digest authentication: digest token expired')
|
||||||
|
raise Unauthorized
|
||||||
|
end
|
||||||
|
ha1 = user.easy_digest_token
|
||||||
|
else
|
||||||
|
unless token
|
||||||
|
log_error("Digest authentication: no digest found for #{user}")
|
||||||
|
raise Unauthorized
|
||||||
|
end
|
||||||
|
ha1 = token.value
|
||||||
|
end
|
||||||
|
ha2 = Digest::MD5.hexdigest("#{request.env['REQUEST_METHOD']}:#{uri}")
|
||||||
|
required_response = if qop
|
||||||
|
Digest::MD5.hexdigest("#{ha1}:#{nonce}:#{nc}:#{cnonce}:#{qop}:#{ha2}")
|
||||||
|
else
|
||||||
|
Digest::MD5.hexdigest("#{ha1}:#{nonce}:#{ha2}")
|
||||||
|
end
|
||||||
|
if required_response == response
|
||||||
|
User.current = user
|
||||||
|
else
|
||||||
|
Rails.logger.error 'Digest authentication: digest response is incorrect'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
raise Unauthorized if User.current.anonymous?
|
||||||
|
|
||||||
|
Rails.logger.info "Current user: #{User.current}, User-Agent: #{request.user_agent}"
|
||||||
|
User.current
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -199,6 +199,10 @@ module RedmineDmsf
|
|||||||
namespaces[ns_href] || add_namespace(ns_href)
|
namespaces[ns_href] || add_namespace(ns_href)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def authentication_realm
|
||||||
|
RedmineDmsf::Webdav::AUTHENTICATION_REALM
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def get_resource_class(path)
|
def get_resource_class(path)
|
||||||
|
|||||||
@ -648,4 +648,31 @@ class DmsfControllerTest < RedmineDmsf::Test::TestCase
|
|||||||
assert_response :redirect
|
assert_response :redirect
|
||||||
assert_nil flash[:error]
|
assert_nil flash[:error]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_digest
|
||||||
|
post '/login', params: { username: 'jsmith', password: 'jsmith' }
|
||||||
|
get '/dmsf/digest', xhr: true
|
||||||
|
assert_response :success
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_digest_unauthorized
|
||||||
|
get '/dmsf/digest', xhr: true
|
||||||
|
assert_response :unauthorized
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_reset_digest
|
||||||
|
post '/login', params: { username: 'jsmith', password: 'jsmith' }
|
||||||
|
post '/dmsf/digest', params: { password: 'jsmith' }
|
||||||
|
assert_response :redirect
|
||||||
|
assert_redirected_to my_account_path
|
||||||
|
token = Token.find_by(user_id: @jsmith.id, action: 'dmsf-webdav-digest')
|
||||||
|
assert token
|
||||||
|
assert_equal Digest::MD5.hexdigest("jsmith:#{RedmineDmsf::Webdav::AUTHENTICATION_REALM}:jsmith"), token.value
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_reset_digest_unauthorized
|
||||||
|
post '/dmsf/digest', params: { password: 'jsmith' }
|
||||||
|
assert_response :redirect
|
||||||
|
assert_redirected_to 'http://www.example.com/login?back_url=http%3A%2F%2Fwww.example.com%2Fdmsf%2Fdigest'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user