Repository: oozie Updated Branches: refs/heads/master 648009e35 -> 6a3764f81
OOZIE-3217 Enable definition of admin users using oozie-site.xml (orova via andras.piros) Project: http://git-wip-us.apache.org/repos/asf/oozie/repo Commit: http://git-wip-us.apache.org/repos/asf/oozie/commit/6a3764f8 Tree: http://git-wip-us.apache.org/repos/asf/oozie/tree/6a3764f8 Diff: http://git-wip-us.apache.org/repos/asf/oozie/diff/6a3764f8 Branch: refs/heads/master Commit: 6a3764f817eb27b9a4d768f4453f7663f38004fa Parents: 648009e Author: Andras Piros <andras.pi...@cloudera.com> Authored: Wed May 16 10:50:07 2018 +0200 Committer: Andras Piros <andras.pi...@cloudera.com> Committed: Wed May 16 10:50:07 2018 +0200 ---------------------------------------------------------------------- .../oozie/service/AuthorizationService.java | 37 ++++++++++--- core/src/main/resources/oozie-default.xml | 8 +++ .../oozie/service/TestAuthorizationService.java | 58 ++++++++++++++------ .../java/org/apache/oozie/test/XTestCase.java | 14 +++++ docs/src/site/twiki/AG_Install.twiki | 12 +++- release-log.txt | 1 + 6 files changed, 105 insertions(+), 25 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/oozie/blob/6a3764f8/core/src/main/java/org/apache/oozie/service/AuthorizationService.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/oozie/service/AuthorizationService.java b/core/src/main/java/org/apache/oozie/service/AuthorizationService.java index 33fd9c3..251838c 100644 --- a/core/src/main/java/org/apache/oozie/service/AuthorizationService.java +++ b/core/src/main/java/org/apache/oozie/service/AuthorizationService.java @@ -25,12 +25,15 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.net.URI; +import java.nio.charset.StandardCharsets; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.ArrayList; import java.util.Set; - +import java.util.LinkedHashSet; +import com.google.common.collect.Sets; +import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang.StringUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; @@ -82,6 +85,11 @@ public class AuthorizationService implements Service { public static final String CONF_SYSTEM_INFO_AUTHORIZED_USERS = CONF_PREFIX + "system.info.authorized.users"; + /** + * Configuration parameter to define admin users in oozie-site.xml. + * These admin users shall be added to the admin users found in adminusers.txt + */ + public static final String CONF_ADMIN_USERS = CONF_PREFIX + "admin.users"; /** * File that contains list of admin users for Oozie. @@ -140,7 +148,8 @@ public class AuthorizationService implements Service { else { log.info("Admin users will be checked against the 'adminusers.txt' file contents"); adminUsers = new HashSet<String>(); - loadAdminUsers(); + loadAdminUsersFromFile(); + loadAdminUsersFromConfiguration(); } } else { @@ -177,13 +186,15 @@ public class AuthorizationService implements Service { * * @throws ServiceException if the admin user list could not be loaded. */ - private void loadAdminUsers() throws ServiceException { + private void loadAdminUsersFromFile() throws ServiceException { String configDir = Services.get().get(ConfigurationService.class).getConfigDir(); if (configDir != null) { - File file = new File(configDir, ADMIN_USERS_FILE); + File file = new File(FilenameUtils.getFullPath(configDir)+FilenameUtils.getBaseName(configDir), + FilenameUtils.getName(ADMIN_USERS_FILE)); if (file.exists()) { try { - BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file))); + BufferedReader br = new BufferedReader( + new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); try { String line = br.readLine(); while (line != null) { @@ -197,13 +208,16 @@ public class AuthorizationService implements Service { catch (IOException ex) { throw new ServiceException(ErrorCode.E0160, file.getAbsolutePath(), ex); } + finally { + br.close(); + } } - catch (FileNotFoundException ex) { + catch (IOException ex) { throw new ServiceException(ErrorCode.E0160, file.getAbsolutePath(), ex); } } else { - log.warn("Admin users file not available in config dir [{0}], running without admin users", configDir); + log.warn("Admin users file not available in config dir [{0}]", configDir); } } else { @@ -211,6 +225,15 @@ public class AuthorizationService implements Service { } } + private void loadAdminUsersFromConfiguration() { + LinkedHashSet<String> adminsFromOozieSite = Sets.newLinkedHashSet(); + adminsFromOozieSite.addAll(Services.get().get(ConfigurationService.class).getConf().getStringCollection(CONF_ADMIN_USERS)); + if (!adminsFromOozieSite.isEmpty()) { + log.info("{0} admin users found in oozie-site.xml", adminsFromOozieSite.size()); + adminUsers.addAll(adminsFromOozieSite); + } + } + /** * Destroy the service. <p> This implementation does a NOP. */ http://git-wip-us.apache.org/repos/asf/oozie/blob/6a3764f8/core/src/main/resources/oozie-default.xml ---------------------------------------------------------------------- diff --git a/core/src/main/resources/oozie-default.xml b/core/src/main/resources/oozie-default.xml index 6f89258..c54db34 100644 --- a/core/src/main/resources/oozie-default.xml +++ b/core/src/main/resources/oozie-default.xml @@ -330,6 +330,14 @@ </property> <property> + <name>oozie.serviceAuthorizationService.admin.users</name> + <value></value> + <description> + Comma separated list of users with admin access for the Authorization service. + </description> + </property> + + <property> <name>oozie.service.AuthorizationService.system.info.authorized.users</name> <value></value> <description> http://git-wip-us.apache.org/repos/asf/oozie/blob/6a3764f8/core/src/test/java/org/apache/oozie/service/TestAuthorizationService.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/oozie/service/TestAuthorizationService.java b/core/src/test/java/org/apache/oozie/service/TestAuthorizationService.java index 8df0904..be5242e 100644 --- a/core/src/test/java/org/apache/oozie/service/TestAuthorizationService.java +++ b/core/src/test/java/org/apache/oozie/service/TestAuthorizationService.java @@ -80,10 +80,12 @@ public class TestAuthorizationService extends XDataTestCase { private Services services; private void init(boolean useDefaultGroup, boolean useAdminUsersFile) throws Exception { - init(useDefaultGroup, useAdminUsersFile, StringUtils.EMPTY); + boolean useAdminGroups = !useAdminUsersFile; + init(useDefaultGroup, StringUtils.EMPTY, useAdminUsersFile, false, useAdminGroups); } - private void init(boolean useDefaultGroup, boolean useAdminUsersFile, String systemInfoAuthUsers) throws + private void init(boolean useDefaultGroup, String systemInfoAuthUsers, + boolean useAdminUsersFile, boolean useOozieSiteForAdminUsers, boolean useAdminGroups) throws Exception { setSystemProperty(SchemaService.WF_CONF_EXT_SCHEMAS, "wf-ext-schema.xsd"); @@ -94,14 +96,20 @@ public class TestAuthorizationService extends XDataTestCase { Writer adminListWriter = new FileWriter(new File(getTestCaseConfDir(), "adminusers.txt")); IOUtils.copyCharStream(adminListReader, adminListWriter); } - else { + if (useAdminGroups) { conf.set(AuthorizationService.CONF_ADMIN_GROUPS, getTestGroup()); } + + if (useOozieSiteForAdminUsers) { + conf.set(AuthorizationService.CONF_ADMIN_USERS, getAdminUser()); + } + conf.set(AuthorizationService.CONF_SYSTEM_INFO_AUTHORIZED_USERS, systemInfoAuthUsers); conf.set(Services.CONF_SERVICE_CLASSES, conf.get(Services.CONF_SERVICE_CLASSES) + "," + AuthorizationService.class.getName() + "," + DummyGroupsService.class.getName()); conf.set(AuthorizationService.CONF_DEFAULT_GROUP_AS_ACL, Boolean.toString(useDefaultGroup)); + conf.setBoolean(AuthorizationService.CONF_AUTHORIZATION_ENABLED, true); services.init(); services.getConf().setBoolean(AuthorizationService.CONF_SECURITY_ENABLED, true); services.get(AuthorizationService.class).init(services); @@ -311,8 +319,10 @@ public class TestAuthorizationService extends XDataTestCase { } } - private void _testAdminUsers(boolean useAdminFile, String adminUser, String regularUser) throws Exception { - init(true, useAdminFile); + + private void _testAdminUsers(boolean useAdminFile, String adminUser, String regularUser, + boolean adminUserFromOozieSite, boolean useAdminGroup) throws Exception { + init(true, StringUtils.EMPTY, useAdminFile, adminUserFromOozieSite, useAdminGroup ); AuthorizationService as = services.get(AuthorizationService.class); as.authorizeForAdmin(adminUser, false); @@ -323,31 +333,25 @@ public class TestAuthorizationService extends XDataTestCase { } catch (AuthorizationException ex) { } - try { - as.authorizeForAdmin(regularUser, true); - fail(); - } - catch (AuthorizationException ex) { - } } public void testAdminUsersWithAdminFile() throws Exception { - _testAdminUsers(true, "admin", getTestUser()); + _testAdminUsers(true, "admin", getTestUser(), false, false); } public void testAdminUsersWithAdminGroup() throws Exception { - _testAdminUsers(false, getTestUser(), getTestUser2()); + _testAdminUsers(false, getTestUser(), getTestUser2(), false, true); } public void testAuthorizedSystemInfoDefaultSuccess() throws Exception { //AuthorizationService.CONF_SYSTEM_INFO_AUTHORIZED_USERS is empty - init(true, false, StringUtils.EMPTY); + init(true, StringUtils.EMPTY, false, false, true); services.get(AuthorizationService.class).authorizeForSystemInfo("regularUser", "proxyUser"); } public void testAuthorizedSystemInfoSuccess() throws Exception { //Set AuthorizationService.CONF_SYSTEM_INFO_AUTHORIZED_USERS to proxyUser,regularUser - init(true, false, "proxyUser,regularUser"); + init(true, "proxyUser,regularUser", false, false, true); //Use proxyUser in request services.get(AuthorizationService.class).authorizeForSystemInfo("regularUser1", "proxyUser"); @@ -361,7 +365,7 @@ public class TestAuthorizationService extends XDataTestCase { } public void testAuthorizedSystemInfoFailure() throws Exception { - init(true, false, "proxyUser,regularUser"); + init(true, "proxyUser,regularUser", false, false, true); try { services.get(AuthorizationService.class).authorizeForSystemInfo("regularUser1", "proxyUser1"); fail("Should have thrown exception because regularUser1 or proxyUser1 are not authorized to access system info"); @@ -371,4 +375,26 @@ public class TestAuthorizationService extends XDataTestCase { "E0503: User [regularUser1] does not have admin " + "privileges", ex.getMessage()); } } + + public void testWhenDefinedInConfigurationThenAdminPrivilegesAllowed() throws Exception { + _testAdminUsers(false, getAdminUser(), getTestUser(), true, false); + } + + public void testWhenDefinedInAdminFileAndConfigurationThenAllowBothAdmins() throws Exception { + init(true, StringUtils.EMPTY, true, true, false ); + + AuthorizationService as = services.get(AuthorizationService.class); + as.authorizeForAdmin(getAdminUser(), false); + as.authorizeForAdmin(getAdminUser(), true); + as.authorizeForAdmin("admin", false); + as.authorizeForAdmin("admin", true); + try { + as.authorizeForAdmin(getTestUser(), true); + fail(); + } + catch (AuthorizationException ex) { + } + + + } } http://git-wip-us.apache.org/repos/asf/oozie/blob/6a3764f8/core/src/test/java/org/apache/oozie/test/XTestCase.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/oozie/test/XTestCase.java b/core/src/test/java/org/apache/oozie/test/XTestCase.java index f471b88..a8be36b 100644 --- a/core/src/test/java/org/apache/oozie/test/XTestCase.java +++ b/core/src/test/java/org/apache/oozie/test/XTestCase.java @@ -258,6 +258,12 @@ public abstract class XTestCase extends TestCase { public static final String TEST_GROUP_PROP = "oozie.test.group"; /** + * System property that specifies the test admin user used in the tests. + * The default value of this property is myAdmin + */ + public static final String TEST_ADMIN_PROP = "oozie.test.admin.user"; + + /** * System property that specifies the test groiup used by the tests. * The default value of this property is <tt>testg</tt>. */ @@ -609,6 +615,14 @@ public abstract class XTestCase extends TestCase { } /** + * Return Admin user + * @return the admin user + */ + protected static String getAdminUser(){ + return System.getProperty(TEST_ADMIN_PROP,"myAdmin"); + } + + /** * Return the alternate test group. * * @return the test group. http://git-wip-us.apache.org/repos/asf/oozie/blob/6a3764f8/docs/src/site/twiki/AG_Install.twiki ---------------------------------------------------------------------- diff --git a/docs/src/site/twiki/AG_Install.twiki b/docs/src/site/twiki/AG_Install.twiki index 77ee4ee..2d48d43 100644 --- a/docs/src/site/twiki/AG_Install.twiki +++ b/docs/src/site/twiki/AG_Install.twiki @@ -528,12 +528,20 @@ Admin users are determined from the list of admin groups, specified in =oozie.service.AuthorizationService.admin.groups= property. Use commas to separate multiple groups, spaces, tabs and ENTER characters are trimmed. -If the above property for admin groups is not set, then the admin users are the users specified in the - =conf/adminusers.txt= file. The syntax of this file is: +If the above property for admin groups is not set, then defining the admin users can happen in the following manners. +The list of admin users can be in the =conf/adminusers.txt= file. The syntax of this file is: * One user name per line * Empty lines and lines starting with '#' are ignored +Admin users can also be defined in +=oozie.serviceAuthorizationService.admin.users= property. Use commas to separate multiple admin users, spaces, tabs +and ENTER characters are trimmed. + +In case there are admin users defined using both methods, the effective list of admin users will be the union +of the admin users found in the adminusers.txt and those specified with =oozie.serviceAuthorizationService.admin.users=. + + ---+++ Oozie System ID Configuration Oozie has a system ID that is is used to generate the Oozie temporary runtime directory, the workflow job IDs, and the http://git-wip-us.apache.org/repos/asf/oozie/blob/6a3764f8/release-log.txt ---------------------------------------------------------------------- diff --git a/release-log.txt b/release-log.txt index e1c359d..5d30c19 100644 --- a/release-log.txt +++ b/release-log.txt @@ -1,5 +1,6 @@ -- Oozie 5.1.0 release (trunk - unreleased) +OOZIE-3217 Enable definition of admin users using oozie-site.xml (orova via andras.piros) OOZIE-3219 Cannot compile with hadoop 3.1.0 (dbist13, andras.piros) OOZIE-3232 Reduce heap waste by reducing duplicate string count (Misha Dmitriev via andras.piros) OOZIE-2914 Consolidate trim calls (Jan Hentschel via andras.piros)