This is an automated email from the ASF dual-hosted git repository.

sijie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-pulsar.git


The following commit(s) were added to refs/heads/master by this push:
     new 0a655c1  Fixed authorization for REST API provided by WebSocket proxy 
(#1959)
0a655c1 is described below

commit 0a655c16615003d03d6057573aaea09b1d3649cf
Author: massakam <massa...@yahoo-corp.jp>
AuthorDate: Thu Jun 14 04:48:12 2018 +0900

    Fixed authorization for REST API provided by WebSocket proxy (#1959)
    
    * Fixed authorization for REST API provided by WebSocket proxy
    
    * Change access modifier
---
 .../websocket/admin/WebSocketWebResource.java      |  16 +-
 .../websocket/admin/WebSocketWebResourceTest.java  | 244 +++++++++++++++++++++
 2 files changed, 255 insertions(+), 5 deletions(-)

diff --git 
a/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/admin/WebSocketWebResource.java
 
b/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/admin/WebSocketWebResource.java
index 66050bc..10e3664 100644
--- 
a/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/admin/WebSocketWebResource.java
+++ 
b/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/admin/WebSocketWebResource.java
@@ -92,7 +92,7 @@ public class WebSocketWebResource {
     /**
      * Checks whether the user has Pulsar Super-User access to the system.
      *
-     * @throws WebApplicationException
+     * @throws RestException
      *             if not authorized
      */
     protected void validateSuperUserAccess() {
@@ -112,19 +112,25 @@ public class WebSocketWebResource {
      * Checks if user has super-user access or user is authorized to 
produce/consume on a given topic
      *
      * @param topic
-     * @return
+     * @throws RestException
      */
-    protected boolean validateUserAccess(TopicName topic) {
+    protected void validateUserAccess(TopicName topic) {
+        boolean isAuthorized = false;
+
         try {
             validateSuperUserAccess();
-            return true;
+            isAuthorized = true;
         } catch (Exception e) {
             try {
-                return isAuthorized(topic);
+                isAuthorized = isAuthorized(topic);
             } catch (Exception ne) {
                 throw new RestException(ne);
             }
         }
+
+        if (!isAuthorized) {
+            throw new RestException(Status.UNAUTHORIZED, "Don't have 
permission to access this topic");
+        }
     }
 
     /**
diff --git 
a/pulsar-websocket/src/test/java/org/apache/pulsar/websocket/admin/WebSocketWebResourceTest.java
 
b/pulsar-websocket/src/test/java/org/apache/pulsar/websocket/admin/WebSocketWebResourceTest.java
new file mode 100644
index 0000000..6d7e8cf
--- /dev/null
+++ 
b/pulsar-websocket/src/test/java/org/apache/pulsar/websocket/admin/WebSocketWebResourceTest.java
@@ -0,0 +1,244 @@
+/**
+ * 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.pulsar.websocket.admin;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Method;
+
+import javax.naming.AuthenticationException;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.core.UriInfo;
+
+import com.google.common.collect.Sets;
+
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import org.apache.pulsar.broker.ServiceConfiguration;
+import org.apache.pulsar.broker.authentication.AuthenticationService;
+import org.apache.pulsar.broker.authentication.AuthenticationDataHttps;
+import org.apache.pulsar.broker.authentication.AuthenticationDataSource;
+import org.apache.pulsar.broker.authorization.AuthorizationService;
+import org.apache.pulsar.common.naming.TopicName;
+import org.apache.pulsar.websocket.WebSocketService;
+
+public class WebSocketWebResourceTest {
+
+    private static final String SUPER_USER = "super";
+    private static final String AUTHORIZED_USER = "authorized";
+    private static final String UNAUTHORIZED_USER = "unauthorized";
+
+    private TopicName topicName;
+
+    @InjectMocks
+    @Spy
+    private WebSocketWebResource webResource;
+    @Mock
+    private ServletContext servletContext;
+    @Mock
+    private HttpServletRequest httpRequest;
+    @Mock
+    private UriInfo uri;
+
+    @BeforeMethod
+    public void setup(Method method) throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        ServiceConfiguration config = new ServiceConfiguration();
+        config.setSuperUserRoles(Sets.newHashSet(SUPER_USER));
+        if ("testAuthenticationDisabled".equals(method.getName())) {
+            config.setAuthenticationEnabled(false);
+            config.setAuthorizationEnabled(false);
+        } else {
+            config.setAuthenticationEnabled(true);
+            config.setAuthorizationEnabled(true);
+        }
+
+        AuthenticationService authnService = mock(AuthenticationService.class);
+        if ("testSuperUserAccess".equals(method.getName())) {
+            
when(authnService.authenticateHttpRequest(any(HttpServletRequest.class))).thenReturn(SUPER_USER);
+        } else if ("testUnauthorizedUserAccess".equals(method.getName())) {
+            
when(authnService.authenticateHttpRequest(any(HttpServletRequest.class))).thenReturn(UNAUTHORIZED_USER);
+        } else if ("testBlankUserAccess".equals(method.getName())) {
+            
when(authnService.authenticateHttpRequest(any(HttpServletRequest.class))).thenReturn("");
+        } else if ("testUnauthenticatedUserAccess".equals(method.getName())) {
+            
when(authnService.authenticateHttpRequest(any(HttpServletRequest.class)))
+                    .thenThrow(new AuthenticationException());
+        } else {
+            
when(authnService.authenticateHttpRequest(any(HttpServletRequest.class))).thenReturn(AUTHORIZED_USER);
+        }
+
+        AuthorizationService authzService = mock(AuthorizationService.class);
+        when(authzService.canLookup(any(TopicName.class), eq(SUPER_USER), 
any(AuthenticationDataSource.class)))
+                .thenReturn(true);
+        when(authzService.canLookup(any(TopicName.class), eq(AUTHORIZED_USER), 
any(AuthenticationDataSource.class)))
+                .thenReturn(true);
+        when(authzService.canLookup(any(TopicName.class), 
eq(UNAUTHORIZED_USER), any(AuthenticationDataSource.class)))
+                .thenReturn(false);
+        when(authzService.canLookup(any(TopicName.class), eq(""), 
any(AuthenticationDataSource.class)))
+                .thenReturn(false);
+
+        WebSocketService socketService = mock(WebSocketService.class);
+        when(socketService.getConfig()).thenReturn(config);
+        
when(socketService.isAuthorizationEnabled()).thenReturn(config.isAuthorizationEnabled());
+        
when(socketService.getAuthenticationService()).thenReturn(authnService);
+        when(socketService.getAuthorizationService()).thenReturn(authzService);
+
+        // Mock WebSocketWebResource
+        
doReturn(mock(AuthenticationDataHttps.class)).when(webResource).authData();
+
+        // Mock ServletContext
+        
when(servletContext.getAttribute(anyString())).thenReturn(socketService);
+
+        // Mock UriInfo
+        when(uri.getRequestUri()).thenReturn(null);
+
+        topicName = TopicName.get("persistent://tenant/cluster/ns/dest");
+    }
+
+    @AfterMethod
+    public void cleanup() throws Exception {
+        this.webResource = null;
+    }
+
+    @Test
+    public void testAuthenticationDisabled() throws Exception {
+        try {
+            Assert.assertEquals(webResource.clientAppId(), AUTHORIZED_USER);
+            webResource.validateSuperUserAccess();
+            webResource.validateUserAccess(topicName);
+        } catch (RestException e) {
+            Assert.fail("Should not fail", e);
+        }
+    }
+
+    @Test
+    public void testSuperUserAccess() throws Exception {
+        try {
+            Assert.assertEquals(webResource.clientAppId(), SUPER_USER);
+            webResource.validateSuperUserAccess();
+            webResource.validateUserAccess(topicName);
+        } catch (RestException e) {
+            Assert.fail("Should not fail", e);
+        }
+    }
+
+    @Test
+    public void testAuthorizedUserAccess() throws Exception {
+        try {
+            webResource.validateSuperUserAccess();
+            Assert.fail("Should fail");
+        } catch (RestException e) {
+            Assert.assertEquals(e.getResponse().getStatus(), 
Status.UNAUTHORIZED.getStatusCode());
+        }
+
+        try {
+            Assert.assertEquals(webResource.clientAppId(), AUTHORIZED_USER);
+            webResource.validateUserAccess(topicName);
+        } catch (RestException e) {
+            Assert.fail("Should not fail", e);
+        }
+    }
+
+    @Test
+    public void testUnauthorizedUserAccess() throws Exception {
+        try {
+            Assert.assertEquals(webResource.clientAppId(), UNAUTHORIZED_USER);
+        } catch (RestException e) {
+            Assert.fail("Should not fail", e);
+        }
+
+        try {
+            webResource.validateSuperUserAccess();
+            Assert.fail("Should fail");
+        } catch (RestException e) {
+            Assert.assertEquals(e.getResponse().getStatus(), 
Status.UNAUTHORIZED.getStatusCode());
+        }
+
+        try {
+            webResource.validateUserAccess(topicName);
+            Assert.fail("Should fail");
+        } catch (RestException e) {
+            Assert.assertEquals(e.getResponse().getStatus(), 
Status.UNAUTHORIZED.getStatusCode());
+        }
+    }
+
+    @Test
+    public void testBlankUserAccess() throws Exception {
+        try {
+            webResource.clientAppId();
+            Assert.fail("Should fail");
+        } catch (RestException e) {
+            Assert.assertEquals(e.getResponse().getStatus(), 
Status.UNAUTHORIZED.getStatusCode());
+        }
+
+        try {
+            webResource.validateSuperUserAccess();
+            Assert.fail("Should fail");
+        } catch (RestException e) {
+            Assert.assertEquals(e.getResponse().getStatus(), 
Status.UNAUTHORIZED.getStatusCode());
+        }
+
+        try {
+            webResource.validateUserAccess(topicName);
+            Assert.fail("Should fail");
+        } catch (RestException e) {
+            Assert.assertEquals(e.getResponse().getStatus(), 
Status.UNAUTHORIZED.getStatusCode());
+        }
+    }
+
+    @Test
+    public void testUnauthenticatedUserAccess() throws Exception {
+        try {
+            webResource.clientAppId();
+            Assert.fail("Should fail");
+        } catch (RestException e) {
+            Assert.assertEquals(e.getResponse().getStatus(), 
Status.UNAUTHORIZED.getStatusCode());
+        }
+
+        try {
+            webResource.validateSuperUserAccess();
+            Assert.fail("Should fail");
+        } catch (RestException e) {
+            Assert.assertEquals(e.getResponse().getStatus(), 
Status.UNAUTHORIZED.getStatusCode());
+        }
+
+        try {
+            webResource.validateUserAccess(topicName);
+            Assert.fail("Should fail");
+        } catch (RestException e) {
+            Assert.assertEquals(e.getResponse().getStatus(), 
Status.UNAUTHORIZED.getStatusCode());
+        }
+    }
+
+}

-- 
To stop receiving notification emails like this one, please contact
si...@apache.org.

Reply via email to