source: trunk/server/www/vendors/simpletest/authentication.php @ 6

Last change on this file since 6 was 6, checked in by sander, 12 years ago

Added SimpleTest? test framework

File size: 7.2 KB
Line 
1<?php
2/**
3 *  Base include file for SimpleTest
4 *  @package    SimpleTest
5 *  @subpackage WebTester
6 *  @version    $Id: authentication.php 1720 2008-04-07 02:32:43Z lastcraft $
7 */
8/**
9 *  include http class
10 */
11require_once(dirname(__FILE__) . '/http.php');
12
13/**
14 *    Represents a single security realm's identity.
15 *    @package SimpleTest
16 *    @subpackage WebTester
17 */
18class SimpleRealm {
19    var $_type;
20    var $_root;
21    var $_username;
22    var $_password;
23   
24    /**
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.
30     *    @access public
31     */
32    function SimpleRealm($type, $url) {
33        $this->_type = $type;
34        $this->_root = $url->getBasePath();
35        $this->_username = false;
36        $this->_password = false;
37    }
38   
39    /**
40     *    Adds another location to the realm.
41     *    @param SimpleUrl $url    Somewhere in realm.
42     *    @access public
43     */
44    function stretch($url) {
45        $this->_root = $this->_getCommonPath($this->_root, $url->getPath());
46    }
47   
48    /**
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.
53     *    @access private
54     */
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)) . '/';
61            }
62        }
63        return implode('/', $first) . '/';
64    }
65   
66    /**
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.
70     *    @access public
71     */
72    function setIdentity($username, $password) {
73        $this->_username = $username;
74        $this->_password = $password;
75    }
76   
77    /**
78     *    Accessor for current identity.
79     *    @return string        Last succesful username.
80     *    @access public
81     */
82    function getUsername() {
83        return $this->_username;
84    }
85   
86    /**
87     *    Accessor for current identity.
88     *    @return string        Last succesful password.
89     *    @access public
90     */
91    function getPassword() {
92        return $this->_password;
93    }
94   
95    /**
96     *    Test to see if the URL is within the directory
97     *    tree of the realm.
98     *    @param SimpleUrl $url    URL to test.
99     *    @return boolean          True if subpath.
100     *    @access public
101     */
102    function isWithin($url) {
103        if ($this->_isIn($this->_root, $url->getBasePath())) {
104            return true;
105        }
106        if ($this->_isIn($this->_root, $url->getBasePath() . $url->getPage() . '/')) {
107            return true;
108        }
109        return false;
110    }
111   
112    /**
113     *    Tests to see if one string is a substring of
114     *    another.
115     *    @param string $part        Small bit.
116     *    @param string $whole       Big bit.
117     *    @return boolean            True if the small bit is
118     *                               in the big bit.
119     *    @access private
120     */
121    function _isIn($part, $whole) {
122        return strpos($whole, $part) === 0;
123    }
124}
125
126/**
127 *    Manages security realms.
128 *    @package SimpleTest
129 *    @subpackage WebTester
130 */
131class SimpleAuthenticator {
132    var $_realms;
133   
134    /**
135     *    Clears the realms.
136     *    @access public
137     */
138    function SimpleAuthenticator() {
139        $this->restartSession();
140    }
141   
142    /**
143     *    Starts with no realms set up.
144     *    @access public
145     */
146    function restartSession() {
147        $this->_realms = array();
148    }
149   
150    /**
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.
164     *    @access public
165     */
166    function addRealm($url, $type, $realm) {
167        $this->_realms[$url->getHost()][$realm] = new SimpleRealm($type, $url);
168    }
169   
170    /**
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.
177     *    @access public
178     */
179    function setIdentityForRealm($host, $realm, $username, $password) {
180        if (isset($this->_realms[$host][$realm])) {
181            $this->_realms[$host][$realm]->setIdentity($username, $password);
182        }
183    }
184   
185    /**
186     *    Finds the name of the realm by comparing URLs.
187     *    @param SimpleUrl $url        URL to test.
188     *    @return SimpleRealm          Name of realm.
189     *    @access private
190     */
191    function _findRealmFromUrl($url) {
192        if (! isset($this->_realms[$url->getHost()])) {
193            return false;
194        }
195        foreach ($this->_realms[$url->getHost()] as $name => $realm) {
196            if ($realm->isWithin($url)) {
197                return $realm;
198            }
199        }
200        return false;
201    }
202   
203    /**
204     *    Presents the appropriate headers for this location.
205     *    @param SimpleHttpRequest $request  Request to modify.
206     *    @param SimpleUrl $url              Base of realm.
207     *    @access public
208     */
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();
216        } else {
217            return;
218        }
219        $this->addBasicHeaders($request, $username, $password);
220    }
221   
222    /**
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.
228     *    @access public
229     *    @static
230     */
231    function addBasicHeaders(&$request, $username, $password) {
232        if ($username && $password) {
233            $request->addHeaderLine(
234                    'Authorization: Basic ' . base64_encode("$username:$password"));
235        }
236    }
237}
238?>
Note: See TracBrowser for help on using the repository browser.