TestTimelineReaderWebServicesBasicAcl.java
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.yarn.server.timelineservice.reader;
import java.util.LinkedHashSet;
import java.util.Set;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.yarn.api.records.timelineservice.TimelineEntity;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.webapp.ForbiddenException;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
public class TestTimelineReaderWebServicesBasicAcl {
private TimelineReaderManager manager;
private static String adminUser = "admin";
private static UserGroupInformation adminUgi =
UserGroupInformation.createRemoteUser(adminUser);
private Configuration config;
@BeforeEach public void setUp() throws Exception {
config = new YarnConfiguration();
}
@AfterEach public void tearDown() throws Exception {
if (manager != null) {
manager.stop();
manager = null;
}
config = null;
}
@Test
void testTimelineReaderManagerAclsWhenDisabled()
throws Exception {
config.setBoolean(YarnConfiguration.YARN_ACL_ENABLE, false);
config.set(YarnConfiguration.YARN_ADMIN_ACL, adminUser);
manager = new TimelineReaderManager(null);
manager.init(config);
manager.start();
// when acls are disabled, always return true
assertTrue(manager.checkAccess(null));
// filter is disabled, so should return false
assertFalse(
TimelineReaderWebServices.isDisplayEntityPerUserFilterEnabled(config));
}
@Test
void testTimelineReaderManagerAclsWhenEnabled()
throws Exception {
Configuration config = new YarnConfiguration();
config.setBoolean(YarnConfiguration.YARN_ACL_ENABLE, true);
config.setBoolean(YarnConfiguration.FILTER_ENTITY_LIST_BY_USER, true);
config.set(YarnConfiguration.YARN_ADMIN_ACL, adminUser);
manager = new TimelineReaderManager(null);
manager.init(config);
manager.start();
String user1 = "user1";
String user2 = "user2";
UserGroupInformation user1Ugi =
UserGroupInformation.createRemoteUser(user1);
UserGroupInformation user2Ugi =
UserGroupInformation.createRemoteUser(user2);
// false because ugi is null
assertFalse(TimelineReaderWebServices
.validateAuthUserWithEntityUser(manager, null, user1));
// false because ugi is null in non-secure cluster. User must pass
// ?user.name as query params in REST end points.
try {
TimelineReaderWebServices.checkAccess(manager, null, user1);
fail("user1Ugi is not allowed to view user1");
} catch (ForbiddenException e) {
// expected
}
// incoming ugi is admin asking for entity owner user1
assertTrue(
TimelineReaderWebServices.checkAccess(manager, adminUgi, user1));
// incoming ugi is admin asking for entity owner user1
assertTrue(
TimelineReaderWebServices.checkAccess(manager, adminUgi, user2));
// incoming ugi is non-admin i.e user1Ugi asking for entity owner user2
try {
TimelineReaderWebServices.checkAccess(manager, user1Ugi, user2);
fail("user1Ugi is not allowed to view user2");
} catch (ForbiddenException e) {
// expected
}
// incoming ugi is non-admin i.e user2Ugi asking for entity owner user1
try {
TimelineReaderWebServices.checkAccess(manager, user1Ugi, user2);
fail("user2Ugi is not allowed to view user1");
} catch (ForbiddenException e) {
// expected
}
String userKey = "user";
// incoming ugi is admin asking for entities
Set<TimelineEntity> entities = createEntities(10, userKey);
TimelineReaderWebServices
.checkAccess(manager, adminUgi, entities, userKey, true);
// admin is allowed to view other entities
assertEquals(10, entities.size());
// incoming ugi is user1Ugi asking for entities
// only user1 entities are allowed to view
entities = createEntities(5, userKey);
TimelineReaderWebServices
.checkAccess(manager, user1Ugi, entities, userKey, true);
assertEquals(1, entities.size());
assertEquals(user1, entities.iterator().next().getInfo().get(userKey));
// incoming ugi is user2Ugi asking for entities
// only user2 entities are allowed to view
entities = createEntities(8, userKey);
TimelineReaderWebServices
.checkAccess(manager, user2Ugi, entities, userKey, true);
assertEquals(1, entities.size());
assertEquals(user2, entities.iterator().next().getInfo().get(userKey));
}
Set<TimelineEntity> createEntities(int noOfUsers, String userKey) {
Set<TimelineEntity> entities = new LinkedHashSet<>();
for (int i = 0; i < noOfUsers; i++) {
TimelineEntity e = new TimelineEntity();
e.setType("user" + i);
e.setId("user" + i);
e.getInfo().put(userKey, "user" + i);
entities.add(e);
}
return entities;
}
}