From 322bb9cd2be9e51422cb2b82684692e825c2bfb7 Mon Sep 17 00:00:00 2001 From: brettp Date: Fri, 2 Oct 2009 18:40:04 +0000 Subject: Added simpletest and start of unit tests. git-svn-id: http://code.elgg.org/elgg/trunk@3503 36083f99-b078-4883-b0ff-0f9b5a30f544 --- .../docs/en/authentication_documentation.html | 355 +++++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100755 vendors/simpletest/docs/en/authentication_documentation.html (limited to 'vendors/simpletest/docs/en/authentication_documentation.html') diff --git a/vendors/simpletest/docs/en/authentication_documentation.html b/vendors/simpletest/docs/en/authentication_documentation.html new file mode 100755 index 000000000..8da2a7f9e --- /dev/null +++ b/vendors/simpletest/docs/en/authentication_documentation.html @@ -0,0 +1,355 @@ + + + +SimpleTest documentation for testing log-in and authentication + + + + +

Authentication documentation

+ This page... + +
+ +

+ One of the trickiest, and yet most important, areas + of testing web sites is the security. + Testing these schemes is one of the core goals of + the SimpleTest web tester. +

+ +

Basic HTTP authentication

+

+ If you fetch a page protected by basic authentication then + rather than receiving content, you will instead get a 401 + header. + We can illustrate this with this test... +

+class AuthenticationTest extends WebTestCase {
+    function test401Header() {
+        $this->get('http://www.lastcraft.com/protected/');
+        $this->showHeaders();
+    }
+}
+
+ This allows us to see the challenge header... +
+

File test

+
+HTTP/1.1 401 Authorization Required
+Date: Sat, 18 Sep 2004 19:25:18 GMT
+Server: Apache/1.3.29 (Unix) PHP/4.3.4
+WWW-Authenticate: Basic realm="SimpleTest basic authentication"
+Connection: close
+Content-Type: text/html; charset=iso-8859-1
+
+
1/1 test cases complete. + 0 passes, 0 fails and 0 exceptions.
+
+ We are trying to get away from visual inspection though, and so SimpleTest + allows to make automated assertions against the challenge. + Here is a thorough test of our header... +
+class AuthenticationTest extends WebTestCase {
+    function test401Header() {
+        $this->get('http://www.lastcraft.com/protected/');
+        $this->assertAuthentication('Basic');
+        $this->assertResponse(401);
+        $this->assertRealm('SimpleTest basic authentication');
+    }
+}
+
+ Any one of these tests would normally do on it's own depending + on the amount of detail you want to see. +

+

+ One theme that runs through SimpleTest is the ability to use + SimpleExpectation objects wherever a simple + match is not enough. + If you want only an approximate match to the realm for + example, you can do this... +

+class AuthenticationTest extends WebTestCase {
+    function test401Header() {
+        $this->get('http://www.lastcraft.com/protected/');
+        $this->assertRealm(new PatternExpectation('/simpletest/i'));
+    }
+}
+
+ Most of the time we are not interested in testing the + authentication itself, but want to get past it to test + the pages underneath. + As soon as the challenge has been issued we can reply with + an authentication response... +
+class AuthenticationTest extends WebTestCase {
+    function testCanAuthenticate() {
+        $this->get('http://www.lastcraft.com/protected/');
+        $this->authenticate('Me', 'Secret');
+        $this->assertTitle(...);
+    }
+}
+
+ The username and password will now be sent with every + subsequent request to that directory and subdirectories. + You will have to authenticate again if you step outside + the authenticated directory, but SimpleTest is smart enough + to merge subdirectories into a common realm. +

+

+ You can shortcut this step further by encoding the log in + details straight into the URL... +

+class AuthenticationTest extends WebTestCase {
+    function testCanReadAuthenticatedPages() {
+        $this->get('http://Me:Secret@www.lastcraft.com/protected/');
+        $this->assertTitle(...);
+    }
+}
+
+ If your username or password has special characters, then you + will have to URL encode them or the request will not be parsed + correctly. + Also this header will not be sent on subsequent requests if + you request a page with a fully qualified URL. + If you navigate with relative URLs though, the authentication + information will be preserved. +

+

+ Only basic authentication is currently supported and this is + only really secure in tandem with HTTPS connections. + This is usually enough to protect test server from prying eyes, + however. + Digest authentication and NTLM authentication may be added + in the future. +

+ +

Cookies

+

+ Basic authentication doesn't give enough control over the + user interface for web developers. + More likely this functionality will be coded directly into + the web architecture using cookies and complicated timeouts. +

+

+ Starting with a simple log-in form... +

+<form>
+    Username:
+    <input type="text" name="u" value="" /><br />
+    Password:
+    <input type="password" name="p" value="" /><br />
+    <input type="submit" value="Log in" />
+</form>
+
+ Which looks like... +

+

+

+ Username: +
+ Password: +
+ +
+

+

+ Let's suppose that in fetching this page a cookie has been + set with a session ID. + We are not going to fill the form in yet, just test that + we are tracking the user. + Here is the test... +

+class LogInTest extends WebTestCase {
+    function testSessionCookieSetBeforeForm() {
+        $this->get('http://www.my-site.com/login.php');
+        $this->assertCookie('SID');
+    }
+}
+
+ All we are doing is confirming that the cookie is set. + As the value is likely to be rather cryptic it's not + really worth testing this with... +
+class LogInTest extends WebTestCase {
+    function testSessionCookieIsCorrectPattern() {
+        $this->get('http://www.my-site.com/login.php');
+        $this->assertCookie('SID', new PatternExpectation('/[a-f0-9]{32}/i'));
+    }
+}
+
+ The rest of the test would be the same as any other form, + but we might want to confirm that we still have the same + cookie after log-in as before we entered. + We wouldn't want to lose track of this after all. + Here is a possible test for this... +
+class LogInTest extends WebTestCase {
+    ...
+    function testSessionCookieSameAfterLogIn() {
+        $this->get('http://www.my-site.com/login.php');
+        $session = $this->getCookie('SID');
+        $this->setField('u', 'Me');
+        $this->setField('p', 'Secret');
+        $this->click('Log in');
+        $this->assertText('Welcome Me');
+        $this->assertCookie('SID', $session);
+    }
+}
+
+ This confirms that the session identifier is maintained + afer log-in. +

+

+ We could even attempt to spoof our own system by setting + arbitrary cookies to gain access... +

+class LogInTest extends WebTestCase {
+    ...
+    function testSessionCookieSameAfterLogIn() {
+        $this->get('http://www.my-site.com/login.php');
+        $this->setCookie('SID', 'Some other session');
+        $this->get('http://www.my-site.com/restricted.php');
+        $this->assertText('Access denied');
+    }
+}
+
+ Is your site protected from this attack? +

+ +

Browser sessions

+

+ If you are testing an authentication system a critical piece + of behaviour is what happens when a user logs back in. + We would like to simulate closing and reopening a browser... +

+class LogInTest extends WebTestCase {
+    ...
+    function testLoseAuthenticationAfterBrowserClose() {
+        $this->get('http://www.my-site.com/login.php');
+        $this->setField('u', 'Me');
+        $this->setField('p', 'Secret');
+        $this->click('Log in');
+        $this->assertText('Welcome Me');
+        
+        $this->restart();
+        $this->get('http://www.my-site.com/restricted.php');
+        $this->assertText('Access denied');
+    }
+}
+
+ The WebTestCase::restart() method will + preserve cookies that have unexpired timeouts, but throw away + those that are temporary or expired. + You can optionally specify the time and date that the restart + happened. +

+

+ Expiring cookies can be a problem. + After all, if you have a cookie that expires after an hour, + you don't want to stall the test for an hour while the + cookie passes it's timeout. +

+

+ To push the cookies over the hour limit you can age them + before you restart the session... +

+class LogInTest extends WebTestCase {
+    ...
+    function testLoseAuthenticationAfterOneHour() {
+        $this->get('http://www.my-site.com/login.php');
+        $this->setField('u', 'Me');
+        $this->setField('p', 'Secret');
+        $this->click('Log in');
+        $this->assertText('Welcome Me');
+        
+        $this->ageCookies(3600);
+        $this->restart();
+        $this->get('http://www.my-site.com/restricted.php');
+        $this->assertText('Access denied');
+    }
+}
+
+ After the restart it will appear that cookies are an + hour older and any that pass their expiry will have + disappeared. +

+ +
+ References and related information... + + + + + -- cgit v1.2.3