xref: /OpenGrok/plugins/src/test/java/opengrok/auth/plugin/LdapAttrPluginTest.java (revision 1161d3e8ef931fd46d781454ef702ebb29de27e5)
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;
33f7f40d76SVladimir Kotal import java.util.HashMap;
34b28a5538SAdam Hornacek import java.util.Map;
35f7f40d76SVladimir Kotal import java.util.Set;
36b28a5538SAdam Hornacek import java.util.TreeMap;
37b28a5538SAdam Hornacek import java.util.TreeSet;
38b28a5538SAdam Hornacek import javax.servlet.http.HttpServletRequest;
39*1161d3e8SAdam Hornacek 
40b28a5538SAdam Hornacek import opengrok.auth.entity.LdapUser;
41b28a5538SAdam Hornacek import opengrok.auth.plugin.entity.User;
42f7f40d76SVladimir Kotal import opengrok.auth.plugin.ldap.AbstractLdapProvider;
4341d15cd7SVladimir Kotal import opengrok.auth.plugin.ldap.FakeLdapFacade;
44f7f40d76SVladimir Kotal import opengrok.auth.plugin.ldap.LdapException;
45f7f40d76SVladimir 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*1161d3e8SAdam Hornacek import static org.junit.Assert.assertNotNull;
56*1161d3e8SAdam Hornacek import static org.junit.Assert.assertTrue;
57*1161d3e8SAdam Hornacek import static org.mockito.ArgumentMatchers.any;
58*1161d3e8SAdam Hornacek import static org.mockito.ArgumentMatchers.anyString;
59f7f40d76SVladimir Kotal import static org.mockito.Mockito.mock;
60f7f40d76SVladimir Kotal import static org.mockito.Mockito.when;
61f7f40d76SVladimir Kotal 
62b28a5538SAdam Hornacek public class LdapAttrPluginTest {
63b28a5538SAdam Hornacek 
64b28a5538SAdam Hornacek     private HttpServletRequest dummyRequest;
65b28a5538SAdam Hornacek     private LdapAttrPlugin plugin;
66b28a5538SAdam Hornacek 
67b28a5538SAdam Hornacek     private static File whitelistFile;
68b28a5538SAdam Hornacek 
69b28a5538SAdam Hornacek     @BeforeClass
beforeClass()70b28a5538SAdam Hornacek     public static void beforeClass() throws IOException {
71b28a5538SAdam Hornacek         whitelistFile = Files.createTempFile("opengrok-auth-", "-check.tmp").toFile();
72b28a5538SAdam Hornacek         try (Writer w = new OutputStreamWriter(new FileOutputStream(whitelistFile))) {
73b28a5538SAdam Hornacek             w.append("james@bond.com\n");
74b28a5538SAdam Hornacek             w.append("random@email.com\n");
75b28a5538SAdam Hornacek             w.append("just_a_text\n");
76b28a5538SAdam Hornacek         }
77b28a5538SAdam Hornacek     }
78b28a5538SAdam Hornacek 
79b28a5538SAdam Hornacek     @AfterClass
afterClass()80b28a5538SAdam Hornacek     public static void afterClass() {
81b28a5538SAdam Hornacek         whitelistFile.delete();
82b28a5538SAdam Hornacek     }
83b28a5538SAdam Hornacek 
84b28a5538SAdam Hornacek     @Before
setUp()85b28a5538SAdam Hornacek     public void setUp() {
86b28a5538SAdam Hornacek         plugin = new LdapAttrPlugin();
87b28a5538SAdam Hornacek         Map<String, Object> parameters = new TreeMap<>();
88b28a5538SAdam Hornacek 
89b28a5538SAdam Hornacek         parameters.put(LdapAttrPlugin.FILE_PARAM, whitelistFile.getAbsolutePath());
90b28a5538SAdam Hornacek         parameters.put(LdapAttrPlugin.ATTR_PARAM, "mail");
91b28a5538SAdam Hornacek 
9241d15cd7SVladimir Kotal         plugin.load(parameters, new FakeLdapFacade());
93b28a5538SAdam Hornacek     }
94b28a5538SAdam Hornacek 
95b28a5538SAdam Hornacek     @SuppressWarnings("unchecked")
prepareRequest(String username, String mail, String... ous)96b28a5538SAdam Hornacek     private void prepareRequest(String username, String mail, String... ous) {
97b28a5538SAdam Hornacek         dummyRequest = new DummyHttpServletRequestLdap();
98b28a5538SAdam Hornacek         dummyRequest.setAttribute(UserPlugin.REQUEST_ATTR,
99ef89dd12SVladimir Kotal                 new User(username, "123"));
100ef89dd12SVladimir Kotal 
101b28a5538SAdam Hornacek         LdapUser ldapUser = new LdapUser();
102b28a5538SAdam Hornacek         ldapUser.setAttribute("mail", new TreeSet<>(Collections.singletonList(mail)));
103b28a5538SAdam Hornacek         ldapUser.setAttribute("uid", new TreeSet<>(Collections.singletonList("123")));
104b28a5538SAdam Hornacek         ldapUser.setAttribute("ou", new TreeSet<>(Arrays.asList(ous)));
105ef89dd12SVladimir Kotal 
106b28a5538SAdam Hornacek         dummyRequest.getSession().setAttribute(LdapUserPlugin.SESSION_ATTR, ldapUser);
107b28a5538SAdam Hornacek         plugin.setSessionEstablished(dummyRequest, true);
108b28a5538SAdam Hornacek         plugin.setSessionUsername(dummyRequest, username);
109b28a5538SAdam Hornacek     }
110b28a5538SAdam Hornacek 
makeProject(String name)111b28a5538SAdam Hornacek     private Project makeProject(String name) {
112b28a5538SAdam Hornacek         Project p = new Project();
113b28a5538SAdam Hornacek         p.setName(name);
114b28a5538SAdam Hornacek         return p;
115b28a5538SAdam Hornacek     }
116b28a5538SAdam Hornacek 
makeGroup(String name)117b28a5538SAdam Hornacek     private Group makeGroup(String name) {
118b28a5538SAdam Hornacek         Group p = new Group();
119b28a5538SAdam Hornacek         p.setName(name);
120b28a5538SAdam Hornacek         return p;
121b28a5538SAdam Hornacek     }
122b28a5538SAdam Hornacek 
123b28a5538SAdam Hornacek     /**
124464d259bSVladimir Kotal      * Test of {@code isAllowed} method.
125b28a5538SAdam Hornacek      */
126b28a5538SAdam Hornacek     @Test
testIsAllowed()127b28a5538SAdam Hornacek     public void testIsAllowed() {
128b28a5538SAdam Hornacek         /*
129b28a5538SAdam Hornacek          * whitelist[mail] => [james@bond.com, random@email.com, just_a_text]
130b28a5538SAdam Hornacek          */
131b28a5538SAdam Hornacek         prepareRequest("007", "james@bond.com", "MI6", "MI7");
132b28a5538SAdam Hornacek 
133*1161d3e8SAdam Hornacek         assertTrue(plugin.isAllowed(dummyRequest, makeProject("Random Project")));
134*1161d3e8SAdam Hornacek         assertTrue(plugin.isAllowed(dummyRequest, makeProject("Project 1")));
135*1161d3e8SAdam Hornacek         assertTrue(plugin.isAllowed(dummyRequest, makeGroup("Group 1")));
136*1161d3e8SAdam Hornacek         assertTrue(plugin.isAllowed(dummyRequest, makeGroup("Group 2")));
137b28a5538SAdam Hornacek 
138b28a5538SAdam Hornacek         prepareRequest("008", "james@bond.com", "MI6", "MI7");
139b28a5538SAdam Hornacek 
140*1161d3e8SAdam Hornacek         assertTrue(plugin.isAllowed(dummyRequest, makeProject("Random Project")));
141*1161d3e8SAdam Hornacek         assertTrue(plugin.isAllowed(dummyRequest, makeProject("Project 1")));
142*1161d3e8SAdam Hornacek         assertTrue(plugin.isAllowed(dummyRequest, makeGroup("Group 1")));
143*1161d3e8SAdam Hornacek         assertTrue(plugin.isAllowed(dummyRequest, makeGroup("Group 2")));
144b28a5538SAdam Hornacek 
145b28a5538SAdam Hornacek         prepareRequest("009", "other@email.com", "MI6");
146b28a5538SAdam Hornacek 
147b28a5538SAdam Hornacek         Assert.assertFalse(plugin.isAllowed(dummyRequest, makeProject("Random Project")));
148b28a5538SAdam Hornacek         Assert.assertFalse(plugin.isAllowed(dummyRequest, makeProject("Project 1")));
149b28a5538SAdam Hornacek         Assert.assertFalse(plugin.isAllowed(dummyRequest, makeGroup("Group 1")));
150b28a5538SAdam Hornacek         Assert.assertFalse(plugin.isAllowed(dummyRequest, makeGroup("Group 2")));
151b28a5538SAdam Hornacek 
152b28a5538SAdam Hornacek         prepareRequest("00A", "random@email.com", "MI6", "MI7");
153b28a5538SAdam Hornacek 
154*1161d3e8SAdam Hornacek         assertTrue(plugin.isAllowed(dummyRequest, makeProject("Random Project")));
155*1161d3e8SAdam Hornacek         assertTrue(plugin.isAllowed(dummyRequest, makeProject("Project 1")));
156*1161d3e8SAdam Hornacek         assertTrue(plugin.isAllowed(dummyRequest, makeGroup("Group 1")));
157*1161d3e8SAdam Hornacek         assertTrue(plugin.isAllowed(dummyRequest, makeGroup("Group 2")));
158b28a5538SAdam Hornacek     }
159f7f40d76SVladimir Kotal 
160f7f40d76SVladimir Kotal     /**
161*1161d3e8SAdam Hornacek      * Test the interaction between {@code LdapUserPlugin} and {@code LdapAttrPlugin}. Namely:
162f7f40d76SVladimir Kotal      * <ul>
163f7f40d76SVladimir Kotal      *     <li>use of DN from the <code>LdapUser</code> object cached in the session by <code>LdapUserPlugin</code></li>
164f7f40d76SVladimir Kotal      *     <li>configuration of the cached session attribute name</li>
165f7f40d76SVladimir Kotal      * </ul>
166f7f40d76SVladimir Kotal      */
167f7f40d76SVladimir Kotal     @Test
testAttrLookup()168f7f40d76SVladimir Kotal     public void testAttrLookup() throws LdapException {
169f7f40d76SVladimir Kotal         String attr_to_get = "mail";
170f7f40d76SVladimir Kotal         String instance_num = "42";
171f7f40d76SVladimir Kotal         String mail_attr_value = "james@bond.com";
172f7f40d76SVladimir Kotal 
173f7f40d76SVladimir Kotal         // Create mock LDAP provider, simulating the work of LdapUserPlugin.
174f7f40d76SVladimir Kotal         AbstractLdapProvider mockprovider = mock(LdapFacade.class);
175f7f40d76SVladimir Kotal         Map<String, Set<String>> attrs = new HashMap<>();
176f7f40d76SVladimir Kotal         attrs.put(attr_to_get, Collections.singleton(mail_attr_value));
177f7f40d76SVladimir Kotal         final String dn = "cn=FOO_BAR,L=EMEA,DC=FOO,DC=COM";
178f7f40d76SVladimir Kotal         AbstractLdapProvider.LdapSearchResult<Map<String, Set<String>>> result =
179f7f40d76SVladimir Kotal                 new AbstractLdapProvider.LdapSearchResult<>(dn, attrs);
180f7f40d76SVladimir Kotal         assertNotNull(result);
181f7f40d76SVladimir Kotal         // TODO use Mockito Argument captor ?
182f7f40d76SVladimir Kotal         when(mockprovider.lookupLdapContent(anyString(), any(String[].class))).
183f7f40d76SVladimir Kotal                 thenReturn(result);
184f7f40d76SVladimir Kotal 
185f7f40d76SVladimir Kotal         // Load the LdapAttrPlugin using the mock LDAP provider.
186f7f40d76SVladimir Kotal         LdapAttrPlugin plugin = new LdapAttrPlugin();
187f7f40d76SVladimir Kotal         Map<String, Object> parameters = new TreeMap<>();
188f7f40d76SVladimir Kotal         parameters.put(LdapAttrPlugin.FILE_PARAM, whitelistFile.getAbsolutePath());
189f7f40d76SVladimir Kotal         parameters.put(LdapAttrPlugin.ATTR_PARAM, attr_to_get);
190f7f40d76SVladimir Kotal         parameters.put(LdapAttrPlugin.INSTANCE_PARAM, instance_num);
191f7f40d76SVladimir Kotal         plugin.load(parameters, mockprovider);
192f7f40d76SVladimir Kotal 
193f7f40d76SVladimir Kotal         // TODO prepareRequest() ?
194f7f40d76SVladimir Kotal         LdapUser ldapUser = new LdapUser(dn, null);
195f7f40d76SVladimir Kotal         HttpServletRequest request = new DummyHttpServletRequestLdap();
196f7f40d76SVladimir Kotal         request.getSession().setAttribute(LdapUserPlugin.SESSION_ATTR + instance_num, ldapUser);
197f7f40d76SVladimir Kotal 
198f7f40d76SVladimir Kotal         // Here it comes all together.
199f7f40d76SVladimir Kotal         User user = new User("foo@bar.cz", "id");
200f7f40d76SVladimir Kotal         plugin.fillSession(request, user);
201f7f40d76SVladimir Kotal 
202f7f40d76SVladimir Kotal         // See if LdapAttrPlugin set its own session attribute based on the mocked query.
203f7f40d76SVladimir Kotal         assertTrue((Boolean) request.getSession().getAttribute(plugin.getSessionAllowedAttrName()));
204f7f40d76SVladimir Kotal         assertTrue(ldapUser.getAttribute(attr_to_get).contains(mail_attr_value));
205f7f40d76SVladimir Kotal     }
206b28a5538SAdam Hornacek }
207