3 * Base include file for SimpleTest
5 * @subpackage WebTester
6 * @version $Id: authentication.php,v 1.8 2004/07/28 16:42:08 lastcraft Exp $
11 require_once(dirname(__FILE__
) . '/http.php');
14 * Represents a single security realm's identity.
16 * @subpackage WebTester
25 * Starts with the initial entry directory.
26 * @param string $type Authentication type for this
27 * realm. Only Basic authentication
28 * is currently supported.
29 * @param SimpleUrl $url Somewhere in realm.
32 function SimpleRealm($type, $url) {
34 $this->_root
= $url->getBasePath();
35 $this->_username
= false
;
36 $this->_password
= false
;
40 * Adds another location to the realm.
41 * @param SimpleUrl $url Somewhere in realm.
44 function stretch($url) {
45 $this->_root
= $this->_getCommonPath($this->_root
, $url->getPath());
49 * Finds the common starting path.
50 * @param string $first Path to compare.
51 * @param string $second Path to compare.
52 * @return string Common directories.
55 function _getCommonPath($first, $second) {
56 $first = explode('/', $first);
57 $second = explode('/', $second);
58 for ($i = 0; $i < min(count($first), count($second)); $i++
) {
59 if ($first[$i] != $second[$i]) {
60 return implode('/', array_slice($first, 0, $i)) . '/';
63 return implode('/', $first) . '/';
67 * Sets the identity to try within this realm.
68 * @param string $username Username in authentication dialog.
69 * @param string $username Password in authentication dialog.
72 function setIdentity($username, $password) {
73 $this->_username
= $username;
74 $this->_password
= $password;
78 * Accessor for current identity.
79 * @return string Last succesful username.
82 function getUsername() {
83 return $this->_username
;
87 * Accessor for current identity.
88 * @return string Last succesful password.
91 function getPassword() {
92 return $this->_password
;
96 * Test to see if the URL is within the directory
98 * @param SimpleUrl $url URL to test.
99 * @return boolean True if subpath.
102 function isWithin($url) {
103 return (strpos($url->getBasePath(), $this->_root
) === 0);
108 * Manages security realms.
109 * @package SimpleTest
110 * @subpackage WebTester
112 class SimpleAuthenticator
{
116 * Starts with no realms set up.
119 function SimpleAuthenticator() {
120 $this->_realms
= array();
124 * Adds a new realm centered the current URL.
125 * Browsers vary wildly on their behaviour in this
126 * regard. Mozilla ignores the realm and presents
127 * only when challenged, wasting bandwidth. IE
128 * just carries on presenting until a new challenge
129 * occours. SimpleTest tries to follow the spirit of
130 * the original standards committee and treats the
131 * base URL as the root of a file tree shaped realm.
132 * @param SimpleUrl $url Base of realm.
133 * @param string $type Authentication type for this
134 * realm. Only Basic authentication
135 * is currently supported.
136 * @param string $realm Name of realm.
139 function addRealm($url, $type, $realm) {
140 $this->_realms
[$url->getHost()][$realm] = new SimpleRealm($type, $url);
144 * Sets the current identity to be presented
145 * against that realm.
146 * @param string $host Server hosting realm.
147 * @param string $realm Name of realm.
148 * @param string $username Username for realm.
149 * @param string $password Password for realm.
152 function setIdentityForRealm($host, $realm, $username, $password) {
153 if (isset($this->_realms
[$host][$realm])) {
154 $this->_realms
[$host][$realm]->setIdentity($username, $password);
159 * Finds the name of the realm by comparing URLs.
160 * @param SimpleUrl $url URL to test.
161 * @return SimpleRealm Name of realm.
164 function _findRealmFromUrl($url) {
165 if (! isset($this->_realms
[$url->getHost()])) {
168 foreach ($this->_realms
[$url->getHost()] as $name => $realm) {
169 if ($realm->isWithin($url)) {
177 * Presents the appropriate headers for this location.
178 * @param SimpleHttpRequest $request Request to modify.
179 * @param SimpleUrl $url Base of realm.
182 function addHeaders(&$request, $url) {
183 if ($url->getUsername() && $url->getPassword()) {
184 $username = $url->getUsername();
185 $password = $url->getPassword();
186 } elseif ($realm = $this->_findRealmFromUrl($url)) {
187 $username = $realm->getUsername();
188 $password = $realm->getPassword();
192 $this->addBasicHeaders($request, $username, $password);
196 * Presents the appropriate headers for this
197 * location for basic authentication.
198 * @param SimpleHttpRequest $request Request to modify.
199 * @param string $username Username for realm.
200 * @param string $password Password for realm.
204 function addBasicHeaders(&$request, $username, $password) {
205 if ($username && $password) {
206 $request->addHeaderLine(
207 'Authorization: Basic ' . base64_encode("$username:$password"));