xref: /OpenGrok/plugins/src/test/java/opengrok/auth/plugin/LdapAttrPluginTest.java (revision f7f40d76d643d3e79fe54dec2ac54810e92997dd)
1b28a5538SAdam Hornacek /*
2b28a5538SAdam Hornacek  * CDDL HEADER START
3b28a5538SAdam Hornacek  *
4b28a5538SAdam Hornacek  * The contents of this file are subject to the terms of the
5b28a5538SAdam Hornacek  * Common Development and Distribution License (the "License").
6b28a5538SAdam Hornacek  * You may not use this file except in compliance with the License.
7b28a5538SAdam Hornacek  *
8b28a5538SAdam Hornacek  * See LICENSE.txt included in this distribution for the specific
9b28a5538SAdam Hornacek  * language governing permissions and limitations under the License.
10b28a5538SAdam Hornacek  *
11b28a5538SAdam Hornacek  * When distributing Covered Code, include this CDDL HEADER in each
12b28a5538SAdam Hornacek  * file and include the License file at LICENSE.txt.
13b28a5538SAdam Hornacek  * If applicable, add the following below this CDDL HEADER, with the
14b28a5538SAdam Hornacek  * fields enclosed by brackets "[]" replaced with your own identifying
15b28a5538SAdam Hornacek  * information: Portions Copyright [yyyy] [name of copyright owner]
16b28a5538SAdam Hornacek  *
17b28a5538SAdam Hornacek  * CDDL HEADER END
18b28a5538SAdam Hornacek  */
19b28a5538SAdam Hornacek 
20b28a5538SAdam Hornacek /*
21b28a5538SAdam Hornacek  * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
22b28a5538SAdam Hornacek  */
23b28a5538SAdam Hornacek package opengrok.auth.plugin;
24b28a5538SAdam Hornacek 
25b28a5538SAdam Hornacek import java.io.File;
26b28a5538SAdam Hornacek import java.io.FileOutputStream;
27b28a5538SAdam Hornacek import java.io.IOException;
28b28a5538SAdam Hornacek import java.io.OutputStreamWriter;
29b28a5538SAdam Hornacek import java.io.Writer;
30b28a5538SAdam Hornacek import java.nio.file.Files;
31b28a5538SAdam Hornacek import java.util.Arrays;
32b28a5538SAdam Hornacek import java.util.Collections;
33*f7f40d76SVladimir Kotal import java.util.HashMap;
34b28a5538SAdam Hornacek import java.util.HashSet;
35b28a5538SAdam Hornacek import java.util.Map;
36*f7f40d76SVladimir Kotal import java.util.Set;
37b28a5538SAdam Hornacek import java.util.TreeMap;
38b28a5538SAdam Hornacek import java.util.TreeSet;
39b28a5538SAdam Hornacek import javax.servlet.http.HttpServletRequest;
40b28a5538SAdam Hornacek import opengrok.auth.entity.LdapUser;
41b28a5538SAdam Hornacek import opengrok.auth.plugin.entity.User;
42*f7f40d76SVladimir Kotal import opengrok.auth.plugin.ldap.AbstractLdapProvider;
4341d15cd7SVladimir Kotal import opengrok.auth.plugin.ldap.FakeLdapFacade;
44*f7f40d76SVladimir Kotal import opengrok.auth.plugin.ldap.LdapException;
45*f7f40d76SVladimir Kotal import opengrok.auth.plugin.ldap.LdapFacade;
46b28a5538SAdam Hornacek import opengrok.auth.plugin.util.DummyHttpServletRequestLdap;
47b28a5538SAdam Hornacek import org.junit.AfterClass;
48b28a5538SAdam Hornacek import org.junit.Assert;
49b28a5538SAdam Hornacek import org.junit.Before;
50b28a5538SAdam Hornacek import org.junit.BeforeClass;
51b28a5538SAdam Hornacek import org.junit.Test;
52b28a5538SAdam Hornacek import org.opengrok.indexer.configuration.Group;
53b28a5538SAdam Hornacek import org.opengrok.indexer.configuration.Project;
54b28a5538SAdam Hornacek 
55*f7f40d76SVladimir Kotal import static org.junit.jupiter.api.Assertions.*;
56*f7f40d76SVladimir Kotal import static org.mockito.ArgumentMatchers.*;
57*f7f40d76SVladimir Kotal import static org.mockito.Mockito.mock;
58*f7f40d76SVladimir Kotal import static org.mockito.Mockito.when;
59*f7f40d76SVladimir Kotal 
60b28a5538SAdam Hornacek public class LdapAttrPluginTest {
61b28a5538SAdam Hornacek 
62b28a5538SAdam Hornacek     private HttpServletRequest dummyRequest;
63b28a5538SAdam Hornacek     private LdapAttrPlugin plugin;
64b28a5538SAdam Hornacek 
65b28a5538SAdam Hornacek     private static File whitelistFile;
66b28a5538SAdam Hornacek 
67b28a5538SAdam Hornacek     @BeforeClass
beforeClass()68b28a5538SAdam Hornacek     public static void beforeClass() throws IOException {
69b28a5538SAdam Hornacek         whitelistFile = Files.createTempFile("opengrok-auth-", "-check.tmp").toFile();
70b28a5538SAdam Hornacek         try (Writer w = new OutputStreamWriter(new FileOutputStream(whitelistFile))) {
71b28a5538SAdam Hornacek             w.append("james@bond.com\n");
72b28a5538SAdam Hornacek             w.append("random@email.com\n");
73b28a5538SAdam Hornacek             w.append("just_a_text\n");
74b28a5538SAdam Hornacek         }
75b28a5538SAdam Hornacek     }
76b28a5538SAdam Hornacek 
77b28a5538SAdam Hornacek     @AfterClass
afterClass()78b28a5538SAdam Hornacek     public static void afterClass() {
79b28a5538SAdam Hornacek         whitelistFile.delete();
80b28a5538SAdam Hornacek     }
81b28a5538SAdam Hornacek 
82b28a5538SAdam Hornacek     @Before
setUp()83b28a5538SAdam Hornacek     public void setUp() {
84b28a5538SAdam Hornacek         plugin = new LdapAttrPlugin();
85b28a5538SAdam Hornacek         Map<String, Object> parameters = new TreeMap<>();
86b28a5538SAdam Hornacek 
87b28a5538SAdam Hornacek         parameters.put(LdapAttrPlugin.FILE_PARAM, whitelistFile.getAbsolutePath());
88b28a5538SAdam Hornacek         parameters.put(LdapAttrPlugin.ATTR_PARAM, "mail");
89b28a5538SAdam Hornacek 
9041d15cd7SVladimir Kotal         plugin.load(parameters, new FakeLdapFacade());
91b28a5538SAdam Hornacek     }
92b28a5538SAdam Hornacek 
93b28a5538SAdam Hornacek     @SuppressWarnings("unchecked")
prepareRequest(String username, String mail, String... ous)94b28a5538SAdam Hornacek     private void prepareRequest(String username, String mail, String... ous) {
95b28a5538SAdam Hornacek         dummyRequest = new DummyHttpServletRequestLdap();
96b28a5538SAdam Hornacek         dummyRequest.setAttribute(UserPlugin.REQUEST_ATTR,
97ef89dd12SVladimir Kotal                 new User(username, "123"));
98ef89dd12SVladimir Kotal 
99b28a5538SAdam Hornacek         LdapUser ldapUser = new LdapUser();
100b28a5538SAdam Hornacek         ldapUser.setAttribute("mail", new TreeSet<>(Collections.singletonList(mail)));
101b28a5538SAdam Hornacek         ldapUser.setAttribute("uid", new TreeSet<>(Collections.singletonList("123")));
102b28a5538SAdam Hornacek         ldapUser.setAttribute("ou", new TreeSet<>(Arrays.asList(ous)));
103ef89dd12SVladimir Kotal 
104b28a5538SAdam Hornacek         dummyRequest.getSession().setAttribute(LdapUserPlugin.SESSION_ATTR, ldapUser);
105b28a5538SAdam Hornacek         plugin.setSessionEstablished(dummyRequest, true);
106b28a5538SAdam Hornacek         plugin.setSessionUsername(dummyRequest, username);
107b28a5538SAdam Hornacek     }
108b28a5538SAdam Hornacek 
makeProject(String name)109b28a5538SAdam Hornacek     private Project makeProject(String name) {
110b28a5538SAdam Hornacek         Project p = new Project();
111b28a5538SAdam Hornacek         p.setName(name);
112b28a5538SAdam Hornacek         return p;
113b28a5538SAdam Hornacek     }
114b28a5538SAdam Hornacek 
makeGroup(String name)115b28a5538SAdam Hornacek     private Group makeGroup(String name) {
116b28a5538SAdam Hornacek         Group p = new Group();
117b28a5538SAdam Hornacek         p.setName(name);
118b28a5538SAdam Hornacek         return p;
119b28a5538SAdam Hornacek     }
120b28a5538SAdam Hornacek 
121b28a5538SAdam Hornacek     /**
122464d259bSVladimir Kotal      * Test of {@code isAllowed} method.
123b28a5538SAdam Hornacek      */
124b28a5538SAdam Hornacek     @Test
testIsAllowed()125b28a5538SAdam Hornacek     public void testIsAllowed() {
126b28a5538SAdam Hornacek         /*
127b28a5538SAdam Hornacek          * whitelist[mail] => [james@bond.com, random@email.com, just_a_text]
128b28a5538SAdam Hornacek          */
129b28a5538SAdam Hornacek         prepareRequest("007", "james@bond.com", "MI6", "MI7");
130b28a5538SAdam Hornacek 
131b28a5538SAdam Hornacek         Assert.assertTrue(plugin.isAllowed(dummyRequest, makeProject("Random Project")));
132b28a5538SAdam Hornacek         Assert.assertTrue(plugin.isAllowed(dummyRequest, makeProject("Project 1")));
133b28a5538SAdam Hornacek         Assert.assertTrue(plugin.isAllowed(dummyRequest, makeGroup("Group 1")));
134b28a5538SAdam Hornacek         Assert.assertTrue(plugin.isAllowed(dummyRequest, makeGroup("Group 2")));
135b28a5538SAdam Hornacek 
136b28a5538SAdam Hornacek         prepareRequest("008", "james@bond.com", "MI6", "MI7");
137b28a5538SAdam Hornacek 
138b28a5538SAdam Hornacek         Assert.assertTrue(plugin.isAllowed(dummyRequest, makeProject("Random Project")));
139b28a5538SAdam Hornacek         Assert.assertTrue(plugin.isAllowed(dummyRequest, makeProject("Project 1")));
140b28a5538SAdam Hornacek         Assert.assertTrue(plugin.isAllowed(dummyRequest, makeGroup("Group 1")));
141b28a5538SAdam Hornacek         Assert.assertTrue(plugin.isAllowed(dummyRequest, makeGroup("Group 2")));
142b28a5538SAdam Hornacek 
143b28a5538SAdam Hornacek         prepareRequest("009", "other@email.com", "MI6");
144b28a5538SAdam Hornacek 
145b28a5538SAdam Hornacek         Assert.assertFalse(plugin.isAllowed(dummyRequest, makeProject("Random Project")));
146b28a5538SAdam Hornacek         Assert.assertFalse(plugin.isAllowed(dummyRequest, makeProject("Project 1")));
147b28a5538SAdam Hornacek         Assert.assertFalse(plugin.isAllowed(dummyRequest, makeGroup("Group 1")));
148b28a5538SAdam Hornacek         Assert.assertFalse(plugin.isAllowed(dummyRequest, makeGroup("Group 2")));
149b28a5538SAdam Hornacek 
150b28a5538SAdam Hornacek         prepareRequest("00A", "random@email.com", "MI6", "MI7");
151b28a5538SAdam Hornacek 
152b28a5538SAdam Hornacek         Assert.assertTrue(plugin.isAllowed(dummyRequest, makeProject("Random Project")));
153b28a5538SAdam Hornacek         Assert.assertTrue(plugin.isAllowed(dummyRequest, makeProject("Project 1")));
154b28a5538SAdam Hornacek         Assert.assertTrue(plugin.isAllowed(dummyRequest, makeGroup("Group 1")));
155b28a5538SAdam Hornacek         Assert.assertTrue(plugin.isAllowed(dummyRequest, makeGroup("Group 2")));
156b28a5538SAdam Hornacek     }
157*f7f40d76SVladimir Kotal 
158*f7f40d76SVladimir Kotal     /**
159*f7f40d76SVladimir Kotal      * Test the interaction between {@code LdapUserPlugin} and {@code LdapAttrPlugin}, namely:
160*f7f40d76SVladimir Kotal      * <ul>
161*f7f40d76SVladimir Kotal      *     <li>use of DN from the <code>LdapUser</code> object cached in the session by <code>LdapUserPlugin</code></li>
162*f7f40d76SVladimir Kotal      *     <li>configuration of the cached session attribute name</li>
163*f7f40d76SVladimir Kotal      * </ul>
164*f7f40d76SVladimir Kotal      */
165*f7f40d76SVladimir Kotal     @Test
testAttrLookup()166*f7f40d76SVladimir Kotal     public void testAttrLookup() throws LdapException {
167*f7f40d76SVladimir Kotal         String attr_to_get = "mail";
168*f7f40d76SVladimir Kotal         String instance_num = "42";
169*f7f40d76SVladimir Kotal         String mail_attr_value = "james@bond.com";
170*f7f40d76SVladimir Kotal 
171*f7f40d76SVladimir Kotal         // Create mock LDAP provider, simulating the work of LdapUserPlugin.
172*f7f40d76SVladimir Kotal         AbstractLdapProvider mockprovider = mock(LdapFacade.class);
173*f7f40d76SVladimir Kotal         Map<String, Set<String>> attrs = new HashMap<>();
174*f7f40d76SVladimir Kotal         attrs.put(attr_to_get, Collections.singleton(mail_attr_value));
175*f7f40d76SVladimir Kotal         final String dn = "cn=FOO_BAR,L=EMEA,DC=FOO,DC=COM";
176*f7f40d76SVladimir Kotal         AbstractLdapProvider.LdapSearchResult<Map<String, Set<String>>> result =
177*f7f40d76SVladimir Kotal                 new AbstractLdapProvider.LdapSearchResult<>(dn, attrs);
178*f7f40d76SVladimir Kotal         assertNotNull(result);
179*f7f40d76SVladimir Kotal         // TODO use Mockito Argument captor ?
180*f7f40d76SVladimir Kotal         when(mockprovider.lookupLdapContent(anyString(), any(String[].class))).
181*f7f40d76SVladimir Kotal                 thenReturn(result);
182*f7f40d76SVladimir Kotal 
183*f7f40d76SVladimir Kotal         // Load the LdapAttrPlugin using the mock LDAP provider.
184*f7f40d76SVladimir Kotal         LdapAttrPlugin plugin = new LdapAttrPlugin();
185*f7f40d76SVladimir Kotal         Map<String, Object> parameters = new TreeMap<>();
186*f7f40d76SVladimir Kotal         parameters.put(LdapAttrPlugin.FILE_PARAM, whitelistFile.getAbsolutePath());
187*f7f40d76SVladimir Kotal         parameters.put(LdapAttrPlugin.ATTR_PARAM, attr_to_get);
188*f7f40d76SVladimir Kotal         parameters.put(LdapAttrPlugin.INSTANCE_PARAM, instance_num);
189*f7f40d76SVladimir Kotal         plugin.load(parameters, mockprovider);
190*f7f40d76SVladimir Kotal 
191*f7f40d76SVladimir Kotal         // TODO prepareRequest() ?
192*f7f40d76SVladimir Kotal         LdapUser ldapUser = new LdapUser(dn, null);
193*f7f40d76SVladimir Kotal         HttpServletRequest request = new DummyHttpServletRequestLdap();
194*f7f40d76SVladimir Kotal         request.getSession().setAttribute(LdapUserPlugin.SESSION_ATTR + instance_num, ldapUser);
195*f7f40d76SVladimir Kotal 
196*f7f40d76SVladimir Kotal         // Here it comes all together.
197*f7f40d76SVladimir Kotal         User user = new User("foo@bar.cz", "id");
198*f7f40d76SVladimir Kotal         plugin.fillSession(request, user);
199*f7f40d76SVladimir Kotal 
200*f7f40d76SVladimir Kotal         // See if LdapAttrPlugin set its own session attribute based on the mocked query.
201*f7f40d76SVladimir Kotal         assertTrue((Boolean)request.getSession().getAttribute(plugin.getSessionAllowedAttrName()));
202*f7f40d76SVladimir Kotal         assertTrue(ldapUser.getAttribute(attr_to_get).contains(mail_attr_value));
203*f7f40d76SVladimir Kotal     }
204b28a5538SAdam Hornacek }
205