Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
    /**
3
     *	Base include file for SimpleTest
4
     *	@package	SimpleTest
5
     *	@subpackage	WebTester
6
     *	@version	$Id: authentication.php 1532 2006-12-01 12:28:55Z xue $
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
        protected $_type;
20
        protected $_root;
21
        protected $_username;
22
        protected $_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
     */
131
    class SimpleAuthenticator {
132
        protected $_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
        static function addBasicHeaders($request, $username, $password) {
232
            if ($username && $password) {
233
                $request->addHeaderLine(
234
                        'Authorization: Basic ' . base64_encode("$username:$password"));
235
            }
236
        }
237
    }
238
?>