YARN-2677 registry punycoding of usernames doesn't fix all usernames to be DNS-valid (stevel)

This commit is contained in:
Steve Loughran 2014-10-30 22:32:08 +00:00
parent cc900b213c
commit cd24075343
5 changed files with 77 additions and 11 deletions

View File

@ -692,6 +692,9 @@ Release 2.6.0 - UNRELEASED
YARN-2700 TestSecureRMRegistryOperations failing on windows: auth problems YARN-2700 TestSecureRMRegistryOperations failing on windows: auth problems
(stevel) (stevel)
YARN-2677 registry punycoding of usernames doesn't fix all usernames to be
DNS-valid (stevel)
--- ---
YARN-2598 GHS should show N/A instead of null for the inaccessible information YARN-2598 GHS should show N/A instead of null for the inaccessible information

View File

@ -44,6 +44,7 @@ import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
/** /**
@ -58,21 +59,46 @@ public class RegistryUtils {
/** /**
* Buld the user path -switches to the system path if the user is "". * Buld the user path -switches to the system path if the user is "".
* It also cross-converts the username to ascii via punycode * It also cross-converts the username to ascii via punycode
* @param shortname username or "" * @param username username or ""
* @return the path to the user * @return the path to the user
*/ */
public static String homePathForUser(String shortname) { public static String homePathForUser(String username) {
Preconditions.checkArgument(shortname != null, "null user"); Preconditions.checkArgument(username != null, "null user");
// catch recursion // catch recursion
if (shortname.startsWith(RegistryConstants.PATH_USERS)) { if (username.startsWith(RegistryConstants.PATH_USERS)) {
return shortname; return username;
} }
if (shortname.isEmpty()) { if (username.isEmpty()) {
return RegistryConstants.PATH_SYSTEM_SERVICES; return RegistryConstants.PATH_SYSTEM_SERVICES;
} }
// convert username to registry name
String convertedName = convertUsername(username);
return RegistryPathUtils.join(RegistryConstants.PATH_USERS, return RegistryPathUtils.join(RegistryConstants.PATH_USERS,
encodeForRegistry(shortname)); encodeForRegistry(convertedName));
}
/**
* Convert the username to that which can be used for registry
* entries. Lower cases it,
* Strip the kerberos realm off a username if needed, and any "/" hostname
* entries
* @param username user
* @return the converted username
*/
public static String convertUsername(String username) {
String converted= username.toLowerCase(Locale.ENGLISH);
int atSymbol = converted.indexOf('@');
if (atSymbol > 0) {
converted = converted.substring(0, atSymbol);
}
int slashSymbol = converted.indexOf('/');
if (slashSymbol > 0) {
converted = converted.substring(0, slashSymbol);
}
return converted;
} }
/** /**

View File

@ -83,12 +83,12 @@ public class RegistryOperationsService extends CuratorService
} }
/** /**
* Validate a path ... this includes checking that they are DNS-valid * Validate a path
* @param path path to validate * @param path path to validate
* @throws InvalidPathnameException if a path is considered invalid * @throws InvalidPathnameException if a path is considered invalid
*/ */
protected void validatePath(String path) throws InvalidPathnameException { protected void validatePath(String path) throws InvalidPathnameException {
RegistryPathUtils.validateElementsAsDNS(path); // currently no checks are performed
} }
@Override @Override

View File

@ -38,10 +38,19 @@ public class TestRegistryOperationUtils extends Assert {
public void testUsernameExtractionCurrentuser() throws Throwable { public void testUsernameExtractionCurrentuser() throws Throwable {
String whoami = RegistryUtils.getCurrentUsernameUnencoded(""); String whoami = RegistryUtils.getCurrentUsernameUnencoded("");
String ugiUser = UserGroupInformation.getCurrentUser().getShortUserName(); String ugiUser = UserGroupInformation.getCurrentUser().getShortUserName();
assertEquals(ugiUser, whoami); assertEquals(ugiUser, whoami);
} }
@Test
public void testShortenUsername() throws Throwable {
assertEquals("hbase",
RegistryUtils.convertUsername("hbase@HADOOP.APACHE.ORG"));
assertEquals("hbase",
RegistryUtils.convertUsername("hbase/localhost@HADOOP.APACHE.ORG"));
assertEquals("hbase",
RegistryUtils.convertUsername("hbase"));
assertEquals("hbase user",
RegistryUtils.convertUsername("hbase user"));
}
} }

View File

@ -301,4 +301,32 @@ public class TestRegistryOperations extends AbstractRegistryTest {
assertEquals(r1stat, stats.get("r1")); assertEquals(r1stat, stats.get("r1"));
assertEquals(r2stat, stats.get("r2")); assertEquals(r2stat, stats.get("r2"));
} }
@Test
public void testComplexUsernames() throws Throwable {
operations.mknode("/users/user with spaces", true);
operations.mknode("/users/user-with_underscores", true);
operations.mknode("/users/000000", true);
operations.mknode("/users/-storm", true);
operations.mknode("/users/windows\\ user", true);
String home = RegistryUtils.homePathForUser("\u0413PA\u0414_3");
operations.mknode(home, true);
operations.mknode(
RegistryUtils.servicePath(home, "service.class", "service 4_5"),
true);
operations.mknode(
RegistryUtils.homePathForUser("hbase@HADOOP.APACHE.ORG"),
true);
operations.mknode(
RegistryUtils.homePathForUser("hbase/localhost@HADOOP.APACHE.ORG"),
true);
home = RegistryUtils.homePathForUser("ADMINISTRATOR/127.0.0.1");
assertTrue("No 'administrator' in " + home, home.contains("administrator"));
operations.mknode(
home,
true);
}
} }