From a3ecc3b910aa3bbc3ede2b8ba1bd040d02a26ca8 Mon Sep 17 00:00:00 2001 From: Aaron Myers Date: Mon, 29 Apr 2013 18:07:55 +0000 Subject: [PATCH] HDFS-4733. Make HttpFS username pattern configurable. Contributed by Alejandro Abdelnur. git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1477241 13f79535-47bb-0310-9956-ffa450edef68 --- .../http/server/HttpFSParametersProvider.java | 6 +- .../fs/http/server/HttpFSServerWebApp.java | 4 + .../apache/hadoop/lib/wsrs/UserProvider.java | 19 +++- .../src/main/resources/httpfs-default.xml | 8 ++ .../http/server/TestHttpFSCustomUserName.java | 94 +++++++++++++++++++ .../hadoop/lib/wsrs/TestUserProvider.java | 25 +++-- 6 files changed, 141 insertions(+), 15 deletions(-) create mode 100644 hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/server/TestHttpFSCustomUserName.java diff --git a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSParametersProvider.java b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSParametersProvider.java index d217322b6ae..1410b8b8cdf 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSParametersProvider.java +++ b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSParametersProvider.java @@ -193,7 +193,7 @@ public class HttpFSParametersProvider extends ParametersProvider { * Constructor. */ public DoAsParam() { - super(NAME, null, UserProvider.USER_PATTERN); + super(NAME, null, UserProvider.getUserPattern()); } /** @@ -248,7 +248,7 @@ public class HttpFSParametersProvider extends ParametersProvider { * Constructor. */ public GroupParam() { - super(NAME, null, UserProvider.USER_PATTERN); + super(NAME, null, UserProvider.getUserPattern()); } } @@ -344,7 +344,7 @@ public class HttpFSParametersProvider extends ParametersProvider { * Constructor. */ public OwnerParam() { - super(NAME, null, UserProvider.USER_PATTERN); + super(NAME, null, UserProvider.getUserPattern()); } } diff --git a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSServerWebApp.java b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSServerWebApp.java index 440d7c9702b..f8e53d4bb3a 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSServerWebApp.java +++ b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSServerWebApp.java @@ -24,6 +24,7 @@ import org.apache.hadoop.fs.CommonConfigurationKeysPublic; import org.apache.hadoop.lib.server.ServerException; import org.apache.hadoop.lib.service.FileSystemAccess; import org.apache.hadoop.lib.servlet.ServerWebApp; +import org.apache.hadoop.lib.wsrs.UserProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -102,6 +103,9 @@ public class HttpFSServerWebApp extends ServerWebApp { LOG.info("Connects to Namenode [{}]", get().get(FileSystemAccess.class).getFileSystemConfiguration(). get(CommonConfigurationKeysPublic.FS_DEFAULT_NAME_KEY)); + String userPattern = getConfig().get(UserProvider.USER_PATTERN_KEY, + UserProvider.USER_PATTERN_DEFAULT); + UserProvider.setUserPattern(userPattern); } /** diff --git a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/UserProvider.java b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/UserProvider.java index fd59b19dc34..cd1cfc7f4ef 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/UserProvider.java +++ b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/UserProvider.java @@ -41,12 +41,27 @@ public class UserProvider extends AbstractHttpContextInjectable imple public static final String USER_NAME_PARAM = "user.name"; - public static final Pattern USER_PATTERN = Pattern.compile("^[A-Za-z_][A-Za-z0-9._-]*[$]?$"); + + public static final String USER_PATTERN_KEY + = "httpfs.user.provider.user.pattern"; + + public static final String USER_PATTERN_DEFAULT + = "^[A-Za-z_][A-Za-z0-9._-]*[$]?$"; + + private static Pattern userPattern = Pattern.compile(USER_PATTERN_DEFAULT); + + public static void setUserPattern(String pattern) { + userPattern = Pattern.compile(pattern); + } + + public static Pattern getUserPattern() { + return userPattern; + } static class UserParam extends StringParam { public UserParam(String user) { - super(USER_NAME_PARAM, user, USER_PATTERN); + super(USER_NAME_PARAM, user, getUserPattern()); } @Override diff --git a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/resources/httpfs-default.xml b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/resources/httpfs-default.xml index 7171d388fe9..87cd73020d1 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/resources/httpfs-default.xml +++ b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/resources/httpfs-default.xml @@ -226,4 +226,12 @@ + + httpfs.user.provider.user.pattern + ^[A-Za-z_][A-Za-z0-9._-]*[$]?$ + + Valid pattern for user and group names, it must be a valid java regex. + + + diff --git a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/server/TestHttpFSCustomUserName.java b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/server/TestHttpFSCustomUserName.java new file mode 100644 index 00000000000..e8407fc30cd --- /dev/null +++ b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/server/TestHttpFSCustomUserName.java @@ -0,0 +1,94 @@ +/** + * 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.hadoop.fs.http.server; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.CommonConfigurationKeysPublic; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.fs.http.client.HttpFSKerberosAuthenticator; +import org.apache.hadoop.lib.server.Service; +import org.apache.hadoop.lib.server.ServiceException; +import org.apache.hadoop.lib.service.Groups; +import org.apache.hadoop.lib.wsrs.UserProvider; +import org.apache.hadoop.security.authentication.client.AuthenticatedURL; +import org.apache.hadoop.security.authentication.server.AuthenticationToken; +import org.apache.hadoop.security.authentication.util.Signer; +import org.apache.hadoop.test.HFSTestCase; +import org.apache.hadoop.test.HadoopUsersConfTestHelper; +import org.apache.hadoop.test.TestDir; +import org.apache.hadoop.test.TestDirHelper; +import org.apache.hadoop.test.TestHdfs; +import org.apache.hadoop.test.TestHdfsHelper; +import org.apache.hadoop.test.TestJetty; +import org.apache.hadoop.test.TestJettyHelper; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.junit.Assert; +import org.junit.Test; +import org.mortbay.jetty.Server; +import org.mortbay.jetty.webapp.WebAppContext; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.Writer; +import java.net.HttpURLConnection; +import java.net.URL; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.List; + +public class TestHttpFSCustomUserName extends HFSTestCase { + + @Test + @TestDir + @TestJetty + public void defaultUserName() throws Exception { + String dir = TestDirHelper.getTestDir().getAbsolutePath(); + + Configuration httpfsConf = new Configuration(false); + HttpFSServerWebApp server = + new HttpFSServerWebApp(dir, dir, dir, dir, httpfsConf); + server.init(); + Assert.assertEquals(UserProvider.USER_PATTERN_DEFAULT, + UserProvider.getUserPattern().pattern()); + server.destroy(); + } + + @Test + @TestDir + @TestJetty + public void customUserName() throws Exception { + String dir = TestDirHelper.getTestDir().getAbsolutePath(); + + Configuration httpfsConf = new Configuration(false); + httpfsConf.set(UserProvider.USER_PATTERN_KEY, "1"); + HttpFSServerWebApp server = + new HttpFSServerWebApp(dir, dir, dir, dir, httpfsConf); + server.init(); + Assert.assertEquals("1", UserProvider.getUserPattern().pattern()); + server.destroy(); + } + +} diff --git a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/wsrs/TestUserProvider.java b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/wsrs/TestUserProvider.java index 694e8dc3185..e8942fbe4ef 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/wsrs/TestUserProvider.java +++ b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/wsrs/TestUserProvider.java @@ -104,34 +104,39 @@ public class TestUserProvider { @Test @TestException(exception = IllegalArgumentException.class) public void userNameEmpty() { - UserProvider.UserParam userParam = new UserProvider.UserParam("username"); - userParam.parseParam(""); + new UserProvider.UserParam(""); } @Test @TestException(exception = IllegalArgumentException.class) public void userNameInvalidStart() { - UserProvider.UserParam userParam = new UserProvider.UserParam("username"); - userParam.parseParam("1x"); + new UserProvider.UserParam("1x"); } @Test @TestException(exception = IllegalArgumentException.class) public void userNameInvalidDollarSign() { - UserProvider.UserParam userParam = new UserProvider.UserParam("username"); - userParam.parseParam("1$x"); + new UserProvider.UserParam("1$x"); } @Test public void userNameMinLength() { - UserProvider.UserParam userParam = new UserProvider.UserParam("username"); - assertNotNull(userParam.parseParam("a")); + new UserProvider.UserParam("a"); } @Test public void userNameValidDollarSign() { - UserProvider.UserParam userParam = new UserProvider.UserParam("username"); - assertNotNull(userParam.parseParam("a$")); + new UserProvider.UserParam("a$"); + } + + @Test + public void customUserPattern() { + try { + UserProvider.setUserPattern("1"); + new UserProvider.UserParam("1"); + } finally { + UserProvider.setUserPattern(UserProvider.USER_PATTERN_DEFAULT); + } } }