forked from simpletest/simpletest
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathauthentication.php
More file actions
237 lines (216 loc) · 6.41 KB
/
authentication.php
File metadata and controls
237 lines (216 loc) · 6.41 KB
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
<?php
require_once dirname(__FILE__) . '/http.php';
/**
* Represents a single security realm's identity.
*/
class SimpleRealm
{
private $type;
private $root;
private $username;
private $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.
*/
public function __construct($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.
*/
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.
*/
protected 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.
*/
public function setIdentity($username, $password)
{
$this->username = $username;
$this->password = $password;
}
/**
* Accessor for current identity.
*
* @return string Last succesful username.
*/
public function getUsername()
{
return $this->username;
}
/**
* Accessor for current identity.
*
* @return string Last succesful password.
*/
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 bool True if subpath.
*/
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 bool True if the small bit is in the big bit.
*/
protected function isIn($part, $whole)
{
return strpos($whole, $part) === 0;
}
}
/**
* Manages security realms.
*/
class SimpleAuthenticator
{
private $realms;
/**
* Clears the realms.
*/
public function __construct()
{
$this->restartSession();
}
/**
* Starts with no realms set up.
*/
public function restartSession()
{
$this->realms = array();
}
/**
* Adds a new realm centered the current URL. Browsers privatey 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
* Basicauthentication is currently supported.
* @param string $realm Name of realm.
*/
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.
*/
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.
*/
protected 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.
*/
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.
*/
public static function addBasicHeaders(&$request, $username, $password)
{
if ($username && $password) {
$request->addHeaderLine(
'Authorization: Basic ' . base64_encode("$username:$password"));
}
}
}