@@ -36,10 +36,9 Authen::Simple::LDAP (and IO::Socket::SSL if LDAPS is used): | |||
|
36 | 36 | |
|
37 | 37 | =head1 CONFIGURATION |
|
38 | 38 | |
|
39 |
## |
|
|
40 |
|
|
|
41 | ## else | |
|
42 | # PerlModule Apache::Authn::Redmine | |
|
39 | ## This module has to be in your perl path | |
|
40 | ## eg: /usr/lib/perl5/Apache/Authn/Redmine.pm | |
|
41 | PerlLoadModule Apache::Authn::Redmine | |
|
43 | 42 | <Location /svn> |
|
44 | 43 | DAV svn |
|
45 | 44 | SVNParentPath "/var/svn" |
@@ -52,12 +51,17 Authen::Simple::LDAP (and IO::Socket::SSL if LDAPS is used): | |||
|
52 | 51 | PerlAuthenHandler Apache::Authn::Redmine::authen_handler |
|
53 | 52 | |
|
54 | 53 | ## for mysql |
|
55 |
|
|
|
56 | ## for postgres | |
|
57 |
# |
|
|
58 | ||
|
59 |
|
|
|
60 | PerlSetVar db_pass password | |
|
54 | RedmineDSN "DBI:mysql:database=databasename;host=my.db.server" | |
|
55 | ## for postgres (there is memory leak in libpq+ssl) | |
|
56 | # RedmineDSN "DBI:Pg:dbname=databasename;host=my.db.server;sslmode=disable" | |
|
57 | ||
|
58 | RedmineDbUser "redmine" | |
|
59 | RedmineDbPass "password" | |
|
60 | ## Optional where clause (fulltext search would be slow and | |
|
61 | ## database dependant). | |
|
62 | # RedmineDbWhereClause "and members.role_id IN (1,2)" | |
|
63 | ## Optional credentials cache size | |
|
64 | # RedmineCacheCredsMax 50 | |
|
61 | 65 | </Location> |
|
62 | 66 | |
|
63 | 67 | To be able to browse repository inside redmine, you must add something |
@@ -92,6 +96,7 And you need to upgrade at least reposman.rb (after r860). | |||
|
92 | 96 | =cut |
|
93 | 97 | |
|
94 | 98 | use strict; |
|
99 | use warnings FATAL => 'all', NONFATAL => 'redefine'; | |
|
95 | 100 | |
|
96 | 101 | use DBI; |
|
97 | 102 | use Digest::SHA1; |
@@ -103,9 +108,87 use Apache2::Access; | |||
|
103 | 108 | use Apache2::ServerRec qw(); |
|
104 | 109 | use Apache2::RequestRec qw(); |
|
105 | 110 | use Apache2::RequestUtil qw(); |
|
106 | use Apache2::Const qw(:common); | |
|
111 | use Apache2::Const qw(:common :override :cmd_how); | |
|
112 | use APR::Pool (); | |
|
113 | use APR::Table (); | |
|
114 | ||
|
107 | 115 | # use Apache2::Directive qw(); |
|
108 | 116 | |
|
117 | my @directives = ( | |
|
118 | { | |
|
119 | name => 'RedmineDSN', | |
|
120 | req_override => OR_AUTHCFG, | |
|
121 | args_how => TAKE1, | |
|
122 | errmsg => 'Dsn in format used by Perl DBI. eg: "DBI:Pg:dbname=databasename;host=my.db.server"', | |
|
123 | }, | |
|
124 | { | |
|
125 | name => 'RedmineDbUser', | |
|
126 | req_override => OR_AUTHCFG, | |
|
127 | args_how => TAKE1, | |
|
128 | }, | |
|
129 | { | |
|
130 | name => 'RedmineDbPass', | |
|
131 | req_override => OR_AUTHCFG, | |
|
132 | args_how => TAKE1, | |
|
133 | }, | |
|
134 | { | |
|
135 | name => 'RedmineDbWhereClause', | |
|
136 | req_override => OR_AUTHCFG, | |
|
137 | args_how => TAKE1, | |
|
138 | }, | |
|
139 | { | |
|
140 | name => 'RedmineCacheCredsMax', | |
|
141 | req_override => OR_AUTHCFG, | |
|
142 | args_how => TAKE1, | |
|
143 | errmsg => 'RedmineCacheCredsMax must be decimal number', | |
|
144 | }, | |
|
145 | ); | |
|
146 | ||
|
147 | sub RedmineDSN { | |
|
148 | my ($self, $parms, $arg) = @_; | |
|
149 | $self->{RedmineDSN} = $arg; | |
|
150 | my $query = "SELECT | |
|
151 | hashed_password, auth_source_id | |
|
152 | FROM members, projects, users | |
|
153 | WHERE | |
|
154 | projects.id=members.project_id | |
|
155 | AND users.id=members.user_id | |
|
156 | AND users.status=1 | |
|
157 | AND login=? | |
|
158 | AND identifier=? "; | |
|
159 | $self->{RedmineQuery} = trim($query); | |
|
160 | } | |
|
161 | sub RedmineDbUser { set_val('RedmineDbUser', @_); } | |
|
162 | sub RedmineDbPass { set_val('RedmineDbPass', @_); } | |
|
163 | sub RedmineDbWhereClause { | |
|
164 | my ($self, $parms, $arg) = @_; | |
|
165 | $self->{RedmineQuery} = trim($self->{RedmineQuery}.($arg ? $arg : "")." "); | |
|
166 | } | |
|
167 | ||
|
168 | sub RedmineCacheCredsMax { | |
|
169 | my ($self, $parms, $arg) = @_; | |
|
170 | if ($arg) { | |
|
171 | $self->{RedmineCachePool} = APR::Pool->new; | |
|
172 | $self->{RedmineCacheCreds} = APR::Table::make($self->{RedmineCachePool}, $arg); | |
|
173 | $self->{RedmineCacheCredsCount} = 0; | |
|
174 | $self->{RedmineCacheCredsMax} = $arg; | |
|
175 | } | |
|
176 | } | |
|
177 | ||
|
178 | sub trim { | |
|
179 | my $string = shift; | |
|
180 | $string =~ s/\s{2,}/ /g; | |
|
181 | return $string; | |
|
182 | } | |
|
183 | ||
|
184 | sub set_val { | |
|
185 | my ($key, $self, $parms, $arg) = @_; | |
|
186 | $self->{$key} = $arg; | |
|
187 | } | |
|
188 | ||
|
189 | Apache2::Module::add(__PACKAGE__, \@directives); | |
|
190 | ||
|
191 | ||
|
109 | 192 | my %read_only_methods = map { $_ => 1 } qw/GET PROPFIND REPORT OPTIONS/; |
|
110 | 193 | |
|
111 | 194 | sub access_handler { |
@@ -117,7 +200,7 sub access_handler { | |||
|
117 | 200 | } |
|
118 | 201 | |
|
119 | 202 | my $method = $r->method; |
|
120 |
return OK |
|
|
203 | return OK if defined $read_only_methods{$method}; | |
|
121 | 204 | |
|
122 | 205 | my $project_id = get_project_identifier($r); |
|
123 | 206 | |
@@ -182,9 +265,14 sub is_member { | |||
|
182 | 265 | |
|
183 | 266 | my $pass_digest = Digest::SHA1::sha1_hex($redmine_pass); |
|
184 | 267 | |
|
185 | my $sth = $dbh->prepare( | |
|
186 | "SELECT hashed_password, auth_source_id FROM members, projects, users WHERE projects.id=members.project_id AND users.id=members.user_id AND users.status=1 AND login=? AND identifier=?;" | |
|
187 | ); | |
|
268 | my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config); | |
|
269 | my $usrprojpass; | |
|
270 | if ($cfg->{RedmineCacheCredsMax}) { | |
|
271 | $usrprojpass = $cfg->{RedmineCacheCreds}->get($redmine_user.":".$project_id); | |
|
272 | return 1 if (defined $usrprojpass and ($usrprojpass eq $pass_digest)); | |
|
273 | } | |
|
274 | my $query = $cfg->{RedmineQuery}; | |
|
275 | my $sth = $dbh->prepare($query); | |
|
188 | 276 | $sth->execute($redmine_user, $project_id); |
|
189 | 277 | |
|
190 | 278 | my $ret; |
@@ -216,6 +304,20 sub is_member { | |||
|
216 | 304 | $sth->finish(); |
|
217 | 305 | $dbh->disconnect(); |
|
218 | 306 | |
|
307 | if ($cfg->{RedmineCacheCredsMax} and $ret) { | |
|
308 | if (defined $usrprojpass) { | |
|
309 | $cfg->{RedmineCacheCreds}->set($redmine_user.":".$project_id, $pass_digest); | |
|
310 | } else { | |
|
311 | if ($cfg->{RedmineCacheCredsCount} < $cfg->{RedmineCacheCredsMax}) { | |
|
312 | $cfg->{RedmineCacheCreds}->set($redmine_user.":".$project_id, $pass_digest); | |
|
313 | $cfg->{RedmineCacheCredsCount}++; | |
|
314 | } else { | |
|
315 | $cfg->{RedmineCacheCreds}->clear(); | |
|
316 | $cfg->{RedmineCacheCredsCount} = 0; | |
|
317 | } | |
|
318 | } | |
|
319 | } | |
|
320 | ||
|
219 | 321 | $ret; |
|
220 | 322 | } |
|
221 | 323 | |
@@ -230,8 +332,8 sub get_project_identifier { | |||
|
230 | 332 | sub connect_database { |
|
231 | 333 | my $r = shift; |
|
232 | 334 | |
|
233 | my ($dsn, $db_user, $db_pass) = map { $r->dir_config($_) } qw/dsn db_user db_pass/; | |
|
234 |
return DBI->connect($ |
|
|
335 | my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config); | |
|
336 | return DBI->connect($cfg->{RedmineDSN}, $cfg->{RedmineDbUser}, $cfg->{RedmineDbPass}); | |
|
235 | 337 | } |
|
236 | 338 | |
|
237 | 339 | 1; |
General Comments 0
You need to be logged in to leave comments.
Login now