RPVerify.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. <?php
  2. /*
  3. * Unit tests for verification of return_to URLs for a realm.
  4. */
  5. require_once 'Auth/OpenID/Discover.php';
  6. require_once 'Auth/OpenID/TrustRoot.php';
  7. require_once 'Auth/Yadis/Yadis.php';
  8. require_once 'PHPUnit.php';
  9. // Because "null" cannot be passed by reference.
  10. $NULL_FETCHER = null;
  11. /*
  12. * Tests for building the discovery URL from a realm and a return_to
  13. * URL
  14. */
  15. class Tests_Auth_OpenID_BuildDiscoveryURL extends PHPUnit_TestCase {
  16. /*
  17. * Build a discovery URL out of the realm and a return_to and make
  18. * sure that it matches the expected discovery URL
  19. */
  20. function failUnlessDiscoURL($realm, $expected_discovery_url)
  21. {
  22. $actual_discovery_url = Auth_OpenID_TrustRoot::buildDiscoveryURL($realm);
  23. $this->assertEquals($expected_discovery_url, $actual_discovery_url);
  24. }
  25. /*
  26. * There is no wildcard and the realm is the same as the return_to
  27. * URL
  28. */
  29. function test_trivial()
  30. {
  31. $this->failUnlessDiscoURL('http://example.com/foo',
  32. 'http://example.com/foo');
  33. }
  34. /*
  35. * There is a wildcard
  36. */
  37. function test_wildcard()
  38. {
  39. $this->failUnlessDiscoURL('http://*.example.com/foo',
  40. 'http://www.example.com/foo');
  41. }
  42. }
  43. class _MockDiscover {
  44. function _MockDiscover(&$data) {
  45. $this->data =& $data;
  46. }
  47. function mockDiscover($uri, $fetcher, $discover_function=null)
  48. {
  49. $result = new Auth_Yadis_DiscoveryResult($uri);
  50. $result->response_text = $this->data;
  51. $result->normalized_uri = $uri;
  52. return $result;
  53. }
  54. }
  55. class Tests_Auth_OpenID_ExtractReturnToURLs extends PHPUnit_TestCase {
  56. var $disco_url = 'http://example.com/';
  57. function failUnlessXRDSHasReturnURLs($data, $expected_return_urls)
  58. {
  59. $discover_object = new _MockDiscover($data);
  60. $actual_return_urls = Auth_OpenID_getAllowedReturnURLs($this->disco_url, $NULL_FETCHER, array(&$discover_object, 'mockDiscover'));
  61. $this->assertEquals($expected_return_urls, $actual_return_urls);
  62. }
  63. function failUnlessDiscoveryFailure($text)
  64. {
  65. $discover_object = new _MockDiscover($text);
  66. $this->assertFalse(Auth_OpenID_getAllowedReturnURLs($this->disco_url, $NULL_FETCHER, array(&$discover_object, 'mockDiscover')));
  67. }
  68. function test_empty()
  69. {
  70. $this->failUnlessDiscoveryFailure('');
  71. }
  72. function test_badXML()
  73. {
  74. $this->failUnlessDiscoveryFailure('>');
  75. }
  76. function test_noEntries()
  77. {
  78. $this->failUnlessXRDSHasReturnURLs('<?xml version="1.0" encoding="UTF-8"?>
  79. <xrds:XRDS xmlns:xrds="xri://$xrds"
  80. xmlns="xri://$xrd*($v*2.0)"
  81. >
  82. <XRD>
  83. </XRD>
  84. </xrds:XRDS>
  85. ', array());
  86. }
  87. function test_noReturnToEntries()
  88. {
  89. $this->failUnlessXRDSHasReturnURLs('<?xml version="1.0" encoding="UTF-8"?>
  90. <xrds:XRDS xmlns:xrds="xri://$xrds"
  91. xmlns="xri://$xrd*($v*2.0)"
  92. >
  93. <XRD>
  94. <Service priority="10">
  95. <Type>http://specs.openid.net/auth/2.0/server</Type>
  96. <URI>http://www.myopenid.com/server</URI>
  97. </Service>
  98. </XRD>
  99. </xrds:XRDS>
  100. ', array());
  101. }
  102. function test_oneEntry()
  103. {
  104. $this->failUnlessXRDSHasReturnURLs('<?xml version="1.0" encoding="UTF-8"?>
  105. <xrds:XRDS xmlns:xrds="xri://$xrds"
  106. xmlns="xri://$xrd*($v*2.0)"
  107. >
  108. <XRD>
  109. <Service>
  110. <Type>http://specs.openid.net/auth/2.0/return_to</Type>
  111. <URI>http://rp.example.com/return</URI>
  112. </Service>
  113. </XRD>
  114. </xrds:XRDS>
  115. ', array('http://rp.example.com/return'));
  116. }
  117. function test_twoEntries()
  118. {
  119. $this->failUnlessXRDSHasReturnURLs('<?xml version="1.0" encoding="UTF-8"?>
  120. <xrds:XRDS xmlns:xrds="xri://$xrds"
  121. xmlns="xri://$xrd*($v*2.0)"
  122. >
  123. <XRD>
  124. <Service priority="0">
  125. <Type>http://specs.openid.net/auth/2.0/return_to</Type>
  126. <URI>http://rp.example.com/return</URI>
  127. </Service>
  128. <Service priority="1">
  129. <Type>http://specs.openid.net/auth/2.0/return_to</Type>
  130. <URI>http://other.rp.example.com/return</URI>
  131. </Service>
  132. </XRD>
  133. </xrds:XRDS>
  134. ', array('http://rp.example.com/return',
  135. 'http://other.rp.example.com/return'));
  136. }
  137. function test_twoEntries_withOther()
  138. {
  139. $this->failUnlessXRDSHasReturnURLs('<?xml version="1.0" encoding="UTF-8"?>
  140. <xrds:XRDS xmlns:xrds="xri://$xrds"
  141. xmlns="xri://$xrd*($v*2.0)"
  142. >
  143. <XRD>
  144. <Service priority="0">
  145. <Type>http://specs.openid.net/auth/2.0/return_to</Type>
  146. <URI>http://rp.example.com/return</URI>
  147. </Service>
  148. <Service priority="1">
  149. <Type>http://specs.openid.net/auth/2.0/return_to</Type>
  150. <URI>http://other.rp.example.com/return</URI>
  151. </Service>
  152. <Service priority="0">
  153. <Type>http://example.com/LOLCATS</Type>
  154. <URI>http://example.com/invisible+uri</URI>
  155. </Service>
  156. </XRD>
  157. </xrds:XRDS>
  158. ', array('http://rp.example.com/return',
  159. 'http://other.rp.example.com/return'));
  160. }
  161. }
  162. class Tests_Auth_OpenID_ReturnToMatches extends PHPUnit_TestCase {
  163. function test_noEntries()
  164. {
  165. $this->assertFalse(Auth_OpenID_returnToMatches(array(), 'anything'));
  166. }
  167. function test_exactMatch()
  168. {
  169. $r = 'http://example.com/return.to';
  170. $this->assertTrue(Auth_OpenID_returnToMatches(array($r), $r));
  171. }
  172. function test_garbageMatch()
  173. {
  174. $r = 'http://example.com/return.to';
  175. $this->assertTrue(Auth_OpenID_returnToMatches(
  176. array('This is not a URL at all. In fact, it has characters, ' .
  177. 'like "<" that are not allowed in URLs', $r), $r));
  178. }
  179. function test_descendant()
  180. {
  181. $r = 'http://example.com/return.to';
  182. $this->assertTrue(Auth_OpenID_returnToMatches(array($r),
  183. 'http://example.com/return.to/user:joe'));
  184. }
  185. function test_wildcard()
  186. {
  187. $this->assertFalse(Auth_OpenID_returnToMatches(
  188. array('http://*.example.com/return.to'),
  189. 'http://example.com/return.to'));
  190. }
  191. function test_noMatch()
  192. {
  193. $r = 'http://example.com/return.to';
  194. $this->assertFalse(Auth_OpenID_returnToMatches(array($r),
  195. 'http://example.com/xss_exploit'));
  196. }
  197. }
  198. class Verifier {
  199. function Verifier(&$test_case, $return_to)
  200. {
  201. $this->tc =& $test_case;
  202. $this->return_to = $return_to;
  203. }
  204. function verify($disco_url)
  205. {
  206. $this->tc->assertEquals('http://www.example.com/', $disco_url);
  207. if ($this->return_to === false) {
  208. return false;
  209. } else {
  210. return array($this->return_to);
  211. }
  212. }
  213. }
  214. class Tests_Auth_OpenID_VerifyReturnTo extends PHPUnit_TestCase {
  215. function test_bogusRealm()
  216. {
  217. $this->assertFalse(Auth_OpenID_verifyReturnTo('', 'http://example.com/', $NULL_FETCHER));
  218. }
  219. function test_verifyWithDiscoveryCalled()
  220. {
  221. $realm = 'http://*.example.com/';
  222. $return_to = 'http://www.example.com/foo';
  223. $v = new Verifier($this, $return_to);
  224. $this->assertTrue(Auth_OpenID_verifyReturnTo($realm, $return_to, $NULL_FETCHER, array(&$v, 'verify')));
  225. }
  226. function test_verifyFailWithDiscoveryCalled()
  227. {
  228. $realm = 'http://*.example.com/';
  229. $return_to = 'http://www.example.com/foo';
  230. $v = new Verifier($this, 'http://something-else.invalid/');
  231. $this->assertFalse(Auth_OpenID_verifyReturnTo($realm, $return_to, $NULL_FETCHER, array(&$v, 'verify')));
  232. }
  233. function test_verifyFailIfDiscoveryRedirects()
  234. {
  235. $realm = 'http://*.example.com/';
  236. $return_to = 'http://www.example.com/foo';
  237. $v = new Verifier($this, false);
  238. $this->assertFalse(Auth_OpenID_verifyReturnTo($realm, $return_to, $NULL_FETCHER, array(&$v, 'verify')));
  239. }
  240. }
  241. class Tests_Auth_OpenID_RPVerify extends PHPUnit_TestSuite {
  242. function getName()
  243. {
  244. return "Tests_Auth_OpenID_RPVerify";
  245. }
  246. function Tests_Auth_OpenID_RPVerify()
  247. {
  248. $this->addTestSuite('Tests_Auth_OpenID_VerifyReturnTo');
  249. $this->addTestSuite('Tests_Auth_OpenID_ReturnToMatches');
  250. $this->addTestSuite('Tests_Auth_OpenID_ExtractReturnToURLs');
  251. $this->addTestSuite('Tests_Auth_OpenID_BuildDiscoveryURL');
  252. }
  253. }
  254. ?>