0,0 → 1,242 |
<?php |
# vim:et:ts=3:sts=3:sw=3:fdm=marker: |
|
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright © 2004-2006 Tim Armes, Matt Sicker |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// auth.inc |
// |
// Handle reading and interpretation of an SVN auth file |
|
require_once("include/accessfile.inc"); |
|
define("UNDEFINED", 0); |
define("ALLOW", 1); |
define("DENY", 2); |
|
class Authentication |
{ |
var $rights; |
var $user; |
var $usersGroups = array(); |
|
// {{{ __construct |
|
function Authentication($accessfile) |
{ |
$this->rights = new IniFile(); |
$this->rights->readIniFile($accessfile); |
$this->setUsername(""); |
$this->identifyGroups(); |
} |
|
// }}} |
|
// {{{ setUsername($username) |
// |
// Set the username if it is given, or |
// get the user of the current http session |
|
function setUsername($username) |
{ |
if ($username == "") // Use the current user |
{ |
$this->user = @$_SERVER["REMOTE_USER"]; |
} |
else |
{ |
$this->user = $username; |
} |
} |
|
// }}} |
|
// {{{ identifyGroups() |
// |
// Checks to see which groups the user belongs to |
|
function identifyGroups() |
{ |
$this->usersGroups[] = "*"; |
|
if (is_array($this->rights->getValues("groups"))) |
{ |
foreach ($this->rights->getValues("groups") as $group => $names) |
{ |
if (in_array(strtolower($this->user), preg_split('/\s*,\s*/', $names))) |
$this->usersGroups[] = "@" . $group; |
} |
} |
} |
|
// }}} |
|
// {{{ inList |
// |
// Check if the user is in the given list and return their read status |
// if they are (UNDEFINED, ALLOW or DENY) |
|
function inList($accessors, $user) |
{ |
$output = UNDEFINED; |
foreach($accessors As $key => $rights) |
{ |
$keymatch = false; |
|
if (in_array($key, $this->usersGroups) || !strcmp($key, strtolower($user))) |
$keymatch = true; |
|
if ($keymatch) |
{ |
if (strpos($rights, "r") !== false) |
return ALLOW; |
else |
$output = DENY; |
} |
} |
|
return $output; |
} |
|
// }}} |
|
// {{{ hasReadAccess |
// |
// Returns true if the user has read access to the given path |
|
function hasReadAccess($repos, $path, $checkSubFolders = false) |
{ |
$access = UNDEFINED; |
if ($path{0} != "/") |
$path = "/$path"; |
|
// If were told to, we should check sub folders of the path to see if there's |
// a read access below this level. This is used to display the folders needed |
// to get to the folder to which read access is granted. |
|
if ($checkSubFolders) |
{ |
$sections = $this->rights->getSections(); |
|
foreach($sections As $section => $accessers) |
{ |
$qualified = $repos.":".$path; |
$len = strlen($qualified); |
|
if ($len < strlen($section) && strncmp($section, $qualified, strlen($qualified)) == 0) |
{ |
$access = $this->inList($accessers, $this->user); |
} |
|
if ($access != ALLOW) |
{ |
$len = strlen($path); |
if ($len < strlen($section) && strncmp($section, $path, strlen($path)) == 0) |
{ |
$access = $this->inList($accessers, $this->user); |
} |
} |
|
if ($access == ALLOW) |
break; |
} |
} |
|
// If we still don't have access, check each subpath of the path until we find an |
// access level... |
|
if ($access != ALLOW) |
{ |
$access = UNDEFINED; |
|
do |
{ |
$accessers = $this->rights->getValues($repos.":".$path); |
if (!empty($accessers)) |
$access = $this->inList($accessers, $this->user); |
|
if ($access == UNDEFINED) |
{ |
$accessers = $this->rights->getValues($path); |
if (!empty($accessers)) |
$access = $this->inList($accessers, $this->user); |
} |
|
// If we've not got a match, remove the sub directory and start again |
if ($access == UNDEFINED) |
{ |
if ($path == "/") break; |
$path = substr($path, 0, strrpos(substr($path, 0, -1), "/") + 1); |
} |
|
} while ($access == UNDEFINED && $path != ""); |
} |
|
return $access == ALLOW; |
} |
|
// }}} |
|
// {{{ hasUnrestrictedReadAccess |
// |
// Returns true if the user has read access to the given path and too |
// all subfolders |
|
function hasUnrestrictedReadAccess($repos, $path) |
{ |
// First make sure that we have full read access at this level |
|
if (!$this->hasReadAccess($repos, $path, false)) |
return false; |
|
// Now check to see if there is a sub folder that's protected |
|
$sections = $this->rights->getSections(); |
|
foreach($sections As $section => $accessers) |
{ |
$qualified = $repos.":".$path; |
$len = strlen($qualified); |
$access = UNDEFINED; |
|
if ($len < strlen($section) && strncmp($section, $qualified, strlen($qualified)) == 0) |
{ |
$access = $this->inList($accessers, $this->user); |
} |
|
if ($access != DENY) |
{ |
$len = strlen($path); |
if ($len < strlen($section) && strncmp($section, $path, strlen($qualified)) == 0) |
{ |
$access = $this->inList($accessers, $this->user); |
} |
} |
|
if ($access == DENY) |
return false; |
} |
|
return true; |
} |
|
// }}} |
|
} |
?> |