3 * Base include file for SimpleTest
5 * @subpackage WebTester
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 if ($this->_isIn($this->_root
, $url->getBasePath())) {
106 if ($this->_isIn($this->_root
, $url->getBasePath() . $url->getPage() . '/')) {
113 * Tests to see if one string is a substring of
115 * @param string $part Small bit.
116 * @param string $whole Big bit.
117 * @return boolean True if the small bit is
121 function _isIn($part, $whole) {
122 return strpos($whole, $part) === 0;
127 * Manages security realms.
128 * @package SimpleTest
129 * @subpackage WebTester
131 class SimpleAuthenticator
{
138 function SimpleAuthenticator() {
139 $this->restartSession();
143 * Starts with no realms set up.
146 function restartSession() {
147 $this->_realms
= array();
151 * Adds a new realm centered the current URL.
152 * Browsers vary wildly on their behaviour in this
153 * regard. Mozilla ignores the realm and presents
154 * only when challenged, wasting bandwidth. IE
155 * just carries on presenting until a new challenge
156 * occours. SimpleTest tries to follow the spirit of
157 * the original standards committee and treats the
158 * base URL as the root of a file tree shaped realm.
159 * @param SimpleUrl $url Base of realm.
160 * @param string $type Authentication type for this
161 * realm. Only Basic authentication
162 * is currently supported.
163 * @param string $realm Name of realm.
166 function addRealm($url, $type, $realm) {
167 $this->_realms
[$url->getHost()][$realm] = new SimpleRealm($type, $url);
171 * Sets the current identity to be presented
172 * against that realm.
173 * @param string $host Server hosting realm.
174 * @param string $realm Name of realm.
175 * @param string $username Username for realm.
176 * @param string $password Password for realm.
179 function setIdentityForRealm($host, $realm, $username, $password) {
180 if (isset($this->_realms
[$host][$realm])) {
181 $this->_realms
[$host][$realm]->setIdentity($username, $password);
186 * Finds the name of the realm by comparing URLs.
187 * @param SimpleUrl $url URL to test.
188 * @return SimpleRealm Name of realm.
191 function _findRealmFromUrl($url) {
192 if (! isset($this->_realms
[$url->getHost()])) {
195 foreach ($this->_realms
[$url->getHost()] as $name => $realm) {
196 if ($realm->isWithin($url)) {
204 * Presents the appropriate headers for this location.
205 * @param SimpleHttpRequest $request Request to modify.
206 * @param SimpleUrl $url Base of realm.
209 function addHeaders(&$request, $url) {
210 if ($url->getUsername() && $url->getPassword()) {
211 $username = $url->getUsername();
212 $password = $url->getPassword();
213 } elseif ($realm = $this->_findRealmFromUrl($url)) {
214 $username = $realm->getUsername();
215 $password = $realm->getPassword();
219 $this->addBasicHeaders($request, $username, $password);
223 * Presents the appropriate headers for this
224 * location for basic authentication.
225 * @param SimpleHttpRequest $request Request to modify.
226 * @param string $username Username for realm.
227 * @param string $password Password for realm.
231 function addBasicHeaders(&$request, $username, $password) {
232 if ($username && $password) {
233 $request->addHeaderLine(
234 'Authorization: Basic ' . base64_encode("$username:$password"));