Mercurial > hg > soundsoftware-site
diff extra/svn/Redmine.pm @ 909:cbb26bc654de redmine-1.3
Update to Redmine 1.3-stable branch (Redmine SVN rev 8964)
author | Chris Cannam |
---|---|
date | Fri, 24 Feb 2012 19:09:32 +0000 |
parents | 051f544170fe |
children | 5f33065ddc4b |
line wrap: on
line diff
--- a/extra/svn/Redmine.pm Fri Feb 24 18:36:29 2012 +0000 +++ b/extra/svn/Redmine.pm Fri Feb 24 19:09:32 2012 +0000 @@ -49,7 +49,7 @@ PerlAccessHandler Apache::Authn::Redmine::access_handler PerlAuthenHandler Apache::Authn::Redmine::authen_handler - + ## for mysql RedmineDSN "DBI:mysql:database=databasename;host=my.db.server" ## for postgres @@ -144,31 +144,32 @@ }, ); -sub RedmineDSN { +sub RedmineDSN { my ($self, $parms, $arg) = @_; $self->{RedmineDSN} = $arg; my $query = "SELECT hashed_password, salt, auth_source_id, permissions - FROM members, projects, users, roles, member_roles + FROM projects, users, roles WHERE - projects.id=members.project_id - AND member_roles.member_id=members.id - AND users.id=members.user_id - AND roles.id=member_roles.role_id + users.login=? + AND projects.identifier=? AND users.status=1 - AND login=? - AND identifier=? "; + AND ( + roles.id IN (SELECT member_roles.role_id FROM members, member_roles WHERE members.user_id = users.id AND members.project_id = projects.id AND members.id = member_roles.member_id) + OR + (roles.builtin=1 AND cast(projects.is_public as CHAR) IN ('t', '1')) + ) "; $self->{RedmineQuery} = trim($query); } sub RedmineDbUser { set_val('RedmineDbUser', @_); } sub RedmineDbPass { set_val('RedmineDbPass', @_); } -sub RedmineDbWhereClause { +sub RedmineDbWhereClause { my ($self, $parms, $arg) = @_; $self->{RedmineQuery} = trim($self->{RedmineQuery}.($arg ? $arg : "")." "); } -sub RedmineCacheCredsMax { +sub RedmineCacheCredsMax { my ($self, $parms, $arg) = @_; if ($arg) { $self->{RedmineCachePool} = APR::Pool->new; @@ -208,17 +209,17 @@ my $project_id = get_project_identifier($r); $r->set_handlers(PerlAuthenHandler => [\&OK]) - if is_public_project($project_id, $r); + if is_public_project($project_id, $r) && anonymous_role_allows_browse_repository($r); return OK } sub authen_handler { my $r = shift; - + my ($res, $redmine_pass) = $r->get_basic_auth_pw(); return $res unless $res == OK; - + if (is_member($r->user, $redmine_pass, $r)) { return OK; } else { @@ -245,7 +246,7 @@ } $sth->finish(); undef $sth; - + $dbh->disconnect(); undef $dbh; @@ -255,7 +256,7 @@ sub is_public_project { my $project_id = shift; my $r = shift; - + if (is_authentication_forced($r)) { return 0; } @@ -280,6 +281,29 @@ $ret; } +sub anonymous_role_allows_browse_repository { + my $r = shift; + + my $dbh = connect_database($r); + my $sth = $dbh->prepare( + "SELECT permissions FROM roles WHERE builtin = 2;" + ); + + $sth->execute(); + my $ret = 0; + if (my @row = $sth->fetchrow_array) { + if ($row[0] =~ /:browse_repository/) { + $ret = 1; + } + } + $sth->finish(); + undef $sth; + $dbh->disconnect(); + undef $dbh; + + $ret; +} + # perhaps we should use repository right (other read right) to check public access. # it could be faster BUT it doesn't work for the moment. # sub is_public_project_by_file { @@ -305,10 +329,12 @@ my $pass_digest = Digest::SHA1::sha1_hex($redmine_pass); + my $access_mode = defined $read_only_methods{$r->method} ? "R" : "W"; + my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config); my $usrprojpass; if ($cfg->{RedmineCacheCredsMax}) { - $usrprojpass = $cfg->{RedmineCacheCreds}->get($redmine_user.":".$project_id); + $usrprojpass = $cfg->{RedmineCacheCreds}->get($redmine_user.":".$project_id.":".$access_mode); return 1 if (defined $usrprojpass and ($usrprojpass eq $pass_digest)); } my $query = $cfg->{RedmineQuery}; @@ -321,7 +347,7 @@ unless ($auth_source_id) { my $method = $r->method; my $salted_password = Digest::SHA1::sha1_hex($salt.$pass_digest); - if ($hashed_password eq $salted_password && ((defined $read_only_methods{$method} && $permissions =~ /:browse_repository/) || $permissions =~ /:commit_access/) ) { + if ($hashed_password eq $salted_password && (($access_mode eq "R" && $permissions =~ /:browse_repository/) || $permissions =~ /:commit_access/) ) { $ret = 1; last; } @@ -340,7 +366,7 @@ filter => "(".$rowldap[6]."=%s)" ); my $method = $r->method; - $ret = 1 if ($ldap->authenticate($redmine_user, $redmine_pass) && ((defined $read_only_methods{$method} && $permissions =~ /:browse_repository/) || $permissions =~ /:commit_access/)); + $ret = 1 if ($ldap->authenticate($redmine_user, $redmine_pass) && (($access_mode eq "R" && $permissions =~ /:browse_repository/) || $permissions =~ /:commit_access/)); } $sthldap->finish(); @@ -354,10 +380,10 @@ if ($cfg->{RedmineCacheCredsMax} and $ret) { if (defined $usrprojpass) { - $cfg->{RedmineCacheCreds}->set($redmine_user.":".$project_id, $pass_digest); + $cfg->{RedmineCacheCreds}->set($redmine_user.":".$project_id.":".$access_mode, $pass_digest); } else { if ($cfg->{RedmineCacheCredsCount} < $cfg->{RedmineCacheCredsMax}) { - $cfg->{RedmineCacheCreds}->set($redmine_user.":".$project_id, $pass_digest); + $cfg->{RedmineCacheCreds}->set($redmine_user.":".$project_id.":".$access_mode, $pass_digest); $cfg->{RedmineCacheCredsCount}++; } else { $cfg->{RedmineCacheCreds}->clear(); @@ -371,7 +397,7 @@ sub get_project_identifier { my $r = shift; - + my $location = $r->location; my ($identifier) = $r->uri =~ m{$location/*([^/]+)}; $identifier; @@ -379,7 +405,7 @@ sub connect_database { my $r = shift; - + my $cfg = Apache2::Module::get_config(__PACKAGE__, $r->server, $r->per_dir_config); return DBI->connect($cfg->{RedmineDSN}, $cfg->{RedmineDbUser}, $cfg->{RedmineDbPass}); }