##// END OF EJS Templates
Initial support for caching credentials in Memcached (debug is enabled)....
Liwiusz Ociepa -
r1630:f7ede727fd0e
parent child
Show More
@@ -60,8 +60,11 Authen::Simple::LDAP (and IO::Socket::SSL if LDAPS is used):
60 60 ## Optional where clause (fulltext search would be slow and
61 61 ## database dependant).
62 62 # RedmineDbWhereClause "and members.role_id IN (1,2)"
63 ## Optional credentials cache size
64 # RedmineCacheCredsMax 50
63 ## Configuration for memcached
64 # RedmineMemcacheServers "127.0.0.1:112211"
65 # RedmineMemcacheExpirySec "12"
66 # # Defaults to "RedminePM:"
67 # RedmineMemcacheNamespace "RedmineCreds:"
65 68 </Location>
66 69
67 70 To be able to browse repository inside redmine, you must add something
@@ -102,6 +105,7 use DBI;
102 105 use Digest::SHA1;
103 106 # optional module for LDAP authentication
104 107 my $CanUseLDAPAuth = eval("use Authen::Simple::LDAP; 1");
108 my $CanUseMemcached = eval("use Cache::Memcached; 1");
105 109
106 110 use Apache2::Module;
107 111 use Apache2::Access;
@@ -109,8 +113,6 use Apache2::ServerRec qw();
109 113 use Apache2::RequestRec qw();
110 114 use Apache2::RequestUtil qw();
111 115 use Apache2::Const qw(:common :override :cmd_how);
112 use APR::Pool ();
113 use APR::Table ();
114 116
115 117 # use Apache2::Directive qw();
116 118
@@ -137,10 +139,19 my @directives = (
137 139 args_how => TAKE1,
138 140 },
139 141 {
140 name => 'RedmineCacheCredsMax',
142 name => 'RedmineMemcacheServers',
143 req_override => OR_AUTHCFG,
144 args_how => TAKE1,
145 },
146 {
147 name => 'RedmineMemcacheExpirySec',
148 req_override => OR_AUTHCFG,
149 args_how => TAKE1,
150 },
151 {
152 name => 'RedmineMemcacheNamespace',
141 153 req_override => OR_AUTHCFG,
142 154 args_how => TAKE1,
143 errmsg => 'RedmineCacheCredsMax must be decimal number',
144 155 },
145 156 );
146 157
@@ -165,13 +176,30 sub RedmineDbWhereClause {
165 176 $self->{RedmineQuery} = trim($self->{RedmineQuery}.($arg ? $arg : "")." ");
166 177 }
167 178
168 sub RedmineCacheCredsMax {
179 sub RedmineMemcacheServers {
169 180 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;
181 if ($arg && $CanUseMemcached) {
182 $self->{RedmineMemcached} = new Cache::Memcached {
183 'servers' => [ $arg, ],
184 'debug' => 1,
185 };
186 $self->{RedmineMemcache} = 1;
187 # Undocumented feature of Cache::Memcached, please don't kill me
188 if (0 == length $self->{RedmineMemcached}->{namespace}) {
189 $self->{RedmineMemcached}->{namespace} = "RedminePM:";
190 $self->{RedmineMemcached}->{namespace_len} = length $self->{RedmineMemcached}->{namespace};
191 }
192 }
193 }
194
195 sub RedmineMemcacheExpirySec { set_val('RedmineMemcacheExpirySec', @_); }
196
197 sub RedmineMemcacheNamespace {
198 my ($self, $parms, $arg) = @_;
199 if ($CanUseMemcached) {
200 # Undocumented feature of Cache::Memcached, please don't kill me
201 $self->{RedmineMemcached}->{namespace} = $arg;
202 $self->{RedmineMemcached}->{namespace_len} = length $self->{RedmineMemcached}->{namespace};
175 203 }
176 204 }
177 205
@@ -228,6 +256,10 sub is_public_project {
228 256 my $project_id = shift;
229 257 my $r = shift;
230 258
259 my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config);
260 if ($cfg->{RedmineMemcache}) {
261 return 1 if ($cfg->{RedmineMemcached}->get($project_id));
262 }
231 263 my $dbh = connect_database($r);
232 264 my $sth = $dbh->prepare(
233 265 "SELECT * FROM projects WHERE projects.identifier=? and projects.is_public=true;"
@@ -237,6 +269,14 sub is_public_project {
237 269 my $ret = $sth->fetchrow_array ? 1 : 0;
238 270 $sth->finish();
239 271 $dbh->disconnect();
272 if ($cfg->{RedmineMemcache}) {
273 if ($cfg->{RedmineMemcacheExpirySec}) {
274 $cfg->{RedmineMemcached}->set($project_id, $ret, $cfg->{RedmineMemcacheExpirySec});
275 } else {
276 $cfg->{RedmineMemcached}->set($project_id, $ret);
277 }
278 }
279
240 280
241 281 $ret;
242 282 }
@@ -268,8 +308,8 sub is_member {
268 308
269 309 my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config);
270 310 my $usrprojpass;
271 if ($cfg->{RedmineCacheCredsMax}) {
272 $usrprojpass = $cfg->{RedmineCacheCreds}->get($redmine_user.":".$project_id);
311 if ($cfg->{RedmineMemcache}) {
312 $usrprojpass = $cfg->{RedmineMemcached}->get($redmine_user.":".$project_id);
273 313 return 1 if (defined $usrprojpass and ($usrprojpass eq $pass_digest));
274 314 }
275 315 my $query = $cfg->{RedmineQuery};
@@ -305,17 +345,11 sub is_member {
305 345 $sth->finish();
306 346 $dbh->disconnect();
307 347
308 if ($cfg->{RedmineCacheCredsMax} and $ret) {
309 if (defined $usrprojpass) {
310 $cfg->{RedmineCacheCreds}->set($redmine_user.":".$project_id, $pass_digest);
348 if ($cfg->{RedmineMemcache} and $ret) {
349 if ($cfg->{RedmineMemcacheExpirySec}) {
350 $cfg->{RedmineMemcached}->set($redmine_user.":".$project_id, $pass_digest, $cfg->{RedmineMemcacheExpirySec});
311 351 } else {
312 if ($cfg->{RedmineCacheCredsCount} < $cfg->{RedmineCacheCredsMax}) {
313 $cfg->{RedmineCacheCreds}->set($redmine_user.":".$project_id, $pass_digest);
314 $cfg->{RedmineCacheCredsCount}++;
315 } else {
316 $cfg->{RedmineCacheCreds}->clear();
317 $cfg->{RedmineCacheCredsCount} = 0;
318 }
352 $cfg->{RedmineMemcached}->set($redmine_user.":".$project_id, $pass_digest);
319 353 }
320 354 }
321 355
General Comments 0
You need to be logged in to leave comments. Login now