Index: app/helpers/repositories_helper.rb
===================================================================
--- app/helpers/repositories_helper.rb (revision 7077)
+++ app/helpers/repositories_helper.rb (working copy)
@@ -186,17 +186,31 @@
end
def subversion_field_tags(form, repository)
+
+ 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 && !repository.root_url.blank?)) +
'
(file:///, http://, https://, svn://, svn+[tunnelscheme]://)') +
+ 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]';"))
+ :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 7077)
+++ app/models/repository.rb (working copy)
@@ -63,8 +63,7 @@
end
def 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)
update_attribute(:root_url, @scm.root_url) if root_url.blank?
@scm
end
Index: extra/svn/Redmine.pm
===================================================================
--- extra/svn/Redmine.pm (revision 7077)
+++ 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 a
+llowing 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
@@ -142,6 +157,12 @@
args_how => TAKE1,
errmsg => 'RedmineCacheCredsMax must be decimal number',
},
+ {
+ name => 'RedmineSecurityToken',
+ req_override => OR_AUTHCFG,
+ args_how => TAKE1,
+ errmsg => 'RedmineSecurityToken additional authentication token',
+ },
);
sub RedmineDSN {
@@ -163,6 +184,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 : "")." ");
@@ -198,7 +220,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 vhost (access_handler)");
return FORBIDDEN;
}
@@ -384,4 +406,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
Index: config/locales/en-GB.yml
===================================================================
--- config/locales/en-GB.yml (revision 7077)
+++ config/locales/en-GB.yml (working copy)
@@ -311,6 +311,12 @@
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
+
+ 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
Index: config/locales/en.yml
===================================================================
--- config/locales/en.yml (revision 7077)
+++ config/locales/en.yml (working copy)
@@ -315,7 +315,13 @@
field_root_directory: Root directory
field_cvsroot: CVSROOT
field_cvs_module: Module
+ field_login_method: Authentication method
+ field_security_token: Security token
+ 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 7077)
+++ 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 7077)
+++ lib/redmine/scm/adapters/abstract_adapter.rb (working copy)
@@ -71,12 +71,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
@@ -91,6 +93,10 @@
respond_to?('annotate')
end
+ def use_current_user
+ @use_current_user
+ end
+
def root_url
@root_url
end