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