AMBARI-6905. POST on /api/v1/persist fails for CLUSTER.OPERATE. (mahadev)

Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/0c46e95e
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/0c46e95e
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/0c46e95e

Branch: refs/heads/branch-alerts-dev
Commit: 0c46e95e646da932d644719377d2584fc2b026c6
Parents: c9fbc84
Author: Mahadev Konar <maha...@apache.org>
Authored: Mon Aug 18 21:01:39 2014 -0700
Committer: Mahadev Konar <maha...@apache.org>
Committed: Tue Aug 19 10:56:11 2014 -0700

----------------------------------------------------------------------
 .../AmbariAuthorizationFilter.java              |  15 ++-
 .../AmbariAuthorizationFilterTest.java          | 124 +++++++++++++++++++
 2 files changed, 136 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/0c46e95e/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java
index 4ba8c7f..bc67cdb 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java
@@ -54,9 +54,10 @@ public class AmbariAuthorizationFilter implements Filter {
     HttpServletRequest httpRequest = (HttpServletRequest) request;
     HttpServletResponse httpResponse = (HttpServletResponse) response;
 
-    SecurityContext context = SecurityContextHolder.getContext();
+    SecurityContext context = getSecurityContext();
 
-    if (context.getAuthentication() == null || 
!context.getAuthentication().isAuthenticated()) {
+    Authentication authentication = context.getAuthentication();
+    if (authentication == null || !authentication.isAuthenticated()) {
       String token = httpRequest.getHeader(INTERNAL_TOKEN_HEADER);
       if (token != null) {
         context.setAuthentication(new InternalAuthenticationToken(token));
@@ -64,7 +65,6 @@ public class AmbariAuthorizationFilter implements Filter {
     } else {
       boolean authorized = false;
 
-      Authentication authentication = context.getAuthentication();
       for (GrantedAuthority grantedAuthority : 
authentication.getAuthorities()) {
         if (grantedAuthority instanceof AmbariGrantedAuthority) {
 
@@ -93,6 +93,11 @@ public class AmbariAuthorizationFilter implements Filter {
               authorized = true;
               break;
             }
+          } else if (requestURI.matches("/api/v[0-9]+/persist.*")) {
+            if 
(permissionId.equals(PermissionEntity.CLUSTER_OPERATE_PERMISSION)) {
+              authorized = true;
+              break;
+            }
           }
         }
       }
@@ -134,4 +139,8 @@ public class AmbariAuthorizationFilter implements Filter {
     }
     return value == null || value.length() == 0 ? defaultValue : value;
   }
+
+  SecurityContext getSecurityContext() {
+    return SecurityContextHolder.getContext();
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/0c46e95e/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilterTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilterTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilterTest.java
new file mode 100644
index 0000000..a950eb6
--- /dev/null
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilterTest.java
@@ -0,0 +1,124 @@
+/*
+ * 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.ambari.server.security.authorization;
+
+import org.apache.ambari.server.orm.entities.PermissionEntity;
+import org.apache.ambari.server.orm.entities.PrivilegeEntity;
+import org.easymock.EasyMock;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContext;
+
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Collection;
+import java.util.Collections;
+
+import static org.easymock.EasyMock.*;
+
+public class AmbariAuthorizationFilterTest {
+
+  @Test
+  public void testDoFilter_postPersist_hasOperatePermission() throws Exception 
{
+    FilterChain chain = createNiceMock(FilterChain.class);
+    HttpServletRequest request = createNiceMock(HttpServletRequest.class);
+    HttpServletResponse response = createNiceMock(HttpServletResponse.class);
+    AmbariAuthorizationFilter filter = 
createMockBuilder(AmbariAuthorizationFilter.class)
+        .addMockedMethod("getSecurityContext").withConstructor().createMock();
+    SecurityContext securityContext = createNiceMock(SecurityContext.class);
+    Authentication authentication = createNiceMock(Authentication.class);
+    AmbariGrantedAuthority authority = 
createNiceMock(AmbariGrantedAuthority.class);
+    PrivilegeEntity privilegeEntity = createNiceMock(PrivilegeEntity.class);
+    PermissionEntity permission = createNiceMock(PermissionEntity.class);
+    FilterConfig filterConfig = createNiceMock(FilterConfig.class);
+
+
+    expect(filterConfig.getInitParameter("realm")).andReturn("AuthFilter");
+    expect(authentication.isAuthenticated()).andReturn(true);
+    expect(request.getRequestURI()).andReturn("/api/v1/persist/some_val");
+    expect(authority.getPrivilegeEntity()).andReturn(privilegeEntity);
+    expect(privilegeEntity.getPermission()).andReturn(permission);
+    EasyMock.<Collection<? extends 
GrantedAuthority>>expect(authentication.getAuthorities())
+        .andReturn(Collections.singletonList(authority));
+    expect(filter.getSecurityContext()).andReturn(securityContext);
+    expect(securityContext.getAuthentication()).andReturn(authentication);
+
+    
expect(permission.getId()).andReturn(PermissionEntity.CLUSTER_OPERATE_PERMISSION);
+
+    // expect continue filtering
+    chain.doFilter(request, response);
+
+    replay(request, response, chain, filter, securityContext, authentication, 
authority,
+        privilegeEntity, permission, filterConfig);
+
+    filter.init(filterConfig);
+    filter.doFilter(request, response, chain);
+
+    verify(request, response, chain, filter, securityContext, authentication, 
authority,
+        privilegeEntity, permission, filterConfig);
+  }
+
+  @Test
+  public void testDoFilter_postPersist_hasNoOperatePermission() throws 
Exception {
+    FilterChain chain = createNiceMock(FilterChain.class);
+    HttpServletRequest request = createNiceMock(HttpServletRequest.class);
+    HttpServletResponse response = createNiceMock(HttpServletResponse.class);
+    AmbariAuthorizationFilter filter = 
createMockBuilder(AmbariAuthorizationFilter.class)
+        .addMockedMethod("getSecurityContext").withConstructor().createMock();
+    SecurityContext securityContext = createNiceMock(SecurityContext.class);
+    Authentication authentication = createNiceMock(Authentication.class);
+    AmbariGrantedAuthority authority = 
createNiceMock(AmbariGrantedAuthority.class);
+    PrivilegeEntity privilegeEntity = createNiceMock(PrivilegeEntity.class);
+    PermissionEntity permission = createNiceMock(PermissionEntity.class);
+    FilterConfig filterConfig = createNiceMock(FilterConfig.class);
+
+
+    expect(filterConfig.getInitParameter("realm")).andReturn("AuthFilter");
+    expect(authentication.isAuthenticated()).andReturn(true);
+    expect(request.getRequestURI()).andReturn("/api/v1/persist/some_val");
+    expect(authority.getPrivilegeEntity()).andReturn(privilegeEntity);
+    expect(privilegeEntity.getPermission()).andReturn(permission);
+    EasyMock.<Collection<? extends 
GrantedAuthority>>expect(authentication.getAuthorities())
+        .andReturn(Collections.singletonList(authority));
+    expect(filter.getSecurityContext()).andReturn(securityContext);
+    expect(securityContext.getAuthentication()).andReturn(authentication);
+
+
+    expect(request.getMethod()).andReturn("POST");
+    expect(permission.getId()).andReturn(PermissionEntity.VIEW_USE_PERMISSION);
+
+    // expect permission denial
+    response.setHeader("WWW-Authenticate", "Basic realm=\"AuthFilter\"");
+    response.sendError(HttpServletResponse.SC_FORBIDDEN, "You do not have 
permissions to access this resource.");
+    response.flushBuffer();
+
+    replay(request, response, chain, filter, securityContext, authentication, 
authority,
+        privilegeEntity, permission, filterConfig);
+
+    filter.init(filterConfig);
+    filter.doFilter(request, response, chain);
+
+    verify(request, response, chain, filter, securityContext, authentication, 
authority,
+        privilegeEntity, permission, filterConfig);
+  }
+}
\ No newline at end of file

Reply via email to