1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
|
<?php
/**
* Base include file for SimpleTest
* @package SimpleTest
* @subpackage WebTester
* @version $Id: authentication.php 1532 2006-12-01 12:28:55Z xue $
*/
/**
* include http class
*/
require_once(dirname(__FILE__) . '/http.php');
/**
* Represents a single security realm's identity.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleRealm {
protected $_type;
protected $_root;
protected $_username;
protected $_password;
/**
* Starts with the initial entry directory.
* @param string $type Authentication type for this
* realm. Only Basic authentication
* is currently supported.
* @param SimpleUrl $url Somewhere in realm.
* @access public
*/
function SimpleRealm($type, $url) {
$this->_type = $type;
$this->_root = $url->getBasePath();
$this->_username = false;
$this->_password = false;
}
/**
* Adds another location to the realm.
* @param SimpleUrl $url Somewhere in realm.
* @access public
*/
function stretch($url) {
$this->_root = $this->_getCommonPath($this->_root, $url->getPath());
}
/**
* Finds the common starting path.
* @param string $first Path to compare.
* @param string $second Path to compare.
* @return string Common directories.
* @access private
*/
function _getCommonPath($first, $second) {
$first = explode('/', $first);
$second = explode('/', $second);
for ($i = 0; $i < min(count($first), count($second)); $i++) {
if ($first[$i] != $second[$i]) {
return implode('/', array_slice($first, 0, $i)) . '/';
}
}
return implode('/', $first) . '/';
}
/**
* Sets the identity to try within this realm.
* @param string $username Username in authentication dialog.
* @param string $username Password in authentication dialog.
* @access public
*/
function setIdentity($username, $password) {
$this->_username = $username;
$this->_password = $password;
}
/**
* Accessor for current identity.
* @return string Last succesful username.
* @access public
*/
function getUsername() {
return $this->_username;
}
/**
* Accessor for current identity.
* @return string Last succesful password.
* @access public
*/
function getPassword() {
return $this->_password;
}
/**
* Test to see if the URL is within the directory
* tree of the realm.
* @param SimpleUrl $url URL to test.
* @return boolean True if subpath.
* @access public
*/
function isWithin($url) {
if ($this->_isIn($this->_root, $url->getBasePath())) {
return true;
}
if ($this->_isIn($this->_root, $url->getBasePath() . $url->getPage() . '/')) {
return true;
}
return false;
}
/**
* Tests to see if one string is a substring of
* another.
* @param string $part Small bit.
* @param string $whole Big bit.
* @return boolean True if the small bit is
* in the big bit.
* @access private
*/
function _isIn($part, $whole) {
return strpos($whole, $part) === 0;
}
}
/**
* Manages security realms.
* @package SimpleTest
* @subpackage WebTester
*/
class SimpleAuthenticator {
protected $_realms;
/**
* Clears the realms.
* @access public
*/
function SimpleAuthenticator() {
$this->restartSession();
}
/**
* Starts with no realms set up.
* @access public
*/
function restartSession() {
$this->_realms = array();
}
/**
* Adds a new realm centered the current URL.
* Browsers vary wildly on their behaviour in this
* regard. Mozilla ignores the realm and presents
* only when challenged, wasting bandwidth. IE
* just carries on presenting until a new challenge
* occours. SimpleTest tries to follow the spirit of
* the original standards committee and treats the
* base URL as the root of a file tree shaped realm.
* @param SimpleUrl $url Base of realm.
* @param string $type Authentication type for this
* realm. Only Basic authentication
* is currently supported.
* @param string $realm Name of realm.
* @access public
*/
function addRealm($url, $type, $realm) {
$this->_realms[$url->getHost()][$realm] = new SimpleRealm($type, $url);
}
/**
* Sets the current identity to be presented
* against that realm.
* @param string $host Server hosting realm.
* @param string $realm Name of realm.
* @param string $username Username for realm.
* @param string $password Password for realm.
* @access public
*/
function setIdentityForRealm($host, $realm, $username, $password) {
if (isset($this->_realms[$host][$realm])) {
$this->_realms[$host][$realm]->setIdentity($username, $password);
}
}
/**
* Finds the name of the realm by comparing URLs.
* @param SimpleUrl $url URL to test.
* @return SimpleRealm Name of realm.
* @access private
*/
function _findRealmFromUrl($url) {
if (! isset($this->_realms[$url->getHost()])) {
return false;
}
foreach ($this->_realms[$url->getHost()] as $name => $realm) {
if ($realm->isWithin($url)) {
return $realm;
}
}
return false;
}
/**
* Presents the appropriate headers for this location.
* @param SimpleHttpRequest $request Request to modify.
* @param SimpleUrl $url Base of realm.
* @access public
*/
function addHeaders($request, $url) {
if ($url->getUsername() && $url->getPassword()) {
$username = $url->getUsername();
$password = $url->getPassword();
} elseif ($realm = $this->_findRealmFromUrl($url)) {
$username = $realm->getUsername();
$password = $realm->getPassword();
} else {
return;
}
$this->addBasicHeaders($request, $username, $password);
}
/**
* Presents the appropriate headers for this
* location for basic authentication.
* @param SimpleHttpRequest $request Request to modify.
* @param string $username Username for realm.
* @param string $password Password for realm.
* @access public
* @static
*/
static function addBasicHeaders($request, $username, $password) {
if ($username && $password) {
$request->addHeaderLine(
'Authorization: Basic ' . base64_encode("$username:$password"));
}
}
}
?>
|