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 + } + } }
