Project

General

Profile

Feature #2647 » repository_auth.7077.patch

Robert Rath, 2011-09-10 04:20

View differences:

app/helpers/repositories_helper.rb (working copy)
186 186
  end
187 187

  
188 188
  def subversion_field_tags(form, repository)
189

  
190
      login_options = [["--- #{l(:actionview_instancetag_blank_option)} ---", '']]
191
      login_options << [l("repository_login_usernamepassword"), 0] 
192
      login_options << [l("repository_login_current_username"), 1] 
193
      login_options << [l("repository_login_current_role"), 2] 
194

  
189 195
      content_tag('p', form.text_field(:url, :size => 60, :required => true,
190 196
                       :disabled => (repository && !repository.root_url.blank?)) +
191 197
                       '<br />(file:///, http://, https://, svn://, svn+[tunnelscheme]://)') +
198
      content_tag('p', form.select(:login_method, login_options)) +
192 199
      content_tag('p', form.text_field(:login, :size => 30)) +
193 200
      content_tag('p', form.password_field(
194 201
                            :password, :size => 30, :name => 'ignore',
195 202
                            :value => ((repository.new_record? || repository.password.blank?) ? '' : ('x'*15)),
196 203
                            :onfocus => "this.value=''; this.name='repository[password]';",
197
                            :onchange => "this.name='repository[password]';"))
204
                            :onchange => "this.name='repository[password]';")) +
205
      content_tag('p', form.password_field(:security_token, :size => 30, :name => 'ignore',
206
                            :value => ((repository.new_record? || repository.security_token.blank?) ? '' : ('x'*15)),
207
                            :onfocus => "this.value=''; this.name='repository[security_token]';",
208
                            :onchange => "this.name='repository[security_token]';"))
198 209
  end
199 210

  
211
#      select_tag('login_method', options_for_select(login_method, repository.class.name.demodulize),
212
#               :onchange => remote_function(:url => { :controller => 'repositories', :action => 'edit', :id => @project }, :method => :get, :with => "Form.serialize(this.form)") ) +
213

  
200 214
  def darcs_field_tags(form, repository)
201 215
    content_tag('p', form.text_field(
202 216
                     :url, :label => l(:field_path_to_repository),
app/models/repository.rb (working copy)
63 63
  end
64 64

  
65 65
  def scm
66
    @scm ||= self.scm_adapter.new(url, root_url,
67
                                  login, password, path_encoding)
66
    @scm ||= self.scm_adapter.new(url, root_url, login, password, path_encoding, login_method, security_token, project)
68 67
    update_attribute(:root_url, @scm.root_url) if root_url.blank?
69 68
    @scm
70 69
  end
extra/svn/Redmine.pm (working copy)
1
package Apache::Authn::Redmine;
1
package Apache::Redmine;
2 2

  
3
=head1 Apache::Authn::Redmine
3
=head1 Apache::Redmine
4 4

  
5 5
Redmine - a mod_perl module to authenticate webdav subversion users
6 6
against redmine database
7 7

  
8
In addition this module allows to authenticate a redmine server
9
for webdav subversion access, bypassing full authentication, still a
10
llowing to apply repository based security (e.g. .authz files)
11

  
12

  
8 13
=head1 SYNOPSIS
9 14

  
10 15
This module allow anonymous users to browse public project and
......
37 42
=head1 CONFIGURATION
38 43

  
39 44
   ## This module has to be in your perl path
40
   ## eg:  /usr/lib/perl5/Apache/Authn/Redmine.pm
41
   PerlLoadModule Apache::Authn::Redmine
45
   ## eg:  /usr/lib/perl5/Apache/Redmine.pm
46
   PerlLoadModule Apache::Redmine
42 47
   <Location /svn>
43 48
     DAV svn
44 49
     SVNParentPath "/var/svn"
......
47 52
     AuthName redmine
48 53
     Require valid-user
49 54

  
50
     PerlAccessHandler Apache::Authn::Redmine::access_handler
51
     PerlAuthenHandler Apache::Authn::Redmine::authen_handler
55
     PerlAccessHandler Apache::Redmine::access_handler
56
     PerlAuthenHandler Apache::Redmine::authen_handler
52 57
  
53 58
     ## for mysql
54 59
     RedmineDSN "DBI:mysql:database=databasename;host=my.db.server"
......
73 78
     Order deny,allow
74 79
     Deny from all
75 80
     # only allow reading orders
81

  
82
     AuthType Basic
83
     AuthName redmine
84
     Require valid-user
85

  
86
     PerlAccessHandler Apache::Redmine::redmine_access_handler
87
     PerlAuthenHandler Apache::Redmine::redmine_authen_handler
88

  
89
     RedmineSecurityToken "redmine"
90

  
76 91
     <Limit GET PROPFIND OPTIONS REPORT>
77 92
       Allow from redmine.server.ip
78 93
     </Limit>
......
142 157
    args_how => TAKE1,
143 158
    errmsg => 'RedmineCacheCredsMax must be decimal number',
144 159
  },
160
  {
161
    name => 'RedmineSecurityToken',
162
    req_override => OR_AUTHCFG,
163
    args_how => TAKE1,
164
    errmsg => 'RedmineSecurityToken additional authentication token',
165
  },
145 166
);
146 167

  
147 168
sub RedmineDSN { 
......
163 184

  
164 185
sub RedmineDbUser { set_val('RedmineDbUser', @_); }
165 186
sub RedmineDbPass { set_val('RedmineDbPass', @_); }
187
sub RedmineSecurityToken { set_val('RedmineSecurityToken', @_); }
166 188
sub RedmineDbWhereClause { 
167 189
  my ($self, $parms, $arg) = @_;
168 190
  $self->{RedmineQuery} = trim($self->{RedmineQuery}.($arg ? $arg : "")." ");
......
198 220
  my $r = shift;
199 221

  
200 222
  unless ($r->some_auth_required) {
201
      $r->log_reason("No authentication has been configured");
223
      $r->log_reason("Apache::Redmine - No authentication has been configured in vhost (access_handler)");
202 224
      return FORBIDDEN;
203 225
  }
204 226

  
......
384 406
    return DBI->connect($cfg->{RedmineDSN}, $cfg->{RedmineDbUser}, $cfg->{RedmineDbPass});
385 407
}
386 408

  
409
sub redmine_access_handler {
410
  my $r = shift;
411

  
412
  unless ($r->some_auth_required) {
413
      $r->log_reason("Apache::Redmine - No auth has been configured in vhost conf (redmine_access_handler)");
414
      return FORBIDDEN;
415
  }
416

  
417
  my $method = $r->method;
418
  return OK unless defined $read_only_methods{$method};
419

  
420
  my $project_id = get_project_identifier($r);
421

  
422
  $r->set_handlers(PerlAuthenHandler => [\&OK])
423
      if is_public_project($project_id, $r);
424

  
425
  return OK
426
}
427

  
428
sub redmine_authen_handler {
429
  my $r = shift;
430

  
431
  my ($res, $redmine_pass) =  $r->get_basic_auth_pw();
432
  return $res unless $res == OK;
433

  
434
  my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config);
435

  
436
  if ($cfg->{RedmineSecurityToken}) {
437
    my $securityToken = $cfg->{RedmineSecurityToken};
438

  
439
    if ($securityToken ne $redmine_pass) {
440
      $r->log_error("Apache::Redmine - Provided SecurityToken did not match (redmine_authen_handler)");
441
      $r->note_auth_failure();
442
      return AUTH_REQUIRED; 
443
    }    
444
  }  
445
  return OK;
446
}
447

  
387 448
1;
db/migrate/109_add_special_repository_security.rb (revision 0)
1
class AddSpecialRepositorySecurity < ActiveRecord::Migration
2
  def self.down
3
    remove_column :repositories, :login_method
4
    remove_column :repositories, :security_token
5
  end
6

  
7
  def self.up
8
    add_column :repositories, :login_method, :int, :default => 0, :null => true
9
    add_column :repositories, :security_token, :string, :limit => 60, :default => "", :null => true
10
  end
11
end
config/locales/en-GB.yml (working copy)
311 311
  field_text: Text field
312 312
  field_visible: Visible
313 313
  field_warn_on_leaving_unsaved: "Warn me when leaving a page with unsaved text"
314
  field_login_method: Authentication method
315
  field_security_token: Security token
316

  
317
  repository_login_usernamepassword: Provided credentials
318
  repository_login_current_username: Name of current user
319
  repository_login_current_role: Role of current user
314 320
  
315 321
  setting_app_title: Application title
316 322
  setting_app_subtitle: Application subtitle
config/locales/en.yml (working copy)
315 315
  field_root_directory: Root directory
316 316
  field_cvsroot: CVSROOT
317 317
  field_cvs_module: Module
318
  field_login_method: Authentication method
319
  field_security_token: Security token
318 320

  
321
  repository_login_usernamepassword: Provided credentials
322
  repository_login_current_username: Name of current user
323
  repository_login_current_role: Role of current user
324

  
319 325
  setting_app_title: Application title
320 326
  setting_app_subtitle: Application subtitle
321 327
  setting_welcome_text: Welcome text
lib/redmine/scm/adapters/subversion_adapter.rb (working copy)
257 257
        private
258 258

  
259 259
        def credentials_string
260
          str = ''
261
          str << " --username #{shell_quote(@login)}" unless @login.blank?
262
          str << " --password #{shell_quote(@password)}" unless @login.blank? || @password.blank?
260
          if !(User.current.is_a?(AnonymousUser))
261

  
262
            if (@login_method == 1)
263
              str = ''
264
              str << " --username #{shell_quote(User.current.login)}"
265
              str << " --password #{shell_quote( (@security_token.blank? ? "foo" : @security_token) )}"   
266
            end
267

  
268
            if (@login_method == 2) && (!@project.nil?)
269
              role = User.current.role_for_project(@project)
270

  
271
              if !role.blank?
272
                str = ''
273
                str << " --username #{shell_quote(role.name)}"
274
                str << " --password #{shell_quote( (@security_token.blank? ? "foo" : @security_token) )}"   
275
              end
276
            end
277

  
278
          end
279

  
280
          if (str.blank?)
281
            str = ''
282
            str << " --username #{shell_quote(@login)}" unless @login.blank?
283
            str << " --password #{shell_quote(@password)}" unless @login.blank? || @password.blank?
284
          end
285

  
263 286
          str << " --no-auth-cache --non-interactive"
264 287
          str
265 288
        end
lib/redmine/scm/adapters/abstract_adapter.rb (working copy)
71 71
          end
72 72
        end
73 73

  
74
        def initialize(url, root_url=nil, login=nil, password=nil,
75
                       path_encoding=nil)
74
        def initialize(url, root_url=nil, login=nil, password=nil, path_encoding=nil, login_method=nil, security_token=nil, project=nil)
76 75
          @url = url
77 76
          @login = login if login && !login.empty?
78 77
          @password = (password || "") if @login
79 78
          @root_url = root_url.blank? ? retrieve_root_url : root_url
79
          @login_method = login_method.blank? ? 0 : login_method
80
          @security_token = security_token.blank? ? "" : security_token
81
          @project = project
80 82
        end
81 83

  
82 84
        def adapter_name
......
91 93
          respond_to?('annotate')
92 94
        end
93 95

  
96
        def use_current_user
97
          @use_current_user
98
        end
99

  
94 100
        def root_url
95 101
          @root_url
96 102
        end
(2-2/6)