Index: app/helpers/repositories_helper.rb
===================================================================
--- app/helpers/repositories_helper.rb	(revision 9291)
+++ app/helpers/repositories_helper.rb	(working copy)
@@ -157,18 +157,34 @@
   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?)) +
                        '<br />'.html_safe +
                        '(file:///, http://, https://, svn://, svn+[tunnelscheme]://)') +
+      content_tag('p', form.text_field(:root_url, :size => 60) +
+                       '<br />(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]';"))
+                            :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 9291)
+++ app/models/repository.rb	(working copy)
@@ -71,8 +71,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: app/models/repository/subversion.rb
===================================================================
--- app/models/repository/subversion.rb	(revision 9291)
+++ 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 => /^(http|https|svn(\+[^\s:\/\\]+)?|file):\/\/.+/i
 
Index: extra/svn/Redmine.pm
===================================================================
--- extra/svn/Redmine.pm	(revision 9291)
+++ 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
    <Location /svn>
      DAV svn
      SVNParentPath "/var/svn"
@@ -47,9 +52,9 @@
      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"
      ## for postgres
@@ -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"
+
      <Limit GET PROPFIND OPTIONS REPORT>
        Allow from redmine.server.ip
      </Limit>
@@ -142,9 +157,15 @@
     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 {
+sub RedmineDSN { 
   my ($self, $parms, $arg) = @_;
   $self->{RedmineDSN} = $arg;
   my $query = "SELECT 
@@ -164,12 +185,13 @@
 
 sub RedmineDbUser { set_val('RedmineDbUser', @_); }
 sub RedmineDbPass { set_val('RedmineDbPass', @_); }
-sub RedmineDbWhereClause {
+sub RedmineSecurityToken { set_val('RedmineSecurityToken', @_); }
+sub RedmineDbWhereClause { 
   my ($self, $parms, $arg) = @_;
   $self->{RedmineQuery} = trim($self->{RedmineQuery}.($arg ? $arg : "")." ");
 }
 
-sub RedmineCacheCredsMax {
+sub RedmineCacheCredsMax { 
   my ($self, $parms, $arg) = @_;
   if ($arg) {
     $self->{RedmineCachePool} = APR::Pool->new;
@@ -199,7 +221,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;
   }
 
@@ -216,10 +238,10 @@
 
 sub authen_handler {
   my $r = shift;
-
+  
   my ($res, $redmine_pass) =  $r->get_basic_auth_pw();
   return $res unless $res == OK;
-
+  
   if (is_member($r->user, $redmine_pass, $r)) {
       return OK;
   } else {
@@ -246,7 +268,7 @@
   }
   $sth->finish();
   undef $sth;
-
+  
   $dbh->disconnect();
   undef $dbh;
 
@@ -256,7 +278,7 @@
 sub is_public_project {
     my $project_id = shift;
     my $r = shift;
-
+    
     if (is_authentication_forced($r)) {
       return 0;
     }
@@ -283,12 +305,12 @@
 
 sub anonymous_role_allows_browse_repository {
   my $r = shift;
-
+  
   my $dbh = connect_database($r);
   my $sth = $dbh->prepare(
       "SELECT permissions FROM roles WHERE builtin = 2;"
   );
-
+  
   $sth->execute();
   my $ret = 0;
   if (my @row = $sth->fetchrow_array) {
@@ -300,7 +322,7 @@
   undef $sth;
   $dbh->disconnect();
   undef $dbh;
-
+  
   $ret;
 }
 
@@ -328,7 +350,7 @@
   my $project_id  = get_project_identifier($r);
 
   my $pass_digest = Digest::SHA::sha1_hex($redmine_pass);
-
+  
   my $access_mode = defined $read_only_methods{$r->method} ? "R" : "W";
 
   my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config);
@@ -397,7 +419,7 @@
 
 sub get_project_identifier {
     my $r = shift;
-
+    
     my $location = $r->location;
     my ($identifier) = $r->uri =~ m{$location/*([^/]+)};
     $identifier;
@@ -405,9 +427,48 @@
 
 sub connect_database {
     my $r = shift;
-
+    
     my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config);
     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: config/locales/en-GB.yml
===================================================================
--- config/locales/en-GB.yml	(revision 9291)
+++ 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 9291)
+++ config/locales/en.yml	(working copy)
@@ -317,7 +317,14 @@
   field_root_directory: Root directory
   field_cvsroot: CVSROOT
   field_cvs_module: Module
+  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 9291)
+++ 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 9291)
+++ lib/redmine/scm/adapters/abstract_adapter.rb	(working copy)
@@ -75,12 +75,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
@@ -95,6 +97,10 @@
           respond_to?('annotate')
         end
 
+        def use_current_user
+          @use_current_user
+        end
+
         def root_url
           @root_url
         end
