Repository: oozie
Updated Branches:
  refs/heads/master c29d9c5fc -> 5f1444496


OOZIE-3126 Add option to allow list of users to access system config 
(satishsaley)


Project: http://git-wip-us.apache.org/repos/asf/oozie/repo
Commit: http://git-wip-us.apache.org/repos/asf/oozie/commit/5f144449
Tree: http://git-wip-us.apache.org/repos/asf/oozie/tree/5f144449
Diff: http://git-wip-us.apache.org/repos/asf/oozie/diff/5f144449

Branch: refs/heads/master
Commit: 5f1444496b0a105100af5f9a62029b7de0de179f
Parents: c29d9c5
Author: satishsaley <[email protected]>
Authored: Tue Nov 28 11:00:21 2017 -0800
Committer: satishsaley <[email protected]>
Committed: Tue Nov 28 11:00:21 2017 -0800

----------------------------------------------------------------------
 .../oozie/service/AuthorizationService.java     | 34 ++++++++++++++-
 .../oozie/service/ConfigurationService.java     |  4 ++
 .../apache/oozie/servlet/BaseAdminServlet.java  | 21 ++++++++++
 .../apache/oozie/servlet/JsonRestServlet.java   | 11 +++++
 core/src/main/resources/oozie-default.xml       |  8 ++++
 .../oozie/service/TestAuthorizationService.java | 44 +++++++++++++++++++-
 release-log.txt                                 |  1 +
 webapp/src/main/webapp/index.jsp                |  5 +++
 webapp/src/main/webapp/oozie-console.js         |  6 ++-
 9 files changed, 129 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/oozie/blob/5f144449/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 49bc672..d76e1ea 100644
--- a/core/src/main/java/org/apache/oozie/service/AuthorizationService.java
+++ b/core/src/main/java/org/apache/oozie/service/AuthorizationService.java
@@ -31,6 +31,7 @@ import java.util.Map;
 import java.util.ArrayList;
 import java.util.Set;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
@@ -79,6 +80,9 @@ public class AuthorizationService implements Service {
      */
     public static final String CONF_ADMIN_GROUPS = CONF_PREFIX + 
"admin.groups";
 
+    public static final String CONF_SYSTEM_INFO_AUTHORIZED_USERS = CONF_PREFIX 
+ "system.info.authorized.users";
+
+
     /**
      * File that contains list of admin users for Oozie.
      */
@@ -89,9 +93,10 @@ public class AuthorizationService implements Service {
 
     private Set<String> adminGroups;
     private Set<String> adminUsers;
+    private Set<String> sysInfoAuthUsers;
     private boolean authorizationEnabled;
     private boolean useDefaultGroupAsAcl;
-
+    private boolean authorizedSystemInfo = false;
     private final XLog log = XLog.getLog(getClass());
     private Instrumentation instrumentation;
 
@@ -113,6 +118,14 @@ public class AuthorizationService implements Service {
         authorizationEnabled =
             ConfigUtils.getWithDeprecatedCheck(services.getConf(), 
CONF_AUTHORIZATION_ENABLED,
                                                CONF_SECURITY_ENABLED, false);
+        String systemInfoAuthUsers = 
ConfigurationService.get(CONF_SYSTEM_INFO_AUTHORIZED_USERS);
+        if (!StringUtils.isBlank(systemInfoAuthUsers)) {
+            authorizedSystemInfo = true;
+            sysInfoAuthUsers = new HashSet<>();
+            for (String user : getTrimmedStrings(systemInfoAuthUsers)) {
+                sysInfoAuthUsers.add(user);
+            }
+        }
         if (authorizationEnabled) {
             log.info("Oozie running with authorization enabled");
             useDefaultGroupAsAcl = 
ConfigurationService.getBoolean(CONF_DEFAULT_GROUP_AS_ACL);
@@ -292,6 +305,21 @@ public class AuthorizationService implements Service {
     }
 
     /**
+     * Check if the user is authorized to access system information.
+     *
+     * @param user user name.
+     * @param proxyUser proxy user name.
+     * @throws AuthorizationException thrown if user does not have admin 
priviledges.
+     */
+    public void authorizeForSystemInfo(String user, String proxyUser) throws 
AuthorizationException {
+        if (authorizationEnabled && authorizedSystemInfo && 
!(sysInfoAuthUsers.contains(user) || sysInfoAuthUsers
+                .contains(proxyUser) || isAdmin(user) || isAdmin(proxyUser))) {
+            incrCounter(INSTR_FAILED_AUTH_COUNTER, 1);
+            throw new AuthorizationException(ErrorCode.E0503, user);
+        }
+    }
+
+    /**
      * Check if the user has admin privileges. <p> Subclasses should override 
the {@link #isUserInGroup} method.
      *
      * @param user user name.
@@ -612,4 +640,8 @@ public class AuthorizationService implements Service {
             instrumentation.incr(INSTRUMENTATION_GROUP, name, count);
         }
     }
+
+    public boolean isAuthorizedSystemInfo() {
+        return authorizedSystemInfo;
+    }
 }

http://git-wip-us.apache.org/repos/asf/oozie/blob/5f144449/core/src/main/java/org/apache/oozie/service/ConfigurationService.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/oozie/service/ConfigurationService.java 
b/core/src/main/java/org/apache/oozie/service/ConfigurationService.java
index 4af022f..4707252 100644
--- a/core/src/main/java/org/apache/oozie/service/ConfigurationService.java
+++ b/core/src/main/java/org/apache/oozie/service/ConfigurationService.java
@@ -529,6 +529,10 @@ public class ConfigurationService implements Service, 
Instrumentable {
         return getBoolean(conf, name);
     }
 
+    public static boolean getBoolean(String name, boolean defaultValue) {
+        return Services.get().getConf().getBoolean(name, defaultValue);
+    }
+
     public static boolean getBoolean(Configuration conf, String name) {
         return conf.getBoolean(name, ConfigUtils.BOOLEAN_DEFAULT);
     }

http://git-wip-us.apache.org/repos/asf/oozie/blob/5f144449/core/src/main/java/org/apache/oozie/servlet/BaseAdminServlet.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/oozie/servlet/BaseAdminServlet.java 
b/core/src/main/java/org/apache/oozie/servlet/BaseAdminServlet.java
index 890097b..97c2007 100644
--- a/core/src/main/java/org/apache/oozie/servlet/BaseAdminServlet.java
+++ b/core/src/main/java/org/apache/oozie/servlet/BaseAdminServlet.java
@@ -127,16 +127,19 @@ public abstract class BaseAdminServlet extends 
JsonRestServlet {
             sendJsonResponse(response, HttpServletResponse.SC_OK, json);
         }
         else if (resource.equals(RestConstants.ADMIN_OS_ENV_RESOURCE)) {
+            authorizeForSystemInfo(request);
             JSONObject json = new JSONObject();
             json.putAll(instr.getOSEnv());
             sendJsonResponse(response, HttpServletResponse.SC_OK, json);
         }
         else if (resource.equals(RestConstants.ADMIN_JAVA_SYS_PROPS_RESOURCE)) 
{
+            authorizeForSystemInfo(request);
             JSONObject json = new JSONObject();
             json.putAll(instr.getJavaSystemProperties());
             sendJsonResponse(response, HttpServletResponse.SC_OK, json);
         }
         else if (resource.equals(RestConstants.ADMIN_CONFIG_RESOURCE)) {
+            authorizeForSystemInfo(request);
             JSONObject json = new JSONObject();
             json.putAll(instr.getConfiguration());
             sendJsonResponse(response, HttpServletResponse.SC_OK, json);
@@ -345,6 +348,24 @@ public abstract class BaseAdminServlet extends 
JsonRestServlet {
         }
     }
 
+    /**
+     * Authorize request.
+     *
+     * @param request the HttpServletRequest
+     * @throws XServletException the x servlet exception
+     */
+    private void authorizeForSystemInfo(HttpServletRequest request) throws 
XServletException {
+        try {
+            AuthorizationService auth = 
Services.get().get(AuthorizationService.class);
+            if (auth.isAuthorizedSystemInfo()) {
+                auth.authorizeForSystemInfo(getUser(request), 
getProxyUser(request));
+            }
+        }
+        catch (AuthorizationException ex) {
+            throw new XServletException(HttpServletResponse.SC_UNAUTHORIZED, 
ex);
+        }
+    }
+
     @Override
     protected void doPost(HttpServletRequest request, HttpServletResponse 
response) throws ServletException,
             IOException {

http://git-wip-us.apache.org/repos/asf/oozie/blob/5f144449/core/src/main/java/org/apache/oozie/servlet/JsonRestServlet.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/oozie/servlet/JsonRestServlet.java 
b/core/src/main/java/org/apache/oozie/servlet/JsonRestServlet.java
index 03cf35c..0f22796 100644
--- a/core/src/main/java/org/apache/oozie/servlet/JsonRestServlet.java
+++ b/core/src/main/java/org/apache/oozie/servlet/JsonRestServlet.java
@@ -584,6 +584,17 @@ public abstract class JsonRestServlet extends HttpServlet {
     }
 
     /**
+     * Gets proxy user.
+     * If there is any proxy user, then <code>HttpServletRequest</code> 
contains proxy user.
+     * Otherwise it is the normal user.
+     * @param request
+     * @return
+     */
+    protected String getProxyUser(HttpServletRequest request) {
+        return (String) request.getAttribute(USER_NAME);
+    }
+
+    /**
      * Set the thread local log info with the given information.
      *
      * @param actionid action ID.

http://git-wip-us.apache.org/repos/asf/oozie/blob/5f144449/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 1fd4ee3..7ec64bc 100644
--- a/core/src/main/resources/oozie-default.xml
+++ b/core/src/main/resources/oozie-default.xml
@@ -329,6 +329,14 @@
         </description>
     </property>
 
+    <property>
+        
<name>oozie.service.AuthorizationService.system.info.authorized.users</name>
+        <value></value>
+        <description>
+            Comma separated list of users authorized for web service calls to 
get system configuration.
+        </description>
+    </property>
+
     <!-- InstrumentationService -->
 
     <property>

http://git-wip-us.apache.org/repos/asf/oozie/blob/5f144449/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 c32bfc2..ca5b940 100644
--- a/core/src/test/java/org/apache/oozie/service/TestAuthorizationService.java
+++ b/core/src/test/java/org/apache/oozie/service/TestAuthorizationService.java
@@ -28,6 +28,7 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.UUID;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
@@ -79,6 +80,11 @@ public class TestAuthorizationService extends XDataTestCase {
     private Services services;
 
     private void init(boolean useDefaultGroup, boolean useAdminUsersFile) 
throws Exception {
+        init(useDefaultGroup, useAdminUsersFile, StringUtils.EMPTY);
+    }
+
+    private void init(boolean useDefaultGroup, boolean useAdminUsersFile, 
String systemInfoAuthUsers) throws
+            Exception {
         setSystemProperty(SchemaService.WF_CONF_EXT_SCHEMAS, 
"wf-ext-schema.xsd");
 
         services = new Services();
@@ -91,9 +97,10 @@ public class TestAuthorizationService extends XDataTestCase {
         else {
             conf.set(AuthorizationService.CONF_ADMIN_GROUPS, getTestGroup());
         }
+        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.get(Services.CONF_SERVICE_CLASSES) + "," + 
AuthorizationService.class.getName() + ","
+                        + DummyGroupsService.class.getName());
         conf.set(AuthorizationService.CONF_DEFAULT_GROUP_AS_ACL, 
Boolean.toString(useDefaultGroup));
         services.init();
         
services.getConf().setBoolean(AuthorizationService.CONF_SECURITY_ENABLED, true);
@@ -331,4 +338,37 @@ public class TestAuthorizationService extends 
XDataTestCase {
     public void testAdminUsersWithAdminGroup() throws Exception {
         _testAdminUsers(false, getTestUser(), getTestUser2());
     }
+
+    public void testAuthorizedSystemInfoDefaultSuccess() throws Exception {
+        //AuthorizationService.CONF_SYSTEM_INFO_AUTHORIZED_USERS is empty
+        init(true, false, StringUtils.EMPTY);
+        
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");
+
+        //Use proxyUser in request
+        
services.get(AuthorizationService.class).authorizeForSystemInfo("regularUser1", 
"proxyUser");
+
+        //Use regularUser in request
+        
services.get(AuthorizationService.class).authorizeForSystemInfo("regularUser", 
"proxyUser1");
+
+        //The proxy user and regular user used in the request are different. 
Proxy user belongs to one of the
+        //admin groups in AuthorizationService.CONF_ADMIN_GROUPS
+        
services.get(AuthorizationService.class).authorizeForSystemInfo("regularUser1", 
getTestUser());
+    }
+
+    public void testAuthorizedSystemInfoFailure() throws Exception {
+        init(true, false, "proxyUser,regularUser");
+        try {
+            
services.get(AuthorizationService.class).authorizeForSystemInfo("regularUser1", 
"proxyUser1");
+            fail("Should have thrown exception because regularUser1 or 
proxyUser1 are not authorized to access system info");
+        }
+        catch (AuthorizationException ex) {
+            assertEquals("Exception message is different than expected",
+                    "E0503: User [regularUser1] does not have admin " + 
"privileges", ex.getMessage());
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/oozie/blob/5f144449/release-log.txt
----------------------------------------------------------------------
diff --git a/release-log.txt b/release-log.txt
index f97b3d5..9a3f7b5 100644
--- a/release-log.txt
+++ b/release-log.txt
@@ -1,5 +1,6 @@
 -- Oozie 5.0.0 release (trunk - unreleased)
 
+OOZIE-3126 Add option to allow list of users to access system config 
(satishsaley)
 OOZIE-2900 Retrieve tokens for oozie.launcher.mapreduce.job.hdfs-servers 
before submission (asasvari)
 OOZIE-3132 Instrument SLACalculatorMemory (andras.piros)
 OOZIE-2945 Update SpotBugs to stable version after GA (dbist13 via gezapeti)

http://git-wip-us.apache.org/repos/asf/oozie/blob/5f144449/webapp/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/webapp/src/main/webapp/index.jsp b/webapp/src/main/webapp/index.jsp
index 61d32ae..112d336 100644
--- a/webapp/src/main/webapp/index.jsp
+++ b/webapp/src/main/webapp/index.jsp
@@ -55,11 +55,15 @@
             import="org.apache.oozie.sla.service.SLAService"
             import="org.apache.oozie.service.InstrumentationService"
             import="org.apache.oozie.service.MetricsInstrumentationService"
+            import="org.apache.oozie.service.AuthorizationService"
+            import="org.apache.oozie.service.Services"
+
         %>
         <%
             boolean isSLAServiceEnabled = SLAService.isEnabled();
             boolean isInstrumentationServiceEnabled = 
InstrumentationService.isEnabled();
             boolean isMetricsInstrumentationServiceEnabled = 
MetricsInstrumentationService.isEnabled();
+            boolean showSystemInfo = 
!Services.get().get(AuthorizationService.class).isAuthorizedSystemInfo();
         %>
         <div id="oozie-body" style="padding:2">
             <div class="x-tab-panel-header x-unselectable x-tab-strip-top" 
style="width:1048">
@@ -69,6 +73,7 @@
                     var isSLAServiceEnabled = "<%=isSLAServiceEnabled%>";
                     var isInstrumentationServiceEnabled = 
"<%=isInstrumentationServiceEnabled%>";
                     var isMetricsInstrumentationServiceEnabled = 
"<%=isMetricsInstrumentationServiceEnabled%>";
+                    var showSystemInfo = "<%=showSystemInfo%>";
                     document.title = msg;
                     document.write(msg);
                  </script>

http://git-wip-us.apache.org/repos/asf/oozie/blob/5f144449/webapp/src/main/webapp/oozie-console.js
----------------------------------------------------------------------
diff --git a/webapp/src/main/webapp/oozie-console.js 
b/webapp/src/main/webapp/oozie-console.js
index a113b3e..1da42d1 100644
--- a/webapp/src/main/webapp/oozie-console.js
+++ b/webapp/src/main/webapp/oozie-console.js
@@ -3242,7 +3242,10 @@ function initConsole() {
     if (isSLAServiceEnabled == "true") {
         tabs.add(slaDashboard);
     }
-    tabs.add(adminGrid);
+    if(showSystemInfo == "true"){
+       tabs.add(adminGrid);
+       viewConfig.execute();
+    }
     if (isInstrumentationServiceEnabled == "true") {
         tabs.add(instrumentationArea);
     }
@@ -3279,7 +3282,6 @@ function initConsole() {
         }
     });
     checkStatus.execute();
-    viewConfig.execute();
     serverVersion.execute();
     if (isInstrumentationServiceEnabled == "true") {
            viewInstrumentation.execute();

Reply via email to