Rev 172 Rev 185
Line 1... Line 1...
1 <?php 1 <?php
2 # vim:et:ts=3:sts=3:sw=3:fdm=marker: 2 # vim:et:ts=3:sts=3:sw=3:fdm=marker:
3   3  
4 // WebSVN - Subversion repository viewing via the web using PHP 4 // WebSVN - Subversion repository viewing via the web using PHP
5 // Copyright © 2004-2006 Tim Armes, Matt Sicker 5 // Copyright © 2004-2006 Tim Armes, Matt Sicker
6 // 6 //
7 // This program is free software; you can redistribute it and/or modify 7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by 8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or 9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version. 10 // (at your option) any later version.
11 // 11 //
12 // This program is distributed in the hope that it will be useful, 12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details. 15 // GNU General Public License for more details.
16 // 16 //
17 // You should have received a copy of the GNU General Public License 17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software 18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // 20 //
21 // -- 21 // --
22 // 22 //
23 // auth.inc 23 // auth.inc
24 // 24 //
25 // Handle reading and interpretation of an SVN auth file 25 // Handle reading and interpretation of an SVN auth file
26   26  
27 require_once("include/accessfile.inc"); 27 require_once("include/accessfile.inc");
28   28  
29 define("UNDEFINED", 0); 29 define("UNDEFINED", 0);
30 define("ALLOW", 1); 30 define("ALLOW", 1);
31 define("DENY", 2); 31 define("DENY", 2);
32   32  
33 class Authentication 33 class Authentication
34 { 34 {
35 var $rights; 35 var $rights;
36 var $user; 36 var $user;
37 var $usersGroups = array(); 37 var $usersGroups = array();
38 38
39 // {{{ __construct 39 // {{{ __construct
40   40  
41 function Authentication($accessfile) 41 function Authentication($accessfile)
42 { 42 {
43 $this->rights = new IniFile(); 43 $this->rights = new IniFile();
44 $this->rights->readIniFile($accessfile); 44 $this->rights->readIniFile($accessfile);
45 $this->setUsername(""); 45 $this->setUsername("");
46 $this->identifyGroups(); 46 $this->identifyGroups();
47 } 47 }
48   48  
49 // }}} 49 // }}}
50 50
51 // {{{ setUsername($username) 51 // {{{ setUsername($username)
52 // 52 //
53 // Set the username if it is given, or 53 // Set the username if it is given, or
54 // get the user of the current http session 54 // get the user of the current http session
55   55  
56 function setUsername($username) 56 function setUsername($username)
57 { 57 {
58 if ($username == "") // Use the current user 58 if ($username == "") // Use the current user
59 { 59 {
60 $this->user = @$_SERVER["REMOTE_USER"]; 60 $this->user = @$_SERVER["REMOTE_USER"];
61 } 61 }
62 else 62 else
63 { 63 {
64 $this->user = $username; 64 $this->user = $username;
65 } 65 }
66 } 66 }
67   67  
68 // }}} 68 // }}}
69   69  
70 // {{{ identifyGroups() 70 // {{{ identifyGroups()
71 // 71 //
72 // Checks to see which groups the user belongs to 72 // Checks to see which groups the user belongs to
73   73  
74 function identifyGroups() 74 function identifyGroups()
75 { 75 {
76 $this->usersGroups[] = "*"; 76 $this->usersGroups[] = "*";
77   77  
78 if (is_array($this->rights->getValues("groups"))) 78 if (is_array($this->rights->getValues("groups")))
79 { 79 {
80 foreach ($this->rights->getValues("groups") as $group => $names) 80 foreach ($this->rights->getValues("groups") as $group => $names)
81 { 81 {
82 if (in_array(strtolower($this->user), preg_split('/\s*,\s*/', $names))) 82 if (in_array(strtolower($this->user), preg_split('/\s*,\s*/', $names)))
83 $this->usersGroups[] = "@" . $group; 83 $this->usersGroups[] = "@" . $group;
84 } 84 }
85 } 85 }
86 } 86 }
87   87  
88 // }}} 88 // }}}
89   89  
90 // {{{ inList 90 // {{{ inList
91 // 91 //
92 // Check if the user is in the given list and return their read status 92 // Check if the user is in the given list and return their read status
93 // if they are (UNDEFINED, ALLOW or DENY) 93 // if they are (UNDEFINED, ALLOW or DENY)
94 94
95 function inList($accessors, $user) 95 function inList($accessors, $user)
96 { 96 {
97 $output = UNDEFINED; 97 $output = UNDEFINED;
98 foreach($accessors As $key => $rights) 98 foreach($accessors As $key => $rights)
99 { 99 {
100 $keymatch = false; 100 $keymatch = false;
101 101
102 if (in_array($key, $this->usersGroups) || !strcmp($key, strtolower($user))) 102 if (in_array($key, $this->usersGroups) || !strcmp($key, strtolower($user)))
103 $keymatch = true; 103 $keymatch = true;
104 104
105 if ($keymatch) 105 if ($keymatch)
106 { 106 {
107 if (strpos($rights, "r") !== false) 107 if (strpos($rights, "r") !== false)
108 return ALLOW; 108 return ALLOW;
109 else 109 else
110 $output = DENY; 110 $output = DENY;
111 } 111 }
112 } 112 }
113 113
114 return $output; 114 return $output;
115 } 115 }
116   116  
117 // }}} 117 // }}}
118 118
119 // {{{ hasReadAccess 119 // {{{ hasReadAccess
120 // 120 //
121 // Returns true if the user has read access to the given path 121 // Returns true if the user has read access to the given path
122 122
123 function hasReadAccess($repos, $path, $checkSubFolders = false) 123 function hasReadAccess($repos, $path, $checkSubFolders = false)
124 { 124 {
125 $access = UNDEFINED; 125 $access = UNDEFINED;
126 if ($path{0} != "/") 126 if ($path{0} != "/")
127 $path = "/$path"; 127 $path = "/$path";
128 128
129 // If were told to, we should check sub folders of the path to see if there's 129 // If were told to, we should check sub folders of the path to see if there's
130 // a read access below this level. This is used to display the folders needed 130 // a read access below this level. This is used to display the folders needed
131 // to get to the folder to which read access is granted. 131 // to get to the folder to which read access is granted.
132 132
133 if ($checkSubFolders) 133 if ($checkSubFolders)
134 { 134 {
135 $sections = $this->rights->getSections(); 135 $sections = $this->rights->getSections();
136 136
137 foreach($sections As $section => $accessers) 137 foreach($sections As $section => $accessers)
138 { 138 {
139 $qualified = $repos.":".$path; 139 $qualified = $repos.":".$path;
140 $len = strlen($qualified); 140 $len = strlen($qualified);
141 141
142 if ($len < strlen($section) && strncmp($section, $qualified, strlen($qualified)) == 0) 142 if ($len < strlen($section) && strncmp($section, $qualified, strlen($qualified)) == 0)
143 { 143 {
144 $access = $this->inList($accessers, $this->user); 144 $access = $this->inList($accessers, $this->user);
145 } 145 }
146   146  
147 if ($access != ALLOW) 147 if ($access != ALLOW)
148 { 148 {
149 $len = strlen($path); 149 $len = strlen($path);
150 if ($len < strlen($section) && strncmp($section, $path, strlen($path)) == 0) 150 if ($len < strlen($section) && strncmp($section, $path, strlen($path)) == 0)
151 { 151 {
152 $access = $this->inList($accessers, $this->user); 152 $access = $this->inList($accessers, $this->user);
153 } 153 }
154 } 154 }
155 155
156 if ($access == ALLOW) 156 if ($access == ALLOW)
157 break; 157 break;
158 } 158 }
159 } 159 }
160 160
161 // If we still don't have access, check each subpath of the path until we find an 161 // If we still don't have access, check each subpath of the path until we find an
162 // access level... 162 // access level...
163 163
164 if ($access != ALLOW) 164 if ($access != ALLOW)
165 { 165 {
166 $access = UNDEFINED; 166 $access = UNDEFINED;
167 167
168 do 168 do
169 { 169 {
170 $accessers = $this->rights->getValues($repos.":".$path); 170 $accessers = $this->rights->getValues($repos.":".$path);
171 if (!empty($accessers)) 171 if (!empty($accessers))
172 $access = $this->inList($accessers, $this->user); 172 $access = $this->inList($accessers, $this->user);
173 173
174 if ($access == UNDEFINED) 174 if ($access == UNDEFINED)
175 { 175 {
176 $accessers = $this->rights->getValues($path); 176 $accessers = $this->rights->getValues($path);
177 if (!empty($accessers)) 177 if (!empty($accessers))
178 $access = $this->inList($accessers, $this->user); 178 $access = $this->inList($accessers, $this->user);
179 } 179 }
180 180
181 // If we've not got a match, remove the sub directory and start again 181 // If we've not got a match, remove the sub directory and start again
182 if ($access == UNDEFINED) 182 if ($access == UNDEFINED)
183 { 183 {
184 if ($path == "/") break; 184 if ($path == "/") break;
185 $path = substr($path, 0, strrpos(substr($path, 0, -1), "/") + 1); 185 $path = substr($path, 0, strrpos(substr($path, 0, -1), "/") + 1);
186 } 186 }
187 187
188 } while ($access == UNDEFINED && $path != ""); 188 } while ($access == UNDEFINED && $path != "");
189 } 189 }
190 190
191 return $access == ALLOW; 191 return $access == ALLOW;
192 } 192 }
193   193  
194 // }}} 194 // }}}
195 195
196 // {{{ hasUnrestrictedReadAccess 196 // {{{ hasUnrestrictedReadAccess
197 // 197 //
198 // Returns true if the user has read access to the given path and too 198 // Returns true if the user has read access to the given path and too
199 // all subfolders 199 // all subfolders
200 200
201 function hasUnrestrictedReadAccess($repos, $path) 201 function hasUnrestrictedReadAccess($repos, $path)
202 { 202 {
203 // First make sure that we have full read access at this level 203 // First make sure that we have full read access at this level
204 204
205 if (!$this->hasReadAccess($repos, $path, false)) 205 if (!$this->hasReadAccess($repos, $path, false))
206 return false; 206 return false;
207 207
208 // Now check to see if there is a sub folder that's protected 208 // Now check to see if there is a sub folder that's protected
209 209
210 $sections = $this->rights->getSections(); 210 $sections = $this->rights->getSections();
211 211
212 foreach($sections As $section => $accessers) 212 foreach($sections As $section => $accessers)
213 { 213 {
214 $qualified = $repos.":".$path; 214 $qualified = $repos.":".$path;
215 $len = strlen($qualified); 215 $len = strlen($qualified);
216 $access = UNDEFINED; 216 $access = UNDEFINED;
217 217
218 if ($len < strlen($section) && strncmp($section, $qualified, strlen($qualified)) == 0) 218 if ($len < strlen($section) && strncmp($section, $qualified, strlen($qualified)) == 0)
219 { 219 {
220 $access = $this->inList($accessers, $this->user); 220 $access = $this->inList($accessers, $this->user);
221 } 221 }
222   222  
223 if ($access != DENY) 223 if ($access != DENY)
224 { 224 {
225 $len = strlen($path); 225 $len = strlen($path);
226 if ($len < strlen($section) && strncmp($section, $path, strlen($qualified)) == 0) 226 if ($len < strlen($section) && strncmp($section, $path, strlen($qualified)) == 0)
227 { 227 {
228 $access = $this->inList($accessers, $this->user); 228 $access = $this->inList($accessers, $this->user);
229 } 229 }
230 } 230 }
231 231
232 if ($access == DENY) 232 if ($access == DENY)
233 return false; 233 return false;
234 } 234 }
235 235
236 return true; 236 return true;
237 } 237 }
238   238  
239 // }}} 239 // }}}
240   240  
241 } 241 }
242 ?> 242 ?>