Rev Author Line No. Line
4988 kaklik 1 <?php
2 // WebSVN - Subversion repository viewing via the web using PHP
3 // Copyright (C) 2004-2006 Tim Armes
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 //
19 // --
20 //
21 // authz.php
22 //
23 // Handle SVN access file
24  
25 class Authorization {
26 var $accessCache = array();
27 var $accessFile = null;
28 var $user = null;
29  
30 // {{{ __construct
31  
32 function __construct() {
33 $this->setUsername();
34 }
35  
36 // }}}
37  
38 function hasUsername() {
39 return $this->user !== null;
40 }
41  
42 function addAccessFile($accessFile) {
43 $this->accessFile = $accessFile;
44 }
45  
46 // {{{ setUsername()
47 //
48 // Set the username from the current http session
49  
50 function setUsername() {
51 if (isset($_SERVER['REMOTE_USER'])) {
52 $this->user = $_SERVER['REMOTE_USER'];
53 } else if (isset($_SERVER['REDIRECT_REMOTE_USER'])) {
54 $this->user = $_SERVER['REDIRECT_REMOTE_USER'];
55 } else if (isset($_SERVER['PHP_AUTH_USER'])) {
56 $this->user = $_SERVER['PHP_AUTH_USER'];
57 }
58 }
59  
60 // }}}
61  
62 // Private function to simplify creation of common SVN authz command string text.
63 function svnAuthzCommandString($repo, $path, $checkSubDirs = false) {
64 global $config;
65  
66 $cmd = $config->getSvnAuthzCommand();
67 $repoAndPath = '--repository ' . quote($repo) . ' --path ' . quote($path);
68 $username = !$this->hasUsername() ? '' : '--username ' . quote($this->user);
69 $subDirs = !$checkSubDirs ? '' : '-R';
70 $authzFile = quote($this->accessFile);
71 $retVal = "{$cmd} {$repoAndPath} {$username} {$subDirs} {$authzFile}";
72  
73 return $retVal;
74 }
75  
76 // {{{ hasReadAccess
77 //
78 // Returns true if the user has read access to the given path
79  
80 function hasReadAccess($repos, $path, $checkSubDirs = false) {
81 if ($this->accessFile == null)
82 return false;
83  
84 if ($path == '' || $path[0] != '/') {
85 $path = '/'.$path;
86 }
87  
88 $cmd = $this->svnAuthzCommandString($repos, $path, $checkSubDirs);
89 $result = 'no';
90  
91 // Access checks might be issued multiple times for the same repos and paths within one and
92 // the same request, introducing a lot of overhead because of "svnauthz" especially with
93 // many repos under Windows. The easiest way to somewhat optimize it for different scenarios
94 // is using a cache.
95 //
96 // https://github.com/websvnphp/websvn/issues/78#issuecomment-489306169
97 $cache =& $this->accessCache;
98 $cached = isset($cache[$cmd]) ? $cache[$cmd] : null;
99 $cachedWhen = isset($cached) ? $cached['when'] : 0;
100 $cachedExpired = (time() - 60) > $cachedWhen;
101  
102 if ($cachedExpired) {
103 // Sorting by "when" should be established somehow to only remove the oldest element
104 // instead of an arbitrary first one, which might be the newest added last time.
105 if (count($cache) >= 1000) {
106 array_shift($cache);
107 }
108  
109 $result = runCommand($cmd)[0];
110 $cache[$cmd] = array('when' => time(),
111 'result' => $result);
112 } else {
113 $result = $cached['result'];
114 }
115  
116 return $result != 'no';
117 }
118  
119 // }}}
120  
121 // {{{ hasUnrestrictedReadAccess
122 //
123 // Returns true if the user has read access to the given path and too
124 // all subdirectories
125  
126 function hasUnrestrictedReadAccess($repos, $path) {
127 return $this->hasReadAccess($repos, $path, true);
128 }
129  
130 // }}}
131  
132 }