Skip to content

Commit c16fa5c

Browse files
RANGER-5346: Test Cases for agents-common Module: Packages (org.apache.ranger: admin.client.datatype, admin.client, authorization.utils, authorization.hadoop.config, plugin.audit, plugin.client) and org.apache.hadoop.security (#692)
1 parent caa4478 commit c16fa5c

21 files changed

+4160
-59
lines changed

agents-common/pom.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,18 @@
224224
<version>${junit.jupiter.version}</version>
225225
<scope>test</scope>
226226
</dependency>
227+
<dependency>
228+
<groupId>org.mockito</groupId>
229+
<artifactId>mockito-inline</artifactId>
230+
<version>${mockito.version}</version>
231+
<scope>test</scope>
232+
</dependency>
233+
<dependency>
234+
<groupId>org.mockito</groupId>
235+
<artifactId>mockito-junit-jupiter</artifactId>
236+
<version>${mockito.version}</version>
237+
<scope>test</scope>
238+
</dependency>
227239
<dependency>
228240
<groupId>org.slf4j</groupId>
229241
<artifactId>log4j-over-slf4j</artifactId>
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package org.apache.hadoop.security;
20+
21+
import org.junit.jupiter.api.MethodOrderer;
22+
import org.junit.jupiter.api.Test;
23+
import org.junit.jupiter.api.TestMethodOrder;
24+
import org.junit.jupiter.api.extension.ExtendWith;
25+
import org.mockito.junit.jupiter.MockitoExtension;
26+
27+
import javax.security.auth.Subject;
28+
import javax.security.auth.callback.CallbackHandler;
29+
30+
import java.util.HashMap;
31+
import java.util.Map;
32+
33+
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
34+
import static org.junit.jupiter.api.Assertions.assertEquals;
35+
import static org.junit.jupiter.api.Assertions.assertTrue;
36+
37+
/**
38+
* @generated by Cursor
39+
* @description <Unit Test for KrbPasswordSaverLoginModule class>
40+
*/
41+
@ExtendWith(MockitoExtension.class)
42+
@TestMethodOrder(MethodOrderer.MethodName.class)
43+
public class TestKrbPasswordSaverLoginModule {
44+
@Test
45+
public void test01_initialize_storesCredentialsInSharedState() throws Exception {
46+
KrbPasswordSaverLoginModule module = new KrbPasswordSaverLoginModule();
47+
Map<String, Object> shared = new HashMap<>();
48+
Map<String, Object> options = new HashMap<>();
49+
options.put(KrbPasswordSaverLoginModule.USERNAME_PARAM, "user1");
50+
options.put(KrbPasswordSaverLoginModule.PASSWORD_PARAM, "secret");
51+
52+
module.initialize(new Subject(), (CallbackHandler) null, shared, options);
53+
54+
assertEquals("user1", shared.get(KrbPasswordSaverLoginModule.USERNAME_PARAM));
55+
assertArrayEquals("secret".toCharArray(), (char[]) shared.get(KrbPasswordSaverLoginModule.PASSWORD_PARAM));
56+
}
57+
58+
@Test
59+
public void test02_login_commit_abort_logout_returnTrue() throws Exception {
60+
KrbPasswordSaverLoginModule module = new KrbPasswordSaverLoginModule();
61+
assertTrue(module.login());
62+
assertTrue(module.commit());
63+
assertTrue(module.abort());
64+
assertTrue(module.logout());
65+
}
66+
67+
@Test
68+
public void test03_initialize_withNullOptions_doesNotPopulateShared() {
69+
KrbPasswordSaverLoginModule module = new KrbPasswordSaverLoginModule();
70+
Map<String, Object> shared = new HashMap<>();
71+
module.initialize(new Subject(), (CallbackHandler) null, shared, null);
72+
assertTrue(shared.isEmpty());
73+
}
74+
}
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package org.apache.hadoop.security;
20+
21+
import org.apache.hadoop.security.authentication.util.KerberosName;
22+
import org.junit.jupiter.api.MethodOrderer;
23+
import org.junit.jupiter.api.Test;
24+
import org.junit.jupiter.api.TestMethodOrder;
25+
import org.junit.jupiter.api.extension.ExtendWith;
26+
import org.mockito.junit.jupiter.MockitoExtension;
27+
28+
import javax.security.auth.Subject;
29+
import javax.security.auth.login.AppConfigurationEntry;
30+
import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
31+
32+
import java.io.File;
33+
import java.io.FileWriter;
34+
import java.io.IOException;
35+
import java.security.Principal;
36+
import java.util.Set;
37+
38+
import static org.junit.jupiter.api.Assertions.assertEquals;
39+
import static org.junit.jupiter.api.Assertions.assertNotNull;
40+
import static org.junit.jupiter.api.Assertions.assertNull;
41+
import static org.junit.jupiter.api.Assertions.assertThrows;
42+
import static org.junit.jupiter.api.Assertions.assertTrue;
43+
44+
/**
45+
* @generated by Cursor
46+
* @description <Unit Test for SecureClientLogin class>
47+
*/
48+
@ExtendWith(MockitoExtension.class)
49+
@TestMethodOrder(MethodOrderer.MethodName.class)
50+
public class TestSecureClientLogin {
51+
@Test
52+
public void test01_isKerberosCredentialExists_nullKeytab_returnsFalse() {
53+
boolean valid = SecureClientLogin.isKerberosCredentialExists("user@EXAMPLE.COM", null);
54+
assertEquals(false, valid);
55+
}
56+
57+
@Test
58+
public void test02_isKerberosCredentialExists_missingFile_returnsFalse() {
59+
File f = new File("/tmp/does-not-exist-" + System.nanoTime());
60+
boolean valid = SecureClientLogin.isKerberosCredentialExists("user@EXAMPLE.COM", f.getAbsolutePath());
61+
assertEquals(false, valid);
62+
}
63+
64+
@Test
65+
public void test03_isKerberosCredentialExists_existingFileAndPrincipal_returnsTrue() throws Exception {
66+
File f = File.createTempFile("keytab", ".kt");
67+
f.deleteOnExit();
68+
try (FileWriter w = new FileWriter(f)) {
69+
w.write("dummy");
70+
}
71+
boolean valid = SecureClientLogin.isKerberosCredentialExists("user@EXAMPLE.COM", f.getAbsolutePath());
72+
assertEquals(true, valid);
73+
}
74+
75+
@Test
76+
public void test04_getPrincipal_noPattern_returnsSame() throws Exception {
77+
String in = "user/host@EXAMPLE.COM";
78+
String out = SecureClientLogin.getPrincipal(in, "host");
79+
assertEquals(in, out);
80+
}
81+
82+
@Test
83+
public void test05_getPrincipal_withPatternAndHost_replacesWithLowercase() throws Exception {
84+
String out = SecureClientLogin.getPrincipal("user/_HOST@EXAMPLE.COM", "FooBar.Example.COM");
85+
assertEquals("user/foobar.example.com@EXAMPLE.COM", out);
86+
}
87+
88+
@Test
89+
public void test05b_getPrincipal_withPatternAndWildcardHost_usesLocalHost() throws Exception {
90+
String out = SecureClientLogin.getPrincipal("user/_HOST@EXAMPLE.COM", "0.0.0.0");
91+
assertTrue(out.startsWith("user/"));
92+
assertTrue(out.endsWith("@EXAMPLE.COM"));
93+
}
94+
95+
@Test
96+
public void test06_getPrincipal_withNullHost_throwsIOException() {
97+
assertThrows(IOException.class, () -> SecureClientLogin.getPrincipal("user/_HOST@EXAMPLE.COM", null));
98+
}
99+
100+
@Test
101+
public void test07_login_returnsSubjectWithPrincipal() throws Exception {
102+
Subject s = SecureClientLogin.login("alice");
103+
assertNotNull(s);
104+
Set<Principal> principals = SecureClientLogin.getUserPrincipals(s);
105+
assertNotNull(principals);
106+
assertTrue(principals.stream().anyMatch(p -> "alice".equals(p.getName())));
107+
}
108+
109+
@Test
110+
public void test08_getUserPrincipals_nullSubject_returnsNull() {
111+
assertNull(SecureClientLogin.getUserPrincipals(null));
112+
}
113+
114+
@Test
115+
public void test09_loginUserFromKeytab_invalid_throwsException() {
116+
assertThrows(Exception.class,
117+
() -> SecureClientLogin.loginUserFromKeytab("user@EXAMPLE.COM", "/path/not/found"));
118+
}
119+
120+
@Test
121+
public void test10_loginUserWithPassword_invalid_throwsException() {
122+
assertThrows(Exception.class, () -> SecureClientLogin.loginUserWithPassword("user@EXAMPLE.COM", "badpass"));
123+
}
124+
125+
@Test
126+
public void test11_loginUserFromKeytab_withNameRules_invalid_throwsException() {
127+
assertThrows(Exception.class,
128+
() -> SecureClientLogin.loginUserFromKeytab("user@EXAMPLE.COM", "/path/not/found", "DEFAULT"));
129+
}
130+
131+
@Test
132+
public void test12_createUserPrincipal_returnsPrincipalWithName() {
133+
Principal p = SecureClientLogin.createUserPrincipal("bob");
134+
assertNotNull(p);
135+
assertEquals("bob", p.getName());
136+
}
137+
138+
@Test
139+
public void test13_secureClientLoginConfiguration_withKeytab_returnsSingleKerberosEntry() {
140+
SecureClientLogin.SecureClientLoginConfiguration conf = new SecureClientLogin.SecureClientLoginConfiguration(
141+
true, "user@EXAMPLE.COM", "/tmp/fake.keytab");
142+
AppConfigurationEntry[] entries = conf.getAppConfigurationEntry("hadoop-keytab-kerberos");
143+
assertNotNull(entries);
144+
assertEquals(1, entries.length);
145+
assertEquals(LoginModuleControlFlag.REQUIRED, entries[0].getControlFlag());
146+
assertEquals("user@EXAMPLE.COM", entries[0].getOptions().get("principal"));
147+
assertEquals("true", entries[0].getOptions().get("useKeyTab"));
148+
assertEquals("/tmp/fake.keytab", entries[0].getOptions().get("keyTab"));
149+
}
150+
151+
@Test
152+
public void test14_secureClientLoginConfiguration_withPassword_returnsPwdSaverThenKerberos() {
153+
SecureClientLogin.SecureClientLoginConfiguration conf = new SecureClientLogin.SecureClientLoginConfiguration(
154+
false, "user@EXAMPLE.COM", "pwd");
155+
AppConfigurationEntry[] entries = conf.getAppConfigurationEntry("hadoop-keytab-kerberos");
156+
assertNotNull(entries);
157+
assertEquals(2, entries.length);
158+
assertEquals(KrbPasswordSaverLoginModule.class.getName(), entries[0].getLoginModuleName());
159+
assertEquals("user@EXAMPLE.COM", entries[0].getOptions().get(KrbPasswordSaverLoginModule.USERNAME_PARAM));
160+
assertEquals("pwd", entries[0].getOptions().get(KrbPasswordSaverLoginModule.PASSWORD_PARAM));
161+
assertTrue(entries[1].getLoginModuleName().contains("Krb5LoginModule"));
162+
}
163+
164+
@Test
165+
public void test15_isKerberosCredentialExists_unreadableFile_returnsFalse() throws Exception {
166+
File f = File.createTempFile("keytab", ".kt");
167+
f.deleteOnExit();
168+
try (FileWriter w = new FileWriter(f)) {
169+
w.write("dummy");
170+
}
171+
// make unreadable if possible
172+
boolean permChanged = f.setReadable(false, false);
173+
// If permission cannot be changed in this environment, skip assert to avoid
174+
// flakiness
175+
if (permChanged) {
176+
boolean valid = SecureClientLogin.isKerberosCredentialExists("user@EXAMPLE.COM", f.getAbsolutePath());
177+
assertEquals(false, valid);
178+
}
179+
}
180+
181+
@Test
182+
public void test16_isKerberosCredentialExists_emptyPrincipal_returnsFalse() throws Exception {
183+
File f = File.createTempFile("keytab", ".kt");
184+
f.deleteOnExit();
185+
try (FileWriter w = new FileWriter(f)) {
186+
w.write("dummy");
187+
}
188+
boolean valid = SecureClientLogin.isKerberosCredentialExists("", f.getAbsolutePath());
189+
assertEquals(false, valid);
190+
}
191+
192+
@Test
193+
public void test17_loginUserFromKeytab_withInvalidNameRules_throwsIllegalArgumentException() {
194+
assertThrows(IllegalArgumentException.class,
195+
() -> SecureClientLogin.loginUserFromKeytab("user@EXAMPLE.COM", "/path/not/found", "INVALID_RULES_FORMAT"));
196+
}
197+
198+
@Test
199+
public void test18_loginUserFromKeytab_twoArg_catchesLoginException() {
200+
String originalRules = "DEFAULT";
201+
String allowExampleRule = "RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*//\nDEFAULT";
202+
try {
203+
KerberosName.setRules(allowExampleRule);
204+
assertThrows(IOException.class,
205+
() -> SecureClientLogin.loginUserFromKeytab("user@EXAMPLE.COM", "/path/not/found"));
206+
} finally {
207+
KerberosName.setRules(originalRules);
208+
}
209+
}
210+
211+
@Test
212+
public void test19_loginUserFromKeytab_threeArg_catchesLoginException() {
213+
String originalRules = "DEFAULT";
214+
String allowExampleRule = "RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*//\nDEFAULT";
215+
try {
216+
assertThrows(IOException.class, () -> SecureClientLogin.loginUserFromKeytab("user@EXAMPLE.COM",
217+
"/path/not/found", allowExampleRule));
218+
} finally {
219+
KerberosName.setRules(originalRules);
220+
}
221+
}
222+
}

0 commit comments

Comments
 (0)