Index: app/helpers/repositories_helper.rb
===================================================================
--- app/helpers/repositories_helper.rb (revision 12119)
+++ app/helpers/repositories_helper.rb (working copy)
@@ -150,18 +150,34 @@
end
def subversion_field_tags(form, repository)
- content_tag('p', form.text_field(:url, :size => 60, :required => true,
- :disabled => !repository.safe_attribute?('url')) +
- '
'.html_safe +
- '(file:///, http://, https://, svn://, svn+[tunnelscheme]://)') +
- content_tag('p', form.text_field(:login, :size => 30)) +
- content_tag('p', form.password_field(
- :password, :size => 30, :name => 'ignore',
- :value => ((repository.new_record? || repository.password.blank?) ? '' : ('x'*15)),
- :onfocus => "this.value=''; this.name='repository[password]';",
- :onchange => "this.name='repository[password]';"))
+
+ login_options = [["--- #{l(:actionview_instancetag_blank_option)} ---", '']]
+ login_options << [l("repository_login_usernamepassword"), 0]
+ login_options << [l("repository_login_current_username"), 1]
+ login_options << [l("repository_login_current_role"), 2]
+
+ content_tag('p', form.text_field(:url, :size => 60, :required => true,
+ :disabled => !repository.safe_attribute?('url')) +
+ '
'.html_safe +
+ '(file:///, http://, https://, svn://, svn+[tunnelscheme]://)') +
+ content_tag('p', form.text_field(:root_url, :size => 60) +
+ '
(this needs to be set to the to the highest level in the SVN tree allowed if not the URL)') +
+ content_tag('p', form.select(:login_method, login_options)) +
+ content_tag('p', form.text_field(:login, :size => 30)) +
+ content_tag('p', form.password_field(
+ :password, :size => 30, :name => 'ignore',
+ :value => ((repository.new_record? || repository.password.blank?) ? '' : ('x'*15)),
+ :onfocus => "this.value=''; this.name='repository[password]';",
+ :onchange => "this.name='repository[password]';")) +
+ content_tag('p', form.password_field(:security_token, :size => 30, :name => 'ignore',
+ :value => ((repository.new_record? || repository.security_token.blank?) ? '' : ('x'*15)),
+ :onfocus => "this.value=''; this.name='repository[security_token]';",
+ :onchange => "this.name='repository[security_token]';"))
end
+# select_tag('login_method', options_for_select(login_method, repository.class.name.demodulize),
+# :onchange => remote_function(:url => { :controller => 'repositories', :action => 'edit', :id => @project }, :method => :get, :with => "Form.serialize(this.form)") ) +
+
def darcs_field_tags(form, repository)
content_tag('p', form.text_field(
:url, :label => l(:field_path_to_repository),
Index: app/models/repository.rb
===================================================================
--- app/models/repository.rb (revision 12119)
+++ app/models/repository.rb (working copy)
@@ -94,8 +94,7 @@
def scm
unless @scm
- @scm = self.scm_adapter.new(url, root_url,
- login, password, path_encoding)
+ @scm = self.scm_adapter.new(url, root_url, login, password, path_encoding, login_method, security_token, project)
if root_url.blank? && @scm.root_url.present?
update_attribute(:root_url, @scm.root_url)
end
Index: app/models/repository/subversion.rb
===================================================================
--- app/models/repository/subversion.rb (revision 12119)
+++ app/models/repository/subversion.rb (working copy)
@@ -18,7 +18,7 @@
require 'redmine/scm/adapters/subversion_adapter'
class Repository::Subversion < Repository
- attr_protected :root_url
+ #attr_protected :root_url
validates_presence_of :url
validates_format_of :url, :with => /\A(http|https|svn(\+[^\s:\/\\]+)?|file):\/\/.+/i
Index: extra/svn/Redmine.pm
===================================================================
--- extra/svn/Redmine.pm (revision 12119)
+++ extra/svn/Redmine.pm (working copy)
@@ -1,10 +1,15 @@
-package Apache::Authn::Redmine;
+package Apache::Redmine;
-=head1 Apache::Authn::Redmine
+=head1 Apache::Redmine
Redmine - a mod_perl module to authenticate webdav subversion users
against redmine database
+In addition this module allows to authenticate a redmine server
+for webdav subversion access, bypassing full authentication, still
+allowing to apply repository based security (e.g. .authz files)
+
+
=head1 SYNOPSIS
This module allow anonymous users to browse public project and
@@ -37,8 +42,8 @@
=head1 CONFIGURATION
## This module has to be in your perl path
- ## eg: /usr/lib/perl5/Apache/Authn/Redmine.pm
- PerlLoadModule Apache::Authn::Redmine
+ ## eg: /usr/lib/perl5/Apache/Redmine.pm
+ PerlLoadModule Apache::Redmine
DAV svn
SVNParentPath "/var/svn"
@@ -47,8 +52,8 @@
AuthName redmine
Require valid-user
- PerlAccessHandler Apache::Authn::Redmine::access_handler
- PerlAuthenHandler Apache::Authn::Redmine::authen_handler
+ PerlAccessHandler Apache::Redmine::access_handler
+ PerlAuthenHandler Apache::Redmine::authen_handler
## for mysql
RedmineDSN "DBI:mysql:database=databasename;host=my.db.server"
@@ -73,6 +78,16 @@
Order deny,allow
Deny from all
# only allow reading orders
+
+ AuthType Basic
+ AuthName redmine
+ Require valid-user
+
+ PerlAccessHandler Apache::Redmine::redmine_access_handler
+ PerlAuthenHandler Apache::Redmine::redmine_authen_handler
+
+ RedmineSecurityToken "redmine"
+
Allow from redmine.server.ip
@@ -229,6 +244,11 @@
errmsg => 'RedmineCacheCredsMax must be decimal number',
},
{
+ name => 'RedmineSecurityToken',
+ req_override => OR_AUTHCFG,
+ args_how => TAKE1,
+ errmsg => 'RedmineSecurityToken additional authentication token',
+ }, {
name => 'RedmineGitSmartHttp',
req_override => OR_AUTHCFG,
args_how => TAKE1,
@@ -256,6 +276,7 @@
sub RedmineDbUser { set_val('RedmineDbUser', @_); }
sub RedmineDbPass { set_val('RedmineDbPass', @_); }
+sub RedmineSecurityToken { set_val('RedmineSecurityToken', @_); }
sub RedmineDbWhereClause {
my ($self, $parms, $arg) = @_;
$self->{RedmineQuery} = trim($self->{RedmineQuery}.($arg ? $arg : "")." ");
@@ -319,7 +340,7 @@
my $r = shift;
unless ($r->some_auth_required) {
- $r->log_reason("No authentication has been configured");
+ $r->log_reason("Apache::Redmine - No authentication has been configured in webserver (access_handler)");
return FORBIDDEN;
}
@@ -541,4 +562,43 @@
return DBI->connect($cfg->{RedmineDSN}, $cfg->{RedmineDbUser}, $cfg->{RedmineDbPass});
}
+sub redmine_access_handler {
+ my $r = shift;
+
+ unless ($r->some_auth_required) {
+ $r->log_reason("Apache::Redmine - No auth has been configured in vhost conf (redmine_access_handler)");
+ return FORBIDDEN;
+ }
+
+ my $method = $r->method;
+ return OK unless defined $read_only_methods{$method};
+
+ my $project_id = get_project_identifier($r);
+
+ $r->set_handlers(PerlAuthenHandler => [\&OK])
+ if is_public_project($project_id, $r);
+
+ return OK
+}
+
+sub redmine_authen_handler {
+ my $r = shift;
+
+ my ($res, $redmine_pass) = $r->get_basic_auth_pw();
+ return $res unless $res == OK;
+
+ my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config);
+
+ if ($cfg->{RedmineSecurityToken}) {
+ my $securityToken = $cfg->{RedmineSecurityToken};
+
+ if ($securityToken ne $redmine_pass) {
+ $r->log_error("Apache::Redmine - Provided SecurityToken did not match (redmine_authen_handler)");
+ $r->note_auth_failure();
+ return AUTH_REQUIRED;
+ }
+ }
+ return OK;
+}
+
1;
Index: db/migrate/109_add_special_repository_security.rb
===================================================================
--- db/migrate/109_add_special_repository_security.rb (revision 0)
+++ db/migrate/109_add_special_repository_security.rb (revision 0)
@@ -0,0 +1,11 @@
+class AddSpecialRepositorySecurity < ActiveRecord::Migration
+ def self.down
+ remove_column :repositories, :login_method
+ remove_column :repositories, :security_token
+ end
+
+ def self.up
+ add_column :repositories, :login_method, :int, :default => 0, :null => true
+ add_column :repositories, :security_token, :string, :limit => 60, :default => "", :null => true
+ end
+end
\ No newline at end of file
Property changes on: db/migrate/109_add_special_repository_security.rb
___________________________________________________________________
Added: svn:executable
+ *
Index: config/locales/en-GB.yml
===================================================================
--- config/locales/en-GB.yml (revision 12119)
+++ config/locales/en-GB.yml (working copy)
@@ -312,7 +312,14 @@
field_text: Text field
field_visible: Visible
field_warn_on_leaving_unsaved: "Warn me when leaving a page with unsaved text"
+ field_login_method: Authentication method
+ field_security_token: Security token
+ field_root_url: Root URL
+ repository_login_usernamepassword: Provided credentials
+ repository_login_current_username: Name of current user
+ repository_login_current_role: Role of current user
+
setting_app_title: Application title
setting_app_subtitle: Application subtitle
setting_welcome_text: Welcome text
Index: config/locales/en.yml
===================================================================
--- config/locales/en.yml (revision 12119)
+++ config/locales/en.yml (working copy)
@@ -331,7 +331,14 @@
field_board_parent: Parent forum
field_private_notes: Private notes
field_inherit_members: Inherit members
+ field_login_method: Authentication method
+ field_security_token: Security token
+ field_root_url: Root URL
+ repository_login_usernamepassword: Provided credentials
+ repository_login_current_username: Name of current user
+ repository_login_current_role: Role of current user
+
setting_app_title: Application title
setting_app_subtitle: Application subtitle
setting_welcome_text: Welcome text
Index: lib/redmine/scm/adapters/subversion_adapter.rb
===================================================================
--- lib/redmine/scm/adapters/subversion_adapter.rb (revision 12119)
+++ lib/redmine/scm/adapters/subversion_adapter.rb (working copy)
@@ -257,9 +257,32 @@
private
def credentials_string
- str = ''
- str << " --username #{shell_quote(@login)}" unless @login.blank?
- str << " --password #{shell_quote(@password)}" unless @login.blank? || @password.blank?
+ if !(User.current.is_a?(AnonymousUser))
+
+ if (@login_method == 1)
+ str = ''
+ str << " --username #{shell_quote(User.current.login)}"
+ str << " --password #{shell_quote( (@security_token.blank? ? "foo" : @security_token) )}"
+ end
+
+ if (@login_method == 2) && (!@project.nil?)
+ role = User.current.role_for_project(@project)
+
+ if !role.blank?
+ str = ''
+ str << " --username #{shell_quote(role.name)}"
+ str << " --password #{shell_quote( (@security_token.blank? ? "foo" : @security_token) )}"
+ end
+ end
+
+ end
+
+ if (str.blank?)
+ str = ''
+ str << " --username #{shell_quote(@login)}" unless @login.blank?
+ str << " --password #{shell_quote(@password)}" unless @login.blank? || @password.blank?
+ end
+
str << " --no-auth-cache --non-interactive"
str
end
Index: lib/redmine/scm/adapters/abstract_adapter.rb
===================================================================
--- lib/redmine/scm/adapters/abstract_adapter.rb (revision 12119)
+++ lib/redmine/scm/adapters/abstract_adapter.rb (working copy)
@@ -79,12 +79,14 @@
end
end
- def initialize(url, root_url=nil, login=nil, password=nil,
- path_encoding=nil)
+ def initialize(url, root_url=nil, login=nil, password=nil, path_encoding=nil, login_method=nil, security_token=nil, project=nil)
@url = url
@login = login if login && !login.empty?
@password = (password || "") if @login
@root_url = root_url.blank? ? retrieve_root_url : root_url
+ @login_method = login_method.blank? ? 0 : login_method
+ @security_token = security_token.blank? ? "" : security_token
+ @project = project
end
def adapter_name
@@ -99,6 +101,10 @@
respond_to?('annotate')
end
+ def use_current_user
+ @use_current_user
+ end
+
def root_url
@root_url
end