0337d704 |
1 | <?php |
2 | /** |
3 | * Base include file for SimpleTest |
4 | * @package SimpleTest |
5 | * @subpackage WebTester |
6 | * @version $Id: authentication.php,v 1.8 2004/07/28 16:42:08 lastcraft Exp $ |
7 | */ |
8 | /** |
9 | * include http class |
10 | */ |
11 | require_once(dirname(__FILE__) . '/http.php'); |
12 | |
13 | /** |
14 | * Represents a single security realm's identity. |
15 | * @package SimpleTest |
16 | * @subpackage WebTester |
17 | */ |
18 | class 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 | return (strpos($url->getBasePath(), $this->_root) === 0); |
104 | } |
105 | } |
106 | |
107 | /** |
108 | * Manages security realms. |
109 | * @package SimpleTest |
110 | * @subpackage WebTester |
111 | */ |
112 | class SimpleAuthenticator { |
113 | var $_realms; |
114 | |
115 | /** |
116 | * Starts with no realms set up. |
117 | * @access public |
118 | */ |
119 | function SimpleAuthenticator() { |
120 | $this->_realms = array(); |
121 | } |
122 | |
123 | /** |
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. |
137 | * @access public |
138 | */ |
139 | function addRealm($url, $type, $realm) { |
140 | $this->_realms[$url->getHost()][$realm] = new SimpleRealm($type, $url); |
141 | } |
142 | |
143 | /** |
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. |
150 | * @access public |
151 | */ |
152 | function setIdentityForRealm($host, $realm, $username, $password) { |
153 | if (isset($this->_realms[$host][$realm])) { |
154 | $this->_realms[$host][$realm]->setIdentity($username, $password); |
155 | } |
156 | } |
157 | |
158 | /** |
159 | * Finds the name of the realm by comparing URLs. |
160 | * @param SimpleUrl $url URL to test. |
161 | * @return SimpleRealm Name of realm. |
162 | * @access private |
163 | */ |
164 | function _findRealmFromUrl($url) { |
165 | if (! isset($this->_realms[$url->getHost()])) { |
166 | return false; |
167 | } |
168 | foreach ($this->_realms[$url->getHost()] as $name => $realm) { |
169 | if ($realm->isWithin($url)) { |
170 | return $realm; |
171 | } |
172 | } |
173 | return false; |
174 | } |
175 | |
176 | /** |
177 | * Presents the appropriate headers for this location. |
178 | * @param SimpleHttpRequest $request Request to modify. |
179 | * @param SimpleUrl $url Base of realm. |
180 | * @access public |
181 | */ |
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(); |
189 | } else { |
190 | return; |
191 | } |
192 | $this->addBasicHeaders($request, $username, $password); |
193 | } |
194 | |
195 | /** |
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. |
201 | * @access public |
202 | * @static |
203 | */ |
204 | function addBasicHeaders(&$request, $username, $password) { |
205 | if ($username && $password) { |
206 | $request->addHeaderLine( |
207 | 'Authorization: Basic ' . base64_encode("$username:$password")); |
208 | } |
209 | } |
210 | } |
211 | ?> |