##// END OF EJS Templates
Added user status criteria in Redmine.pm...
Jean-Philippe Lang -
r917:f2a12d9eb5ae
parent child
Show More
@@ -1,210 +1,210
1 1 package Apache::Authn::Redmine;
2 2
3 3 =head1 Apache::Authn::Redmine
4 4
5 5 Redmine - a mod_perl module to authenticate webdav subversion users
6 6 against redmine database
7 7
8 8 =head1 SYNOPSIS
9 9
10 10 This module allow anonymous users to browse public project and
11 11 registred users to browse and commit their project. authentication is
12 12 done on the redmine database.
13 13
14 14 This method is far simpler than the one with pam_* and works with all
15 15 database without an hassle but you need to have apache/mod_perl on the
16 16 svn server.
17 17
18 18 =head1 INSTALLATION
19 19
20 20 For this to automagically work, you need to have a recent reposman.rb
21 21 (after r860) and if you already use reposman, read the last section to
22 22 migrate.
23 23
24 24 Sorry ruby users but you need some perl modules, at least mod_perl2,
25 25 DBI and DBD::mysql (or the DBD driver for you database as it should
26 26 work on allmost all databases).
27 27
28 28 On debian/ubuntu you must do :
29 29
30 30 aptitude install libapache-dbi-perl libapache2-mod-perl2 libdbd-mysql-perl
31 31
32 32 =head1 CONFIGURATION
33 33
34 34 ## if the module isn't in your perl path
35 35 PerlRequire /usr/local/apache/Redmine.pm
36 36 ## else
37 37 # PerlModule Apache::Authn::Redmine
38 38 <Location /svn>
39 39 DAV svn
40 40 SVNParentPath "/var/svn"
41 41
42 42 AuthType Basic
43 43 AuthName redmine
44 44 Require valid-user
45 45
46 46 PerlAccessHandler Apache::Authn::Redmine::access_handler
47 47 PerlAuthenHandler Apache::Authn::Redmine::authen_handler
48 48
49 49 ## for mysql
50 50 PerlSetVar dsn DBI:mysql:database=databasename;host=my.db.server
51 51 ## for postgres
52 52 # PerlSetVar dsn DBI:Pg:dbname=databasename;host=my.db.server
53 53
54 54 PerlSetVar db_user redmine
55 55 PerlSetVar db_pass password
56 56 </Location>
57 57
58 58 To be able to browse repository inside redmine, you must add something
59 59 like that :
60 60
61 61 <Location /svn-private>
62 62 DAV svn
63 63 SVNParentPath "/var/svn"
64 64 Order deny,allow
65 65 Deny from all
66 66 # only allow reading orders
67 67 <Limit GET PROPFIND OPTIONS REPORT>
68 68 Allow from redmine.server.ip
69 69 </Limit>
70 70 </Location>
71 71
72 72 and you will have to use this reposman.rb command line to create repository :
73 73
74 74 reposman.rb --redmine my.redmine.server --svn-dir /var/svn --owner www-data -u http://svn.server/svn-private/
75 75
76 76 =head1 MIGRATION FROM OLDER RELEASES
77 77
78 78 If you use an older reposman.rb (r860 or before), you need to change
79 79 rights on repositories to allow the apache user to read and write
80 80 S<them :>
81 81
82 82 sudo chown -R www-data /var/svn/*
83 83 sudo chmod -R u+w /var/svn/*
84 84
85 85 And you need to upgrade at least reposman.rb (after r860).
86 86
87 87 =cut
88 88
89 89 use strict;
90 90
91 91 use DBI;
92 92 use Digest::SHA1;
93 93
94 94 use Apache2::Module;
95 95 use Apache2::Access;
96 96 use Apache2::ServerRec qw();
97 97 use Apache2::RequestRec qw();
98 98 use Apache2::RequestUtil qw();
99 99 use Apache2::Const qw(:common);
100 100 # use Apache2::Directive qw();
101 101
102 102 my %read_only_methods = map { $_ => 1 } qw/GET PROPFIND REPORT OPTIONS/;
103 103
104 104 sub access_handler {
105 105 my $r = shift;
106 106
107 107 unless ($r->some_auth_required) {
108 108 $r->log_reason("No authentication has been configured");
109 109 return FORBIDDEN;
110 110 }
111 111
112 112 my $method = $r->method;
113 113 return OK unless 1 == $read_only_methods{$method};
114 114
115 115 my $project_id = get_project_identifier($r);
116 116
117 117 $r->set_handlers(PerlAuthenHandler => [\&OK])
118 118 if is_public_project($project_id, $r);
119 119
120 120 return OK
121 121 }
122 122
123 123 sub authen_handler {
124 124 my $r = shift;
125 125
126 126 my ($res, $redmine_pass) = $r->get_basic_auth_pw();
127 127 return $res unless $res == OK;
128 128
129 129 if (is_member($r->user, $redmine_pass, $r)) {
130 130 return OK;
131 131 } else {
132 132 $r->note_auth_failure();
133 133 return AUTH_REQUIRED;
134 134 }
135 135 }
136 136
137 137 sub is_public_project {
138 138 my $project_id = shift;
139 139 my $r = shift;
140 140
141 141 my $dbh = connect_database($r);
142 142 my $sth = $dbh->prepare(
143 143 "SELECT * FROM projects WHERE projects.identifier=? and projects.is_public=true;"
144 144 );
145 145
146 146 $sth->execute($project_id);
147 147 my $ret = $sth->fetchrow_array ? 1 : 0;
148 148 $dbh->disconnect();
149 149
150 150 $ret;
151 151 }
152 152
153 153 # perhaps we should use repository right (other read right) to check public access.
154 154 # it could be faster BUT it doesn't work for the moment.
155 155 # sub is_public_project_by_file {
156 156 # my $project_id = shift;
157 157 # my $r = shift;
158 158
159 159 # my $tree = Apache2::Directive::conftree();
160 160 # my $node = $tree->lookup('Location', $r->location);
161 161 # my $hash = $node->as_hash;
162 162
163 163 # my $svnparentpath = $hash->{SVNParentPath};
164 164 # my $repos_path = $svnparentpath . "/" . $project_id;
165 165 # return 1 if (stat($repos_path))[2] & 00007;
166 166 # }
167 167
168 168 sub is_member {
169 169 my $redmine_user = shift;
170 170 my $redmine_pass = shift;
171 171 my $r = shift;
172 172
173 173 my $dbh = connect_database($r);
174 174 my $project_id = get_project_identifier($r);
175 175
176 176 my $pass_digest = Digest::SHA1::sha1_hex($redmine_pass);
177 177
178 178 my $sth = $dbh->prepare(
179 "SELECT hashed_password FROM members, projects, users WHERE projects.id=members.project_id AND users.id=members.user_id AND login=? AND identifier=?;"
179 "SELECT hashed_password FROM members, projects, users WHERE projects.id=members.project_id AND users.id=members.user_id AND users.status=1 AND login=? AND identifier=?;"
180 180 );
181 181 $sth->execute($redmine_user, $project_id);
182 182
183 183 my $ret;
184 184 while (my @row = $sth->fetchrow_array) {
185 185 if ($row[0] eq $pass_digest) {
186 186 $ret = 1;
187 187 last;
188 188 }
189 189 }
190 190 $dbh->disconnect();
191 191
192 192 $ret;
193 193 }
194 194
195 195 sub get_project_identifier {
196 196 my $r = shift;
197 197
198 198 my $location = $r->location;
199 199 my ($identifier) = $r->uri =~ m{$location/*([^/]+)};
200 200 $identifier;
201 201 }
202 202
203 203 sub connect_database {
204 204 my $r = shift;
205 205
206 206 my ($dsn, $db_user, $db_pass) = map { $r->dir_config($_) } qw/dsn db_user db_pass/;
207 207 return DBI->connect($dsn, $db_user, $db_pass);
208 208 }
209 209
210 210 1;
General Comments 0
You need to be logged in to leave comments. Login now