Repository: incubator-sentry
Updated Branches:
  refs/heads/master 60db85bab -> f6fc0422b


SENTRY-469: TListSentryPrivilegesByAuthRequest API should support impersonation 
( Prasad Mujumdar via Sravya Tirukkovalur)


Project: http://git-wip-us.apache.org/repos/asf/incubator-sentry/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-sentry/commit/f6fc0422
Tree: http://git-wip-us.apache.org/repos/asf/incubator-sentry/tree/f6fc0422
Diff: http://git-wip-us.apache.org/repos/asf/incubator-sentry/diff/f6fc0422

Branch: refs/heads/master
Commit: f6fc0422b61c88922d4e40db8e76d4ff89e8120b
Parents: 60db85b
Author: Sravya Tirukkovalur <[email protected]>
Authored: Wed Sep 24 20:35:59 2014 -0700
Committer: Sravya Tirukkovalur <[email protected]>
Committed: Wed Sep 24 20:35:59 2014 -0700

----------------------------------------------------------------------
 .../TListSentryPrivilegesByAuthRequest.java     | 125 ++++++++++++++++--
 .../TListSentryPrivilegesByAuthResponse.java    |  91 +++++++------
 .../thrift/SentryPolicyServiceClient.java       |   8 +-
 .../thrift/SentryPolicyStoreProcessor.java      |  36 +++++-
 .../main/resources/sentry_policy_service.thrift |   9 +-
 .../thrift/TestSentryServiceIntegration.java    | 128 +++++++++++++++++--
 6 files changed, 327 insertions(+), 70 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/f6fc0422/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesByAuthRequest.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesByAuthRequest.java
 
b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesByAuthRequest.java
index 6f78641..2bd860e 100644
--- 
a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesByAuthRequest.java
+++ 
b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesByAuthRequest.java
@@ -35,9 +35,10 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new 
org.apache.thrift.protocol.TStruct("TListSentryPrivilegesByAuthRequest");
 
   private static final org.apache.thrift.protocol.TField 
PROTOCOL_VERSION_FIELD_DESC = new 
org.apache.thrift.protocol.TField("protocol_version", 
org.apache.thrift.protocol.TType.I32, (short)1);
-  private static final org.apache.thrift.protocol.TField 
AUTHORIZABLE_SET_FIELD_DESC = new 
org.apache.thrift.protocol.TField("authorizableSet", 
org.apache.thrift.protocol.TType.SET, (short)2);
-  private static final org.apache.thrift.protocol.TField GROUPS_FIELD_DESC = 
new org.apache.thrift.protocol.TField("groups", 
org.apache.thrift.protocol.TType.SET, (short)3);
-  private static final org.apache.thrift.protocol.TField ROLE_SET_FIELD_DESC = 
new org.apache.thrift.protocol.TField("roleSet", 
org.apache.thrift.protocol.TType.STRUCT, (short)4);
+  private static final org.apache.thrift.protocol.TField 
REQUESTOR_USER_NAME_FIELD_DESC = new 
org.apache.thrift.protocol.TField("requestorUserName", 
org.apache.thrift.protocol.TType.STRING, (short)2);
+  private static final org.apache.thrift.protocol.TField 
AUTHORIZABLE_SET_FIELD_DESC = new 
org.apache.thrift.protocol.TField("authorizableSet", 
org.apache.thrift.protocol.TType.SET, (short)3);
+  private static final org.apache.thrift.protocol.TField GROUPS_FIELD_DESC = 
new org.apache.thrift.protocol.TField("groups", 
org.apache.thrift.protocol.TType.SET, (short)4);
+  private static final org.apache.thrift.protocol.TField ROLE_SET_FIELD_DESC = 
new org.apache.thrift.protocol.TField("roleSet", 
org.apache.thrift.protocol.TType.STRUCT, (short)5);
 
   private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = 
new HashMap<Class<? extends IScheme>, SchemeFactory>();
   static {
@@ -46,6 +47,7 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
   }
 
   private int protocol_version; // required
+  private String requestorUserName; // required
   private Set<TSentryAuthorizable> authorizableSet; // required
   private Set<String> groups; // optional
   private TSentryActiveRoleSet roleSet; // optional
@@ -53,9 +55,10 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
   /** The set of fields this struct contains, along with convenience methods 
for finding and manipulating them. */
   public enum _Fields implements org.apache.thrift.TFieldIdEnum {
     PROTOCOL_VERSION((short)1, "protocol_version"),
-    AUTHORIZABLE_SET((short)2, "authorizableSet"),
-    GROUPS((short)3, "groups"),
-    ROLE_SET((short)4, "roleSet");
+    REQUESTOR_USER_NAME((short)2, "requestorUserName"),
+    AUTHORIZABLE_SET((short)3, "authorizableSet"),
+    GROUPS((short)4, "groups"),
+    ROLE_SET((short)5, "roleSet");
 
     private static final Map<String, _Fields> byName = new HashMap<String, 
_Fields>();
 
@@ -72,11 +75,13 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
       switch(fieldId) {
         case 1: // PROTOCOL_VERSION
           return PROTOCOL_VERSION;
-        case 2: // AUTHORIZABLE_SET
+        case 2: // REQUESTOR_USER_NAME
+          return REQUESTOR_USER_NAME;
+        case 3: // AUTHORIZABLE_SET
           return AUTHORIZABLE_SET;
-        case 3: // GROUPS
+        case 4: // GROUPS
           return GROUPS;
-        case 4: // ROLE_SET
+        case 5: // ROLE_SET
           return ROLE_SET;
         default:
           return null;
@@ -126,6 +131,8 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
     Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new 
EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.PROTOCOL_VERSION, new 
org.apache.thrift.meta_data.FieldMetaData("protocol_version", 
org.apache.thrift.TFieldRequirementType.REQUIRED, 
         new 
org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
+    tmpMap.put(_Fields.REQUESTOR_USER_NAME, new 
org.apache.thrift.meta_data.FieldMetaData("requestorUserName", 
org.apache.thrift.TFieldRequirementType.REQUIRED, 
+        new 
org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
     tmpMap.put(_Fields.AUTHORIZABLE_SET, new 
org.apache.thrift.meta_data.FieldMetaData("authorizableSet", 
org.apache.thrift.TFieldRequirementType.REQUIRED, 
         new 
org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
             new 
org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT,
 TSentryAuthorizable.class))));
@@ -145,11 +152,13 @@ public class TListSentryPrivilegesByAuthRequest 
implements org.apache.thrift.TBa
 
   public TListSentryPrivilegesByAuthRequest(
     int protocol_version,
+    String requestorUserName,
     Set<TSentryAuthorizable> authorizableSet)
   {
     this();
     this.protocol_version = protocol_version;
     setProtocol_versionIsSet(true);
+    this.requestorUserName = requestorUserName;
     this.authorizableSet = authorizableSet;
   }
 
@@ -159,6 +168,9 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
   public TListSentryPrivilegesByAuthRequest(TListSentryPrivilegesByAuthRequest 
other) {
     __isset_bitfield = other.__isset_bitfield;
     this.protocol_version = other.protocol_version;
+    if (other.isSetRequestorUserName()) {
+      this.requestorUserName = other.requestorUserName;
+    }
     if (other.isSetAuthorizableSet()) {
       Set<TSentryAuthorizable> __this__authorizableSet = new 
HashSet<TSentryAuthorizable>();
       for (TSentryAuthorizable other_element : other.authorizableSet) {
@@ -186,6 +198,7 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
   public void clear() {
     this.protocol_version = 1;
 
+    this.requestorUserName = null;
     this.authorizableSet = null;
     this.groups = null;
     this.roleSet = null;
@@ -213,6 +226,29 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
     __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, 
__PROTOCOL_VERSION_ISSET_ID, value);
   }
 
+  public String getRequestorUserName() {
+    return this.requestorUserName;
+  }
+
+  public void setRequestorUserName(String requestorUserName) {
+    this.requestorUserName = requestorUserName;
+  }
+
+  public void unsetRequestorUserName() {
+    this.requestorUserName = null;
+  }
+
+  /** Returns true if field requestorUserName is set (has been assigned a 
value) and false otherwise */
+  public boolean isSetRequestorUserName() {
+    return this.requestorUserName != null;
+  }
+
+  public void setRequestorUserNameIsSet(boolean value) {
+    if (!value) {
+      this.requestorUserName = null;
+    }
+  }
+
   public int getAuthorizableSetSize() {
     return (this.authorizableSet == null) ? 0 : this.authorizableSet.size();
   }
@@ -322,6 +358,14 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
       }
       break;
 
+    case REQUESTOR_USER_NAME:
+      if (value == null) {
+        unsetRequestorUserName();
+      } else {
+        setRequestorUserName((String)value);
+      }
+      break;
+
     case AUTHORIZABLE_SET:
       if (value == null) {
         unsetAuthorizableSet();
@@ -354,6 +398,9 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
     case PROTOCOL_VERSION:
       return Integer.valueOf(getProtocol_version());
 
+    case REQUESTOR_USER_NAME:
+      return getRequestorUserName();
+
     case AUTHORIZABLE_SET:
       return getAuthorizableSet();
 
@@ -376,6 +423,8 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
     switch (field) {
     case PROTOCOL_VERSION:
       return isSetProtocol_version();
+    case REQUESTOR_USER_NAME:
+      return isSetRequestorUserName();
     case AUTHORIZABLE_SET:
       return isSetAuthorizableSet();
     case GROUPS:
@@ -408,6 +457,15 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
         return false;
     }
 
+    boolean this_present_requestorUserName = true && 
this.isSetRequestorUserName();
+    boolean that_present_requestorUserName = true && 
that.isSetRequestorUserName();
+    if (this_present_requestorUserName || that_present_requestorUserName) {
+      if (!(this_present_requestorUserName && that_present_requestorUserName))
+        return false;
+      if (!this.requestorUserName.equals(that.requestorUserName))
+        return false;
+    }
+
     boolean this_present_authorizableSet = true && this.isSetAuthorizableSet();
     boolean that_present_authorizableSet = true && that.isSetAuthorizableSet();
     if (this_present_authorizableSet || that_present_authorizableSet) {
@@ -447,6 +505,11 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
     if (present_protocol_version)
       builder.append(protocol_version);
 
+    boolean present_requestorUserName = true && (isSetRequestorUserName());
+    builder.append(present_requestorUserName);
+    if (present_requestorUserName)
+      builder.append(requestorUserName);
+
     boolean present_authorizableSet = true && (isSetAuthorizableSet());
     builder.append(present_authorizableSet);
     if (present_authorizableSet)
@@ -483,6 +546,16 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
         return lastComparison;
       }
     }
+    lastComparison = 
Boolean.valueOf(isSetRequestorUserName()).compareTo(typedOther.isSetRequestorUserName());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetRequestorUserName()) {
+      lastComparison = 
org.apache.thrift.TBaseHelper.compareTo(this.requestorUserName, 
typedOther.requestorUserName);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
     lastComparison = 
Boolean.valueOf(isSetAuthorizableSet()).compareTo(typedOther.isSetAuthorizableSet());
     if (lastComparison != 0) {
       return lastComparison;
@@ -537,6 +610,14 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
     sb.append(this.protocol_version);
     first = false;
     if (!first) sb.append(", ");
+    sb.append("requestorUserName:");
+    if (this.requestorUserName == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.requestorUserName);
+    }
+    first = false;
+    if (!first) sb.append(", ");
     sb.append("authorizableSet:");
     if (this.authorizableSet == null) {
       sb.append("null");
@@ -574,6 +655,10 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
       throw new org.apache.thrift.protocol.TProtocolException("Required field 
'protocol_version' is unset! Struct:" + toString());
     }
 
+    if (!isSetRequestorUserName()) {
+      throw new org.apache.thrift.protocol.TProtocolException("Required field 
'requestorUserName' is unset! Struct:" + toString());
+    }
+
     if (!isSetAuthorizableSet()) {
       throw new org.apache.thrift.protocol.TProtocolException("Required field 
'authorizableSet' is unset! Struct:" + toString());
     }
@@ -628,7 +713,15 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, 
schemeField.type);
             }
             break;
-          case 2: // AUTHORIZABLE_SET
+          case 2: // REQUESTOR_USER_NAME
+            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+              struct.requestorUserName = iprot.readString();
+              struct.setRequestorUserNameIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, 
schemeField.type);
+            }
+            break;
+          case 3: // AUTHORIZABLE_SET
             if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
               {
                 org.apache.thrift.protocol.TSet _set82 = iprot.readSetBegin();
@@ -647,7 +740,7 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, 
schemeField.type);
             }
             break;
-          case 3: // GROUPS
+          case 4: // GROUPS
             if (schemeField.type == org.apache.thrift.protocol.TType.SET) {
               {
                 org.apache.thrift.protocol.TSet _set85 = iprot.readSetBegin();
@@ -665,7 +758,7 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, 
schemeField.type);
             }
             break;
-          case 4: // ROLE_SET
+          case 5: // ROLE_SET
             if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
               struct.roleSet = new TSentryActiveRoleSet();
               struct.roleSet.read(iprot);
@@ -690,6 +783,11 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
       oprot.writeFieldBegin(PROTOCOL_VERSION_FIELD_DESC);
       oprot.writeI32(struct.protocol_version);
       oprot.writeFieldEnd();
+      if (struct.requestorUserName != null) {
+        oprot.writeFieldBegin(REQUESTOR_USER_NAME_FIELD_DESC);
+        oprot.writeString(struct.requestorUserName);
+        oprot.writeFieldEnd();
+      }
       if (struct.authorizableSet != null) {
         oprot.writeFieldBegin(AUTHORIZABLE_SET_FIELD_DESC);
         {
@@ -741,6 +839,7 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
     public void write(org.apache.thrift.protocol.TProtocol prot, 
TListSentryPrivilegesByAuthRequest struct) throws org.apache.thrift.TException {
       TTupleProtocol oprot = (TTupleProtocol) prot;
       oprot.writeI32(struct.protocol_version);
+      oprot.writeString(struct.requestorUserName);
       {
         oprot.writeI32(struct.authorizableSet.size());
         for (TSentryAuthorizable _iter90 : struct.authorizableSet)
@@ -775,6 +874,8 @@ public class TListSentryPrivilegesByAuthRequest implements 
org.apache.thrift.TBa
       TTupleProtocol iprot = (TTupleProtocol) prot;
       struct.protocol_version = iprot.readI32();
       struct.setProtocol_versionIsSet(true);
+      struct.requestorUserName = iprot.readString();
+      struct.setRequestorUserNameIsSet(true);
       {
         org.apache.thrift.protocol.TSet _set92 = new 
org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, 
iprot.readI32());
         struct.authorizableSet = new 
HashSet<TSentryAuthorizable>(2*_set92.size);

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/f6fc0422/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesByAuthResponse.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesByAuthResponse.java
 
b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesByAuthResponse.java
index 6fe5a7e..d0cfe0b 100644
--- 
a/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesByAuthResponse.java
+++ 
b/sentry-provider/sentry-provider-db/src/gen/thrift/gen-javabean/org/apache/sentry/provider/db/service/thrift/TListSentryPrivilegesByAuthResponse.java
@@ -44,7 +44,7 @@ public class TListSentryPrivilegesByAuthResponse implements 
org.apache.thrift.TB
   }
 
   private org.apache.sentry.service.thrift.TSentryResponseStatus status; // 
required
-  private Map<TSentryAuthorizable,TSentryPrivilegeMap> privilegesMapByAuth; // 
required
+  private Map<TSentryAuthorizable,TSentryPrivilegeMap> privilegesMapByAuth; // 
optional
 
   /** The set of fields this struct contains, along with convenience methods 
for finding and manipulating them. */
   public enum _Fields implements org.apache.thrift.TFieldIdEnum {
@@ -108,12 +108,13 @@ public class TListSentryPrivilegesByAuthResponse 
implements org.apache.thrift.TB
   }
 
   // isset id assignments
+  private _Fields optionals[] = {_Fields.PRIVILEGES_MAP_BY_AUTH};
   public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> 
metaDataMap;
   static {
     Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new 
EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.STATUS, new 
org.apache.thrift.meta_data.FieldMetaData("status", 
org.apache.thrift.TFieldRequirementType.REQUIRED, 
         new 
org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT,
 org.apache.sentry.service.thrift.TSentryResponseStatus.class)));
-    tmpMap.put(_Fields.PRIVILEGES_MAP_BY_AUTH, new 
org.apache.thrift.meta_data.FieldMetaData("privilegesMapByAuth", 
org.apache.thrift.TFieldRequirementType.REQUIRED, 
+    tmpMap.put(_Fields.PRIVILEGES_MAP_BY_AUTH, new 
org.apache.thrift.meta_data.FieldMetaData("privilegesMapByAuth", 
org.apache.thrift.TFieldRequirementType.OPTIONAL, 
         new 
org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
             new 
org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT,
 TSentryAuthorizable.class), 
             new 
org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT,
 TSentryPrivilegeMap.class))));
@@ -125,12 +126,10 @@ public class TListSentryPrivilegesByAuthResponse 
implements org.apache.thrift.TB
   }
 
   public TListSentryPrivilegesByAuthResponse(
-    org.apache.sentry.service.thrift.TSentryResponseStatus status,
-    Map<TSentryAuthorizable,TSentryPrivilegeMap> privilegesMapByAuth)
+    org.apache.sentry.service.thrift.TSentryResponseStatus status)
   {
     this();
     this.status = status;
-    this.privilegesMapByAuth = privilegesMapByAuth;
   }
 
   /**
@@ -378,14 +377,16 @@ public class TListSentryPrivilegesByAuthResponse 
implements org.apache.thrift.TB
       sb.append(this.status);
     }
     first = false;
-    if (!first) sb.append(", ");
-    sb.append("privilegesMapByAuth:");
-    if (this.privilegesMapByAuth == null) {
-      sb.append("null");
-    } else {
-      sb.append(this.privilegesMapByAuth);
+    if (isSetPrivilegesMapByAuth()) {
+      if (!first) sb.append(", ");
+      sb.append("privilegesMapByAuth:");
+      if (this.privilegesMapByAuth == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.privilegesMapByAuth);
+      }
+      first = false;
     }
-    first = false;
     sb.append(")");
     return sb.toString();
   }
@@ -396,10 +397,6 @@ public class TListSentryPrivilegesByAuthResponse 
implements org.apache.thrift.TB
       throw new org.apache.thrift.protocol.TProtocolException("Required field 
'status' is unset! Struct:" + toString());
     }
 
-    if (!isSetPrivilegesMapByAuth()) {
-      throw new org.apache.thrift.protocol.TProtocolException("Required field 
'privilegesMapByAuth' is unset! Struct:" + toString());
-    }
-
     // check for sub-struct validity
     if (status != null) {
       status.validate();
@@ -490,17 +487,19 @@ public class TListSentryPrivilegesByAuthResponse 
implements org.apache.thrift.TB
         oprot.writeFieldEnd();
       }
       if (struct.privilegesMapByAuth != null) {
-        oprot.writeFieldBegin(PRIVILEGES_MAP_BY_AUTH_FIELD_DESC);
-        {
-          oprot.writeMapBegin(new 
org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRUCT, 
org.apache.thrift.protocol.TType.STRUCT, struct.privilegesMapByAuth.size()));
-          for (Map.Entry<TSentryAuthorizable, TSentryPrivilegeMap> _iter102 : 
struct.privilegesMapByAuth.entrySet())
+        if (struct.isSetPrivilegesMapByAuth()) {
+          oprot.writeFieldBegin(PRIVILEGES_MAP_BY_AUTH_FIELD_DESC);
           {
-            _iter102.getKey().write(oprot);
-            _iter102.getValue().write(oprot);
+            oprot.writeMapBegin(new 
org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRUCT, 
org.apache.thrift.protocol.TType.STRUCT, struct.privilegesMapByAuth.size()));
+            for (Map.Entry<TSentryAuthorizable, TSentryPrivilegeMap> _iter102 
: struct.privilegesMapByAuth.entrySet())
+            {
+              _iter102.getKey().write(oprot);
+              _iter102.getValue().write(oprot);
+            }
+            oprot.writeMapEnd();
           }
-          oprot.writeMapEnd();
+          oprot.writeFieldEnd();
         }
-        oprot.writeFieldEnd();
       }
       oprot.writeFieldStop();
       oprot.writeStructEnd();
@@ -520,12 +519,19 @@ public class TListSentryPrivilegesByAuthResponse 
implements org.apache.thrift.TB
     public void write(org.apache.thrift.protocol.TProtocol prot, 
TListSentryPrivilegesByAuthResponse struct) throws org.apache.thrift.TException 
{
       TTupleProtocol oprot = (TTupleProtocol) prot;
       struct.status.write(oprot);
-      {
-        oprot.writeI32(struct.privilegesMapByAuth.size());
-        for (Map.Entry<TSentryAuthorizable, TSentryPrivilegeMap> _iter103 : 
struct.privilegesMapByAuth.entrySet())
+      BitSet optionals = new BitSet();
+      if (struct.isSetPrivilegesMapByAuth()) {
+        optionals.set(0);
+      }
+      oprot.writeBitSet(optionals, 1);
+      if (struct.isSetPrivilegesMapByAuth()) {
         {
-          _iter103.getKey().write(oprot);
-          _iter103.getValue().write(oprot);
+          oprot.writeI32(struct.privilegesMapByAuth.size());
+          for (Map.Entry<TSentryAuthorizable, TSentryPrivilegeMap> _iter103 : 
struct.privilegesMapByAuth.entrySet())
+          {
+            _iter103.getKey().write(oprot);
+            _iter103.getValue().write(oprot);
+          }
         }
       }
     }
@@ -536,21 +542,24 @@ public class TListSentryPrivilegesByAuthResponse 
implements org.apache.thrift.TB
       struct.status = new 
org.apache.sentry.service.thrift.TSentryResponseStatus();
       struct.status.read(iprot);
       struct.setStatusIsSet(true);
-      {
-        org.apache.thrift.protocol.TMap _map104 = new 
org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRUCT, 
org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
-        struct.privilegesMapByAuth = new 
HashMap<TSentryAuthorizable,TSentryPrivilegeMap>(2*_map104.size);
-        for (int _i105 = 0; _i105 < _map104.size; ++_i105)
+      BitSet incoming = iprot.readBitSet(1);
+      if (incoming.get(0)) {
         {
-          TSentryAuthorizable _key106; // required
-          TSentryPrivilegeMap _val107; // required
-          _key106 = new TSentryAuthorizable();
-          _key106.read(iprot);
-          _val107 = new TSentryPrivilegeMap();
-          _val107.read(iprot);
-          struct.privilegesMapByAuth.put(_key106, _val107);
+          org.apache.thrift.protocol.TMap _map104 = new 
org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRUCT, 
org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+          struct.privilegesMapByAuth = new 
HashMap<TSentryAuthorizable,TSentryPrivilegeMap>(2*_map104.size);
+          for (int _i105 = 0; _i105 < _map104.size; ++_i105)
+          {
+            TSentryAuthorizable _key106; // required
+            TSentryPrivilegeMap _val107; // required
+            _key106 = new TSentryAuthorizable();
+            _key106.read(iprot);
+            _val107 = new TSentryPrivilegeMap();
+            _val107.read(iprot);
+            struct.privilegesMapByAuth.put(_key106, _val107);
+          }
         }
+        struct.setPrivilegesMapByAuthIsSet(true);
       }
-      struct.setPrivilegesMapByAuthIsSet(true);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/f6fc0422/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClient.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClient.java
 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClient.java
index 0668912..65905f5 100644
--- 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClient.java
+++ 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClient.java
@@ -574,15 +574,17 @@ TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
   }
 
   public synchronized Map<TSentryAuthorizable, TSentryPrivilegeMap> 
listPrivilegsbyAuthorizable(
-      Set<List<? extends Authorizable>> authorizables, Set<String> groups, 
ActiveRoleSet roleSet)
-      throws SentryUserException {
+      String requestorUserName,
+      Set<List<? extends Authorizable>> authorizables, Set<String> groups,
+      ActiveRoleSet roleSet) throws SentryUserException {
     Set<TSentryAuthorizable> authSet = Sets.newTreeSet();
 
     for (List<? extends Authorizable> authorizableHierarchy : authorizables) {
       authSet.add(setupSentryAuthorizable(authorizableHierarchy));
     }
     TListSentryPrivilegesByAuthRequest request = new 
TListSentryPrivilegesByAuthRequest(
-        ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, authSet);
+        ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
+        authSet);
     if (groups != null) {
       request.setGroups(groups);
     }

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/f6fc0422/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
index e3cdfc2..67dc1f8 100644
--- 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
+++ 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
@@ -537,14 +537,48 @@ public class SentryPolicyStoreProcessor implements 
SentryPolicyService.Iface {
       TListSentryPrivilegesByAuthRequest request) throws TException {
     TListSentryPrivilegesByAuthResponse response = new 
TListSentryPrivilegesByAuthResponse();
     Map<TSentryAuthorizable, TSentryPrivilegeMap> authRoleMap = 
Maps.newHashMap();
+    String subject = request.getRequestorUserName();
+    Set<String> requestedGroups = request.getGroups();
+    TSentryActiveRoleSet requestedRoleSet = request.getRoleSet();
     try {
+      Set<String> memberGroups = getRequestorGroups(subject);
+      if(!inAdminGroups(memberGroups)) {
+        // disallow non-admin to lookup groups that they are not part of
+        if (requestedGroups != null && !requestedGroups.isEmpty()) {
+          for (String requestedGroup : requestedGroups) {
+            if (!memberGroups.contains(requestedGroup)) {
+              // if user doesn't belong to one of the requested group then 
raise error
+              throw new SentryAccessDeniedException("Access denied to " + 
subject);
+            }
+          }
+        } else {
+          // non-admin's search is limited to it's own groups
+          requestedGroups = memberGroups;
+        }
+
+        // disallow non-admin to lookup roles that they are not part of
+        if (requestedRoleSet != null && !requestedRoleSet.isAll()) {
+          Set<String> roles = toTrimedLower(sentryStore
+              .getRoleNamesForGroups(memberGroups));
+          for (String role : toTrimedLower(requestedRoleSet.getRoles())) {
+            if (!roles.contains(role)) {
+              throw new SentryAccessDeniedException("Access denied to "
+                  + subject);
+            }
+          }
+        }
+      }
+
       for (TSentryAuthorizable authorizable : request.getAuthorizableSet()) {
         authRoleMap.put(authorizable, sentryStore
-            .listSentryPrivilegesByAuthorizable(request.getGroups(),
+            .listSentryPrivilegesByAuthorizable(requestedGroups,
                 request.getRoleSet(), authorizable));
       }
       response.setPrivilegesMapByAuth(authRoleMap);
       response.setStatus(Status.OK());
+    } catch (SentryAccessDeniedException e) {
+      LOGGER.error(e.getMessage(), e);
+      response.setStatus(Status.AccessDenied(e.getMessage(), e));
     } catch (Exception e) {
       String msg = "Unknown error for request: " + request + ", message: "
           + e.getMessage();

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/f6fc0422/sentry-provider/sentry-provider-db/src/main/resources/sentry_policy_service.thrift
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/main/resources/sentry_policy_service.thrift
 
b/sentry-provider/sentry-provider-db/src/main/resources/sentry_policy_service.thrift
index d8357aa..d9a3913 100644
--- 
a/sentry-provider/sentry-provider-db/src/main/resources/sentry_policy_service.thrift
+++ 
b/sentry-provider/sentry-provider-db/src/main/resources/sentry_policy_service.thrift
@@ -206,13 +206,14 @@ struct TSentryPrivilegeMap {
 }
 struct TListSentryPrivilegesByAuthRequest {
 1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1,
-2: required set<TSentryAuthorizable> authorizableSet,
-3: optional set<string> groups,
-4: optional TSentryActiveRoleSet roleSet
+2: required string requestorUserName, # user on whose behalf the request is 
issued
+3: required set<TSentryAuthorizable> authorizableSet,
+4: optional set<string> groups,
+5: optional TSentryActiveRoleSet roleSet
 }
 struct TListSentryPrivilegesByAuthResponse {
 1: required sentry_common_service.TSentryResponseStatus status,
-2: required map<TSentryAuthorizable, TSentryPrivilegeMap> privilegesMapByAuth
+2: optional map<TSentryAuthorizable, TSentryPrivilegeMap> privilegesMapByAuth 
# will not be set in case of an error
 }
 
 service SentryPolicyService

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/f6fc0422/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceIntegration.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceIntegration.java
 
b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceIntegration.java
index 38cb39b..95c908f 100644
--- 
a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceIntegration.java
+++ 
b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceIntegration.java
@@ -20,7 +20,9 @@ package org.apache.sentry.provider.db.service.thrift;
 
 import static junit.framework.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -33,6 +35,7 @@ import org.apache.sentry.core.model.db.AccessURI;
 import org.apache.sentry.core.model.db.Database;
 import org.apache.sentry.core.model.db.Server;
 import org.apache.sentry.core.model.db.Table;
+import org.apache.sentry.provider.db.SentryAccessDeniedException;
 import org.apache.sentry.service.thrift.SentryServiceIntegrationBase;
 import org.junit.Test;
 
@@ -359,31 +362,31 @@ public class TestSentryServiceIntegration extends 
SentryServiceIntegrationBase {
 
     // verify for null group and null roleset
     Map<TSentryAuthorizable, TSentryPrivilegeMap> authPrivMap = client
-        .listPrivilegsbyAuthorizable(authorizableSet, null, null);
+        .listPrivilegsbyAuthorizable(requestorUserName, authorizableSet, null, 
null);
     assertEquals(expectedResults, authPrivMap);
 
     // verify for null group and specific roleset
-    authPrivMap = client.listPrivilegsbyAuthorizable(authorizableSet, null,
-        new ActiveRoleSet(testRoleSet));
+    authPrivMap = client.listPrivilegsbyAuthorizable(requestorUserName, 
authorizableSet,
+        null, new ActiveRoleSet(testRoleSet));
     assertEquals(expectedResults, authPrivMap);
 
     // verify for null group and specific roleset
-    authPrivMap = client.listPrivilegsbyAuthorizable(authorizableSet, null,
+    authPrivMap = client.listPrivilegsbyAuthorizable(requestorUserName, 
authorizableSet, null,
         ActiveRoleSet.ALL);
     assertEquals(expectedResults, authPrivMap);
 
     // verify for specific group and null roleset
-    authPrivMap = client.listPrivilegsbyAuthorizable(authorizableSet,
+    authPrivMap = client.listPrivilegsbyAuthorizable(requestorUserName, 
authorizableSet,
         testGroupSet, null);
     assertEquals(expectedResults, authPrivMap);
 
     // verify for specific group and specific roleset
-    authPrivMap = client.listPrivilegsbyAuthorizable(authorizableSet,
+    authPrivMap = client.listPrivilegsbyAuthorizable(requestorUserName, 
authorizableSet,
         testGroupSet, new ActiveRoleSet(testRoleSet));
     assertEquals(expectedResults, authPrivMap);
 
     // verify for specific group and ALL roleset
-    authPrivMap = client.listPrivilegsbyAuthorizable(authorizableSet,
+    authPrivMap = client.listPrivilegsbyAuthorizable(requestorUserName, 
authorizableSet,
         testGroupSet, ActiveRoleSet.ALL);
     assertEquals(expectedResults, authPrivMap);
   }
@@ -445,7 +448,7 @@ public class TestSentryServiceIntegration extends 
SentryServiceIntegrationBase {
     Set<List<? extends Authorizable>> authorizableSet = Sets.newHashSet();
     authorizableSet.add(db2TabAuthrizable);
     Map<TSentryAuthorizable, TSentryPrivilegeMap> authPrivMap = client
-        .listPrivilegsbyAuthorizable(authorizableSet, null, null);
+        .listPrivilegsbyAuthorizable(requestorUserName, authorizableSet, null, 
null);
 
     assertEquals(expectedResults, authPrivMap);
   }
@@ -505,9 +508,116 @@ public class TestSentryServiceIntegration extends 
SentryServiceIntegrationBase {
     Set<List<? extends Authorizable>> authorizableSet = Sets.newHashSet();
     authorizableSet.add(uri1Authrizable);
     Map<TSentryAuthorizable, TSentryPrivilegeMap> authPrivMap = client
-        .listPrivilegsbyAuthorizable(authorizableSet, null, null);
+        .listPrivilegsbyAuthorizable(requestorUserName, authorizableSet, null, 
null);
 
     assertEquals(expectedResults, authPrivMap);
   }
 
+  /**
+   * List privileges by authorizables executed by non-admin user
+   * Test various positive and negative cases for non-admin user
+   * @throws Exception
+   */
+  @Test
+  public void testListByAuthTabForNonAdmin() throws Exception {
+    String requestorUserName = ADMIN_USER;
+    String user1 = "user1";
+    String group1 = "group1";
+    String group2 = "group2";
+    Set<String> requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP);
+    Set<String> userGroupNames1 = Sets.newHashSet(group1);
+    Set<String> userGroupNames2 = Sets.newHashSet(group2);
+    String roleName1 = "role1";
+    String roleName2 = "role2";
+    String server = "server1";
+    String db = "testDB";
+    String db2 = "testDB2";
+    String tab = "testTab";
+    setLocalGroupMapping(requestorUserName, requestorUserGroupNames);
+    setLocalGroupMapping(user1, userGroupNames1);
+    writePolicyFile();
+
+    client.dropRoleIfExists(requestorUserName, roleName1);
+    client.createRole(requestorUserName, roleName1);
+    client.dropRoleIfExists(requestorUserName, roleName2);
+    client.createRole(requestorUserName, roleName2);
+
+    client.grantDatabasePrivilege(requestorUserName, roleName1, server, db,
+        AccessConstants.SELECT);
+    client.grantTablePrivilege(requestorUserName, roleName1, server, db, tab,
+        AccessConstants.ALL);
+    TSentryPrivilege role1db2tab = client.grantTablePrivilege(
+        requestorUserName, roleName1, server, db2, tab, 
AccessConstants.SELECT);
+    client.grantRoleToGroup(requestorUserName, group1, roleName1);
+
+    client.grantDatabasePrivilege(requestorUserName, roleName2, server, db,
+        AccessConstants.ALL);
+    client.grantDatabasePrivilege(requestorUserName, roleName2, server, db2,
+        AccessConstants.SELECT);
+    client.grantTablePrivilege(requestorUserName, roleName2, server, db2, tab,
+        AccessConstants.ALL);
+    client.grantURIPrivilege(requestorUserName, roleName1, server,
+        "hdfs:///fooUri");
+
+    // build expected output. user1 should see privileges on tab1 from role1
+    TSentryPrivilegeMap db1RoleToPrivMap = new TSentryPrivilegeMap(
+        new TreeMap<String, Set<TSentryPrivilege>>());
+    db1RoleToPrivMap.getPrivilegeMap().put(roleName1, 
Sets.newHashSet(role1db2tab));
+    Map<TSentryAuthorizable, TSentryPrivilegeMap> expectedResults = 
Maps.newTreeMap();
+    List<? extends Authorizable> db2TabAuthorizable = Lists.newArrayList(
+        new Server(server), new Database(db2), new Table(tab));
+    expectedResults.put(
+        SentryPolicyServiceClient.setupSentryAuthorizable(db2TabAuthorizable),
+        db1RoleToPrivMap);
+
+    Set<List<? extends Authorizable>> authorizableSet = Sets.newHashSet();
+    authorizableSet.add(db2TabAuthorizable);
+
+    // list privileges with null group and roles
+    Map<TSentryAuthorizable, TSentryPrivilegeMap> authPrivMap = client
+        .listPrivilegsbyAuthorizable(user1, authorizableSet, null, null);
+    assertEquals(expectedResults, authPrivMap);
+
+    // list privileges with empty group set and null roles
+    authPrivMap = client.listPrivilegsbyAuthorizable(user1, authorizableSet,
+        new HashSet<String>(), null);
+    assertEquals(expectedResults, authPrivMap);
+
+    // list privileges with null group set and ALL roleset
+    authPrivMap = client.listPrivilegsbyAuthorizable(user1, authorizableSet,
+        null, new ActiveRoleSet(true));
+    assertEquals(expectedResults, authPrivMap);
+
+    // list privileges with user1's group set and null roles
+    authPrivMap = client.listPrivilegsbyAuthorizable(user1, authorizableSet,
+        userGroupNames1, null);
+    assertEquals(expectedResults, authPrivMap);
+
+    // list privileges with user1's group set and ALL roles
+    authPrivMap = client.listPrivilegsbyAuthorizable(user1, authorizableSet,
+        userGroupNames1, new ActiveRoleSet(true));
+    assertEquals(expectedResults, authPrivMap);
+
+    // list privileges with null group and user's specific roles with 
uppercase name
+    authPrivMap = client.listPrivilegsbyAuthorizable(user1, authorizableSet,
+        null, new ActiveRoleSet(Sets.newHashSet(roleName1.toUpperCase())));
+    assertEquals(expectedResults, authPrivMap);
+
+    // verify that user1 can't query group2
+    try {
+      client.listPrivilegsbyAuthorizable(user1, authorizableSet, 
userGroupNames2, null);
+      fail("listPrivilegsbyAuthorizable() should fail for user1 accessing " + 
group2);
+    } catch (SentryAccessDeniedException e) {
+      // expected
+    }
+
+    // verify that user1 can't query role2
+    ActiveRoleSet roleSet2 = new ActiveRoleSet(Sets.newHashSet(roleName2));
+    try {
+      client.listPrivilegsbyAuthorizable(user1, authorizableSet, null, 
roleSet2);
+      fail("listPrivilegsbyAuthorizable() should fail for user1 accessing " + 
roleName2);
+    } catch (SentryAccessDeniedException e) {
+      // expected
+    }
+  }
 }

Reply via email to