You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by ra...@apache.org on 2014/08/14 09:20:16 UTC
git commit: HBASE-11438 - [Visibility Controller] Support UTF8
character as Visibility Labels (Ram)
Repository: hbase
Updated Branches:
refs/heads/branch-1 cd59a023c -> ae2a94402
HBASE-11438 - [Visibility Controller] Support UTF8 character as Visibility
Labels (Ram)
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/ae2a9440
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/ae2a9440
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/ae2a9440
Branch: refs/heads/branch-1
Commit: ae2a944027bc146efd20e3fe3498e4c717b7baed
Parents: cd59a02
Author: Ramkrishna <ra...@intel.com>
Authored: Thu Aug 14 12:48:57 2014 +0530
Committer: Ramkrishna <ra...@intel.com>
Committed: Thu Aug 14 12:48:57 2014 +0530
----------------------------------------------------------------------
.../security/visibility/Authorizations.java | 11 --
.../security/visibility/CellVisibility.java | 37 +++++++
.../visibility/VisibilityLabelsValidator.java | 8 +-
.../apache/hadoop/hbase/client/TestScan.java | 41 +------
.../hadoop/hbase/rest/model/ScannerModel.java | 8 +-
.../security/visibility/ExpressionParser.java | 107 +++++++++++++------
.../visibility/VisibilityController.java | 42 +++-----
.../visibility/TestExpressionParser.java | 95 +++++++++++++++-
.../visibility/TestVisibilityLabels.java | 85 ++++++++++++++-
9 files changed, 302 insertions(+), 132 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hbase/blob/ae2a9440/hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/Authorizations.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/Authorizations.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/Authorizations.java
index 2a07625..a82d6d8 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/Authorizations.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/Authorizations.java
@@ -36,22 +36,11 @@ public class Authorizations {
public Authorizations(String... labels) {
this.labels = new ArrayList<String>(labels.length);
for (String label : labels) {
- validateLabel(label);
this.labels.add(label);
}
}
- private void validateLabel(String label) {
- if (!VisibilityLabelsValidator.isValidLabel(label)) {
- throw new IllegalArgumentException("Invalid authorization label : " + label
- + ". Authorizations cannot contain '(', ')' ,'&' ,'|', '!'" + " and cannot be empty");
- }
- }
-
public Authorizations(List<String> labels) {
- for (String label : labels) {
- validateLabel(label);
- }
this.labels = labels;
}
http://git-wip-us.apache.org/repos/asf/hbase/blob/ae2a9440/hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/CellVisibility.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/CellVisibility.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/CellVisibility.java
index 3bd527b..0e71a0a 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/CellVisibility.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/CellVisibility.java
@@ -19,6 +19,7 @@ package org.apache.hadoop.hbase.security.visibility;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.hbase.util.Bytes;
/**
* This contains a visibility expression which can be associated with a cell. When it is set with a
@@ -46,4 +47,40 @@ public class CellVisibility {
public String toString() {
return this.expression;
}
+
+ /**
+ * Helps in quoting authentication Strings. Use this if unicode characters to
+ * be used in expression or special characters like '(', ')',
+ * '"','\','&','|','!'
+ */
+ public static String quote(String auth) {
+ return quote(Bytes.toBytes(auth));
+ }
+
+ /**
+ * Helps in quoting authentication Strings. Use this if unicode characters to
+ * be used in expression or special characters like '(', ')',
+ * '"','\','&','|','!'
+ */
+ public static String quote(byte[] auth) {
+ int escapeChars = 0;
+
+ for (int i = 0; i < auth.length; i++)
+ if (auth[i] == '"' || auth[i] == '\\')
+ escapeChars++;
+
+ byte[] escapedAuth = new byte[auth.length + escapeChars + 2];
+ int index = 1;
+ for (int i = 0; i < auth.length; i++) {
+ if (auth[i] == '"' || auth[i] == '\\') {
+ escapedAuth[index++] = '\\';
+ }
+ escapedAuth[index++] = auth[i];
+ }
+
+ escapedAuth[0] = '"';
+ escapedAuth[escapedAuth.length - 1] = '"';
+
+ return Bytes.toString(escapedAuth);
+ }
}
http://git-wip-us.apache.org/repos/asf/hbase/blob/ae2a9440/hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityLabelsValidator.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityLabelsValidator.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityLabelsValidator.java
index 9700b55..49b1778 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityLabelsValidator.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityLabelsValidator.java
@@ -17,7 +17,6 @@
*/
package org.apache.hadoop.hbase.security.visibility;
-import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.hadoop.classification.InterfaceAudience;
@@ -60,7 +59,7 @@ public class VisibilityLabelsValidator {
return validAuthChars[0xff & b];
}
- static final boolean isValidLabel(byte[] label) {
+ public static final boolean isValidLabel(byte[] label) {
for (int i = 0; i < label.length; i++) {
if (!isValidAuthChar(label[i])) {
return false;
@@ -68,9 +67,4 @@ public class VisibilityLabelsValidator {
}
return true;
}
-
- public static final boolean isValidLabel(String label) {
- Matcher matcher = pattern.matcher(label);
- return matcher.matches();
- }
}
http://git-wip-us.apache.org/repos/asf/hbase/blob/ae2a9440/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestScan.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestScan.java b/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestScan.java
index 97c5f0f..10da121 100644
--- a/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestScan.java
+++ b/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestScan.java
@@ -114,56 +114,21 @@ public class TestScan {
@Test
public void testSetAuthorizations() {
Scan scan = new Scan();
- scan.setAuthorizations(new Authorizations("A", "B", "0123", "A0", "1A1", "_a"));
try {
+ scan.setAuthorizations(new Authorizations("\u002b|\u0029"));
+ scan.setAuthorizations(new Authorizations("A", "B", "0123", "A0", "1A1", "_a"));
scan.setAuthorizations(new Authorizations("A|B"));
- fail("Should have failed for A|B.");
- } catch (IllegalArgumentException e) {
- }
- try {
scan.setAuthorizations(new Authorizations("A&B"));
- fail("Should have failed for A&B.");
- } catch (IllegalArgumentException e) {
- }
- try {
scan.setAuthorizations(new Authorizations("!B"));
- fail("Should have failed for !B.");
- } catch (IllegalArgumentException e) {
- }
- try {
scan.setAuthorizations(new Authorizations("A", "(A)"));
- fail("Should have failed for (A).");
- } catch (IllegalArgumentException e) {
- }
- try {
scan.setAuthorizations(new Authorizations("A", "{A"));
- fail("Should have failed for {A.");
- } catch (IllegalArgumentException e) {
- }
- try {
scan.setAuthorizations(new Authorizations(" "));
- fail("Should have failed for empty");
- } catch (IllegalArgumentException e) {
- }
- try {
scan.setAuthorizations(new Authorizations(":B"));
- } catch (IllegalArgumentException e) {
- fail("Should not have failed for :B");
- }
- try {
scan.setAuthorizations(new Authorizations("-B"));
- } catch (IllegalArgumentException e) {
- fail("Should not have failed for -B");
- }
- try {
scan.setAuthorizations(new Authorizations(".B"));
- } catch (IllegalArgumentException e) {
- fail("Should not have failed for .B");
- }
- try {
scan.setAuthorizations(new Authorizations("/B"));
} catch (IllegalArgumentException e) {
- fail("Should not have failed for /B");
+ fail("should not throw exception");
}
}
}
http://git-wip-us.apache.org/repos/asf/hbase/blob/ae2a9440/hbase-server/src/main/java/org/apache/hadoop/hbase/rest/model/ScannerModel.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/rest/model/ScannerModel.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/rest/model/ScannerModel.java
index 2fa53f4..1fc0a5d 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/rest/model/ScannerModel.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/rest/model/ScannerModel.java
@@ -70,12 +70,11 @@ import org.apache.hadoop.hbase.filter.WhileMatchFilter;
import org.apache.hadoop.hbase.rest.ProtobufMessageHandler;
import org.apache.hadoop.hbase.rest.protobuf.generated.ScannerMessage.Scanner;
import org.apache.hadoop.hbase.security.visibility.Authorizations;
-import org.apache.hadoop.hbase.security.visibility.VisibilityLabelsValidator;
import org.apache.hadoop.hbase.util.Base64;
+import org.apache.hadoop.hbase.util.ByteStringer;
import org.apache.hadoop.hbase.util.Bytes;
import com.google.protobuf.ByteString;
-import org.apache.hadoop.hbase.util.ByteStringer;
import com.sun.jersey.api.json.JSONConfiguration;
import com.sun.jersey.api.json.JSONJAXBContext;
import com.sun.jersey.api.json.JSONMarshaller;
@@ -527,11 +526,6 @@ public class ScannerModel implements ProtobufMessageHandler, Serializable {
if (authorizations != null) {
List<String> labels = authorizations.getLabels();
for (String label : labels) {
- if (!VisibilityLabelsValidator.isValidLabel(label)) {
- throw new IllegalArgumentException("Invalid authorization label : " + label
- + ". Authorizations cannot contain '(', ')' ,'&' ,'|', '!'" + " " +
- "and cannot be empty");
- }
model.addLabel(label);
}
}
http://git-wip-us.apache.org/repos/asf/hbase/blob/ae2a9440/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/ExpressionParser.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/ExpressionParser.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/ExpressionParser.java
index f6ddf75..bb17b48 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/ExpressionParser.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/ExpressionParser.java
@@ -17,6 +17,8 @@
*/
package org.apache.hadoop.hbase.security.visibility;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Stack;
import org.apache.hadoop.classification.InterfaceAudience;
@@ -35,49 +37,80 @@ public class ExpressionParser {
private static final char AND = '&';
private static final char NOT = '!';
private static final char SPACE = ' ';
-
+ private static final char DOUBLE_QUOTES = '"';
public ExpressionNode parse(String expS) throws ParseException {
expS = expS.trim();
Stack<ExpressionNode> expStack = new Stack<ExpressionNode>();
int index = 0;
- int endPos = expS.length();
byte[] exp = Bytes.toBytes(expS);
+ int endPos = exp.length;
while (index < endPos) {
byte b = exp[index];
switch (b) {
- case OPEN_PARAN:
- processOpenParan(expStack, expS, index);
- index = skipSpaces(exp, index);
- break;
- case CLOSE_PARAN:
- processCloseParan(expStack, expS, index);
- index = skipSpaces(exp, index);
- break;
- case AND:
- case OR:
- processANDorOROp(getOperator(b), expStack, expS, index);
- index = skipSpaces(exp, index);
- break;
- case NOT:
- processNOTOp(expStack, expS, index);
- break;
- default:
- int labelOffset = index;
- do {
- if (!VisibilityLabelsValidator.isValidAuthChar(exp[index])) {
- throw new ParseException("Error parsing expression " + expS + " at column : "
- + index);
+ case OPEN_PARAN:
+ processOpenParan(expStack, expS, index);
+ index = skipSpaces(exp, index);
+ break;
+ case CLOSE_PARAN:
+ processCloseParan(expStack, expS, index);
+ index = skipSpaces(exp, index);
+ break;
+ case AND:
+ case OR:
+ processANDorOROp(getOperator(b), expStack, expS, index);
+ index = skipSpaces(exp, index);
+ break;
+ case NOT:
+ processNOTOp(expStack, expS, index);
+ break;
+ case DOUBLE_QUOTES:
+ int labelOffset = ++index;
+ // We have to rewrite the expression within double quotes as incase of expressions
+ // with escape characters we may have to avoid them as the original expression did
+ // not have them
+ List<Byte> list = new ArrayList<Byte>();
+ while (index < endPos && !endDoubleQuotesFound(exp[index])) {
+ if (exp[index] == '\\') {
+ index++;
+ if (exp[index] != '\\' && exp[index] != '"')
+ throw new ParseException("invalid escaping with quotes " + expS + " at column : "
+ + index);
+ }
+ list.add(exp[index]);
+ index++;
}
- index++;
- } while (index < endPos && !isEndOfLabel(exp[index]));
- String leafExp = new String(exp, labelOffset, index - labelOffset).trim();
- if (leafExp.isEmpty()) {
- throw new ParseException("Error parsing expression " + expS + " at column : " + index);
- }
- processLabelExpNode(new LeafExpressionNode(leafExp), expStack, expS, index);
- // We already crossed the label node index. So need to reduce 1 here.
- index--;
- index = skipSpaces(exp, index);
+ // The expression has come to the end. still no double quotes found
+ if(index == endPos) {
+ throw new ParseException("No terminating quotes " + expS + " at column : " + index);
+ }
+ // This could be costly. but do we have any alternative?
+ // If we don't do this way then we may have to handle while checking the authorizations.
+ // Better to do it here.
+ byte[] array = com.google.common.primitives.Bytes.toArray(list);
+ String leafExp = new String(array).trim();
+ if (leafExp.isEmpty()) {
+ throw new ParseException("Error parsing expression " + expS + " at column : " + index);
+ }
+ processLabelExpNode(new LeafExpressionNode(leafExp), expStack, expS, index);
+ index = skipSpaces(exp, index);
+ break;
+ default:
+ labelOffset = index;
+ do {
+ if (!VisibilityLabelsValidator.isValidAuthChar(exp[index])) {
+ throw new ParseException("Error parsing expression "
+ + expS + " at column : " + index);
+ }
+ index++;
+ } while (index < endPos && !isEndOfLabel(exp[index]));
+ leafExp = new String(exp, labelOffset, index - labelOffset).trim();
+ if (leafExp.isEmpty()) {
+ throw new ParseException("Error parsing expression " + expS + " at column : " + index);
+ }
+ processLabelExpNode(new LeafExpressionNode(leafExp), expStack, expS, index);
+ // We already crossed the label node index. So need to reduce 1 here.
+ index--;
+ index = skipSpaces(exp, index);
}
index++;
}
@@ -255,8 +288,12 @@ public class ExpressionParser {
expStack.push(new NonLeafExpressionNode(Operator.NOT));
}
+ private static boolean endDoubleQuotesFound(byte b) {
+ return (b == DOUBLE_QUOTES);
+ }
private static boolean isEndOfLabel(byte b) {
- return (b == OPEN_PARAN || b == CLOSE_PARAN || b == OR || b == AND || b == NOT || b == SPACE);
+ return (b == OPEN_PARAN || b == CLOSE_PARAN || b == OR || b == AND ||
+ b == NOT || b == SPACE);
}
private static Operator getOperator(byte op) {
http://git-wip-us.apache.org/repos/asf/hbase/blob/ae2a9440/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java
index 661d188..9439ea5 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java
@@ -53,11 +53,11 @@ import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.KeyValue.Type;
import org.apache.hadoop.hbase.KeyValueUtil;
-import org.apache.hadoop.hbase.MetaTableAccessor;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.Tag;
+import org.apache.hadoop.hbase.MetaTableAccessor;
import org.apache.hadoop.hbase.client.Append;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
@@ -1149,13 +1149,6 @@ public class VisibilityController extends BaseRegionObserver implements MasterOb
if (table.isSystemTable() && !table.equals(LABELS_TABLE_NAME)) {
return null;
}
- } else {
- for (String label : authorizations.getLabels()) {
- if (!VisibilityLabelsValidator.isValidLabel(label)) {
- throw new IllegalArgumentException("Invalid authorization label : " + label
- + ". Authorizations cannot contain '(', ')' ,'&' ,'|', '!'" + " and cannot be empty");
- }
- }
}
Filter visibilityLabelFilter = null;
if (this.scanLabelGenerators != null) {
@@ -1310,30 +1303,21 @@ public class VisibilityController extends BaseRegionObserver implements MasterOb
for (VisibilityLabel visLabel : labels) {
byte[] label = visLabel.getLabel().toByteArray();
String labelStr = Bytes.toString(label);
- if (VisibilityLabelsValidator.isValidLabel(label)) {
- if (this.visibilityManager.getLabelOrdinal(labelStr) > 0) {
- RegionActionResult.Builder failureResultBuilder = RegionActionResult.newBuilder();
- failureResultBuilder.setException(ResponseConverter
- .buildException(new LabelAlreadyExistsException("Label '" + labelStr
- + "' already exists")));
- response.addResult(failureResultBuilder.build());
- } else {
- Put p = new Put(Bytes.toBytes(ordinalCounter));
- p.addImmutable(
- LABELS_TABLE_FAMILY, LABEL_QUALIFIER, label, LABELS_TABLE_TAGS);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Adding the label "+labelStr);
- }
- puts.add(p);
- ordinalCounter++;
- response.addResult(successResult);
- }
- } else {
+ if (this.visibilityManager.getLabelOrdinal(labelStr) > 0) {
RegionActionResult.Builder failureResultBuilder = RegionActionResult.newBuilder();
failureResultBuilder.setException(ResponseConverter
- .buildException(new InvalidLabelException("Invalid visibility label '" + labelStr
- + "'")));
+ .buildException(new LabelAlreadyExistsException("Label '" + labelStr
+ + "' already exists")));
response.addResult(failureResultBuilder.build());
+ } else {
+ Put p = new Put(Bytes.toBytes(ordinalCounter));
+ p.addImmutable(LABELS_TABLE_FAMILY, LABEL_QUALIFIER, label, LABELS_TABLE_TAGS);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Adding the label " + labelStr);
+ }
+ puts.add(p);
+ ordinalCounter++;
+ response.addResult(successResult);
}
}
OperationStatus[] opStatus = this.regionEnv.getRegion().batchMutate(
http://git-wip-us.apache.org/repos/asf/hbase/blob/ae2a9440/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestExpressionParser.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestExpressionParser.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestExpressionParser.java
index f7a8dfd..ed2a1d5 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestExpressionParser.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestExpressionParser.java
@@ -17,9 +17,9 @@
*/
package org.apache.hadoop.hbase.security.visibility;
-import static org.junit.Assert.fail;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import org.apache.hadoop.hbase.SmallTests;
import org.apache.hadoop.hbase.security.visibility.expression.ExpressionNode;
@@ -308,6 +308,99 @@ public class TestExpressionParser {
executeNegativeCase("! a");
}
+ @Test
+ public void testNonAsciiCases() throws Exception {
+ ExpressionNode node = parser.parse(CellVisibility.quote("\u0027") + "&"
+ + CellVisibility.quote("\u002b") + "|" + CellVisibility.quote("\u002d") + "&"
+ + CellVisibility.quote("\u003f"));
+ assertTrue(node instanceof NonLeafExpressionNode);
+ NonLeafExpressionNode nlNode = (NonLeafExpressionNode) node;
+ assertEquals(Operator.AND, nlNode.getOperator());
+ assertEquals(2, nlNode.getChildExps().size());
+ assertEquals("\u003f", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
+ assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
+ nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
+ assertEquals(Operator.OR, nlNode.getOperator());
+ assertEquals(2, nlNode.getChildExps().size());
+ assertEquals("\u002d", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
+ assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
+ nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
+ assertEquals(Operator.AND, nlNode.getOperator());
+ assertEquals(2, nlNode.getChildExps().size());
+ assertEquals("\u002b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
+ assertEquals("\u0027", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
+
+ node = parser.parse(CellVisibility.quote("\u0027") + "&" + CellVisibility.quote("\u002b") + "|"
+ + CellVisibility.quote("\u002d") + "&" + CellVisibility.quote("\u003f"));
+ assertTrue(node instanceof NonLeafExpressionNode);
+ nlNode = (NonLeafExpressionNode) node;
+ assertEquals(Operator.AND, nlNode.getOperator());
+ assertEquals(2, nlNode.getChildExps().size());
+ assertEquals("\u003f", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
+ assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
+ nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
+ assertEquals(Operator.OR, nlNode.getOperator());
+ assertEquals(2, nlNode.getChildExps().size());
+ assertEquals("\u002d", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
+ assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
+ nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
+ assertEquals(Operator.AND, nlNode.getOperator());
+ assertEquals(2, nlNode.getChildExps().size());
+ assertEquals("\u002b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
+ assertEquals("\u0027", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
+ }
+
+ @Test
+ public void testCasesSeperatedByDoubleQuotes() throws Exception {
+ ExpressionNode node = null;
+ try {
+ node = parser.parse("\u0027&\"|\u002b&\u003f");
+ fail("Excpetion must be thrown as there are special characters without quotes");
+ } catch (ParseException e) {
+ }
+ node = parser.parse(CellVisibility.quote("\u0027") + "&" + CellVisibility.quote("\"") + "|"
+ + CellVisibility.quote("\u002b" + "&" + "\u003f"));
+ assertTrue(node instanceof NonLeafExpressionNode);
+ NonLeafExpressionNode nlNode = (NonLeafExpressionNode) node;
+ assertEquals(Operator.OR, nlNode.getOperator());
+ assertEquals(2, nlNode.getChildExps().size());
+ assertEquals("\u002b" + "&" + "\u003f",
+ ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
+ assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
+ nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
+ assertEquals(Operator.AND, nlNode.getOperator());
+ assertEquals(2, nlNode.getChildExps().size());
+ assertEquals("\"", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
+ assertEquals("\u0027", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
+ try {
+ node = parser.parse(CellVisibility.quote("\u0027&\\") + "|"
+ + CellVisibility.quote("\u002b" + "&" + "\\") + CellVisibility.quote("$$\""));
+ fail("Excpetion must be thrown as there is not operator");
+ } catch (ParseException e) {
+ }
+ node = parser.parse(CellVisibility.quote("\u0027" + "&" + "\\") + "|"
+ + CellVisibility.quote("\u003f" + "&" + "\\") + "&" + CellVisibility.quote("$$\""));
+ assertTrue(node instanceof NonLeafExpressionNode);
+ nlNode = (NonLeafExpressionNode) node;
+ assertEquals(Operator.AND, nlNode.getOperator());
+ assertEquals(2, nlNode.getChildExps().size());
+ assertEquals("$$\"", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
+ assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
+ nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
+ assertEquals(Operator.OR, nlNode.getOperator());
+ assertEquals(2, nlNode.getChildExps().size());
+ assertEquals("\u0027" + "&" + "\\",
+ ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
+ assertEquals("\u003f" + "&" + "\\",
+ ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
+ try {
+ node = parser.parse(CellVisibility.quote("\u002b&\\") + "|" + CellVisibility.quote("\u0027&\\") + "&"
+ + "\"$$");
+ fail("Excpetion must be thrown as there is no end quote");
+ } catch (ParseException e) {
+ }
+ }
+
private void executeNegativeCase(String exp) {
try {
parser.parse(exp);
http://git-wip-us.apache.org/repos/asf/hbase/blob/ae2a9440/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestVisibilityLabels.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestVisibilityLabels.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestVisibilityLabels.java
index 84ecf6a..654dfd9 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestVisibilityLabels.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestVisibilityLabels.java
@@ -83,6 +83,12 @@ public class TestVisibilityLabels {
private static final String PRIVATE = "private";
private static final String CONFIDENTIAL = "confidential";
private static final String SECRET = "secret";
+ private static final String COPYRIGHT = "\u00A9ABC";
+ private static final String ACCENT = "\u0941";
+ private static final String UNICODE_VIS_TAG = COPYRIGHT + "\"" + ACCENT + "\\" + SECRET + "\""
+ + "\u0027&\\";
+ private static final String UC1 = "\u0027\"\u002b";
+ private static final String UC2 = "\u002d\u003f";
public static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
private static final byte[] row1 = Bytes.toBytes("row1");
private static final byte[] row2 = Bytes.toBytes("row2");
@@ -154,6 +160,77 @@ public class TestVisibilityLabels {
}
}
}
+
+ @Test
+ public void testSimpleVisibilityLabelsWithUniCodeCharacters() throws Exception {
+ TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
+ HTable table = createTableAndWriteDataWithLabels(tableName,
+ SECRET + "|" + CellVisibility.quote(COPYRIGHT), "(" + CellVisibility.quote(COPYRIGHT) + "&"
+ + CellVisibility.quote(ACCENT) + ")|" + CONFIDENTIAL,
+ CellVisibility.quote(UNICODE_VIS_TAG) + "&" + SECRET);
+ try {
+ Scan s = new Scan();
+ s.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL, PRIVATE, COPYRIGHT, ACCENT,
+ UNICODE_VIS_TAG));
+ ResultScanner scanner = table.getScanner(s);
+ Result[] next = scanner.next(3);
+ assertTrue(next.length == 3);
+ CellScanner cellScanner = next[0].cellScanner();
+ cellScanner.advance();
+ Cell current = cellScanner.current();
+ assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
+ current.getRowLength(), row1, 0, row1.length));
+ cellScanner = next[1].cellScanner();
+ cellScanner.advance();
+ current = cellScanner.current();
+ assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
+ current.getRowLength(), row2, 0, row2.length));
+ cellScanner = next[2].cellScanner();
+ cellScanner.advance();
+ current = cellScanner.current();
+ assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
+ current.getRowLength(), row3, 0, row3.length));
+ } finally {
+ if (table != null) {
+ table.close();
+ }
+ }
+ }
+
+ @Test
+ public void testAuthorizationsWithSpecialUnicodeCharacters() throws Exception {
+ TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
+ HTable table = createTableAndWriteDataWithLabels(tableName,
+ CellVisibility.quote(UC1) + "|" + CellVisibility.quote(UC2), CellVisibility.quote(UC1),
+ CellVisibility.quote(UNICODE_VIS_TAG));
+ try {
+ Scan s = new Scan();
+ s.setAuthorizations(new Authorizations(UC1, UC2, ACCENT,
+ UNICODE_VIS_TAG));
+ ResultScanner scanner = table.getScanner(s);
+ Result[] next = scanner.next(3);
+ assertTrue(next.length == 3);
+ CellScanner cellScanner = next[0].cellScanner();
+ cellScanner.advance();
+ Cell current = cellScanner.current();
+ assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
+ current.getRowLength(), row1, 0, row1.length));
+ cellScanner = next[1].cellScanner();
+ cellScanner.advance();
+ current = cellScanner.current();
+ assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
+ current.getRowLength(), row2, 0, row2.length));
+ cellScanner = next[2].cellScanner();
+ cellScanner.advance();
+ current = cellScanner.current();
+ assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
+ current.getRowLength(), row3, 0, row3.length));
+ } finally {
+ if (table != null) {
+ table.close();
+ }
+ }
+ }
@Test
public void testVisibilityLabelsWithComplexLabels() throws Exception {
@@ -406,7 +483,7 @@ public class TestVisibilityLabels {
}
}
// One label is the "system" label.
- Assert.assertEquals("The count should be 8", 8, i);
+ Assert.assertEquals("The count should be 13", 13, i);
}
private void waitForLabelsRegionAvailability(HRegionServer regionServer) {
@@ -466,8 +543,7 @@ public class TestVisibilityLabels {
assertEquals("org.apache.hadoop.hbase.security.visibility.LabelAlreadyExistsException",
resultList.get(1).getException().getName());
assertTrue(resultList.get(2).getException().getValue().isEmpty());
- assertEquals("org.apache.hadoop.hbase.security.visibility.InvalidLabelException",
- resultList.get(3).getException().getName());
+ assertTrue(resultList.get(3).getException().getValue().isEmpty());
assertTrue(resultList.get(4).getException().getValue().isEmpty());
return null;
}
@@ -929,7 +1005,8 @@ public class TestVisibilityLabels {
PrivilegedExceptionAction<VisibilityLabelsResponse> action =
new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
public VisibilityLabelsResponse run() throws Exception {
- String[] labels = { SECRET, TOPSECRET, CONFIDENTIAL, PUBLIC, PRIVATE };
+ String[] labels = { SECRET, TOPSECRET, CONFIDENTIAL, PUBLIC, PRIVATE, COPYRIGHT, ACCENT,
+ UNICODE_VIS_TAG, UC1, UC2 };
try {
VisibilityClient.addLabels(conf, labels);
} catch (Throwable t) {