/tests/ZendTest/Ldap/BindTest.php

https://github.com/zucchi/zf2 · PHP · 274 lines · 211 code · 32 blank · 31 comment · 13 complexity · bc2e5445d1b8bfc0e5165ad776dd1d87 MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. * @package Zend_Ldap
  9. */
  10. namespace ZendTest\Ldap;
  11. use Zend\Ldap;
  12. use Zend\Ldap\Exception;
  13. /* Note: The ldap_connect function does not actually try to connect. This
  14. * is why many tests attempt to bind with invalid credentials. If the
  15. * bind returns 'Invalid credentials' we know the transport related work
  16. * was successful.
  17. */
  18. /**
  19. * @category Zend
  20. * @package Zend_Ldap
  21. * @subpackage UnitTests
  22. * @group Zend_Ldap
  23. */
  24. class BindTest extends \PHPUnit_Framework_TestCase
  25. {
  26. protected $options = null;
  27. protected $principalName = TESTS_ZEND_LDAP_PRINCIPAL_NAME;
  28. protected $altUsername = TESTS_ZEND_LDAP_ALT_USERNAME;
  29. protected $bindRequiresDn = false;
  30. public function setUp()
  31. {
  32. if (!constant('TESTS_ZEND_LDAP_ONLINE_ENABLED')) {
  33. $this->markTestSkipped("Zend_Ldap online tests are not enabled");
  34. }
  35. $this->options = array(
  36. 'host' => TESTS_ZEND_LDAP_HOST,
  37. 'username' => TESTS_ZEND_LDAP_USERNAME,
  38. 'password' => TESTS_ZEND_LDAP_PASSWORD,
  39. 'baseDn' => TESTS_ZEND_LDAP_BASE_DN,
  40. );
  41. if (defined('TESTS_ZEND_LDAP_PORT')) {
  42. $this->options['port'] = TESTS_ZEND_LDAP_PORT;
  43. }
  44. if (defined('TESTS_ZEND_LDAP_USE_START_TLS')) {
  45. $this->options['useStartTls'] = TESTS_ZEND_LDAP_USE_START_TLS;
  46. }
  47. if (defined('TESTS_ZEND_LDAP_USE_SSL')) {
  48. $this->options['useSsl'] = TESTS_ZEND_LDAP_USE_SSL;
  49. }
  50. if (defined('TESTS_ZEND_LDAP_BIND_REQUIRES_DN')) {
  51. $this->options['bindRequiresDn'] = TESTS_ZEND_LDAP_BIND_REQUIRES_DN;
  52. }
  53. if (defined('TESTS_ZEND_LDAP_ACCOUNT_FILTER_FORMAT')) {
  54. $this->options['accountFilterFormat'] = TESTS_ZEND_LDAP_ACCOUNT_FILTER_FORMAT;
  55. }
  56. if (defined('TESTS_ZEND_LDAP_ACCOUNT_DOMAIN_NAME')) {
  57. $this->options['accountDomainName'] = TESTS_ZEND_LDAP_ACCOUNT_DOMAIN_NAME;
  58. }
  59. if (defined('TESTS_ZEND_LDAP_ACCOUNT_DOMAIN_NAME_SHORT')) {
  60. $this->options['accountDomainNameShort'] = TESTS_ZEND_LDAP_ACCOUNT_DOMAIN_NAME_SHORT;
  61. }
  62. if (defined('TESTS_ZEND_LDAP_ALT_USERNAME')) {
  63. $this->altUsername = TESTS_ZEND_LDAP_ALT_USERNAME;
  64. }
  65. if (isset($this->options['bindRequiresDn'])) {
  66. $this->bindRequiresDn = $this->options['bindRequiresDn'];
  67. }
  68. }
  69. public function testEmptyOptionsBind()
  70. {
  71. $ldap = new Ldap\Ldap(array());
  72. try {
  73. $ldap->bind();
  74. $this->fail('Expected exception for empty options');
  75. } catch (Exception\LdapException $zle) {
  76. $this->assertContains('A host parameter is required', $zle->getMessage());
  77. }
  78. }
  79. public function testAnonymousBind()
  80. {
  81. $options = $this->options;
  82. unset($options['password']);
  83. $ldap = new Ldap\Ldap($options);
  84. try {
  85. $ldap->bind();
  86. } catch (Exception\LdapException $zle) {
  87. // or I guess the server doesn't allow unauthenticated binds
  88. $this->assertContains('unauthenticated bind', $zle->getMessage());
  89. }
  90. }
  91. public function testNoBaseDnBind()
  92. {
  93. $options = $this->options;
  94. unset($options['baseDn']);
  95. $options['bindRequiresDn'] = true;
  96. $ldap = new Ldap\Ldap($options);
  97. try {
  98. $ldap->bind('invalid', 'ignored');
  99. $this->fail('Expected exception for baseDn missing');
  100. } catch (Exception\LdapException $zle) {
  101. $this->assertContains('Base DN not set', $zle->getMessage());
  102. }
  103. }
  104. public function testNoDomainNameBind()
  105. {
  106. $options = $this->options;
  107. unset($options['accountDomainName']);
  108. $options['bindRequiresDn'] = false;
  109. $options['accountCanonicalForm'] = Ldap\Ldap::ACCTNAME_FORM_PRINCIPAL;
  110. $ldap = new Ldap\Ldap($options);
  111. try {
  112. $ldap->bind('invalid', 'ignored');
  113. $this->fail('Expected exception for missing accountDomainName');
  114. } catch (Exception\LdapException $zle) {
  115. $this->assertContains('Option required: accountDomainName', $zle->getMessage());
  116. }
  117. }
  118. public function testPlainBind()
  119. {
  120. $ldap = new Ldap\Ldap($this->options);
  121. $ldap->bind();
  122. $this->assertNotNull($ldap->getResource());
  123. }
  124. public function testConnectBind()
  125. {
  126. $ldap = new Ldap\Ldap($this->options);
  127. $ldap->connect()->bind();
  128. $this->assertNotNull($ldap->getResource());
  129. }
  130. public function testExplicitParamsBind()
  131. {
  132. $options = $this->options;
  133. $username = $options['username'];
  134. $password = $options['password'];
  135. unset($options['username']);
  136. unset($options['password']);
  137. $ldap = new Ldap\Ldap($options);
  138. $ldap->bind($username, $password);
  139. $this->assertNotNull($ldap->getResource());
  140. }
  141. public function testRequiresDnBind()
  142. {
  143. $options = $this->options;
  144. $options['bindRequiresDn'] = true;
  145. $ldap = new Ldap\Ldap($options);
  146. try {
  147. $ldap->bind($this->altUsername, 'invalid');
  148. $this->fail('Expected exception not thrown');
  149. } catch (Exception\LdapException $zle) {
  150. $this->assertContains('Invalid credentials', $zle->getMessage());
  151. }
  152. }
  153. public function testRequiresDnWithoutDnBind()
  154. {
  155. $options = $this->options;
  156. $options['bindRequiresDn'] = true;
  157. unset($options['username']);
  158. $ldap = new Ldap\Ldap($options);
  159. try {
  160. $ldap->bind($this->principalName);
  161. $this->fail('Expected exception not thrown');
  162. } catch (Exception\LdapException $zle) {
  163. /* Note that if your server actually allows anonymous binds this test will fail.
  164. */
  165. $this->assertContains('Failed to retrieve DN', $zle->getMessage());
  166. }
  167. }
  168. public function testBindWithEmptyPassword()
  169. {
  170. $options = $this->options;
  171. $options['allowEmptyPassword'] = false;
  172. $ldap = new Ldap\Ldap($options);
  173. try {
  174. $ldap->bind($this->altUsername, '');
  175. $this->fail('Expected exception for empty password');
  176. } catch (Exception\LdapException $zle) {
  177. $this->assertContains('Empty password not allowed - see allowEmptyPassword option.',
  178. $zle->getMessage()
  179. );
  180. }
  181. $options['allowEmptyPassword'] = true;
  182. $ldap = new Ldap\Ldap($options);
  183. try {
  184. $ldap->bind($this->altUsername, '');
  185. } catch (Exception\LdapException $zle) {
  186. if ($zle->getMessage() ===
  187. 'Empty password not allowed - see allowEmptyPassword option.'
  188. ) {
  189. $this->fail('Exception for empty password');
  190. } else {
  191. $message = $zle->getMessage();
  192. $this->assertTrue(strstr($message, 'Invalid credentials')
  193. || strstr($message, 'Server is unwilling to perform')
  194. );
  195. return;
  196. }
  197. }
  198. $this->assertNotNull($ldap->getResource());
  199. }
  200. public function testBindWithoutDnUsernameAndDnRequired()
  201. {
  202. $options = $this->options;
  203. $options['username'] = TESTS_ZEND_LDAP_ALT_USERNAME;
  204. $options['bindRequiresDn'] = true;
  205. $ldap = new Ldap\Ldap($options);
  206. try {
  207. $ldap->bind();
  208. $this->fail('Expected exception for empty password');
  209. } catch (Exception\LdapException $zle) {
  210. $this->assertContains('Binding requires username in DN form',
  211. $zle->getMessage()
  212. );
  213. }
  214. }
  215. /**
  216. * @group ZF-8259
  217. */
  218. public function testBoundUserIsFalseIfNotBoundToLDAP()
  219. {
  220. $ldap = new Ldap\Ldap($this->options);
  221. $this->assertFalse($ldap->getBoundUser());
  222. }
  223. /**
  224. * @group ZF-8259
  225. */
  226. public function testBoundUserIsReturnedAfterBinding()
  227. {
  228. $ldap = new Ldap\Ldap($this->options);
  229. $ldap->bind();
  230. $this->assertEquals(TESTS_ZEND_LDAP_USERNAME, $ldap->getBoundUser());
  231. }
  232. /**
  233. * @group ZF-8259
  234. */
  235. public function testResourceIsAlwaysReturned()
  236. {
  237. $ldap = new Ldap\Ldap($this->options);
  238. $this->assertNotNull($ldap->getResource());
  239. $this->assertTrue(is_resource($ldap->getResource()));
  240. $this->assertEquals(TESTS_ZEND_LDAP_USERNAME, $ldap->getBoundUser());
  241. }
  242. }