accumulo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ctubb...@apache.org
Subject svn commit: r1479039 - in /accumulo/branches/1.5/core/src: main/java/org/apache/accumulo/core/security/ test/java/org/apache/accumulo/core/security/
Date Sat, 04 May 2013 05:07:35 GMT
Author: ctubbsii
Date: Sat May  4 05:07:35 2013
New Revision: 1479039

URL: http://svn.apache.org/r1479039
Log:
ACCUMULO-1005 Applying patch contributed by Tim Reardon to remove Charset options from Authorizations
and ColumnVisibility, with minor edits from John Vines and minor documentation additions and
cleanup from myself

Modified:
    accumulo/branches/1.5/core/src/main/java/org/apache/accumulo/core/security/Authorizations.java
    accumulo/branches/1.5/core/src/main/java/org/apache/accumulo/core/security/ColumnVisibility.java
    accumulo/branches/1.5/core/src/test/java/org/apache/accumulo/core/security/AuthorizationsTest.java
    accumulo/branches/1.5/core/src/test/java/org/apache/accumulo/core/security/ColumnVisibilityTest.java
    accumulo/branches/1.5/core/src/test/java/org/apache/accumulo/core/security/VisibilityEvaluatorTest.java

Modified: accumulo/branches/1.5/core/src/main/java/org/apache/accumulo/core/security/Authorizations.java
URL: http://svn.apache.org/viewvc/accumulo/branches/1.5/core/src/main/java/org/apache/accumulo/core/security/Authorizations.java?rev=1479039&r1=1479038&r2=1479039&view=diff
==============================================================================
--- accumulo/branches/1.5/core/src/main/java/org/apache/accumulo/core/security/Authorizations.java
(original)
+++ accumulo/branches/1.5/core/src/main/java/org/apache/accumulo/core/security/Authorizations.java
Sat May  4 05:07:35 2013
@@ -17,9 +17,7 @@
 package org.apache.accumulo.core.security;
 
 import java.io.Serializable;
-import java.io.UnsupportedEncodingException;
 import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -27,6 +25,7 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 
+import org.apache.accumulo.core.Constants;
 import org.apache.accumulo.core.data.ArrayByteSequence;
 import org.apache.accumulo.core.data.ByteSequence;
 import org.apache.accumulo.core.util.ArgumentChecker;
@@ -44,7 +43,7 @@ public class Authorizations implements I
   private static final boolean[] validAuthChars = new boolean[256];
   
   public static final String HEADER = "!AUTH1:";
-
+  
   static {
     for (int i = 0; i < 256; i++) {
       validAuthChars[i] = false;
@@ -84,6 +83,11 @@ public class Authorizations implements I
     }
   }
   
+  /**
+   * A convenience constructor that accepts a collection of string authorizations that have
each already been encoded as UTF-8 bytes.
+   * 
+   * @see #Authorizations(String...)
+   */
   public Authorizations(Collection<byte[]> authorizations) {
     ArgumentChecker.notNull(authorizations);
     for (byte[] auth : authorizations)
@@ -91,6 +95,11 @@ public class Authorizations implements I
     checkAuths();
   }
   
+  /**
+   * A convenience constructor that accepts a collection of string authorizations that have
each already been encoded as UTF-8 bytes.
+   * 
+   * @see #Authorizations(String...)
+   */
   public Authorizations(List<ByteBuffer> authorizations) {
     ArgumentChecker.notNull(authorizations);
     for (ByteBuffer buffer : authorizations) {
@@ -100,102 +109,124 @@ public class Authorizations implements I
   }
   
   /**
+   * Constructs an authorizations object a serialized form. This is NOT a constructor for
a set of authorizations of size one.
+   * 
    * @param authorizations
-   *          a serialized authorizations string produced by {@link #getAuthorizationsArray()}
or {@link #serialize()}
+   *          a serialized authorizations string produced by {@link #getAuthorizationsArray()}
or {@link #serialize()} (converted to UTF-8 bytes)
    */
-
   public Authorizations(byte[] authorizations) {
     
     ArgumentChecker.notNull(authorizations);
-
-    String authsString = new String(authorizations);
+    
+    String authsString = new String(authorizations, Constants.UTF8);
     if (authsString.startsWith(HEADER)) {
-      // its the new format
+      // it's the new format
       authsString = authsString.substring(HEADER.length());
       if (authsString.length() > 0) {
         for (String encAuth : authsString.split(",")) {
-          byte[] auth = Base64.decodeBase64(encAuth.getBytes());
+          byte[] auth = Base64.decodeBase64(encAuth.getBytes(Constants.UTF8));
           auths.add(new ArrayByteSequence(auth));
         }
         checkAuths();
       }
     } else {
-      // its the old format
+      // it's the old format
       ArgumentChecker.notNull(authorizations);
       if (authorizations.length > 0)
         setAuthorizations(authsString.split(","));
     }
   }
   
+  /**
+   * Constructs an empty set of authorizations.
+   * 
+   * @see #Authorizations(String...)
+   */
   public Authorizations() {}
   
   /**
+   * Constructs an authorizations object from a set of human-readable authorizations.
    * 
-   * @param charset
-   *          used to convert each authorization to a byte array
    * @param authorizations
    *          array of authorizations
    */
-  
-  public Authorizations(Charset charset, String... authorizations) {
-    setAuthorizations(charset, authorizations);
-  }
-
   public Authorizations(String... authorizations) {
     setAuthorizations(authorizations);
   }
   
   private void setAuthorizations(String... authorizations) {
-    setAuthorizations(Charset.defaultCharset(), authorizations);
-  }
-  
-  private void setAuthorizations(Charset charset, String... authorizations) {
     ArgumentChecker.notNull(authorizations);
     auths.clear();
     for (String str : authorizations) {
       str = str.trim();
-      try {
-        auths.add(new ArrayByteSequence(str.getBytes(charset.name())));
-      } catch (UnsupportedEncodingException e) {
-        throw new RuntimeException(e);
-      }
+      auths.add(new ArrayByteSequence(str.getBytes(Constants.UTF8)));
     }
     
     checkAuths();
   }
   
+  /**
+   * Retrieve a serialized form of the underlying set of authorizations.
+   * 
+   * @see #Authorizations(byte[])
+   */
   public byte[] getAuthorizationsArray() {
-    return serialize().getBytes();
+    return serialize().getBytes(Constants.UTF8);
   }
   
+  /**
+   * Retrieve authorizations as a list of strings that have been encoded as UTF-8 bytes.
+   * 
+   * @see #Authorizations(Collection)
+   */
   public List<byte[]> getAuthorizations() {
     return immutableList;
   }
   
+  /**
+   * Retrieve authorizations as a list of strings that have been encoded as UTF-8 bytes.
+   * 
+   * @see #Authorizations(List)
+   */
   public List<ByteBuffer> getAuthorizationsBB() {
     return ByteBufferUtil.toByteBuffers(immutableList);
   }
   
+  @Override
   public String toString() {
     StringBuilder sb = new StringBuilder();
     String sep = "";
     for (ByteSequence auth : auths) {
       sb.append(sep);
       sep = ",";
-      sb.append(new String(auth.toArray()));
+      sb.append(new String(auth.toArray(), Constants.UTF8));
     }
     
     return sb.toString();
   }
   
+  /**
+   * Checks for the existence of this UTF-8 encoded authorization.
+   */
   public boolean contains(byte[] auth) {
     return auths.contains(new ArrayByteSequence(auth));
   }
   
+  /**
+   * Checks for the existence of this UTF-8 encoded authorization.
+   */
   public boolean contains(ByteSequence auth) {
     return auths.contains(auth);
   }
   
+  /**
+   * Checks for the existence of this authorization.
+   */
+  public boolean contains(String auth) {
+    return auths.contains(auth.getBytes(Constants.UTF8));
+  }
+  
+  @Override
   public boolean equals(Object o) {
     if (o == null) {
       return false;
@@ -210,6 +241,7 @@ public class Authorizations implements I
     return false;
   }
   
+  @Override
   public int hashCode() {
     int result = 0;
     for (ByteSequence b : auths)
@@ -230,13 +262,16 @@ public class Authorizations implements I
     return immutableList.iterator();
   }
   
+  /**
+   * Returns a serialized form of these authorizations. Convert to UTF-8 bytes to deserialize
with {@link #Authorizations(byte[])}
+   */
   public String serialize() {
     StringBuilder sb = new StringBuilder(HEADER);
     String sep = "";
     for (ByteSequence auth : auths) {
       sb.append(sep);
       sep = ",";
-      sb.append(new String(Base64.encodeBase64(auth.toArray())));
+      sb.append(new String(Base64.encodeBase64(auth.toArray()), Constants.UTF8));
     }
     
     return sb.toString();

Modified: accumulo/branches/1.5/core/src/main/java/org/apache/accumulo/core/security/ColumnVisibility.java
URL: http://svn.apache.org/viewvc/accumulo/branches/1.5/core/src/main/java/org/apache/accumulo/core/security/ColumnVisibility.java?rev=1479039&r1=1479038&r2=1479039&view=diff
==============================================================================
--- accumulo/branches/1.5/core/src/main/java/org/apache/accumulo/core/security/ColumnVisibility.java
(original)
+++ accumulo/branches/1.5/core/src/main/java/org/apache/accumulo/core/security/ColumnVisibility.java
Sat May  4 05:07:35 2013
@@ -16,7 +16,6 @@
  */
 package org.apache.accumulo.core.security;
 
-import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -24,6 +23,7 @@ import java.util.Comparator;
 import java.util.List;
 import java.util.TreeSet;
 
+import org.apache.accumulo.core.Constants;
 import org.apache.accumulo.core.data.ArrayByteSequence;
 import org.apache.accumulo.core.data.ByteSequence;
 import org.apache.accumulo.core.util.BadArgumentException;
@@ -96,7 +96,7 @@ public class ColumnVisibility {
     public ByteSequence getTerm(byte expression[]) {
       if (type != NodeType.TERM)
         throw new RuntimeException();
-
+      
       if (expression[start] == '"') {
         // its a quoted term
         int qStart = start + 1;
@@ -138,26 +138,29 @@ public class ColumnVisibility {
       return 0;
     }
   }
-
-  /* Convience method that delegates to normalize with a new
-   * NodeComparator constructed using the supplied expression.
+  
+  /*
+   * Convience method that delegates to normalize with a new NodeComparator constructed using
the supplied expression.
    */
   private static Node normalize(Node root, byte[] expression) {
     return normalize(root, expression, new NodeComparator(expression));
-  } 
-
-  /* Walks an expression's AST in order to:
+  }
+  
+  // @formatter:off
+  /*
+   * Walks an expression's AST in order to:
    *  1) roll up expressions with the same operant (`a&(b&c) becomes a&b&c`)
    *  2) sorts labels lexicographically (permutations of `a&b&c` are re-ordered to
appear as `a&b&c`)
    *  3) dedupes labels (`a&b&a` becomes `a&b`)
    */
+  // @formatter:on
   private static Node normalize(Node root, byte[] expression, NodeComparator comparator)
{
-    if(root.type != NodeType.TERM) {
+    if (root.type != NodeType.TERM) {
       TreeSet<Node> rolledUp = new TreeSet<Node>(comparator);
       java.util.Iterator<Node> itr = root.children.iterator();
-      while(itr.hasNext()) { 
+      while (itr.hasNext()) {
         Node c = normalize(itr.next(), expression, comparator);
-        if(c.type == root.type) {
+        if (c.type == root.type) {
           rolledUp.addAll(c.children);
           itr.remove();
         }
@@ -166,23 +169,22 @@ public class ColumnVisibility {
       root.children.clear();
       root.children.addAll(rolledUp);
       
-      //need to promote a child if it's an only child
-      if(root.children.size() == 1) {
+      // need to promote a child if it's an only child
+      if (root.children.size() == 1) {
         return root.children.get(0);
       }
     }
-
+    
     return root;
   }
-
-  /* Walks an expression's AST and appends a string representation to a supplied
-   * StringBuilder. This method adds parens where necessary.
+  
+  /*
+   * Walks an expression's AST and appends a string representation to a supplied StringBuilder.
This method adds parens where necessary.
    */
   private static void stringify(Node root, byte[] expression, StringBuilder out) {
     if (root.type == NodeType.TERM) {
       out.append(new String(expression, root.start, root.end - root.start));
-    }
-    else {
+    } else {
       String sep = "";
       for (Node c : root.children) {
         out.append(sep);
@@ -196,11 +198,10 @@ public class ColumnVisibility {
       }
     }
   }
-
+  
   /**
-   * Generates a byte[] that represents a normalized, but logically equivalent,
-   * form of the supplied expression.
-   *
+   * Generates a byte[] that represents a normalized, but logically equivalent, form of the
supplied expression.
+   * 
    * @return normalized expression in byte[] form
    */
   public byte[] flatten() {
@@ -208,7 +209,7 @@ public class ColumnVisibility {
     StringBuilder builder = new StringBuilder(expression.length);
     stringify(normRoot, expression, builder);
     return builder.toString().getBytes();
-  } 
+  }
   
   private static class ColumnVisibilityParser {
     private int index = 0;
@@ -246,7 +247,7 @@ public class ColumnVisibility {
       Node expr = null;
       int termStart = index;
       boolean termComplete = false;
-
+      
       while (index < expression.length) {
         switch (expression[index++]) {
           case '&': {
@@ -304,7 +305,7 @@ public class ColumnVisibility {
           case '"': {
             if (termStart != index - 1)
               throw new BadArgumentException("expression needs & or |", new String(expression),
index - 1);
-
+            
             while (index < expression.length && expression[index] != '"') {
               if (expression[index] == '\\') {
                 index++;
@@ -319,17 +320,17 @@ public class ColumnVisibility {
             
             if (termStart + 1 == index)
               throw new BadArgumentException("empty term", new String(expression), termStart);
-
+            
             index++;
             
             termComplete = true;
-
+            
             break;
           }
           default: {
             if (termComplete)
               throw new BadArgumentException("expression needs & or |", new String(expression),
index - 1);
-
+            
             byte c = expression[index - 1];
             if (!Authorizations.isValidAuthChar(c))
               throw new BadArgumentException("bad character (" + c + ")", new String(expression),
index - 1);
@@ -358,37 +359,14 @@ public class ColumnVisibility {
   
   /**
    * Empty visibility. Normally, elements with empty visibility can be seen by everyone.
Though, one could change this behavior with filters.
+   * 
+   * @see #ColumnVisibility(String)
    */
   public ColumnVisibility() {
     expression = new byte[0];
   }
   
   /**
-   * See {@link #ColumnVisibility(byte[])}
-   * 
-   * @param expression
-   */
-  public ColumnVisibility(String expression) {
-    this(expression.getBytes());
-  }
-  
-  /**
-   * See {@link #ColumnVisibility(byte[])}
-   * 
-   * @param expression
-   * @param encoding
-   *          uses this encoding to convert the expression to a byte array
-   * @throws UnsupportedEncodingException
-   */
-  public ColumnVisibility(String expression, String encoding) throws UnsupportedEncodingException
{
-    this(expression.getBytes(encoding));
-  }
-
-  public ColumnVisibility(Text expression) {
-    this(TextUtil.getBytes(expression));
-  }
-  
-  /**
    * Set the column visibility for a Mutation.
    * 
    * @param expression
@@ -422,17 +400,35 @@ public class ColumnVisibility {
    *          them with '\'. The {@link #quote(String)} method will properly quote and escape
terms for you.
    * 
    *          <pre>
-   * &quot;A#C&quot;&B
+   * &quot;A#C&quot;<span />&amp;<span />B
    * </pre>
    * 
    */
+  public ColumnVisibility(String expression) {
+    this(expression.getBytes(Constants.UTF8));
+  }
+  
+  /**
+   * A convenience method for constructing from a string already encoded in UTF-8 bytes and
contained in a {@link Text} object.
+   * 
+   * @see #ColumnVisibility(String)
+   */
+  public ColumnVisibility(Text expression) {
+    this(TextUtil.getBytes(expression));
+  }
+  
+  /**
+   * A convenience method for constructing from a string already encoded in UTF-8 bytes.
+   * 
+   * @see #ColumnVisibility(String)
+   */
   public ColumnVisibility(byte[] expression) {
     validate(expression);
   }
   
   @Override
   public String toString() {
-    return "[" + new String(expression) + "]";
+    return "[" + new String(expression, Constants.UTF8) + "]";
   }
   
   /**
@@ -462,26 +458,6 @@ public class ColumnVisibility {
   }
   
   /**
-   * see {@link #quote(byte[])}
-   * 
-   */
-  public static String quote(String term) {
-    return quote(term, "UTF-8");
-  }
-  
-  /**
-   * see {@link #quote(byte[])}
-   * 
-   */
-  public static String quote(String term, String encoding) {
-    try {
-      return new String(quote(term.getBytes(encoding)), encoding);
-    } catch (UnsupportedEncodingException e) {
-      throw new RuntimeException(e);
-    }
-  }
-  
-  /**
    * Use to properly quote terms in a column visibility expression. If no quoting is needed,
then nothing is done.
    * 
    * <p>
@@ -496,7 +472,15 @@ public class ColumnVisibility {
    * </pre>
    * 
    */
-
+  public static String quote(String term) {
+    return new String(quote(term.getBytes(Constants.UTF8)), Constants.UTF8);
+  }
+  
+  /**
+   * A convenience method to quote terms which are already encoded as UTF-8 bytes.
+   * 
+   * @see #quote(String)
+   */
   public static byte[] quote(byte[] term) {
     boolean needsQuote = false;
     

Modified: accumulo/branches/1.5/core/src/test/java/org/apache/accumulo/core/security/AuthorizationsTest.java
URL: http://svn.apache.org/viewvc/accumulo/branches/1.5/core/src/test/java/org/apache/accumulo/core/security/AuthorizationsTest.java?rev=1479039&r1=1479038&r2=1479039&view=diff
==============================================================================
--- accumulo/branches/1.5/core/src/test/java/org/apache/accumulo/core/security/AuthorizationsTest.java
(original)
+++ accumulo/branches/1.5/core/src/test/java/org/apache/accumulo/core/security/AuthorizationsTest.java
Sat May  4 05:07:35 2013
@@ -41,6 +41,12 @@ public class AuthorizationsTest {
     array = a.getAuthorizationsArray();
     b = new Authorizations(array);
     assertEquals(a, b);
+    
+    // test encoding multi-byte auths
+    a = new Authorizations("五", "b", "c", "九");
+    array = a.getAuthorizationsArray();
+    b = new Authorizations(array);
+    assertEquals(a, b);
   }
   
 }

Modified: accumulo/branches/1.5/core/src/test/java/org/apache/accumulo/core/security/ColumnVisibilityTest.java
URL: http://svn.apache.org/viewvc/accumulo/branches/1.5/core/src/test/java/org/apache/accumulo/core/security/ColumnVisibilityTest.java?rev=1479039&r1=1479038&r2=1479039&view=diff
==============================================================================
--- accumulo/branches/1.5/core/src/test/java/org/apache/accumulo/core/security/ColumnVisibilityTest.java
(original)
+++ accumulo/branches/1.5/core/src/test/java/org/apache/accumulo/core/security/ColumnVisibilityTest.java
Sat May  4 05:07:35 2013
@@ -16,7 +16,9 @@
  */
 package org.apache.accumulo.core.security;
 
+import static org.apache.accumulo.core.security.ColumnVisibility.quote;
 import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
 import org.junit.Test;
@@ -84,7 +86,7 @@ public class ColumnVisibilityTest {
     normalized("a", "a", "(a)", "a", "b|a", "a|b", "(b)|a", "a|b", "(b|(a|c))&x", "x&(a|b|c)",
"(((a)))", "a");
     final String normForm = "a&b&c";
     normalized("b&c&a", normForm, "c&b&a", normForm, "a&(b&c)", normForm,
"(a&c)&b", normForm);
-
+    
     // this an expression that's basically `expr | expr`
     normalized("(d&c&b&a)|(b&c&a&d)", "a&b&c&d");
   }
@@ -133,4 +135,14 @@ public class ColumnVisibilityTest {
     shouldNotThrow("A&\"B\\\\D\"");
     shouldNotThrow("A&\"B\\\"D\"");
   }
+  
+  @Test
+  public void testToString() {
+    ColumnVisibility cv = new ColumnVisibility(quote("a"));
+    assertEquals("[a]", cv.toString());
+    
+    // multi-byte
+    cv = new ColumnVisibility(quote("五"));
+    assertEquals("[\"五\"]", cv.toString());
+  }
 }

Modified: accumulo/branches/1.5/core/src/test/java/org/apache/accumulo/core/security/VisibilityEvaluatorTest.java
URL: http://svn.apache.org/viewvc/accumulo/branches/1.5/core/src/test/java/org/apache/accumulo/core/security/VisibilityEvaluatorTest.java?rev=1479039&r1=1479038&r2=1479039&view=diff
==============================================================================
--- accumulo/branches/1.5/core/src/test/java/org/apache/accumulo/core/security/VisibilityEvaluatorTest.java
(original)
+++ accumulo/branches/1.5/core/src/test/java/org/apache/accumulo/core/security/VisibilityEvaluatorTest.java
Sat May  4 05:07:35 2013
@@ -22,9 +22,6 @@ import static org.junit.Assert.assertFal
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.Charset;
-
 import org.apache.accumulo.core.util.BadArgumentException;
 import org.apache.accumulo.core.util.ByteArraySet;
 import org.junit.Test;
@@ -116,14 +113,14 @@ public class VisibilityEvaluatorTest {
   }
   
   @Test
-  public void testNonAscii() throws VisibilityParseException, UnsupportedEncodingException
{
-    VisibilityEvaluator ct = new VisibilityEvaluator(new Authorizations(Charset.forName("UTF-8"),
"五", "六", "八", "九", "五十"));
+  public void testNonAscii() throws VisibilityParseException {
+    VisibilityEvaluator ct = new VisibilityEvaluator(new Authorizations("五", "六",
"八", "九", "五十"));
     
-    assertTrue(ct.evaluate(new ColumnVisibility(quote("五") + "|" + quote("四"),
"UTF-8")));
-    assertFalse(ct.evaluate(new ColumnVisibility(quote("五") + "&" + quote("四"),
"UTF-8")));
-    assertTrue(ct.evaluate(new ColumnVisibility(quote("五") + "&(" + quote("四")
+ "|" + quote("九") + ")", "UTF-8")));
-    assertTrue(ct.evaluate(new ColumnVisibility("\"五\"&(\"四\"|\"五十\")",
"UTF-8")));
-    assertFalse(ct.evaluate(new ColumnVisibility(quote("五") + "&(" + quote("四")
+ "|" + quote("三") + ")", "UTF-8")));
-    assertFalse(ct.evaluate(new ColumnVisibility("\"五\"&(\"四\"|\"三\")",
"UTF-8")));
+    assertTrue(ct.evaluate(new ColumnVisibility(quote("五") + "|" + quote("四"))));
+    assertFalse(ct.evaluate(new ColumnVisibility(quote("五") + "&" + quote("四"))));
+    assertTrue(ct.evaluate(new ColumnVisibility(quote("五") + "&(" + quote("四")
+ "|" + quote("九") + ")")));
+    assertTrue(ct.evaluate(new ColumnVisibility("\"五\"&(\"四\"|\"五十\")")));
+    assertFalse(ct.evaluate(new ColumnVisibility(quote("五") + "&(" + quote("四")
+ "|" + quote("三") + ")")));
+    assertFalse(ct.evaluate(new ColumnVisibility("\"五\"&(\"四\"|\"三\")")));
   }
 }



Mime
View raw message