xref: /OpenGrok/plugins/src/test/java/opengrok/auth/plugin/LdapServerTest.java (revision cb97e8782f9c60c94308b0e334f4e3b4930f04a6)
11161d3e8SAdam Hornacek /*
21161d3e8SAdam Hornacek  * CDDL HEADER START
31161d3e8SAdam Hornacek  *
41161d3e8SAdam Hornacek  * The contents of this file are subject to the terms of the
51161d3e8SAdam Hornacek  * Common Development and Distribution License (the "License").
61161d3e8SAdam Hornacek  * You may not use this file except in compliance with the License.
71161d3e8SAdam Hornacek  *
81161d3e8SAdam Hornacek  * See LICENSE.txt included in this distribution for the specific
91161d3e8SAdam Hornacek  * language governing permissions and limitations under the License.
101161d3e8SAdam Hornacek  *
111161d3e8SAdam Hornacek  * When distributing Covered Code, include this CDDL HEADER in each
121161d3e8SAdam Hornacek  * file and include the License file at LICENSE.txt.
131161d3e8SAdam Hornacek  * If applicable, add the following below this CDDL HEADER, with the
141161d3e8SAdam Hornacek  * fields enclosed by brackets "[]" replaced with your own identifying
151161d3e8SAdam Hornacek  * information: Portions Copyright [yyyy] [name of copyright owner]
161161d3e8SAdam Hornacek  *
171161d3e8SAdam Hornacek  * CDDL HEADER END
181161d3e8SAdam Hornacek  */
191161d3e8SAdam Hornacek 
201161d3e8SAdam Hornacek /*
212f7dccc7SAdam Hornacek  * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
221161d3e8SAdam Hornacek  */
2314c8a3ffSVladimir Kotal package opengrok.auth.plugin;
2414c8a3ffSVladimir Kotal 
2514c8a3ffSVladimir Kotal import opengrok.auth.plugin.ldap.LdapServer;
262f7dccc7SAdam Hornacek import org.junit.jupiter.api.Test;
2714c8a3ffSVladimir Kotal import org.mockito.Mockito;
28*cb97e878SVladimir Kotal import org.opengrok.web.api.v1.controller.PortChecker;
2914c8a3ffSVladimir Kotal 
3014c8a3ffSVladimir Kotal import java.io.IOException;
3114c8a3ffSVladimir Kotal import java.net.InetAddress;
3214c8a3ffSVladimir Kotal import java.net.ServerSocket;
3314c8a3ffSVladimir Kotal import java.net.Socket;
3414c8a3ffSVladimir Kotal import java.net.URISyntaxException;
3514c8a3ffSVladimir Kotal import java.net.UnknownHostException;
36*cb97e878SVladimir Kotal import java.util.Random;
3714c8a3ffSVladimir Kotal 
381161d3e8SAdam Hornacek import static org.junit.jupiter.api.Assertions.assertEquals;
391161d3e8SAdam Hornacek import static org.junit.jupiter.api.Assertions.assertFalse;
401161d3e8SAdam Hornacek import static org.junit.jupiter.api.Assertions.assertNotNull;
411161d3e8SAdam Hornacek import static org.junit.jupiter.api.Assertions.assertNull;
421161d3e8SAdam Hornacek import static org.junit.jupiter.api.Assertions.assertTrue;
4314c8a3ffSVladimir Kotal import static org.mockito.ArgumentMatchers.any;
4414c8a3ffSVladimir Kotal import static org.mockito.Mockito.doReturn;
4514c8a3ffSVladimir Kotal 
4614c8a3ffSVladimir Kotal public class LdapServerTest {
4714c8a3ffSVladimir Kotal 
4814c8a3ffSVladimir Kotal     @Test
testInvalidURI()4914c8a3ffSVladimir Kotal     public void testInvalidURI() {
5014c8a3ffSVladimir Kotal         LdapServer server = new LdapServer("foo:/\\/\\foo.bar");
5114c8a3ffSVladimir Kotal         assertFalse(server.isReachable());
5214c8a3ffSVladimir Kotal     }
5314c8a3ffSVladimir Kotal 
5414c8a3ffSVladimir Kotal     @Test
testGetPort()5514c8a3ffSVladimir Kotal     public void testGetPort() throws URISyntaxException {
5614c8a3ffSVladimir Kotal         LdapServer server = new LdapServer("ldaps://foo.bar");
5714c8a3ffSVladimir Kotal         assertEquals(636, server.getPort());
5814c8a3ffSVladimir Kotal 
5914c8a3ffSVladimir Kotal         server = new LdapServer("ldap://foo.bar");
6014c8a3ffSVladimir Kotal         assertEquals(389, server.getPort());
6114c8a3ffSVladimir Kotal 
6214c8a3ffSVladimir Kotal         server = new LdapServer("crumble://foo.bar");
6314c8a3ffSVladimir Kotal         assertEquals(-1, server.getPort());
6414c8a3ffSVladimir Kotal     }
6514c8a3ffSVladimir Kotal 
6614c8a3ffSVladimir Kotal     @Test
testSetGetUsername()6714c8a3ffSVladimir Kotal     public void testSetGetUsername() {
6814c8a3ffSVladimir Kotal         LdapServer server = new LdapServer();
6914c8a3ffSVladimir Kotal 
7014c8a3ffSVladimir Kotal         assertNull(server.getUsername());
7114c8a3ffSVladimir Kotal         assertNull(server.getPassword());
7214c8a3ffSVladimir Kotal 
7314c8a3ffSVladimir Kotal         final String testUsername = "foo";
7414c8a3ffSVladimir Kotal         server.setUsername(testUsername);
7514c8a3ffSVladimir Kotal         assertEquals(testUsername, server.getUsername());
7614c8a3ffSVladimir Kotal 
7714c8a3ffSVladimir Kotal         final String testPassword = "bar";
7814c8a3ffSVladimir Kotal         server.setPassword(testPassword);
7914c8a3ffSVladimir Kotal         assertEquals(testPassword, server.getPassword());
8014c8a3ffSVladimir Kotal     }
8114c8a3ffSVladimir Kotal 
8214c8a3ffSVladimir Kotal     @Test
testIsReachable()8314c8a3ffSVladimir Kotal     public void testIsReachable() throws IOException, InterruptedException, URISyntaxException {
84*cb97e878SVladimir Kotal         final int testPortBase = 6336;    // It has to be > 1024 to avoid BindException due to permission denied.
85*cb97e878SVladimir Kotal         final int randomRange = 49152;
86*cb97e878SVladimir Kotal         int triesCount = 0;
87*cb97e878SVladimir Kotal         final int MAX_PORT_TRIES = 20;
88*cb97e878SVladimir Kotal         Random rand = new Random();
89*cb97e878SVladimir Kotal         int testPort;
90*cb97e878SVladimir Kotal         while (true) {
91*cb97e878SVladimir Kotal             testPort = testPortBase + rand.nextInt(randomRange);
92*cb97e878SVladimir Kotal             if (PortChecker.available(testPort)) {
93*cb97e878SVladimir Kotal                 break;
94*cb97e878SVladimir Kotal             }
95*cb97e878SVladimir Kotal             if (++triesCount > MAX_PORT_TRIES) {
96*cb97e878SVladimir Kotal                 throw new RuntimeException("Could not find an available port after " +
97*cb97e878SVladimir Kotal                         MAX_PORT_TRIES + " tries");
98*cb97e878SVladimir Kotal             }
99*cb97e878SVladimir Kotal         }
100*cb97e878SVladimir Kotal 
101*cb97e878SVladimir Kotal         // Start simple TCP server on test port.
10214c8a3ffSVladimir Kotal         InetAddress localhostAddr = InetAddress.getLocalHost();
10314c8a3ffSVladimir Kotal         ServerSocket serverSocket = new ServerSocket(testPort, 1, localhostAddr);
10414c8a3ffSVladimir Kotal         Thread thread = new Thread(() -> {
10514c8a3ffSVladimir Kotal             try {
10614c8a3ffSVladimir Kotal                 while (true) {
10714c8a3ffSVladimir Kotal                     Socket client = serverSocket.accept();
10814c8a3ffSVladimir Kotal                     client.close();
10914c8a3ffSVladimir Kotal                 }
11014c8a3ffSVladimir Kotal             } catch (IOException e) {
11114c8a3ffSVladimir Kotal                 e.printStackTrace();
11214c8a3ffSVladimir Kotal             }
11314c8a3ffSVladimir Kotal         });
11414c8a3ffSVladimir Kotal 
11514c8a3ffSVladimir Kotal         thread.start();
11614c8a3ffSVladimir Kotal         Socket socket = null;
11714c8a3ffSVladimir Kotal         for (int i = 0; i < 3; i++) {
11814c8a3ffSVladimir Kotal             try {
11914c8a3ffSVladimir Kotal                 socket = new Socket(localhostAddr, testPort);
12014c8a3ffSVladimir Kotal             } catch (IOException e) {
12114c8a3ffSVladimir Kotal                 Thread.sleep(1000);
12214c8a3ffSVladimir Kotal             }
12314c8a3ffSVladimir Kotal         }
12414c8a3ffSVladimir Kotal 
12514c8a3ffSVladimir Kotal         assertNotNull(socket);
12614c8a3ffSVladimir Kotal         assertTrue(socket.isConnected());
12714c8a3ffSVladimir Kotal 
128*cb97e878SVladimir Kotal         // Mock getAddresses() to return single localhost IP address and getPort() to return the test port.
12914c8a3ffSVladimir Kotal         LdapServer server = new LdapServer("ldaps://foo.bar.com");
13014c8a3ffSVladimir Kotal         LdapServer serverSpy = Mockito.spy(server);
13114c8a3ffSVladimir Kotal         Mockito.when(serverSpy.getAddresses(any())).thenReturn(new InetAddress[]{localhostAddr});
13214c8a3ffSVladimir Kotal         doReturn(testPort).when(serverSpy).getPort();
13314c8a3ffSVladimir Kotal 
13414c8a3ffSVladimir Kotal         // Test reachability.
13514c8a3ffSVladimir Kotal         boolean reachable = serverSpy.isReachable();
13614c8a3ffSVladimir Kotal         serverSocket.close();
13714c8a3ffSVladimir Kotal         thread.join(5000);
13814c8a3ffSVladimir Kotal         thread.interrupt();
13914c8a3ffSVladimir Kotal         assertTrue(reachable);
14014c8a3ffSVladimir Kotal 
14114c8a3ffSVladimir Kotal         // Test non-reachability.
14214c8a3ffSVladimir Kotal         reachable = serverSpy.isReachable();
14314c8a3ffSVladimir Kotal         assertFalse(reachable);
14414c8a3ffSVladimir Kotal     }
14514c8a3ffSVladimir Kotal 
14614c8a3ffSVladimir Kotal     @Test
testEmptyAddressArray()14714c8a3ffSVladimir Kotal     public void testEmptyAddressArray() throws UnknownHostException {
14814c8a3ffSVladimir Kotal         LdapServer server = new LdapServer("ldaps://foo.bar.com");
14914c8a3ffSVladimir Kotal         LdapServer serverSpy = Mockito.spy(server);
15014c8a3ffSVladimir Kotal         Mockito.when(serverSpy.getAddresses(any())).thenReturn(new InetAddress[]{});
15114c8a3ffSVladimir Kotal         assertFalse(serverSpy.isReachable());
15214c8a3ffSVladimir Kotal     }
153d0624dbbSVladimir Kotal 
154d0624dbbSVladimir Kotal     @Test
testToString()155d0624dbbSVladimir Kotal     public void testToString() {
156d0624dbbSVladimir Kotal         LdapServer server = new LdapServer("ldaps://foo.bar.com", "foo", "bar");
157d0624dbbSVladimir Kotal         server.setConnectTimeout(2000);
158d0624dbbSVladimir Kotal         server.setReadTimeout(1000);
159d0624dbbSVladimir Kotal         assertEquals("ldaps://foo.bar.com, connect timeout: 2000, read timeout: 1000, username: foo",
160d0624dbbSVladimir Kotal                 server.toString());
161d0624dbbSVladimir Kotal     }
16214c8a3ffSVladimir Kotal }
163