Skip to content

Commit 3c95ca4

Browse files
author
Vrushali C
committed
YARN-8247 Incorrect HTTP status code returned by ATSv2 for non-whitelisted users. Contributed by Rohith Sharma K S
1 parent cc0310a commit 3c95ca4

File tree

2 files changed

+44
-28
lines changed

2 files changed

+44
-28
lines changed

hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice/src/main/java/org/apache/hadoop/yarn/server/timelineservice/reader/security/TimelineReaderWhitelistAuthorizationFilter.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,13 @@
2727
import javax.servlet.ServletRequest;
2828
import javax.servlet.ServletResponse;
2929
import javax.servlet.http.HttpServletRequest;
30-
import javax.ws.rs.core.Response;
31-
import javax.ws.rs.core.Response.Status;
30+
import javax.servlet.http.HttpServletResponse;
3231

3332
import org.apache.commons.lang3.StringUtils;
3433
import org.apache.hadoop.security.UserGroupInformation;
3534
import org.apache.hadoop.security.authorize.AccessControlList;
3635
import org.apache.hadoop.security.authorize.AuthorizationException;
3736
import org.apache.hadoop.yarn.conf.YarnConfiguration;
38-
import org.apache.hadoop.yarn.webapp.ForbiddenException;
3937
import org.slf4j.Logger;
4038
import org.slf4j.LoggerFactory;
4139
import org.apache.hadoop.yarn.server.timelineservice.reader.TimelineReaderWebServicesUtils;
@@ -64,9 +62,12 @@ public void destroy() {
6462
@Override
6563
public void doFilter(ServletRequest request, ServletResponse response,
6664
FilterChain chain) throws IOException, ServletException {
65+
HttpServletRequest httpRequest = (HttpServletRequest) request;
66+
HttpServletResponse httpResponse = (HttpServletResponse) response;
67+
6768
if (isWhitelistReadAuthEnabled) {
6869
UserGroupInformation callerUGI = TimelineReaderWebServicesUtils
69-
.getCallerUserGroupInformation((HttpServletRequest) request, true);
70+
.getCallerUserGroupInformation(httpRequest, true);
7071
if (callerUGI == null) {
7172
String msg = "Unable to obtain user name, user not authenticated";
7273
throw new AuthorizationException(msg);
@@ -76,9 +77,8 @@ public void doFilter(ServletRequest request, ServletResponse response,
7677
String userName = callerUGI.getShortUserName();
7778
String msg = "User " + userName
7879
+ " is not allowed to read TimelineService V2 data.";
79-
Response.status(Status.FORBIDDEN).entity(msg).build();
80-
throw new ForbiddenException("user " + userName
81-
+ " is not allowed to read TimelineService V2 data");
80+
httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, msg);
81+
return;
8282
}
8383
}
8484
if (chain != null) {

hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice/src/test/java/org/apache/hadoop/yarn/server/timelineservice/reader/TestTimelineReaderWhitelistAuthorizationFilter.java

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
package org.apache.hadoop.yarn.server.timelineservice.reader;
2020

21+
import static org.mockito.Matchers.eq;
2122
import static org.mockito.Mockito.mock;
2223
import static org.mockito.Mockito.when;
2324

@@ -32,13 +33,12 @@
3233
import javax.servlet.FilterConfig;
3334
import javax.servlet.ServletContext;
3435
import javax.servlet.ServletException;
35-
import javax.servlet.ServletResponse;
3636
import javax.servlet.http.HttpServletRequest;
37+
import javax.servlet.http.HttpServletResponse;
3738

3839
import org.apache.hadoop.security.UserGroupInformation;
3940
import org.apache.hadoop.yarn.conf.YarnConfiguration;
4041
import org.apache.hadoop.yarn.server.timelineservice.reader.security.TimelineReaderWhitelistAuthorizationFilter;
41-
import org.apache.hadoop.yarn.webapp.ForbiddenException;
4242
import org.junit.Test;
4343
import org.mockito.Mockito;
4444

@@ -100,11 +100,11 @@ public String getName() {
100100
}
101101
});
102102

103-
ServletResponse r = Mockito.mock(ServletResponse.class);
103+
HttpServletResponse r = Mockito.mock(HttpServletResponse.class);
104104
f.doFilter(mockHsr, r, null);
105105
}
106106

107-
@Test(expected = ForbiddenException.class)
107+
@Test
108108
public void checkFilterNotAllowedUser() throws ServletException, IOException {
109109
Map<String, String> map = new HashMap<String, String>();
110110
map.put(YarnConfiguration.TIMELINE_SERVICE_READ_AUTH_ENABLED, "true");
@@ -115,14 +115,20 @@ public void checkFilterNotAllowedUser() throws ServletException, IOException {
115115
FilterConfig fc = new DummyFilterConfig(map);
116116
f.init(fc);
117117
HttpServletRequest mockHsr = Mockito.mock(HttpServletRequest.class);
118+
String userName = "testuser1";
118119
Mockito.when(mockHsr.getUserPrincipal()).thenReturn(new Principal() {
119120
@Override
120121
public String getName() {
121-
return "testuser1";
122+
return userName;
122123
}
123124
});
124-
ServletResponse r = Mockito.mock(ServletResponse.class);
125+
HttpServletResponse r = Mockito.mock(HttpServletResponse.class);
125126
f.doFilter(mockHsr, r, null);
127+
128+
String msg = "User " + userName
129+
+ " is not allowed to read TimelineService V2 data.";
130+
Mockito.verify(r)
131+
.sendError(eq(HttpServletResponse.SC_FORBIDDEN), eq(msg));
126132
}
127133

128134
@Test
@@ -143,7 +149,7 @@ public String getName() {
143149
return "user1";
144150
}
145151
});
146-
ServletResponse r = Mockito.mock(ServletResponse.class);
152+
HttpServletResponse r = Mockito.mock(HttpServletResponse.class);
147153
UserGroupInformation user1 =
148154
UserGroupInformation.createUserForTesting("user1", GROUP_NAMES);
149155
user1.doAs(new PrivilegedExceptionAction<Object>() {
@@ -155,7 +161,7 @@ public Object run() throws Exception {
155161
});
156162
}
157163

158-
@Test(expected = ForbiddenException.class)
164+
@Test
159165
public void checkFilterNotAlloweGroup()
160166
throws ServletException, IOException, InterruptedException {
161167
Map<String, String> map = new HashMap<String, String>();
@@ -167,22 +173,27 @@ public void checkFilterNotAlloweGroup()
167173
FilterConfig fc = new DummyFilterConfig(map);
168174
f.init(fc);
169175
HttpServletRequest mockHsr = Mockito.mock(HttpServletRequest.class);
176+
String userName = "user200";
170177
Mockito.when(mockHsr.getUserPrincipal()).thenReturn(new Principal() {
171178
@Override
172179
public String getName() {
173-
return "user200";
180+
return userName;
174181
}
175182
});
176-
ServletResponse r = Mockito.mock(ServletResponse.class);
183+
HttpServletResponse r = Mockito.mock(HttpServletResponse.class);
177184
UserGroupInformation user1 =
178-
UserGroupInformation.createUserForTesting("user200", GROUP_NAMES);
185+
UserGroupInformation.createUserForTesting(userName, GROUP_NAMES);
179186
user1.doAs(new PrivilegedExceptionAction<Object>() {
180187
@Override
181188
public Object run() throws Exception {
182189
f.doFilter(mockHsr, r, null);
183190
return null;
184191
}
185192
});
193+
String msg = "User " + userName
194+
+ " is not allowed to read TimelineService V2 data.";
195+
Mockito.verify(r)
196+
.sendError(eq(HttpServletResponse.SC_FORBIDDEN), eq(msg));
186197
}
187198

188199
@Test
@@ -205,7 +216,7 @@ public String getName() {
205216
return "user90";
206217
}
207218
});
208-
ServletResponse r = Mockito.mock(ServletResponse.class);
219+
HttpServletResponse r = Mockito.mock(HttpServletResponse.class);
209220
UserGroupInformation user1 =
210221
UserGroupInformation.createUserForTesting("user90", GROUP_NAMES);
211222
user1.doAs(new PrivilegedExceptionAction<Object>() {
@@ -235,7 +246,7 @@ public String getName() {
235246
return "user90";
236247
}
237248
});
238-
ServletResponse r = Mockito.mock(ServletResponse.class);
249+
HttpServletResponse r = Mockito.mock(HttpServletResponse.class);
239250
UserGroupInformation user1 =
240251
UserGroupInformation.createUserForTesting("user90", GROUP_NAMES);
241252
user1.doAs(new PrivilegedExceptionAction<Object>() {
@@ -247,7 +258,7 @@ public Object run() throws Exception {
247258
});
248259
}
249260

250-
@Test(expected = ForbiddenException.class)
261+
@Test
251262
public void checkFilterAllowNoOneWhenAdminAclsEmptyAndUserAclsEmpty()
252263
throws ServletException, IOException, InterruptedException {
253264
// check that users in admin acl list are allowed to read
@@ -258,22 +269,27 @@ public void checkFilterAllowNoOneWhenAdminAclsEmptyAndUserAclsEmpty()
258269
FilterConfig fc = new DummyFilterConfig(map);
259270
f.init(fc);
260271
HttpServletRequest mockHsr = Mockito.mock(HttpServletRequest.class);
272+
String userName = "user88";
261273
Mockito.when(mockHsr.getUserPrincipal()).thenReturn(new Principal() {
262274
@Override
263275
public String getName() {
264-
return "user88";
276+
return userName;
265277
}
266278
});
267-
ServletResponse r = Mockito.mock(ServletResponse.class);
279+
HttpServletResponse r = Mockito.mock(HttpServletResponse.class);
268280
UserGroupInformation user1 =
269-
UserGroupInformation.createUserForTesting("user88", GROUP_NAMES);
281+
UserGroupInformation.createUserForTesting(userName, GROUP_NAMES);
270282
user1.doAs(new PrivilegedExceptionAction<Object>() {
271283
@Override
272284
public Object run() throws Exception {
273285
f.doFilter(mockHsr, r, null);
274286
return null;
275287
}
276288
});
289+
String msg = "User " + userName
290+
+ " is not allowed to read TimelineService V2 data.";
291+
Mockito.verify(r)
292+
.sendError(eq(HttpServletResponse.SC_FORBIDDEN), eq(msg));
277293
}
278294

279295
@Test
@@ -293,7 +309,7 @@ public String getName() {
293309
return "user437";
294310
}
295311
});
296-
ServletResponse r = Mockito.mock(ServletResponse.class);
312+
HttpServletResponse r = Mockito.mock(HttpServletResponse.class);
297313
UserGroupInformation user1 =
298314
UserGroupInformation.createUserForTesting("user437", GROUP_NAMES);
299315
user1.doAs(new PrivilegedExceptionAction<Object>() {
@@ -327,7 +343,7 @@ public String getName() {
327343
}
328344
});
329345

330-
ServletResponse r = Mockito.mock(ServletResponse.class);
346+
HttpServletResponse r = Mockito.mock(HttpServletResponse.class);
331347
UserGroupInformation user1 =
332348
// both username and group name are not part of admin and
333349
// read allowed users
@@ -348,7 +364,7 @@ public String getName() {
348364
return "user27";
349365
}
350366
});
351-
ServletResponse r2 = Mockito.mock(ServletResponse.class);
367+
HttpServletResponse r2 = Mockito.mock(HttpServletResponse.class);
352368
UserGroupInformation user2 =
353369
UserGroupInformation.createUserForTesting("user27", GROUP_NAMES);
354370
user2.doAs(new PrivilegedExceptionAction<Object>() {
@@ -366,7 +382,7 @@ public String getName() {
366382
return "user2";
367383
}
368384
});
369-
ServletResponse r3 = Mockito.mock(ServletResponse.class);
385+
HttpServletResponse r3 = Mockito.mock(HttpServletResponse.class);
370386
UserGroupInformation user3 =
371387
UserGroupInformation.createUserForTesting("user2", GROUP_NAMES);
372388
user3.doAs(new PrivilegedExceptionAction<Object>() {

0 commit comments

Comments
 (0)