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