Project

General

Profile

Feature #2647 » repository_auth.patch

Patch against trunk version 2361 - Mathias Kühn, 2009-02-05 18:44

View differences:

app/helpers/repositories_helper.rb (working copy)
146 146
  end
147 147

  
148 148
  def subversion_field_tags(form, repository)
149
  
150
      login_options = [["--- #{l(:actionview_instancetag_blank_option)} ---", '']]
151
      login_options << [l("repository_login_usernamepassword"), 0] 
152
      login_options << [l("repository_login_current_username"), 1] 
153
      login_options << [l("repository_login_current_role"), 2] 
154
  
149 155
      content_tag('p', form.text_field(:url, :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)) +
150 156
                       '<br />(http://, https://, svn://, file:///)') +
157
      content_tag('p', form.select(:login_method, login_options)) +
151 158
      content_tag('p', form.text_field(:login, :size => 30)) +
152 159
      content_tag('p', form.password_field(:password, :size => 30, :name => 'ignore',
153 160
                                           :value => ((repository.new_record? || repository.password.blank?) ? '' : ('x'*15)),
154 161
                                           :onfocus => "this.value=''; this.name='repository[password]';",
155
                                           :onchange => "this.name='repository[password]';"))
162
                                           :onchange => "this.name='repository[password]';")) +
163
      content_tag('p', form.password_field(:security_token, :size => 30, :name => 'ignore',
164
                                           :value => ((repository.new_record? || repository.security_token.blank?) ? '' : ('x'*15)),
165
                                           :onfocus => "this.value=''; this.name='repository[security_token]';",
166
                                           :onchange => "this.name='repository[security_token]';"))
156 167
  end
157 168

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

  
158 172
  def darcs_field_tags(form, repository)
159 173
      content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.new_record?)))
160 174
  end
app/models/repository.rb (working copy)
38 38
  end
39 39

  
40 40
  def scm
41
    @scm ||= self.scm_adapter.new url, root_url, login, password
41
    @scm ||= self.scm_adapter.new url, root_url, login, password, login_method, security_token, project
42 42
    update_attribute(:root_url, @scm.root_url) if root_url.blank?
43 43
    @scm
44 44
  end
db/migrate/107_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
extra/svn/Redmine.pm (working copy)
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
......
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::Authn::Redmine::redmine_access_handler
87
     PerlAuthenHandler Apache::Authn::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 { 
......
161 182
}
162 183
sub RedmineDbUser { set_val('RedmineDbUser', @_); }
163 184
sub RedmineDbPass { set_val('RedmineDbPass', @_); }
185
sub RedmineSecurityToken { set_val('RedmineSecurityToken', @_); }
164 186
sub RedmineDbWhereClause { 
165 187
  my ($self, $parms, $arg) = @_;
166 188
  $self->{RedmineQuery} = trim($self->{RedmineQuery}.($arg ? $arg : "")." ");
......
340 362
    return DBI->connect($cfg->{RedmineDSN}, $cfg->{RedmineDbUser}, $cfg->{RedmineDbPass});
341 363
}
342 364

  
365

  
366
sub redmine_access_handler {
367
  my $r = shift;
368

  
369
  unless ($r->some_auth_required) {
370
      $r->log_reason("No authentication has been configured");
371
      return FORBIDDEN;
372
  }
373

  
374
  my $method = $r->method;
375
  return OK unless defined $read_only_methods{$method};
376

  
377
  my $project_id = get_project_identifier($r);
378

  
379
  $r->set_handlers(PerlAuthenHandler => [\&OK])
380
      if is_public_project($project_id, $r);
381

  
382
  return OK
383
}
384

  
385
sub redmine_authen_handler {
386
  my $r = shift;
387
  
388
  my ($res, $redmine_pass) =  $r->get_basic_auth_pw();
389
  return $res unless $res == OK;
390
  
391
  my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config);
392
  
393
  if ($cfg->{RedmineSecurityToken}) {
394
    my $securityToken = $cfg->{RedmineSecurityToken};
395

  
396
    if ($securityToken ne $redmine_pass) {
397
      $r->log_error("Apache::Authn::Redmine - Provided SecurityToken did not match");
398
      $r->note_auth_failure();
399
      return AUTH_REQUIRED; 
400
    }    
401
  }  
402
  
403
  return OK;
404
}
405

  
343 406
1;
lang/en.yml (working copy)
187 187
field_comments_sorting: Display comments
188 188
field_parent_title: Parent page
189 189
field_editable: Editable
190
field_login_method: Authentication method
191
field_security_token: Security token
190 192

  
193
repository_login_usernamepassword: Provided credentials
194
repository_login_current_username: Name of current user
195
repository_login_current_role: Role of current user
196

  
191 197
setting_app_title: Application title
192 198
setting_app_subtitle: Application subtitle
193 199
setting_welcome_text: Welcome text
lib/redmine/scm/adapters/abstract_adapter.rb (working copy)
47 47
          end
48 48
        end
49 49
                
50
        def initialize(url, root_url=nil, login=nil, password=nil)
50
        def initialize(url, root_url=nil, login=nil, password=nil, login_method=nil, security_token=nil, project=nil)
51 51
          @url = url
52 52
          @login = login if login && !login.empty?
53 53
          @password = (password || "") if @login
54 54
          @root_url = root_url.blank? ? retrieve_root_url : root_url
55
          @login_method = login_method.blank? ? 0 : login_method
56
          @security_token = security_token.blank? ? "" : security_token
57
          @project = project
55 58
        end
56 59
        
57 60
        def adapter_name
......
65 68
        def supports_annotate?
66 69
          respond_to?('annotate')
67 70
        end
68
        
71

  
72
	def use_current_user
73
	  @use_current_user
74
	end
75
	
69 76
        def root_url
70 77
          @root_url
71 78
        end
lib/redmine/scm/adapters/subversion_adapter.rb (working copy)
222 222
        private
223 223
        
224 224
        def credentials_string
225
          str = ''
226
          str << " --username #{shell_quote(@login)}" unless @login.blank?
227
          str << " --password #{shell_quote(@password)}" unless @login.blank? || @password.blank?
225

  
226

  
227
	  if !(User.current.is_a?(AnonymousUser))
228
	  
229
            if (@login_method == 1)
230
	       str = ''
231
               str << " --username #{shell_quote(User.current.login)}"
232
               str << " --password #{shell_quote( (@security_token.blank? ? "foo" : @security_token) )}"   
233
	    end
234

  
235
            if (@login_method == 2) && (!@project.nil?)
236
	       role = User.current.role_for_project(@project)
237

  
238
	       if !role.blank?
239
	         str = ''
240
                 str << " --username #{shell_quote(role.name)}"
241
                 str << " --password #{shell_quote( (@security_token.blank? ? "foo" : @security_token) )}"   
242
               end
243
            end
244

  
245
          end
246
          
247
	  if (str.blank?)
248
	    str = ''
249
            str << " --username #{shell_quote(@login)}" unless @login.blank?
250
            str << " --password #{shell_quote(@password)}" unless @login.blank? || @password.blank?
251
          end
252
          
228 253
          str
229 254
        end
230 255
      end
(1-1/6)