You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by ar...@apache.org on 2015/07/07 18:00:01 UTC
hadoop git commit: HDFS-8654. OzoneHandler : Add ACL support.
(Contributed by Anu Engineer)
Repository: hadoop
Updated Branches:
refs/heads/HDFS-7240 6551e11c0 -> 93cebb2e2
HDFS-8654. OzoneHandler : Add ACL support. (Contributed by Anu Engineer)
Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/93cebb2e
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/93cebb2e
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/93cebb2e
Branch: refs/heads/HDFS-7240
Commit: 93cebb2e286fcb3e2733c4501b64bd3a744d3c43
Parents: 6551e11
Author: Arpit Agarwal <ar...@apache.org>
Authored: Tue Jul 7 08:59:28 2015 -0700
Committer: Arpit Agarwal <ar...@apache.org>
Committed: Tue Jul 7 08:59:28 2015 -0700
----------------------------------------------------------------------
.../hadoop-hdfs/CHANGES-HDFS-7240.txt | 2 +
.../hadoop/ozone/web/request/OzoneAcl.java | 203 +++++++++++++++++++
.../hadoop/ozone/web/utils/OzoneConsts.java | 9 +
.../apache/hadoop/ozone/web/TestOzoneAcls.java | 139 +++++++++++++
4 files changed, 353 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hadoop/blob/93cebb2e/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-7240.txt
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-7240.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-7240.txt
index 123fbc8..bf68394 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-7240.txt
+++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-7240.txt
@@ -26,3 +26,5 @@
HDFS-8661. DataNode should filter the set of NameSpaceInfos passed to
Datasets. (Arpit Agarwal)
+ HDFS-8654. OzoneHandler : Add ACL support. (Anu Engineer via Arpit Agarwal)
+
http://git-wip-us.apache.org/repos/asf/hadoop/blob/93cebb2e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/request/OzoneAcl.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/request/OzoneAcl.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/request/OzoneAcl.java
new file mode 100644
index 0000000..521c277
--- /dev/null
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/request/OzoneAcl.java
@@ -0,0 +1,203 @@
+/*
+ * 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.ozone.web.request;
+
+import org.apache.hadoop.ozone.web.utils.OzoneConsts;
+
+import java.util.Objects;
+
+/**
+ * OzoneACL classes define bucket ACLs used in OZONE.
+ *
+ * ACLs in Ozone follow this pattern.
+ * • user:name:rw
+ * • group:name:rw
+ * • world::rw
+ */
+public class OzoneAcl {
+ private OzoneACLType type;
+ private String name;
+ private OzoneACLRights rights;
+
+ /**
+ * Constructor for OzoneAcl.
+ *
+ * @param type - Type
+ * @param name - Name of user
+ * @param rights - Rights
+ */
+ public OzoneAcl(OzoneACLType type, String name, OzoneACLRights rights) {
+ this.name = name;
+ this.rights = rights;
+ this.type = type;
+ }
+
+ /**
+ * Parses an ACL string and returns the ACL object.
+ *
+ * @param acl - Acl String , Ex. user:anu:rw
+ *
+ * @return - Ozone ACLs
+ */
+ public static OzoneAcl parseAcl(String acl) throws IllegalArgumentException {
+ if ((acl == null) || acl.isEmpty()) {
+ throw new IllegalArgumentException("ACLs cannot be null or empty");
+ }
+ String[] parts = acl.trim().split(":");
+ if (parts.length < 3) {
+ throw new IllegalArgumentException("ACLs are not in expected format");
+ }
+
+ OzoneACLType aclType = OzoneACLType.valueOf(parts[0].toUpperCase());
+ OzoneACLRights rights = OzoneACLRights.getACLRight(parts[2].toLowerCase());
+
+ if (((aclType == OzoneACLType.USER) || (aclType == OzoneACLType.GROUP))
+ && (parts[1].length() == 0)) {
+ throw new IllegalArgumentException("User or group name is required");
+ }
+
+ if ((aclType == OzoneACLType.WORLD) && (parts[1].length() != 0)) {
+ throw new IllegalArgumentException("Unexpected name part in world type");
+ }
+ // TODO : Support sanitation of these user names by calling into
+ // userAuth Interface.
+ return new OzoneAcl(aclType, parts[1], rights);
+ }
+
+ /**
+ * Returns a hash code value for the object. This method is
+ * supported for the benefit of hash tables.
+ *
+ * @return a hash code value for this object.
+ *
+ * @see Object#equals(Object)
+ * @see System#identityHashCode
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.getName(), this.getRights().toString(),
+ this.getType().toString());
+ }
+
+ /**
+ * Returns name.
+ *
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns Rights.
+ *
+ * @return - Rights
+ */
+ public OzoneACLRights getRights() {
+ return rights;
+ }
+
+ /**
+ * Returns Type.
+ *
+ * @return type
+ */
+ public OzoneACLType getType() {
+ return type;
+ }
+
+ /**
+ * Indicates whether some other object is "equal to" this one.
+ *
+ * @param obj the reference object with which to compare.
+ *
+ * @return {@code true} if this object is the same as the obj
+ * argument; {@code false} otherwise.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ OzoneAcl otherAcl = (OzoneAcl) obj;
+ return otherAcl.getName().equals(this.getName()) &&
+ otherAcl.getRights() == this.getRights() &&
+ otherAcl.getType() == this.getType();
+ }
+
+ /**
+ * ACL types.
+ */
+ public enum OzoneACLType {
+ USER(OzoneConsts.OZONE_ACL_USER_TYPE),
+ GROUP(OzoneConsts.OZONE_ACL_GROUP_TYPE),
+ WORLD(OzoneConsts.OZONE_ACL_WORLD_TYPE);
+
+ /**
+ * String value for this Enum.
+ */
+ private final String value;
+
+ /**
+ * Init OzoneACLtypes enum.
+ *
+ * @param val String type for this enum.
+ */
+ OzoneACLType(String val) {
+ value = val;
+ }
+ }
+
+ /**
+ * ACL rights.
+ */
+ public enum OzoneACLRights {
+ READ, WRITE, READ_WRITE;
+
+ /**
+ * Returns the ACL rights based on passed in String.
+ *
+ * @param type ACL right string
+ *
+ * @return OzoneACLRights
+ */
+ public static OzoneACLRights getACLRight(String type) {
+ if (type == null || type.isEmpty()) {
+ throw new IllegalArgumentException("ACL right cannot be empty");
+ }
+
+ switch (type) {
+ case OzoneConsts.OZONE_ACL_READ:
+ return OzoneACLRights.READ;
+ case OzoneConsts.OZONE_ACL_WRITE:
+ return OzoneACLRights.WRITE;
+ case OzoneConsts.OZONE_ACL_READ_WRITE:
+ case OzoneConsts.OZONE_ACL_WRITE_READ:
+ return OzoneACLRights.READ_WRITE;
+ default:
+ throw new IllegalArgumentException("ACL right is not recognized");
+ }
+
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/93cebb2e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/utils/OzoneConsts.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/utils/OzoneConsts.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/utils/OzoneConsts.java
index 56c814e..bdd7b6d 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/utils/OzoneConsts.java
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/ozone/web/utils/OzoneConsts.java
@@ -34,6 +34,15 @@ public final class OzoneConsts {
public static final int OZONE_MIN_BUCKET_NAME_LENGTH = 3;
public static final int OZONE_MAX_BUCKET_NAME_LENGTH = 63;
+ public static final String OZONE_ACL_USER_TYPE = "user";
+ public static final String OZONE_ACL_GROUP_TYPE = "group";
+ public static final String OZONE_ACL_WORLD_TYPE = "world";
+
+ public static final String OZONE_ACL_READ = "r";
+ public static final String OZONE_ACL_WRITE = "w";
+ public static final String OZONE_ACL_READ_WRITE = "rw";
+ public static final String OZONE_ACL_WRITE_READ = "wr";
+
private OzoneConsts() {
// Never Constructed
}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/93cebb2e/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/ozone/web/TestOzoneAcls.java
----------------------------------------------------------------------
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/ozone/web/TestOzoneAcls.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/ozone/web/TestOzoneAcls.java
new file mode 100644
index 0000000..87e0a28
--- /dev/null
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/ozone/web/TestOzoneAcls.java
@@ -0,0 +1,139 @@
+/**
+ * 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.ozone.web;
+
+import org.apache.hadoop.ozone.web.request.OzoneAcl;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class TestOzoneAcls {
+
+ @Test
+ public void TestACLParse() {
+ HashMap<String, Boolean> testMatrix;
+ testMatrix = new HashMap<>();
+
+ testMatrix.put("user:bilbo:r", Boolean.TRUE);
+ testMatrix.put("user:bilbo:w", Boolean.TRUE);
+ testMatrix.put("user:bilbo:rw", Boolean.TRUE);
+ testMatrix.put("user:bilbo:wr", Boolean.TRUE);
+ testMatrix.put(" user:bilbo:wr ", Boolean.TRUE);
+
+
+ // ACLs makes no judgement on the quality of
+ // user names. it is for the userAuth interface
+ // to determine if a user name is really a name
+ testMatrix.put(" user:*:rw", Boolean.TRUE);
+ testMatrix.put(" user:~!:rw", Boolean.TRUE);
+
+
+ testMatrix.put("", Boolean.FALSE);
+ testMatrix.put(null, Boolean.FALSE);
+ testMatrix.put(" user:bilbo:", Boolean.FALSE);
+ testMatrix.put(" user:bilbo:rx", Boolean.FALSE);
+ testMatrix.put(" user:bilbo:mk", Boolean.FALSE);
+ testMatrix.put(" user::rw", Boolean.FALSE);
+ testMatrix.put("user11:bilbo:rw", Boolean.FALSE);
+ testMatrix.put(" user:::rw", Boolean.FALSE);
+
+ testMatrix.put(" group:hobbit:r", Boolean.TRUE);
+ testMatrix.put(" group:hobbit:w", Boolean.TRUE);
+ testMatrix.put(" group:hobbit:rw", Boolean.TRUE);
+ testMatrix.put(" group:hobbit:wr", Boolean.TRUE);
+ testMatrix.put(" group:*:rw", Boolean.TRUE);
+ testMatrix.put(" group:~!:rw", Boolean.TRUE);
+
+ testMatrix.put(" group:hobbit:", Boolean.FALSE);
+ testMatrix.put(" group:hobbit:rx", Boolean.FALSE);
+ testMatrix.put(" group:hobbit:mk", Boolean.FALSE);
+ testMatrix.put(" group::", Boolean.FALSE);
+ testMatrix.put(" group::rw", Boolean.FALSE);
+ testMatrix.put(" group22:hobbit:", Boolean.FALSE);
+ testMatrix.put(" group:::rw", Boolean.FALSE);
+
+ testMatrix.put("JUNK group:hobbit:r", Boolean.FALSE);
+ testMatrix.put("JUNK group:hobbit:w", Boolean.FALSE);
+ testMatrix.put("JUNK group:hobbit:rw", Boolean.FALSE);
+ testMatrix.put("JUNK group:hobbit:wr", Boolean.FALSE);
+ testMatrix.put("JUNK group:*:rw", Boolean.FALSE);
+ testMatrix.put("JUNK group:~!:rw", Boolean.FALSE);
+
+ testMatrix.put(" world::r", Boolean.TRUE);
+ testMatrix.put(" world::w", Boolean.TRUE);
+ testMatrix.put(" world::rw", Boolean.TRUE);
+ testMatrix.put(" world::wr", Boolean.TRUE);
+
+ testMatrix.put(" world:bilbo:w", Boolean.FALSE);
+ testMatrix.put(" world:bilbo:rw", Boolean.FALSE);
+
+ Set<String> keys = testMatrix.keySet();
+ for (String key : keys) {
+ if (testMatrix.get(key)) {
+ OzoneAcl.parseAcl(key);
+ } else {
+ try {
+ OzoneAcl.parseAcl(key);
+ // should never get here since parseAcl will throw
+ fail("An exception was expected but did not happen.");
+ } catch (IllegalArgumentException e) {
+ // nothing to do
+ }
+ }
+ }
+ }
+
+ @Test
+ public void TestACLValues() {
+ OzoneAcl acl = OzoneAcl.parseAcl("user:bilbo:rw");
+ assertEquals(acl.getName(), "bilbo");
+ assertEquals(acl.getRights(), OzoneAcl.OzoneACLRights.READ_WRITE);
+ assertEquals(acl.getType(), OzoneAcl.OzoneACLType.USER);
+
+ acl = OzoneAcl.parseAcl("user:bilbo:wr");
+ assertEquals(acl.getName(), "bilbo");
+ assertEquals(acl.getRights(), OzoneAcl.OzoneACLRights.READ_WRITE);
+ assertEquals(acl.getType(), OzoneAcl.OzoneACLType.USER);
+
+ acl = OzoneAcl.parseAcl("user:bilbo:r");
+ assertEquals(acl.getName(), "bilbo");
+ assertEquals(acl.getRights(), OzoneAcl.OzoneACLRights.READ);
+ assertEquals(acl.getType(), OzoneAcl.OzoneACLType.USER);
+
+ acl = OzoneAcl.parseAcl("user:bilbo:w");
+ assertEquals(acl.getName(), "bilbo");
+ assertEquals(acl.getRights(), OzoneAcl.OzoneACLRights.WRITE);
+ assertEquals(acl.getType(), OzoneAcl.OzoneACLType.USER);
+
+ acl = OzoneAcl.parseAcl("group:hobbit:wr");
+ assertEquals(acl.getName(), "hobbit");
+ assertEquals(acl.getRights(), OzoneAcl.OzoneACLRights.READ_WRITE);
+ assertEquals(acl.getType(), OzoneAcl.OzoneACLType.GROUP);
+
+ acl = OzoneAcl.parseAcl("world::wr");
+ assertEquals(acl.getName(), "");
+ assertEquals(acl.getRights(), OzoneAcl.OzoneACLRights.READ_WRITE);
+ assertEquals(acl.getType(), OzoneAcl.OzoneACLType.WORLD);
+ }
+
+}