xref: /OpenGrok/plugins/src/test/java/opengrok/auth/plugin/LdapUserPluginTest.java (revision d630fdc80623f85cf43a81c7f7168517ae5f6794)
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) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
22  */
23 package opengrok.auth.plugin;
24 
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.Map;
28 import java.util.Set;
29 import java.util.TreeMap;
30 
31 import jakarta.servlet.http.HttpServletRequest;
32 import opengrok.auth.entity.LdapUser;
33 import opengrok.auth.plugin.entity.User;
34 import opengrok.auth.plugin.ldap.AbstractLdapProvider;
35 import opengrok.auth.plugin.ldap.LdapException;
36 import opengrok.auth.plugin.ldap.LdapFacade;
37 import opengrok.auth.plugin.util.DummyHttpServletRequestLdap;
38 import org.junit.jupiter.api.BeforeEach;
39 import org.junit.jupiter.api.Test;
40 import org.mockito.Mockito;
41 import org.opengrok.indexer.configuration.Group;
42 import org.opengrok.indexer.configuration.Project;
43 
44 import static opengrok.auth.plugin.LdapUserPlugin.SESSION_ATTR;
45 import static org.junit.jupiter.api.Assertions.assertEquals;
46 import static org.junit.jupiter.api.Assertions.assertFalse;
47 import static org.junit.jupiter.api.Assertions.assertNotNull;
48 import static org.junit.jupiter.api.Assertions.assertSame;
49 import static org.junit.jupiter.api.Assertions.assertThrows;
50 import static org.mockito.ArgumentMatchers.any;
51 import static org.mockito.ArgumentMatchers.anyBoolean;
52 import static org.mockito.ArgumentMatchers.anyString;
53 import static org.mockito.ArgumentMatchers.eq;
54 import static org.mockito.ArgumentMatchers.isNull;
55 import static org.mockito.Mockito.mock;
56 import static org.mockito.Mockito.times;
57 import static org.mockito.Mockito.verify;
58 import static org.mockito.Mockito.when;
59 
60 /**
61  * @author Vladimir Kotal
62  */
63 class LdapUserPluginTest {
64 
65     private LdapUserPlugin plugin;
66 
67     @BeforeEach
setUp()68     public void setUp() {
69         plugin = new LdapUserPlugin();
70     }
71 
getParamsMap()72     private Map<String, Object> getParamsMap() {
73         Map<String, Object> params = new TreeMap<>();
74         params.put(AbstractLdapPlugin.CONFIGURATION_PARAM,
75                 getClass().getResource("config.xml").getFile());
76 
77         return params;
78     }
79 
80     @Test
loadTestNegative1()81     void loadTestNegative1() {
82         Map<String, Object> params = getParamsMap();
83         params.put("foo", "bar");
84         assertThrows(NullPointerException.class, () -> plugin.load(params));
85     }
86 
87     @Test
loadTestPositive()88     void loadTestPositive() {
89         Map<String, Object> params = getParamsMap();
90         params.put(LdapUserPlugin.ATTRIBUTES, "mail");
91         plugin.load(params);
92     }
93 
94     @Test
filterTest()95     void filterTest() {
96         Map<String, Object> params = getParamsMap();
97         params.put(LdapUserPlugin.LDAP_FILTER, "(&(objectclass=person)(mail=%username%))");
98         params.put(LdapUserPlugin.ATTRIBUTES, "uid,mail");
99         plugin.load(params);
100 
101         User user = new User("foo@example.com", "id", null, false);
102         String filter = plugin.expandFilter(user);
103         assertEquals("(&(objectclass=person)(mail=foo@example.com))", filter);
104     }
105 
106     @Test
testFillSessionWithDnOff()107     void testFillSessionWithDnOff() throws LdapException {
108         AbstractLdapProvider mockprovider = mock(LdapFacade.class);
109         Map<String, Set<String>> attrs = new HashMap<>();
110         attrs.put("mail", Collections.singleton("foo@example.com"));
111         final String dn = "cn=FOO_BAR,L=EMEA,DC=EXAMPLE,DC=COM";
112         AbstractLdapProvider.LdapSearchResult<Map<String, Set<String>>> result =
113                 new AbstractLdapProvider.LdapSearchResult<>(dn, attrs);
114         assertNotNull(result);
115         when(mockprovider.lookupLdapContent(isNull(), isNull(), any(String[].class))).
116                 thenReturn(result);
117 
118         Map<String, Object> params = getParamsMap();
119         params.put(LdapUserPlugin.ATTRIBUTES, "mail");
120         params.put(LdapUserPlugin.USE_DN, false);
121         LdapUserPlugin plugin = new LdapUserPlugin();
122         plugin.load(params, mockprovider);
123         assertSame(mockprovider, plugin.getLdapProvider());
124 
125         HttpServletRequest request = new DummyHttpServletRequestLdap();
126         User user = new User("foo@example.com", "id");
127         plugin.fillSession(request, user);
128 
129         assertNotNull(request.getSession().getAttribute(SESSION_ATTR));
130         assertEquals(dn, ((LdapUser) request.getSession().getAttribute(SESSION_ATTR)).getDn());
131     }
132 
133     @Test
testNegativeCache()134     void testNegativeCache() throws LdapException {
135         AbstractLdapProvider mockprovider = mock(LdapFacade.class);
136         when(mockprovider.lookupLdapContent(isNull(), isNull(), any(String[].class))).thenReturn(null);
137 
138         Map<String, Object> params = getParamsMap();
139         params.put(LdapUserPlugin.ATTRIBUTES, "mail");
140         params.put(LdapUserPlugin.USE_DN, false);
141         LdapUserPlugin origPlugin = new LdapUserPlugin();
142         LdapUserPlugin plugin = Mockito.spy(origPlugin);
143         plugin.load(params, mockprovider);
144         assertSame(mockprovider, plugin.getLdapProvider());
145 
146         HttpServletRequest dummyRequest = new DummyHttpServletRequestLdap();
147         User user = new User("foo@example.com", "id");
148         dummyRequest.setAttribute(UserPlugin.REQUEST_ATTR, new User("foo", "123"));
149         plugin.fillSession(dummyRequest, user);
150 
151         assertNotNull(dummyRequest.getSession().getAttribute(SESSION_ATTR));
152         assertFalse(plugin.isAllowed(dummyRequest, new Project("foo")));
153         assertFalse(plugin.isAllowed(dummyRequest, new Group("bar")));
154         // Make sure that the session was filled so that the second call to isAllowed() did not fill it again.
155         verify(plugin, times(2)).updateSession(eq(dummyRequest), anyString(), anyBoolean());
156     }
157 
158     @Test
testInstance()159     void testInstance() {
160         Map<String, Object> params = getParamsMap();
161         params.put(LdapUserPlugin.ATTRIBUTES, "mail");
162         params.put(LdapUserPlugin.INSTANCE, "42");
163         plugin.load(params);
164 
165         HttpServletRequest request = new DummyHttpServletRequestLdap();
166         LdapUser ldapUser = new LdapUser();
167         plugin.updateSession(request, ldapUser);
168         assertEquals(request.getSession().getAttribute(SESSION_ATTR + "42"), ldapUser);
169     }
170 
171     @Test
testInvalidInstance()172     void testInvalidInstance() {
173         Map<String, Object> params = getParamsMap();
174         params.put(LdapUserPlugin.ATTRIBUTES, "mail");
175         params.put(LdapUserPlugin.INSTANCE, "foobar");
176         assertThrows(NumberFormatException.class, () -> plugin.load(params));
177     }
178 }
179