##// 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 ## Optional where clause (fulltext search would be slow and
60 ## Optional where clause (fulltext search would be slow and
61 ## database dependant).
61 ## database dependant).
62 # RedmineDbWhereClause "and members.role_id IN (1,2)"
62 # RedmineDbWhereClause "and members.role_id IN (1,2)"
63 ## Optional credentials cache size
63 ## Configuration for memcached
64 # RedmineCacheCredsMax 50
64 # RedmineMemcacheServers "127.0.0.1:112211"
65 # RedmineMemcacheExpirySec "12"
66 # # Defaults to "RedminePM:"
67 # RedmineMemcacheNamespace "RedmineCreds:"
65 </Location>
68 </Location>
66
69
67 To be able to browse repository inside redmine, you must add something
70 To be able to browse repository inside redmine, you must add something
@@ -102,6 +105,7 use DBI;
102 use Digest::SHA1;
105 use Digest::SHA1;
103 # optional module for LDAP authentication
106 # optional module for LDAP authentication
104 my $CanUseLDAPAuth = eval("use Authen::Simple::LDAP; 1");
107 my $CanUseLDAPAuth = eval("use Authen::Simple::LDAP; 1");
108 my $CanUseMemcached = eval("use Cache::Memcached; 1");
105
109
106 use Apache2::Module;
110 use Apache2::Module;
107 use Apache2::Access;
111 use Apache2::Access;
@@ -109,8 +113,6 use Apache2::ServerRec qw();
109 use Apache2::RequestRec qw();
113 use Apache2::RequestRec qw();
110 use Apache2::RequestUtil qw();
114 use Apache2::RequestUtil qw();
111 use Apache2::Const qw(:common :override :cmd_how);
115 use Apache2::Const qw(:common :override :cmd_how);
112 use APR::Pool ();
113 use APR::Table ();
114
116
115 # use Apache2::Directive qw();
117 # use Apache2::Directive qw();
116
118
@@ -137,10 +139,19 my @directives = (
137 args_how => TAKE1,
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 req_override => OR_AUTHCFG,
153 req_override => OR_AUTHCFG,
142 args_how => TAKE1,
154 args_how => TAKE1,
143 errmsg => 'RedmineCacheCredsMax must be decimal number',
144 },
155 },
145 );
156 );
146
157
@@ -165,13 +176,30 sub RedmineDbWhereClause {
165 $self->{RedmineQuery} = trim($self->{RedmineQuery}.($arg ? $arg : "")." ");
176 $self->{RedmineQuery} = trim($self->{RedmineQuery}.($arg ? $arg : "")." ");
166 }
177 }
167
178
168 sub RedmineCacheCredsMax {
179 sub RedmineMemcacheServers {
169 my ($self, $parms, $arg) = @_;
180 my ($self, $parms, $arg) = @_;
170 if ($arg) {
181 if ($arg && $CanUseMemcached) {
171 $self->{RedmineCachePool} = APR::Pool->new;
182 $self->{RedmineMemcached} = new Cache::Memcached {
172 $self->{RedmineCacheCreds} = APR::Table::make($self->{RedmineCachePool}, $arg);
183 'servers' => [ $arg, ],
173 $self->{RedmineCacheCredsCount} = 0;
184 'debug' => 1,
174 $self->{RedmineCacheCredsMax} = $arg;
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 my $project_id = shift;
256 my $project_id = shift;
229 my $r = shift;
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 my $dbh = connect_database($r);
263 my $dbh = connect_database($r);
232 my $sth = $dbh->prepare(
264 my $sth = $dbh->prepare(
233 "SELECT * FROM projects WHERE projects.identifier=? and projects.is_public=true;"
265 "SELECT * FROM projects WHERE projects.identifier=? and projects.is_public=true;"
@@ -237,6 +269,14 sub is_public_project {
237 my $ret = $sth->fetchrow_array ? 1 : 0;
269 my $ret = $sth->fetchrow_array ? 1 : 0;
238 $sth->finish();
270 $sth->finish();
239 $dbh->disconnect();
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 $ret;
281 $ret;
242 }
282 }
@@ -268,8 +308,8 sub is_member {
268
308
269 my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config);
309 my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config);
270 my $usrprojpass;
310 my $usrprojpass;
271 if ($cfg->{RedmineCacheCredsMax}) {
311 if ($cfg->{RedmineMemcache}) {
272 $usrprojpass = $cfg->{RedmineCacheCreds}->get($redmine_user.":".$project_id);
312 $usrprojpass = $cfg->{RedmineMemcached}->get($redmine_user.":".$project_id);
273 return 1 if (defined $usrprojpass and ($usrprojpass eq $pass_digest));
313 return 1 if (defined $usrprojpass and ($usrprojpass eq $pass_digest));
274 }
314 }
275 my $query = $cfg->{RedmineQuery};
315 my $query = $cfg->{RedmineQuery};
@@ -305,17 +345,11 sub is_member {
305 $sth->finish();
345 $sth->finish();
306 $dbh->disconnect();
346 $dbh->disconnect();
307
347
308 if ($cfg->{RedmineCacheCredsMax} and $ret) {
348 if ($cfg->{RedmineMemcache} and $ret) {
309 if (defined $usrprojpass) {
349 if ($cfg->{RedmineMemcacheExpirySec}) {
310 $cfg->{RedmineCacheCreds}->set($redmine_user.":".$project_id, $pass_digest);
350 $cfg->{RedmineMemcached}->set($redmine_user.":".$project_id, $pass_digest, $cfg->{RedmineMemcacheExpirySec});
311 } else {
351 } else {
312 if ($cfg->{RedmineCacheCredsCount} < $cfg->{RedmineCacheCredsMax}) {
352 $cfg->{RedmineMemcached}->set($redmine_user.":".$project_id, $pass_digest);
313 $cfg->{RedmineCacheCreds}->set($redmine_user.":".$project_id, $pass_digest);
314 $cfg->{RedmineCacheCredsCount}++;
315 } else {
316 $cfg->{RedmineCacheCreds}->clear();
317 $cfg->{RedmineCacheCredsCount} = 0;
318 }
319 }
353 }
320 }
354 }
321
355
General Comments 0
You need to be logged in to leave comments. Login now