Selaa lähdekoodia

AMBARI-8027 Admin View: need better username validation. (atkach)

atkach 10 vuotta sitten
vanhempi
commit
90855a0dba

+ 2 - 2
ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/users/UsersCreateCtrl.js

@@ -33,7 +33,7 @@ angular.module('ambariAdminConsole')
         'Users/active': !!$scope.user.active,
         'Users/admin': !!$scope.user.admin
       }).then(function() {
-        Alert.success('Created user <a href="#/users/' + $scope.user.user_name + '">' + $scope.user.user_name + "</a>");
+        Alert.success('Created user <a href="#/users/' + encodeURIComponent($scope.user.user_name) + '">' + $scope.user.user_name + "</a>");
         $scope.form.$setPristine();
         $location.path(targetUrl);
       }).catch(function(data) {
@@ -68,4 +68,4 @@ angular.module('ambariAdminConsole')
       event.preventDefault();
     }
   });
-}]);
+}]);

+ 5 - 2
ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/users/UsersListCtrl.js

@@ -43,7 +43,10 @@ angular.module('ambariAdminConsole')
       admin: $scope.adminFilter
     }).then(function(data) {
       $scope.totalUsers = data.data.itemTotal;
-      $scope.users = data.data.items;
+      $scope.users = data.data.items.map(function (user) {
+        user.Users.encoded_name = encodeURIComponent(user.Users.user_name);
+        return user;
+      });
     });
   };
 
@@ -85,4 +88,4 @@ angular.module('ambariAdminConsole')
       $scope.loadUsers();
     }
   });
-}]);
+}]);

+ 1 - 1
ambari-admin/src/main/resources/ui/admin-web/app/scripts/directives/editableList.js

@@ -121,7 +121,7 @@ angular.module('ambariAdminConsole')
             
           } else {
             // Load typeahed items based on current input
-            $resource.listByName(newValue).then(function(data) {
+            $resource.listByName(encodeURIComponent(newValue)).then(function(data) {
               var items = [];
               angular.forEach(data.data.items, function(item) {
                 var name;

+ 1 - 1
ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js

@@ -41,7 +41,7 @@ angular.module('ambariAdminConsole')
       controller: 'UsersCreateCtrl'
     },
     show: {
-      url: '/users/:id',
+      url: '/users/:id*',
       templateUrl: 'views/users/show.html',
       controller: 'UsersShowCtrl'
     }

+ 1 - 1
ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/Group.js

@@ -123,7 +123,7 @@ angular.module('ambariAdminConsole')
 
     $http({
       method: 'POST',
-      url: Settings.baseUrl + '/groups/' + this.group_name + '/members' + '/'+ member.user_name
+      url: Settings.baseUrl + '/groups/' + this.group_name + '/members' + '/'+ encodeURIComponent(member.user_name)
     })
     .success(function(data) {
       deferred.resolve(data)

+ 2 - 2
ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/User.js

@@ -82,10 +82,10 @@ angular.module('ambariAdminConsole')
       return $http.get(Settings.baseUrl + '/privileges', {
         params:{
           'PrivilegeInfo/principal_type': 'USER',
-          'PrivilegeInfo/principal_name': userId,
+          'PrivilegeInfo/principal_name': encodeURIComponent(userId),
           'fields': '*'
         }
       });
     }
   };
-}]);
+}]);

+ 2 - 2
ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html

@@ -68,7 +68,7 @@
           <span class="glyphicon" tooltip="{{user.Users.admin ? 'Ambari Admin' : ''}}" ng-class="{'glyphicon-flash' : user.Users.admin}"></span>
         </td>
         <td>
-          <link-to route="users.show" id="{{user.Users.user_name}}">{{user.Users.user_name}}</link-to>
+           <a href="#/users/{{user.Users.encoded_name}}">{{user.Users.user_name}}</a>
         </td>
         <td>{{user.Users.ldap_user ? 'LDAP' : 'Local'}}</td>
         <td><span ng-class="user.Users.active ? 'text-success' : 'text-danger'">{{user.Users.active ? 'Active' : 'Inactive'}}</span></td>
@@ -84,4 +84,4 @@
     </div>
     
   </div>
-</div>
+</div>

+ 6 - 6
ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java

@@ -155,11 +155,7 @@ public abstract class BaseRequest implements Request {
 
   @Override
   public String getURI() {
-    try {
-      return URLDecoder.decode(m_uriInfo.getRequestUri().toASCIIString(), "UTF-8");
-    } catch (UnsupportedEncodingException e) {
-      throw new RuntimeException("Unable to decode URI: " + e, e);
-    }
+    return m_uriInfo.getRequestUri().toASCIIString();
   }
 
   @Override
@@ -314,7 +310,11 @@ public abstract class BaseRequest implements Request {
     }
 
     if (queryString != null) {
-      m_predicate = getPredicateCompiler().compile(queryString);
+      try {
+        m_predicate = getPredicateCompiler().compile(URLDecoder.decode(queryString, "UTF-8"));
+      } catch (UnsupportedEncodingException e) {
+        throw new RuntimeException("Unable to decode URI: " + e, e);
+      }
     }
   }
 

+ 7 - 1
ambari-server/src/main/java/org/apache/ambari/server/api/services/ResultPostProcessorImpl.java

@@ -24,6 +24,8 @@ import org.apache.ambari.server.api.resources.ResourceInstance;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.api.util.TreeNode;
 
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -79,7 +81,11 @@ public class ResultPostProcessorImpl implements ResultPostProcessor {
       href = node.getProperty("href");
       int i = href.indexOf('?');
       if (i != -1) {
-        href = href.substring(0, i);
+        try {
+          href = URLDecoder.decode(href.substring(0, i), "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+          throw new RuntimeException("Unable to decode URI: " + e, e);
+        }
       }
     } else {
       String isItemsCollection = node.getProperty("isCollection");

+ 7 - 1
ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java

@@ -19,6 +19,8 @@
 package org.apache.ambari.server.security.authorization;
 
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -222,7 +224,11 @@ public class AmbariAuthorizationFilter implements Filter {
     if (!matcher.matches()) {
       return null;
     } else {
-      return matcher.group(1);
+      try {
+        return URLDecoder.decode(matcher.group(1), "UTF-8");
+      } catch (UnsupportedEncodingException e) {
+        throw new RuntimeException("Unable to decode URI: " + e, e);
+      }
     }
   }
 

+ 3 - 2
ambari-server/src/test/java/org/apache/ambari/server/api/services/BaseRequestTest.java

@@ -171,8 +171,9 @@ public abstract class BaseRequestTest {
   @Test
   public void testProcess_QueryInURI() throws Exception {
     HttpHeaders headers = createNiceMock(HttpHeaders.class);
-    String uriString = "http://localhost.com:8080/api/v1/clusters/c1?foo=foo-value&bar=bar-value";
-    URI uri = new URI(URLEncoder.encode(uriString, "UTF-8"));
+    String path = URLEncoder.encode("http://localhost.com:8080/api/v1/clusters/c1", "UTF-8");
+    String query = URLEncoder.encode("foo=foo-value&bar=bar-value", "UTF-8");
+    URI uri = new URI(path + "?" + query);
     PredicateCompiler compiler = createStrictMock(PredicateCompiler.class);
     Predicate predicate = createNiceMock(Predicate.class);
     UriInfo uriInfo = createMock(UriInfo.class);

+ 36 - 1
ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilterTest.java

@@ -355,6 +355,41 @@ public class AmbariAuthorizationFilterTest {
     }
   }
 
+  @Test
+  public void testParseUserNameSpecial() throws Exception {
+    String contextPath = "/api/v1/users/user%3F";
+    String username = AmbariAuthorizationFilter.parseUserName(contextPath);
+    Assert.assertEquals("user?", username);
+
+    contextPath = "/api/v1/users/a%20b";
+    username = AmbariAuthorizationFilter.parseUserName(contextPath);
+    Assert.assertEquals("a b", username);
+
+    contextPath = "/api/v1/users/a%2Bb";
+    username = AmbariAuthorizationFilter.parseUserName(contextPath);
+    Assert.assertEquals("a+b", username);
+
+    contextPath = "/api/v1/users/a%21";
+    username = AmbariAuthorizationFilter.parseUserName(contextPath);
+    Assert.assertEquals("a!", username);
+
+    contextPath = "/api/v1/users/a%3D";
+    username = AmbariAuthorizationFilter.parseUserName(contextPath);
+    Assert.assertEquals("a=", username);
+
+    contextPath = "/api/v1/users/a%2Fb";
+    username = AmbariAuthorizationFilter.parseUserName(contextPath);
+    Assert.assertEquals("a/b", username);
+
+    contextPath = "/api/v1/users/a%23";
+    username = AmbariAuthorizationFilter.parseUserName(contextPath);
+    Assert.assertEquals("a#", username);
+
+    contextPath = "/api/v1/users/%3F%3F";
+    username = AmbariAuthorizationFilter.parseUserName(contextPath);
+    Assert.assertEquals("??", username);
+  }
+
   @Test
   public void testParseViewContextPath() throws Exception {
     final String[] pathesToTest = {
@@ -369,4 +404,4 @@ public class AmbariAuthorizationFilterTest {
       Assert.assertEquals("1.0.0", dto.getVersion());
     }
   }
-}
+}

+ 1 - 1
ambari-web/app/router.js

@@ -204,7 +204,7 @@ App.Router = Em.Router.extend({
       data: {
         auth: "Basic " + hash,
         usr: usr,
-        loginName: loginName
+        loginName: encodeURIComponent(loginName)
       },
       beforeSend: 'authBeforeSend',
       success: 'loginSuccessCallback',