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)

Reply via email to