Skip to content

Commit fdc6a35

Browse files
committed
RANGER-5351:Test Cases for agents-cred [ranger-plugins-cred] Module
1 parent 0aef900 commit fdc6a35

File tree

5 files changed

+408
-1
lines changed

5 files changed

+408
-1
lines changed

agents-cred/pom.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,18 @@
118118
<version>${junit.jupiter.version}</version>
119119
<scope>test</scope>
120120
</dependency>
121+
<dependency>
122+
<groupId>org.mockito</groupId>
123+
<artifactId>mockito-inline</artifactId>
124+
<version>${mockito.version}</version>
125+
<scope>test</scope>
126+
</dependency>
127+
<dependency>
128+
<groupId>org.mockito</groupId>
129+
<artifactId>mockito-junit-jupiter</artifactId>
130+
<version>${mockito.version}</version>
131+
<scope>test</scope>
132+
</dependency>
121133
<dependency>
122134
<groupId>org.slf4j</groupId>
123135
<artifactId>log4j-over-slf4j</artifactId>
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+
* <p>
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
* <p>
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+
package org.apache.ranger.authorization.credutils;
19+
20+
import org.apache.http.auth.AuthScope;
21+
import org.apache.http.auth.Credentials;
22+
import org.apache.http.auth.UsernamePasswordCredentials;
23+
import org.apache.http.client.CredentialsProvider;
24+
import org.ietf.jgss.GSSCredential;
25+
import org.ietf.jgss.GSSException;
26+
import org.ietf.jgss.GSSManager;
27+
import org.ietf.jgss.GSSName;
28+
import org.ietf.jgss.Oid;
29+
import org.junit.jupiter.api.AfterEach;
30+
import org.junit.jupiter.api.BeforeEach;
31+
import org.junit.jupiter.api.MethodOrderer;
32+
import org.junit.jupiter.api.Test;
33+
import org.junit.jupiter.api.TestMethodOrder;
34+
import org.junit.jupiter.api.extension.ExtendWith;
35+
import org.mockito.MockedConstruction;
36+
import org.mockito.MockedStatic;
37+
import org.mockito.junit.jupiter.MockitoExtension;
38+
39+
import javax.security.auth.Subject;
40+
import javax.security.auth.kerberos.KerberosPrincipal;
41+
import javax.security.auth.kerberos.KerberosTicket;
42+
import javax.security.auth.login.LoginContext;
43+
import javax.security.auth.login.LoginException;
44+
45+
import java.security.AccessControlContext;
46+
import java.security.AccessController;
47+
import java.security.PrivilegedActionException;
48+
import java.security.PrivilegedExceptionAction;
49+
import java.util.Date;
50+
51+
import static org.junit.jupiter.api.Assertions.assertEquals;
52+
import static org.junit.jupiter.api.Assertions.assertFalse;
53+
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
54+
import static org.junit.jupiter.api.Assertions.assertNotNull;
55+
import static org.junit.jupiter.api.Assertions.assertNull;
56+
import static org.junit.jupiter.api.Assertions.assertSame;
57+
import static org.junit.jupiter.api.Assertions.assertThrows;
58+
import static org.junit.jupiter.api.Assertions.assertTrue;
59+
import static org.mockito.ArgumentMatchers.any;
60+
import static org.mockito.ArgumentMatchers.anyString;
61+
import static org.mockito.ArgumentMatchers.eq;
62+
import static org.mockito.Mockito.CALLS_REAL_METHODS;
63+
import static org.mockito.Mockito.doThrow;
64+
import static org.mockito.Mockito.mock;
65+
import static org.mockito.Mockito.mockConstruction;
66+
import static org.mockito.Mockito.mockStatic;
67+
import static org.mockito.Mockito.times;
68+
import static org.mockito.Mockito.verify;
69+
import static org.mockito.Mockito.when;
70+
71+
/**
72+
* @generated by Cursor
73+
* @description : Unit Test cases for CredentialsProviderUtil
74+
*/
75+
76+
@ExtendWith(MockitoExtension.class)
77+
@TestMethodOrder(MethodOrderer.MethodName.class)
78+
public class CredentialsProviderUtilTest {
79+
private MockedStatic<GSSManager> gssManagerStatic;
80+
private MockedStatic<AccessController> accessControllerStatic;
81+
82+
@BeforeEach
83+
void setup() {
84+
CredentialsProviderUtil.ticketExpireTime80 = 0L;
85+
}
86+
87+
@AfterEach
88+
void tearDown() {
89+
if (gssManagerStatic != null) {
90+
gssManagerStatic.close();
91+
}
92+
if (accessControllerStatic != null) {
93+
accessControllerStatic.close();
94+
}
95+
}
96+
97+
@Test
98+
void getBasicCredentials_setsUsernamePasswordOnAnyScope() {
99+
CredentialsProvider provider = CredentialsProviderUtil.getBasicCredentials("user", "pass");
100+
Credentials creds = provider.getCredentials(AuthScope.ANY);
101+
assertNotNull(creds);
102+
assertInstanceOf(UsernamePasswordCredentials.class, creds);
103+
UsernamePasswordCredentials upc = (UsernamePasswordCredentials) creds;
104+
assertEquals("user", upc.getUserName());
105+
assertEquals("pass", upc.getPassword());
106+
}
107+
108+
@Test
109+
void getKerberosCredentials_wrapsGssException() {
110+
GSSManager mockManager = mock(GSSManager.class);
111+
gssManagerStatic = mockStatic(GSSManager.class);
112+
gssManagerStatic.when(GSSManager::getInstance).thenReturn(mockManager);
113+
try {
114+
when(mockManager.createName(anyString(), any())).thenThrow(new GSSException(GSSException.FAILURE));
115+
} catch (GSSException e) {
116+
// ignored
117+
}
118+
RuntimeException ex = assertThrows(RuntimeException.class, () -> CredentialsProviderUtil.getKerberosCredentials("user", "pw"));
119+
assertNotNull(ex.getCause());
120+
}
121+
122+
@Test
123+
void getKerberosCredentials_wrapsPrivilegedActionException() throws Exception {
124+
GSSManager mockManager = mock(GSSManager.class);
125+
gssManagerStatic = mockStatic(GSSManager.class);
126+
gssManagerStatic.when(GSSManager::getInstance).thenReturn(mockManager);
127+
GSSName mockName = mock(GSSName.class);
128+
when(mockManager.createName(eq("[email protected]"), eq(GSSName.NT_USER_NAME))).thenReturn(mockName);
129+
when(mockManager.createCredential(eq(mockName), eq(GSSCredential.DEFAULT_LIFETIME), any(Oid.class), eq(GSSCredential.INITIATE_ONLY))).thenThrow(new GSSException(GSSException.FAILURE));
130+
131+
try (MockedStatic<CredentialsProviderUtil> cpu = mockStatic(CredentialsProviderUtil.class, CALLS_REAL_METHODS)) {
132+
Subject subject = new Subject();
133+
cpu.when(() -> CredentialsProviderUtil.login(eq("[email protected]"), eq("/tmp/keytab"))).thenReturn(subject);
134+
135+
RuntimeException ex = assertThrows(RuntimeException.class, () -> CredentialsProviderUtil.getKerberosCredentials("[email protected]", "/tmp/keytab"));
136+
assertInstanceOf(PrivilegedActionException.class, ex.getCause());
137+
}
138+
}
139+
140+
@Test
141+
void doAsPrivilegedWrapper_unwrapsNestedPrivilegedActionException() throws Exception {
142+
Subject subject = new Subject();
143+
PrivilegedActionException inner = new PrivilegedActionException(new Exception("root"));
144+
PrivilegedExceptionAction<Object> action = () -> {
145+
throw inner;
146+
};
147+
PrivilegedActionException thrown = assertThrows(PrivilegedActionException.class, () -> CredentialsProviderUtil.doAsPrivilegedWrapper(subject, action, mock(AccessControlContext.class)));
148+
assertInstanceOf(PrivilegedActionException.class, thrown.getCause());
149+
assertInstanceOf(Exception.class, thrown.getCause().getCause());
150+
assertEquals("root", thrown.getCause().getCause().getMessage());
151+
}
152+
153+
@Test
154+
void getTGT_returnsTicketMatchingTgtPattern() {
155+
Subject subject = new Subject();
156+
KerberosPrincipal client = new KerberosPrincipal("[email protected]");
157+
KerberosPrincipal server = new KerberosPrincipal("krbtgt/[email protected]");
158+
Date now = new Date();
159+
Date end = new Date(System.currentTimeMillis() + 60_000);
160+
Date renew = new Date(end.getTime() + 60_000);
161+
KerberosTicket tgt = new KerberosTicket(new byte[] {1}, client, server, new byte[] {1}, 1, null, now, now, end, renew, null);
162+
subject.getPrivateCredentials().add(tgt);
163+
164+
KerberosTicket found = CredentialsProviderUtil.getTGT(subject);
165+
assertNotNull(found);
166+
assertEquals(server, found.getServer());
167+
}
168+
169+
@Test
170+
void ticketWillExpire_computes80PercentThresholdAndResets() {
171+
KerberosPrincipal client = new KerberosPrincipal("[email protected]");
172+
KerberosPrincipal server = new KerberosPrincipal("krbtgt/[email protected]");
173+
Date start = new Date(System.currentTimeMillis() - 1000);
174+
Date end = new Date(System.currentTimeMillis() + 10_000);
175+
Date renew = new Date(end.getTime() + 10_000);
176+
KerberosTicket ticket = new KerberosTicket(new byte[] {1}, client, server, new byte[] {1}, 1, null, start, start, end, renew, null);
177+
178+
Boolean first = CredentialsProviderUtil.ticketWillExpire(ticket);
179+
assertFalse(first);
180+
CredentialsProviderUtil.ticketExpireTime80 = System.currentTimeMillis() - 1;
181+
Boolean second = CredentialsProviderUtil.ticketWillExpire(ticket);
182+
assertTrue(second);
183+
assertEquals(0L, CredentialsProviderUtil.ticketExpireTime80);
184+
}
185+
186+
@Test
187+
void getTGT_returnsNullWhenNoTgt() {
188+
Subject subject = new Subject();
189+
KerberosPrincipal client = new KerberosPrincipal("[email protected]");
190+
KerberosPrincipal server = new KerberosPrincipal("HTTP/[email protected]");
191+
Date now = new Date();
192+
Date end = new Date(System.currentTimeMillis() + 60_000);
193+
Date renew = new Date(end.getTime() + 60_000);
194+
KerberosTicket notTgt = new KerberosTicket(new byte[] {1}, client, server, new byte[] {1}, 1, null, now, now, end, renew, null);
195+
subject.getPrivateCredentials().add(notTgt);
196+
197+
assertNull(CredentialsProviderUtil.getTGT(subject));
198+
}
199+
200+
@Test
201+
void login_success_returnsSubjectFromLoginContext() throws Exception {
202+
Subject subject = new Subject();
203+
try (MockedConstruction<LoginContext> mocked = mockConstruction(LoginContext.class, (mock, context) -> {
204+
when(mock.getSubject()).thenReturn(subject);
205+
})) {
206+
Subject out = CredentialsProviderUtil.login("[email protected]", "/tmp/user.keytab");
207+
assertSame(subject, out);
208+
verify(mocked.constructed().get(0), times(1)).login();
209+
}
210+
}
211+
212+
@Test
213+
void login_throwsPrivilegedActionException_whenLoginContextFails() throws Exception {
214+
try (MockedConstruction<LoginContext> mocked = mockConstruction(LoginContext.class, (mock, context) -> {
215+
doThrow(new LoginException("boom")).when(mock).login();
216+
})) {
217+
PrivilegedActionException pae = assertThrows(PrivilegedActionException.class, () -> CredentialsProviderUtil.login("[email protected]", "/tmp/user.keytab"));
218+
assertTrue(pae.getException() instanceof LoginException);
219+
assertEquals("boom", pae.getException().getMessage());
220+
}
221+
}
222+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
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,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.ranger.authorization.credutils.kerberos;
20+
21+
import org.apache.http.auth.AuthScope;
22+
import org.apache.http.auth.Credentials;
23+
import org.apache.http.client.config.AuthSchemes;
24+
import org.junit.jupiter.api.MethodOrderer;
25+
import org.junit.jupiter.api.Test;
26+
import org.junit.jupiter.api.TestMethodOrder;
27+
import org.junit.jupiter.api.extension.ExtendWith;
28+
import org.mockito.junit.jupiter.MockitoExtension;
29+
30+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
31+
import static org.junit.jupiter.api.Assertions.assertNotNull;
32+
import static org.junit.jupiter.api.Assertions.assertNull;
33+
import static org.junit.jupiter.api.Assertions.assertSame;
34+
import static org.junit.jupiter.api.Assertions.assertThrows;
35+
import static org.junit.jupiter.api.Assertions.assertTrue;
36+
import static org.mockito.Mockito.mock;
37+
38+
/**
39+
* @generated by Cursor
40+
* @description : Unit Test cases for KerberosCredentialsProvider
41+
*/
42+
43+
@ExtendWith(MockitoExtension.class)
44+
@TestMethodOrder(MethodOrderer.MethodName.class)
45+
public class KerberosCredentialsProviderTest {
46+
@Test
47+
public void setCredentials_acceptsOnlySpnego() {
48+
KerberosCredentialsProvider provider = new KerberosCredentialsProvider();
49+
Credentials creds = mock(Credentials.class);
50+
51+
AuthScope spnego = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, AuthSchemes.SPNEGO);
52+
assertDoesNotThrow(() -> provider.setCredentials(spnego, creds));
53+
54+
AuthScope basic = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, AuthSchemes.BASIC);
55+
IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> provider.setCredentials(basic, creds));
56+
assertTrue(ex.getMessage().contains(AuthSchemes.SPNEGO));
57+
}
58+
59+
@Test
60+
public void getCredentials_matchesOnScope_andReturnsNullWhenNoMatch() {
61+
KerberosCredentialsProvider provider = new KerberosCredentialsProvider();
62+
Credentials creds = mock(Credentials.class);
63+
AuthScope setScope = new AuthScope("host", 8080, AuthScope.ANY_REALM, AuthSchemes.SPNEGO);
64+
provider.setCredentials(setScope, creds);
65+
66+
// exact match
67+
assertSame(creds, provider.getCredentials(new AuthScope("host", 8080, AuthScope.ANY_REALM, AuthSchemes.SPNEGO)));
68+
// partial match with ANY_HOST/ANY_PORT should still match
69+
assertSame(creds, provider.getCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, AuthSchemes.SPNEGO)));
70+
// different scheme should not match
71+
assertNull(provider.getCredentials(new AuthScope("host", 8080, AuthScope.ANY_REALM, AuthSchemes.BASIC)));
72+
// null arg returns null
73+
assertNull(provider.getCredentials(null));
74+
}
75+
76+
@Test
77+
public void clear_resetsState() {
78+
KerberosCredentialsProvider provider = new KerberosCredentialsProvider();
79+
Credentials creds = mock(Credentials.class);
80+
provider.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, AuthSchemes.SPNEGO), creds);
81+
82+
assertNotNull(provider.getCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, AuthSchemes.SPNEGO)));
83+
provider.clear();
84+
assertNull(provider.getCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, AuthSchemes.SPNEGO)));
85+
}
86+
}

0 commit comments

Comments
 (0)