blob: 2196ad19e5c8710cfa3aff7f962fad3853f689e3 [file] [log] [blame]
/**
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.falcon.security;
import org.apache.falcon.FalconException;
import org.apache.falcon.cluster.util.EntityBuilderTestUtil;
import org.apache.falcon.entity.EntityNotRegisteredException;
import org.apache.falcon.entity.Storage;
import org.apache.falcon.entity.store.ConfigurationStore;
import org.apache.falcon.entity.v0.EntityType;
import org.apache.falcon.entity.v0.cluster.Cluster;
import org.apache.falcon.entity.v0.feed.CatalogTable;
import org.apache.falcon.entity.v0.feed.Feed;
import org.apache.falcon.entity.v0.feed.Location;
import org.apache.falcon.entity.v0.feed.LocationType;
import org.apache.falcon.entity.v0.feed.Locations;
import org.apache.falcon.util.FalconTestUtil;
import org.apache.falcon.util.StartupProperties;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.authorize.AuthorizationException;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.Collection;
/**
* Unit tests for DefaultAuthorizationProvider.
*/
public class DefaultAuthorizationProviderTest {
public static final String CLUSTER_ENTITY_NAME = "primary-cluster";
public static final String PROCESS_ENTITY_NAME = "sample-process";
private UserGroupInformation realUser;
private ConfigurationStore configStore;
private Cluster clusterEntity;
private Feed feedEntity;
private org.apache.falcon.entity.v0.process.Process processEntity;
@BeforeClass
public void setUp() throws Exception {
realUser = UserGroupInformation.createUserForTesting(FalconTestUtil.TEST_USER_1, new String[]{"falcon", });
CurrentUser.authenticate(EntityBuilderTestUtil.USER);
org.testng.Assert.assertEquals(CurrentUser.getUser(), EntityBuilderTestUtil.USER);
configStore = ConfigurationStore.get();
addClusterEntity();
addFeedEntity();
addProcessEntity();
org.testng.Assert.assertNotNull(processEntity);
}
public void addClusterEntity() throws Exception {
clusterEntity = EntityBuilderTestUtil.buildCluster(CLUSTER_ENTITY_NAME);
configStore.publish(EntityType.CLUSTER, clusterEntity);
}
public void addFeedEntity() throws Exception {
feedEntity = EntityBuilderTestUtil.buildFeed("sample-feed", clusterEntity,
"classified-as=Secure", "analytics");
addStorage(feedEntity, Storage.TYPE.FILESYSTEM, "/falcon/impression-feed/${YEAR}/${MONTH}/${DAY}");
configStore.publish(EntityType.FEED, feedEntity);
}
private static void addStorage(Feed feed, Storage.TYPE storageType, String uriTemplate) {
if (storageType == Storage.TYPE.FILESYSTEM) {
Locations locations = new Locations();
feed.setLocations(locations);
Location location = new Location();
location.setType(LocationType.DATA);
location.setPath(uriTemplate);
feed.getLocations().getLocations().add(location);
} else {
CatalogTable table = new CatalogTable();
table.setUri(uriTemplate);
feed.setTable(table);
}
}
public void addProcessEntity() throws Exception {
processEntity = EntityBuilderTestUtil.buildProcess(PROCESS_ENTITY_NAME,
clusterEntity, "classified-as=Critical");
EntityBuilderTestUtil.addProcessWorkflow(processEntity);
EntityBuilderTestUtil.addProcessACL(processEntity);
configStore.publish(EntityType.PROCESS, processEntity);
}
@AfterClass
public void tearDown() throws Exception {
cleanupStore();
}
protected void cleanupStore() throws FalconException {
configStore = ConfigurationStore.get();
for (EntityType type : EntityType.values()) {
Collection<String> entities = configStore.getEntities(type);
for (String entity : entities) {
configStore.remove(type, entity);
}
}
}
@Test
public void testAuthorizeAdminResourceVersionAction() throws Exception {
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
"blah", realUser, new String[]{"blah-group", });
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeResource("admin", "version", null, null, proxyUgi);
}
@Test
public void testAuthorizeSuperUser() throws Exception {
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
EntityBuilderTestUtil.USER, realUser, new String[]{"group", });
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeResource("entities", "schedule", "feed", feedEntity.getName(), proxyUgi);
provider.authorizeResource("instance", "status", "feed", feedEntity.getName(), proxyUgi);
}
@Test
public void testAuthorizeSuperUserGroup() throws Exception {
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
"blah", realUser, new String[]{"falcon", });
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeResource("entities", "schedule", "feed", feedEntity.getName(), proxyUgi);
provider.authorizeResource("instance", "status", "feed", feedEntity.getName(), proxyUgi);
}
@DataProvider(name = "adminResourceActions")
private Object[][] createAdminResourceActions() {
return new Object[][] {
{"version"},
{"stack"},
{"config"},
};
}
@Test (dataProvider = "adminResourceActions")
public void testAuthorizeAdminResourceAdmin(String action) throws Exception {
StartupProperties.get().setProperty("falcon.security.authorization.admin.users", "admin");
StartupProperties.get().setProperty("falcon.security.authorization.admin.groups", "admin");
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
"admin", realUser, new String[]{"admin", });
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeResource("admin", action, null, null, proxyUgi);
}
@Test
public void testAuthorizeAdminResourceAdminUserBadGroup() throws Exception {
StartupProperties.get().setProperty("falcon.security.authorization.admin.users", "admin");
StartupProperties.get().setProperty("falcon.security.authorization.admin.groups", "admin");
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
"admin", realUser, new String[]{"admin-group", });
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeResource("admin", "version", null, null, proxyUgi);
}
@Test
public void testAuthorizeAdminResourceAdminGroupBadUser() throws Exception {
StartupProperties.get().setProperty("falcon.security.authorization.admin.users", "admin");
StartupProperties.get().setProperty(
"falcon.security.authorization.admin.groups", "admin-group");
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
"admin-user", realUser, new String[]{"admin-group", });
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeResource("admin", "version", null, null, proxyUgi);
}
@Test (expectedExceptions = AuthorizationException.class)
public void testAuthorizeAdminResourceInvalidUserAndGroup() throws Exception {
StartupProperties.get().setProperty("falcon.security.authorization.admin.groups", "admin");
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
"admin-user", realUser, new String[]{"admin-group", });
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeResource("admin", "stack", null, null, proxyUgi);
Assert.fail("User does not belong to both admin-users not groups");
}
@DataProvider(name = "entityResourceActions")
private Object[][] createEntityResourceActions() {
return new Object[][] {
{"entities", "list", "feed"},
{"entities", "list", "process"},
{"entities", "list", "cluster"},
};
}
@Test (dataProvider = "entityResourceActions")
public void testAuthorizeEntitiesInstancesReadOnlyResource(String resource,
String action,
String entityType) throws Exception {
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
"admin-user", realUser, new String[]{"admin-group", });
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeResource(resource, action, entityType, null, proxyUgi);
}
@DataProvider(name = "entityLifecycleResourceActions")
private Object[][] createEntityLifecycleResourceActions() {
return new Object[][] {
{"entities", "status", "cluster", "primary-cluster"},
{"entities", "status", "process", "sample-process"},
{"entities", "status", "feed", "sample-feed"},
{"instance", "status", "process", "sample-process"},
{"instance", "running", "process", "sample-process"},
{"instance", "running", "feed", "sample-feed"},
};
}
@Test(dataProvider = "entityLifecycleResourceActions")
public void testAuthorizeEntitiesInstancesLifecycleResource(String resource, String action,
String entityType,
String entityName) throws Exception {
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
EntityBuilderTestUtil.USER, realUser, new String[]{EntityBuilderTestUtil.USER, });
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeResource(resource, action, entityType, entityName, proxyUgi);
}
@Test(dataProvider = "entityLifecycleResourceActions",
expectedExceptions = AuthorizationException.class)
public void testAuthorizeEntitiesInstancesLifecycleResourceBadUGI(String resource,
String action,
String entityType,
String entityName)
throws Exception {
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
"admin-user", realUser, new String[]{"admin-group", });
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeResource(resource, action, entityType, entityName, proxyUgi);
}
@Test (expectedExceptions = IllegalArgumentException.class)
public void testAuthorizeBadResource() throws Exception {
StartupProperties.get().setProperty("falcon.security.authorization.admin.users", "admin");
StartupProperties.get().setProperty("falcon.security.authorization.admin.groups", "admin");
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
"admin", realUser, new String[]{"admin", });
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeResource("invalid", "version", null, null, proxyUgi);
Assert.fail("Bad resource");
}
@Test (expectedExceptions = IllegalArgumentException.class)
public void testAuthorizeNullResource() throws Exception {
StartupProperties.get().setProperty("falcon.security.authorization.admin.users", "admin");
StartupProperties.get().setProperty("falcon.security.authorization.admin.groups", "admin");
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
"admin", realUser, new String[]{"admin", });
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeResource(null, "version", null, null, proxyUgi);
Assert.fail("Bad resource");
}
@Test (expectedExceptions = IllegalArgumentException.class)
public void testAuthorizeBadAction() throws Exception {
StartupProperties.get().setProperty("falcon.security.authorization.admin.users", "admin");
StartupProperties.get().setProperty("falcon.security.authorization.admin.groups", "admin");
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
"admin", realUser, new String[]{"admin", });
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeResource("entities", null, "feedz", null, proxyUgi);
Assert.fail("Bad action");
}
@Test (expectedExceptions = IllegalArgumentException.class)
public void testAuthorizeNullEntityType() throws Exception {
StartupProperties.get().setProperty("falcon.security.authorization.admin.users", "admin");
StartupProperties.get().setProperty("falcon.security.authorization.admin.groups", "admin");
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
"admin", realUser, new String[]{"admin", });
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeResource("instance", "list", null, "sample-process", proxyUgi);
Assert.fail("Bad entity type");
}
@Test (expectedExceptions = IllegalArgumentException.class)
public void testAuthorizeBadEntityType() throws Exception {
StartupProperties.get().setProperty("falcon.security.authorization.admin.users", "admin");
StartupProperties.get().setProperty("falcon.security.authorization.admin.groups", "admin");
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
"admin", realUser, new String[]{"admin", });
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeResource("instance", "list", "processz", "sample-process", proxyUgi);
Assert.fail("Bad entity type");
}
@Test
public void testAuthorizeValidatePOSTOperations() throws Exception {
StartupProperties.get().setProperty("falcon.security.authorization.admin.users", "admin");
StartupProperties.get().setProperty("falcon.security.authorization.admin.groups", "admin");
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
"admin", realUser, new String[]{"admin", });
EntityBuilderTestUtil.addProcessACL(processEntity, "admin", "admin");
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeEntity(processEntity.getName(), "process",
processEntity.getACL(), "submit", proxyUgi);
}
@Test (expectedExceptions = EntityNotRegisteredException.class)
public void testAuthorizeResourceOperationsBadEntity() throws Exception {
StartupProperties.get().setProperty("falcon.security.authorization.admin.users", "admin");
StartupProperties.get().setProperty("falcon.security.authorization.admin.groups", "admin");
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
"admin", realUser, new String[]{"admin", });
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeResource("entities", "status", "process", feedEntity.getName(), proxyUgi);
Assert.fail("Bad entity");
}
@Test
public void testAuthorizeValidatePOSTOperationsGroupBadUser() throws Exception {
StartupProperties.get().setProperty("falcon.security.authorization.enabled", "true");
StartupProperties.get().setProperty("falcon.security.authorization.admin.users", "admin");
StartupProperties.get().setProperty("falcon.security.authorization.admin.groups", "admin");
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
"admin", realUser, new String[]{"admin", });
EntityBuilderTestUtil.addProcessACL(processEntity, "admin-user", "admin");
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeEntity(processEntity.getName(), "process",
processEntity.getACL(), "submit", proxyUgi);
}
@Test (expectedExceptions = AuthorizationException.class)
public void testAuthorizeValidatePOSTOperationsBadUserAndGroup() throws Exception {
StartupProperties.get().setProperty("falcon.security.authorization.enabled", "true");
StartupProperties.get().setProperty("falcon.security.authorization.admin.users", "admin");
StartupProperties.get().setProperty("falcon.security.authorization.admin.groups", "admin");
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
"admin", realUser, new String[]{"admin", });
EntityBuilderTestUtil.addProcessACL(processEntity, "admin-user", "admin-group");
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeEntity(processEntity.getName(), "process",
processEntity.getACL(), "submit", proxyUgi);
}
@Test
public void testAuthorizeLineageResource() throws Exception {
StartupProperties.get().setProperty("falcon.security.authorization.admin.users", "admin");
StartupProperties.get().setProperty("falcon.security.authorization.admin.groups", "admin");
UserGroupInformation proxyUgi = UserGroupInformation.createProxyUserForTesting(
"admin", realUser, new String[]{"admin", });
DefaultAuthorizationProvider provider = new DefaultAuthorizationProvider();
provider.authorizeResource("metadata", "lineage", null, null, proxyUgi);
}
}