+ $this->mockUserLogin()->assertRedirect('/login');
+ $this->get('/login')->assertSee('Please enter an email to use for this account.');
+
+ $resp = $this->mockUserLogin($this->mockUser->email);
+ $resp->assertRedirect('/');
+ $this->get('/')->assertSee($this->mockUser->name);
+ $this->assertDatabaseHas('users', [
+ 'email' => $this->mockUser->email,
+ 'email_confirmed' => false,
+ 'external_auth_id' => $this->mockUser->name,
+ 'name' => $this->mockUser->name,
+ ]);
+ }
+
+ protected function checkLdapReceivesCorrectDetails($serverString, $expectedHostString): void
+ {
+ app('config')->set(['services.ldap.server' => $serverString]);
+
+ $this->mockLdap->shouldReceive('connect')
+ ->once()
+ ->with($expectedHostString)
+ ->andReturn(false);
+
+ $this->mockUserLogin();
+ }
+
+ public function test_ldap_receives_correct_connect_host_from_config()
+ {
+ $expectedResultByInput = [
+ 'ldaps://bookstack:8080' => 'ldaps://bookstack:8080',
+ 'ldap.bookstack.com:8080' => 'ldap://ldap.bookstack.com:8080',
+ 'ldap.bookstack.com' => 'ldap://ldap.bookstack.com',
+ 'ldaps://ldap.bookstack.com' => 'ldaps://ldap.bookstack.com',
+ 'ldaps://ldap.bookstack.com ldap://a.b.com' => 'ldaps://ldap.bookstack.com ldap://a.b.com',
+ ];
+
+ foreach ($expectedResultByInput as $input => $expectedResult) {
+ $this->checkLdapReceivesCorrectDetails($input, $expectedResult);
+ $this->refreshApplication();
+ $this->setUp();
+ }
+ }
+
+ public function test_forgot_password_routes_inaccessible()
+ {
+ $resp = $this->get('/password/email');
+ $this->assertPermissionError($resp);
+
+ $resp = $this->post('/password/email');
+ $this->assertPermissionError($resp);
+
+ $resp = $this->get('/password/reset/abc123');
+ $this->assertPermissionError($resp);
+
+ $resp = $this->post('/password/reset');
+ $this->assertPermissionError($resp);
+ }
+
+ public function test_user_invite_routes_inaccessible()
+ {
+ $resp = $this->get('/register/invite/abc123');
+ $this->assertPermissionError($resp);
+
+ $resp = $this->post('/register/invite/abc123');
+ $this->assertPermissionError($resp);
+ }
+
+ public function test_user_register_routes_inaccessible()
+ {
+ $resp = $this->get('/register');
+ $this->assertPermissionError($resp);
+
+ $resp = $this->post('/register');
+ $this->assertPermissionError($resp);
+ }
+
+ public function test_dump_user_details_option_works()
+ {
+ config()->set(['services.ldap.dump_user_details' => true, 'services.ldap.thumbnail_attribute' => 'jpegphoto']);
+
+ $this->commonLdapMocks(1, 1, 1, 1, 1);
+ $this->mockLdap->shouldReceive('searchAndGetEntries')->times(1)
+ ->with($this->resourceId, config('services.ldap.base_dn'), \Mockery::type('string'), \Mockery::type('array'))
+ ->andReturn(['count' => 1, 0 => [
+ 'uid' => [$this->mockUser->name],
+ 'cn' => [$this->mockUser->name],
+ // Test dumping binary data for avatar responses
+ 'jpegphoto' => base64_decode('/9j/4AAQSkZJRg=='),
+ 'dn' => 'dc=test' . config('services.ldap.base_dn'),
+ ]]);
+
+ $resp = $this->post('/login', [
+ 'username' => $this->mockUser->name,
+ 'password' => $this->mockUser->password,
+ ]);
+ $resp->assertJsonStructure([
+ 'details_from_ldap' => [],
+ 'details_bookstack_parsed' => [],
+ ]);
+ }
+
+ public function test_start_tls_called_if_option_set()
+ {
+ config()->set(['services.ldap.start_tls' => true]);
+ $this->mockLdap->shouldReceive('startTls')->once()->andReturn(true);
+ $this->runFailedAuthLogin();
+ }