RPVerify.php 8.1 KB

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