Repository: sentry Updated Branches: refs/heads/master 7a4320968 -> 097cf0b05
SENTRY-2452: Change the thrift interface to send the list of authorizable to sentry server. (Kalyan Kumar Kalvagadda reviewed by Sergio Pena and Na Li) Project: http://git-wip-us.apache.org/repos/asf/sentry/repo Commit: http://git-wip-us.apache.org/repos/asf/sentry/commit/097cf0b0 Tree: http://git-wip-us.apache.org/repos/asf/sentry/tree/097cf0b0 Diff: http://git-wip-us.apache.org/repos/asf/sentry/diff/097cf0b0 Branch: refs/heads/master Commit: 097cf0b05d52c291868debfb2a52afa02aa32eca Parents: 7a43209 Author: Kalyan Kumar Kalvagadda <[email protected]> Authored: Mon Dec 10 13:51:43 2018 -0600 Committer: Kalyan Kumar Kalvagadda <[email protected]> Committed: Mon Dec 10 13:51:43 2018 -0600 ---------------------------------------------------------------------- .../core/common/utils/SentryConstants.java | 1 + .../service/thrift/TPrivilegePrincipalType.java | 2 +- .../thrift/TSentryExportMappingDataRequest.java | 170 ++++++++++++------- .../thrift/TSentryPrivilegesResponse.java | 76 ++++----- .../sentry/api/common/SentryServiceUtil.java | 68 +++++--- .../SentryPolicyServiceClientDefaultImpl.java | 7 +- .../main/resources/sentry_policy_service.thrift | 2 +- .../api/common/TestSentryServiceUtil.java | 59 +++++++ .../thrift/SentryPolicyStoreProcessor.java | 18 +- .../thrift/TestSentryServiceImportExport.java | 7 +- 10 files changed, 280 insertions(+), 130 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/sentry/blob/097cf0b0/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/SentryConstants.java ---------------------------------------------------------------------- diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/SentryConstants.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/SentryConstants.java index d8c1061..9c2ba6f 100644 --- a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/SentryConstants.java +++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/SentryConstants.java @@ -22,6 +22,7 @@ import com.google.common.base.Splitter; public class SentryConstants { public static final String ROLE_SEPARATOR = ","; + public static final String COMMA_SEPARATOR = ","; public static final String AUTHORIZABLE_SEPARATOR = "->"; public static final String KV_SEPARATOR = "="; http://git-wip-us.apache.org/repos/asf/sentry/blob/097cf0b0/sentry-hdfs/sentry-hdfs-common/src/gen/thrift/gen-javabean/org/apache/sentry/hdfs/service/thrift/TPrivilegePrincipalType.java ---------------------------------------------------------------------- diff --git a/sentry-hdfs/sentry-hdfs-common/src/gen/thrift/gen-javabean/org/apache/sentry/hdfs/service/thrift/TPrivilegePrincipalType.java b/sentry-hdfs/sentry-hdfs-common/src/gen/thrift/gen-javabean/org/apache/sentry/hdfs/service/thrift/TPrivilegePrincipalType.java index 6eb8521..5f0cb86 100644 --- a/sentry-hdfs/sentry-hdfs-common/src/gen/thrift/gen-javabean/org/apache/sentry/hdfs/service/thrift/TPrivilegePrincipalType.java +++ b/sentry-hdfs/sentry-hdfs-common/src/gen/thrift/gen-javabean/org/apache/sentry/hdfs/service/thrift/TPrivilegePrincipalType.java @@ -33,7 +33,7 @@ public enum TPrivilegePrincipalType implements org.apache.thrift.TEnum { * Find a the enum type by its integer value, as defined in the Thrift IDL. * @return null if the value is not found. */ - public static TPrivilegePrincipalType findByValue(int value) { + public static TPrivilegePrincipalType findByValue(int value) { switch (value) { case 0: return ROLE; http://git-wip-us.apache.org/repos/asf/sentry/blob/097cf0b0/sentry-service/sentry-service-api/src/gen/thrift/gen-javabean/org/apache/sentry/api/service/thrift/TSentryExportMappingDataRequest.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-api/src/gen/thrift/gen-javabean/org/apache/sentry/api/service/thrift/TSentryExportMappingDataRequest.java b/sentry-service/sentry-service-api/src/gen/thrift/gen-javabean/org/apache/sentry/api/service/thrift/TSentryExportMappingDataRequest.java index 13e57e0..d380a03 100644 --- a/sentry-service/sentry-service-api/src/gen/thrift/gen-javabean/org/apache/sentry/api/service/thrift/TSentryExportMappingDataRequest.java +++ b/sentry-service/sentry-service-api/src/gen/thrift/gen-javabean/org/apache/sentry/api/service/thrift/TSentryExportMappingDataRequest.java @@ -40,7 +40,7 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< 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 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 OBJECT_PATH_FIELD_DESC = new org.apache.thrift.protocol.TField("objectPath", org.apache.thrift.protocol.TType.STRING, (short)3); + private static final org.apache.thrift.protocol.TField AUTHORIZABLES_FIELD_DESC = new org.apache.thrift.protocol.TField("authorizables", org.apache.thrift.protocol.TType.SET, (short)3); private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>(); static { @@ -50,13 +50,13 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< private int protocol_version; // required private String requestorUserName; // required - private String objectPath; // optional + private Set<TSentryAuthorizable> authorizables; // 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 { PROTOCOL_VERSION((short)1, "protocol_version"), REQUESTOR_USER_NAME((short)2, "requestorUserName"), - OBJECT_PATH((short)3, "objectPath"); + AUTHORIZABLES((short)3, "authorizables"); private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); @@ -75,8 +75,8 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< return PROTOCOL_VERSION; case 2: // REQUESTOR_USER_NAME return REQUESTOR_USER_NAME; - case 3: // OBJECT_PATH - return OBJECT_PATH; + case 3: // AUTHORIZABLES + return AUTHORIZABLES; default: return null; } @@ -119,7 +119,7 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< // isset id assignments private static final int __PROTOCOL_VERSION_ISSET_ID = 0; private byte __isset_bitfield = 0; - private static final _Fields optionals[] = {_Fields.OBJECT_PATH}; + private static final _Fields optionals[] = {_Fields.AUTHORIZABLES}; 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); @@ -127,8 +127,9 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< 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.OBJECT_PATH, new org.apache.thrift.meta_data.FieldMetaData("objectPath", org.apache.thrift.TFieldRequirementType.OPTIONAL, - new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); + tmpMap.put(_Fields.AUTHORIZABLES, new org.apache.thrift.meta_data.FieldMetaData("authorizables", org.apache.thrift.TFieldRequirementType.OPTIONAL, + 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)))); metaDataMap = Collections.unmodifiableMap(tmpMap); org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TSentryExportMappingDataRequest.class, metaDataMap); } @@ -157,8 +158,12 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< if (other.isSetRequestorUserName()) { this.requestorUserName = other.requestorUserName; } - if (other.isSetObjectPath()) { - this.objectPath = other.objectPath; + if (other.isSetAuthorizables()) { + Set<TSentryAuthorizable> __this__authorizables = new HashSet<TSentryAuthorizable>(other.authorizables.size()); + for (TSentryAuthorizable other_element : other.authorizables) { + __this__authorizables.add(new TSentryAuthorizable(other_element)); + } + this.authorizables = __this__authorizables; } } @@ -171,7 +176,7 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< this.protocol_version = 1; this.requestorUserName = null; - this.objectPath = null; + this.authorizables = null; } public int getProtocol_version() { @@ -219,26 +224,41 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< } } - public String getObjectPath() { - return this.objectPath; + public int getAuthorizablesSize() { + return (this.authorizables == null) ? 0 : this.authorizables.size(); + } + + public java.util.Iterator<TSentryAuthorizable> getAuthorizablesIterator() { + return (this.authorizables == null) ? null : this.authorizables.iterator(); + } + + public void addToAuthorizables(TSentryAuthorizable elem) { + if (this.authorizables == null) { + this.authorizables = new HashSet<TSentryAuthorizable>(); + } + this.authorizables.add(elem); } - public void setObjectPath(String objectPath) { - this.objectPath = objectPath; + public Set<TSentryAuthorizable> getAuthorizables() { + return this.authorizables; } - public void unsetObjectPath() { - this.objectPath = null; + public void setAuthorizables(Set<TSentryAuthorizable> authorizables) { + this.authorizables = authorizables; } - /** Returns true if field objectPath is set (has been assigned a value) and false otherwise */ - public boolean isSetObjectPath() { - return this.objectPath != null; + public void unsetAuthorizables() { + this.authorizables = null; } - public void setObjectPathIsSet(boolean value) { + /** Returns true if field authorizables is set (has been assigned a value) and false otherwise */ + public boolean isSetAuthorizables() { + return this.authorizables != null; + } + + public void setAuthorizablesIsSet(boolean value) { if (!value) { - this.objectPath = null; + this.authorizables = null; } } @@ -260,11 +280,11 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< } break; - case OBJECT_PATH: + case AUTHORIZABLES: if (value == null) { - unsetObjectPath(); + unsetAuthorizables(); } else { - setObjectPath((String)value); + setAuthorizables((Set<TSentryAuthorizable>)value); } break; @@ -279,8 +299,8 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< case REQUESTOR_USER_NAME: return getRequestorUserName(); - case OBJECT_PATH: - return getObjectPath(); + case AUTHORIZABLES: + return getAuthorizables(); } throw new IllegalStateException(); @@ -297,8 +317,8 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< return isSetProtocol_version(); case REQUESTOR_USER_NAME: return isSetRequestorUserName(); - case OBJECT_PATH: - return isSetObjectPath(); + case AUTHORIZABLES: + return isSetAuthorizables(); } throw new IllegalStateException(); } @@ -334,12 +354,12 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< return false; } - boolean this_present_objectPath = true && this.isSetObjectPath(); - boolean that_present_objectPath = true && that.isSetObjectPath(); - if (this_present_objectPath || that_present_objectPath) { - if (!(this_present_objectPath && that_present_objectPath)) + boolean this_present_authorizables = true && this.isSetAuthorizables(); + boolean that_present_authorizables = true && that.isSetAuthorizables(); + if (this_present_authorizables || that_present_authorizables) { + if (!(this_present_authorizables && that_present_authorizables)) return false; - if (!this.objectPath.equals(that.objectPath)) + if (!this.authorizables.equals(that.authorizables)) return false; } @@ -360,10 +380,10 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< if (present_requestorUserName) list.add(requestorUserName); - boolean present_objectPath = true && (isSetObjectPath()); - list.add(present_objectPath); - if (present_objectPath) - list.add(objectPath); + boolean present_authorizables = true && (isSetAuthorizables()); + list.add(present_authorizables); + if (present_authorizables) + list.add(authorizables); return list.hashCode(); } @@ -396,12 +416,12 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< return lastComparison; } } - lastComparison = Boolean.valueOf(isSetObjectPath()).compareTo(other.isSetObjectPath()); + lastComparison = Boolean.valueOf(isSetAuthorizables()).compareTo(other.isSetAuthorizables()); if (lastComparison != 0) { return lastComparison; } - if (isSetObjectPath()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.objectPath, other.objectPath); + if (isSetAuthorizables()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.authorizables, other.authorizables); if (lastComparison != 0) { return lastComparison; } @@ -437,13 +457,13 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< sb.append(this.requestorUserName); } first = false; - if (isSetObjectPath()) { + if (isSetAuthorizables()) { if (!first) sb.append(", "); - sb.append("objectPath:"); - if (this.objectPath == null) { + sb.append("authorizables:"); + if (this.authorizables == null) { sb.append("null"); } else { - sb.append(this.objectPath); + sb.append(this.authorizables); } first = false; } @@ -516,10 +536,21 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; - case 3: // OBJECT_PATH - if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.objectPath = iprot.readString(); - struct.setObjectPathIsSet(true); + case 3: // AUTHORIZABLES + if (schemeField.type == org.apache.thrift.protocol.TType.SET) { + { + org.apache.thrift.protocol.TSet _set228 = iprot.readSetBegin(); + struct.authorizables = new HashSet<TSentryAuthorizable>(2*_set228.size); + TSentryAuthorizable _elem229; + for (int _i230 = 0; _i230 < _set228.size; ++_i230) + { + _elem229 = new TSentryAuthorizable(); + _elem229.read(iprot); + struct.authorizables.add(_elem229); + } + iprot.readSetEnd(); + } + struct.setAuthorizablesIsSet(true); } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } @@ -545,10 +576,17 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< oprot.writeString(struct.requestorUserName); oprot.writeFieldEnd(); } - if (struct.objectPath != null) { - if (struct.isSetObjectPath()) { - oprot.writeFieldBegin(OBJECT_PATH_FIELD_DESC); - oprot.writeString(struct.objectPath); + if (struct.authorizables != null) { + if (struct.isSetAuthorizables()) { + oprot.writeFieldBegin(AUTHORIZABLES_FIELD_DESC); + { + oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, struct.authorizables.size())); + for (TSentryAuthorizable _iter231 : struct.authorizables) + { + _iter231.write(oprot); + } + oprot.writeSetEnd(); + } oprot.writeFieldEnd(); } } @@ -572,12 +610,18 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< oprot.writeI32(struct.protocol_version); oprot.writeString(struct.requestorUserName); BitSet optionals = new BitSet(); - if (struct.isSetObjectPath()) { + if (struct.isSetAuthorizables()) { optionals.set(0); } oprot.writeBitSet(optionals, 1); - if (struct.isSetObjectPath()) { - oprot.writeString(struct.objectPath); + if (struct.isSetAuthorizables()) { + { + oprot.writeI32(struct.authorizables.size()); + for (TSentryAuthorizable _iter232 : struct.authorizables) + { + _iter232.write(oprot); + } + } } } @@ -590,8 +634,18 @@ public class TSentryExportMappingDataRequest implements org.apache.thrift.TBase< struct.setRequestorUserNameIsSet(true); BitSet incoming = iprot.readBitSet(1); if (incoming.get(0)) { - struct.objectPath = iprot.readString(); - struct.setObjectPathIsSet(true); + { + org.apache.thrift.protocol.TSet _set233 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32()); + struct.authorizables = new HashSet<TSentryAuthorizable>(2*_set233.size); + TSentryAuthorizable _elem234; + for (int _i235 = 0; _i235 < _set233.size; ++_i235) + { + _elem234 = new TSentryAuthorizable(); + _elem234.read(iprot); + struct.authorizables.add(_elem234); + } + } + struct.setAuthorizablesIsSet(true); } } } http://git-wip-us.apache.org/repos/asf/sentry/blob/097cf0b0/sentry-service/sentry-service-api/src/gen/thrift/gen-javabean/org/apache/sentry/api/service/thrift/TSentryPrivilegesResponse.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-api/src/gen/thrift/gen-javabean/org/apache/sentry/api/service/thrift/TSentryPrivilegesResponse.java b/sentry-service/sentry-service-api/src/gen/thrift/gen-javabean/org/apache/sentry/api/service/thrift/TSentryPrivilegesResponse.java index cea868f..f5b44e9 100644 --- a/sentry-service/sentry-service-api/src/gen/thrift/gen-javabean/org/apache/sentry/api/service/thrift/TSentryPrivilegesResponse.java +++ b/sentry-service/sentry-service-api/src/gen/thrift/gen-javabean/org/apache/sentry/api/service/thrift/TSentryPrivilegesResponse.java @@ -468,26 +468,26 @@ public class TSentryPrivilegesResponse implements org.apache.thrift.TBase<TSentr case 2: // PRIVILEGES_MAP if (schemeField.type == org.apache.thrift.protocol.TType.MAP) { { - org.apache.thrift.protocol.TMap _map228 = iprot.readMapBegin(); - struct.privilegesMap = new HashMap<String,Set<TSentryPrivilege>>(2*_map228.size); - String _key229; - Set<TSentryPrivilege> _val230; - for (int _i231 = 0; _i231 < _map228.size; ++_i231) + org.apache.thrift.protocol.TMap _map236 = iprot.readMapBegin(); + struct.privilegesMap = new HashMap<String,Set<TSentryPrivilege>>(2*_map236.size); + String _key237; + Set<TSentryPrivilege> _val238; + for (int _i239 = 0; _i239 < _map236.size; ++_i239) { - _key229 = iprot.readString(); + _key237 = iprot.readString(); { - org.apache.thrift.protocol.TSet _set232 = iprot.readSetBegin(); - _val230 = new HashSet<TSentryPrivilege>(2*_set232.size); - TSentryPrivilege _elem233; - for (int _i234 = 0; _i234 < _set232.size; ++_i234) + org.apache.thrift.protocol.TSet _set240 = iprot.readSetBegin(); + _val238 = new HashSet<TSentryPrivilege>(2*_set240.size); + TSentryPrivilege _elem241; + for (int _i242 = 0; _i242 < _set240.size; ++_i242) { - _elem233 = new TSentryPrivilege(); - _elem233.read(iprot); - _val230.add(_elem233); + _elem241 = new TSentryPrivilege(); + _elem241.read(iprot); + _val238.add(_elem241); } iprot.readSetEnd(); } - struct.privilegesMap.put(_key229, _val230); + struct.privilegesMap.put(_key237, _val238); } iprot.readMapEnd(); } @@ -518,14 +518,14 @@ public class TSentryPrivilegesResponse implements org.apache.thrift.TBase<TSentr oprot.writeFieldBegin(PRIVILEGES_MAP_FIELD_DESC); { oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, struct.privilegesMap.size())); - for (Map.Entry<String, Set<TSentryPrivilege>> _iter235 : struct.privilegesMap.entrySet()) + for (Map.Entry<String, Set<TSentryPrivilege>> _iter243 : struct.privilegesMap.entrySet()) { - oprot.writeString(_iter235.getKey()); + oprot.writeString(_iter243.getKey()); { - oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, _iter235.getValue().size())); - for (TSentryPrivilege _iter236 : _iter235.getValue()) + oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, _iter243.getValue().size())); + for (TSentryPrivilege _iter244 : _iter243.getValue()) { - _iter236.write(oprot); + _iter244.write(oprot); } oprot.writeSetEnd(); } @@ -554,14 +554,14 @@ public class TSentryPrivilegesResponse implements org.apache.thrift.TBase<TSentr struct.status.write(oprot); { oprot.writeI32(struct.privilegesMap.size()); - for (Map.Entry<String, Set<TSentryPrivilege>> _iter237 : struct.privilegesMap.entrySet()) + for (Map.Entry<String, Set<TSentryPrivilege>> _iter245 : struct.privilegesMap.entrySet()) { - oprot.writeString(_iter237.getKey()); + oprot.writeString(_iter245.getKey()); { - oprot.writeI32(_iter237.getValue().size()); - for (TSentryPrivilege _iter238 : _iter237.getValue()) + oprot.writeI32(_iter245.getValue().size()); + for (TSentryPrivilege _iter246 : _iter245.getValue()) { - _iter238.write(oprot); + _iter246.write(oprot); } } } @@ -575,25 +575,25 @@ public class TSentryPrivilegesResponse implements org.apache.thrift.TBase<TSentr struct.status.read(iprot); struct.setStatusIsSet(true); { - org.apache.thrift.protocol.TMap _map239 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, iprot.readI32()); - struct.privilegesMap = new HashMap<String,Set<TSentryPrivilege>>(2*_map239.size); - String _key240; - Set<TSentryPrivilege> _val241; - for (int _i242 = 0; _i242 < _map239.size; ++_i242) + org.apache.thrift.protocol.TMap _map247 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, iprot.readI32()); + struct.privilegesMap = new HashMap<String,Set<TSentryPrivilege>>(2*_map247.size); + String _key248; + Set<TSentryPrivilege> _val249; + for (int _i250 = 0; _i250 < _map247.size; ++_i250) { - _key240 = iprot.readString(); + _key248 = iprot.readString(); { - org.apache.thrift.protocol.TSet _set243 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32()); - _val241 = new HashSet<TSentryPrivilege>(2*_set243.size); - TSentryPrivilege _elem244; - for (int _i245 = 0; _i245 < _set243.size; ++_i245) + org.apache.thrift.protocol.TSet _set251 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32()); + _val249 = new HashSet<TSentryPrivilege>(2*_set251.size); + TSentryPrivilege _elem252; + for (int _i253 = 0; _i253 < _set251.size; ++_i253) { - _elem244 = new TSentryPrivilege(); - _elem244.read(iprot); - _val241.add(_elem244); + _elem252 = new TSentryPrivilege(); + _elem252.read(iprot); + _val249.add(_elem252); } } - struct.privilegesMap.put(_key240, _val241); + struct.privilegesMap.put(_key248, _val249); } } struct.setPrivilegesMapIsSet(true); http://git-wip-us.apache.org/repos/asf/sentry/blob/097cf0b0/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/common/SentryServiceUtil.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/common/SentryServiceUtil.java b/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/common/SentryServiceUtil.java index 83393a9..3f874a4 100644 --- a/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/common/SentryServiceUtil.java +++ b/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/common/SentryServiceUtil.java @@ -23,10 +23,8 @@ import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Collections; import java.util.Date; -import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; @@ -45,6 +43,7 @@ import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.conf.HiveConf.ConfVars; import org.apache.sentry.core.common.exception.SentryGrantDeniedException; import org.apache.sentry.core.common.exception.SentryInvalidInputException; +import org.apache.sentry.core.common.exception.SentryUserException; import org.apache.sentry.core.common.utils.SentryConstants; import org.apache.sentry.core.common.utils.KeyValue; import org.apache.sentry.core.common.utils.PolicyFileConstants; @@ -56,9 +55,12 @@ import org.apache.sentry.api.service.thrift.TSentryPrivilege; import com.google.common.collect.Lists; import org.apache.sentry.service.common.ServiceConstants; import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class SentryServiceUtil { + private static final Logger LOGGER = LoggerFactory + .getLogger(SentryServiceUtil.class); private static boolean firstCallHDFSSyncEnabled = true; private static boolean hdfsSyncEnabled = false; @@ -92,28 +94,54 @@ public final class SentryServiceUtil { return tSentryPrivilege; } - /** - * Parse the object path from string to map. - * @param objectPath the string format as db=db1->table=tbl1 - * @return Map + /** + * Parse the objects and returns a locations of thrift objects. + * @param objects the string format as db=db1->table=tbl1,db=db2->table=tbl2 + * @return Collection of Authorizables + * @throws Exception if there was a error while parsing the inputs. */ - public static Map<String, String> parseObjectPath(String objectPath) { - Map<String, String> objectMap = new HashMap<String, String>(); - if (StringUtils.isEmpty(objectPath)) { - return objectMap; + public static Set<TSentryAuthorizable> parseAuthorizables(String objects) throws SentryUserException { + if (StringUtils.isEmpty(objects)) { + return Collections.emptySet(); } - for (String kvStr : SentryConstants.AUTHORIZABLE_SPLITTER.split(objectPath)) { - KeyValue kv = new KeyValue(kvStr); - String key = kv.getKey(); - String value = kv.getValue(); - - if (PolicyFileConstants.PRIVILEGE_DATABASE_NAME.equalsIgnoreCase(key)) { - objectMap.put(PolicyFileConstants.PRIVILEGE_DATABASE_NAME, value); - } else if (PolicyFileConstants.PRIVILEGE_TABLE_NAME.equalsIgnoreCase(key)) { - objectMap.put(PolicyFileConstants.PRIVILEGE_TABLE_NAME, value); + Set<TSentryAuthorizable> authorizables = new HashSet<>(); + for (String object : objects.split(SentryConstants.COMMA_SEPARATOR)) { + Set<String> ketSet = new HashSet<>(); + String objectTrimmed = object.trim(); + if (objectTrimmed.isEmpty()) { + continue; + } + TSentryAuthorizable authorizable = new TSentryAuthorizable(""); + ketSet.clear(); + for (String kvStr : SentryConstants.AUTHORIZABLE_SPLITTER.split(objectTrimmed)) { + KeyValue kv; + String key; + String value; + try { + kv = new KeyValue(kvStr); + key = kv.getKey(); + value = kv.getValue(); + } catch (Exception exception) { + throw new SentryUserException("Wrongly formatted authorizable " + objectTrimmed); + } + if(!ketSet.add(key)) { + // There should not be any duplicate keys + throw new SentryUserException("Wrongly formatted authorizable " + objectTrimmed); + } + if (PolicyFileConstants.PRIVILEGE_DATABASE_NAME.equalsIgnoreCase(key)) { + authorizable.setDb(value); + } else if (PolicyFileConstants.PRIVILEGE_TABLE_NAME.equalsIgnoreCase(key)) { + authorizable.setTable(value); + } else if (PolicyFileConstants.PRIVILEGE_URI_NAME.equalsIgnoreCase(key)) { + authorizable.setUri(value); + } else { + LOGGER.error("Wrongly formatted authorizable " + objectTrimmed ); + throw new SentryUserException("Wrongly formatted authorizable " + objectTrimmed); + } } + authorizables.add(authorizable); } - return objectMap; + return authorizables; } // for the different hierarchy for hive: http://git-wip-us.apache.org/repos/asf/sentry/blob/097cf0b0/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyServiceClientDefaultImpl.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyServiceClientDefaultImpl.java b/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyServiceClientDefaultImpl.java index 68d864c..102228b 100644 --- a/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyServiceClientDefaultImpl.java +++ b/sentry-service/sentry-service-api/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyServiceClientDefaultImpl.java @@ -1092,12 +1092,11 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService // export the sentry mapping data with map structure @Override - public Map<String, Map<String, Set<String>>> exportPolicy(String - requestorUserName, - String objectPath) throws SentryUserException { + public Map<String, Map<String, Set<String>>> exportPolicy(String requestorUserName, + String objects) throws SentryUserException { TSentryExportMappingDataRequest request = new TSentryExportMappingDataRequest( ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName); - request.setObjectPath(objectPath); + request.setAuthorizables(SentryServiceUtil.parseAuthorizables(objects)); try { TSentryExportMappingDataResponse response = client.export_sentry_mapping_data(request); Status.throwIfNotOk(response.getStatus()); http://git-wip-us.apache.org/repos/asf/sentry/blob/097cf0b0/sentry-service/sentry-service-api/src/main/resources/sentry_policy_service.thrift ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-api/src/main/resources/sentry_policy_service.thrift b/sentry-service/sentry-service-api/src/main/resources/sentry_policy_service.thrift index 3364648..74b5b03 100644 --- a/sentry-service/sentry-service-api/src/main/resources/sentry_policy_service.thrift +++ b/sentry-service/sentry-service-api/src/main/resources/sentry_policy_service.thrift @@ -295,7 +295,7 @@ struct TSentryMappingData { struct TSentryExportMappingDataRequest { 1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1, 2: required string requestorUserName, # user on whose behalf the request is issued -3: optional string objectPath # for specific auth object +3: optional set<TSentryAuthorizable> authorizables # for which permission information needs to be exported. } struct TSentryExportMappingDataResponse { http://git-wip-us.apache.org/repos/asf/sentry/blob/097cf0b0/sentry-service/sentry-service-api/src/test/java/org/apache/sentry/api/common/TestSentryServiceUtil.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-api/src/test/java/org/apache/sentry/api/common/TestSentryServiceUtil.java b/sentry-service/sentry-service-api/src/test/java/org/apache/sentry/api/common/TestSentryServiceUtil.java index 2dc0975..8d24b2b 100644 --- a/sentry-service/sentry-service-api/src/test/java/org/apache/sentry/api/common/TestSentryServiceUtil.java +++ b/sentry-service/sentry-service-api/src/test/java/org/apache/sentry/api/common/TestSentryServiceUtil.java @@ -18,14 +18,19 @@ */ package org.apache.sentry.api.common; +import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; +import static org.apache.sentry.api.common.SentryServiceUtil.parseAuthorizables; import static org.apache.sentry.service.common.ServiceConstants.ServerConfig.SENTRY_DB_EXPLICIT_GRANTS_PERMITTED; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import com.google.common.collect.Sets; import java.util.Collections; +import java.util.Set; + import org.apache.hadoop.conf.Configuration; +import org.apache.sentry.api.service.thrift.TSentryAuthorizable; import org.apache.sentry.api.service.thrift.TSentryPrivilege; import org.apache.sentry.core.common.exception.SentryGrantDeniedException; import org.junit.Test; @@ -79,6 +84,60 @@ public class TestSentryServiceUtil { } } + @Test + public void testparseAuthorizables() throws Exception { + // Test valid authorizables + // db=db1->table=tb1,db=db1->table=tbl2 + Set<TSentryAuthorizable> authorizables; + authorizables = parseAuthorizables("db=db1->table=tb1,db=db1->table=tbl2"); + assertEquals(2, authorizables.size()); + // uri=/path/for/test + authorizables = parseAuthorizables("uri=/path/for/test"); + assertEquals(1, authorizables.size()); + // db=db1->table=tb1,db=db1->table=tbl2,uri=/path/for/test + authorizables = parseAuthorizables("db=db1->table=tb1,db=db1->table=tbl2,uri=/path/for/test"); + assertEquals(3, authorizables.size()); + // db=db1->table=tb1 , db=db1->table=tbl2 , uri=/path/for/test + authorizables = parseAuthorizables("db=db1->table=tb1 , db=db1->table=tbl2 , uri=/path/for/test"); + assertEquals(3, authorizables.size()); + // Test wrongly formatted authorizables + // db=db1->table=tb1,,,db=db1->table=tbl2 + authorizables = parseAuthorizables("db=db1->table=tb1,,,db=db1->table=tbl2"); + assertEquals(2, authorizables.size()); + + // db=db1->table=,db=db1->table=tbl1 + try { + authorizables = parseAuthorizables("db=db1->table=,db=db1->table=tbl1"); + fail("There should been an exception"); + } catch (Exception ex) { + assertTrue(ex.getMessage().contains("db=db1->table=")); + } + // db=db1->table,db=db1->table=tbl1 + try { + authorizables = parseAuthorizables("db=db1->table,db=db1->table=tbl1"); + fail("There should been an exception"); + } catch (Exception ex) { + assertTrue(ex.getMessage().contains("db=db1->table")); + } + + // db=db1->table=tbl1,d=db1->table=tbl2 + try { + authorizables = parseAuthorizables("db=db1->table=tbl1,d=db1->table=tbl2"); + fail("There should been an exception"); + } catch (Exception ex) { + assertTrue(ex.getMessage().contains("d=db1->table=tbl2")); + } + + // db=db1->table=tbl1,db=db1->table=tbl2db=db1->table=tbl3 + try { + authorizables = parseAuthorizables("db=db1->table=tbl1,db=db1->table=tbl2db=db1->table=tbl3"); + fail("There should been an exception"); + } catch (Exception ex) { + assertTrue(ex.getMessage().contains("db=db1->table=tbl2db=db1->table=tbl3")); + } + + } + private TSentryPrivilege newTSentryPrivilege(String action) { return new TSentryPrivilege("", "server1", action); } http://git-wip-us.apache.org/repos/asf/sentry/blob/097cf0b0/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessor.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessor.java b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessor.java index b9e3bf2..a232923 100644 --- a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessor.java +++ b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessor.java @@ -43,7 +43,6 @@ import org.apache.sentry.core.common.exception.SentrySiteConfigurationException; import org.apache.sentry.core.common.utils.SentryConstants; import org.apache.sentry.core.model.db.AccessConstants; import org.apache.sentry.provider.common.GroupMappingService; -import org.apache.sentry.core.common.utils.PolicyFileConstants; import org.apache.sentry.core.common.exception.SentryGroupNotFoundException; import org.apache.sentry.core.common.exception.SentryAccessDeniedException; import org.apache.sentry.core.common.exception.SentryAlreadyExistsException; @@ -1320,21 +1319,26 @@ public class SentryPolicyStoreProcessor implements SentryPolicyService.Iface { // get the sentry mapping data and return the data with map structure @Override + @SuppressWarnings("PMD.AvoidBranchingStatementAsLastInLoop") public TSentryExportMappingDataResponse export_sentry_mapping_data( TSentryExportMappingDataRequest request) throws TException { TSentryExportMappingDataResponse response = new TSentryExportMappingDataResponse(); try { String requestor = request.getRequestorUserName(); Set<String> memberGroups = getRequestorGroups(requestor); - String objectPath = request.getObjectPath(); String databaseName = null; String tableName = null; - Map<String, String> objectMap = - SentryServiceUtil.parseObjectPath(objectPath); - databaseName = objectMap.get(PolicyFileConstants.PRIVILEGE_DATABASE_NAME); - tableName = objectMap.get(PolicyFileConstants.PRIVILEGE_TABLE_NAME); - + if(request.getAuthorizables() != null && request.getAuthorizables().size() > 0) { + for (TSentryAuthorizable authorizable : request.getAuthorizables()) { + databaseName = authorizable.getDb(); + tableName = authorizable.getTable(); + // TODO This change is added to maintain the current functionality. + // This code will be updated sentry sentry client/server are enhanced to handle export og permissions for + // multiple authorizables. + break; + } + } if (!inAdminGroups(memberGroups)) { // disallow non-admin to import the metadata of sentry throw new SentryAccessDeniedException("Access denied to " + requestor http://git-wip-us.apache.org/repos/asf/sentry/blob/097cf0b0/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceImportExport.java ---------------------------------------------------------------------- diff --git a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceImportExport.java b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceImportExport.java index 69be166..18a91ae 100644 --- a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceImportExport.java +++ b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceImportExport.java @@ -25,6 +25,7 @@ import static org.junit.Assert.fail; import java.util.Map; import java.util.Set; +import org.apache.sentry.core.common.exception.SentryUserException; import org.apache.sentry.core.common.utils.SentryConstants; import org.apache.sentry.core.common.utils.PolicyFileConstants; import org.apache.sentry.service.thrift.SentryServiceIntegrationBase; @@ -625,6 +626,10 @@ public class TestSentryServiceImportExport extends SentryServiceIntegrationBase sentryMappingData = client.exportPolicy(ADMIN_USER, "db=db1->table=tbl1"); validateSentryMappingData(sentryMappingData, expectedMappingData); + sentryMappingData = client.exportPolicy(ADMIN_USER, "db=db1->table=tbl1,db=db3->table=tbl2"); + // Verify that client is able to take comma separated objects and still gets the results only for the first object + validateSentryMappingData(sentryMappingData, expectedMappingData); + // verify the rolePrivilegesMap and groupRolesMap for db=db1->table=tbl2 expectedMappingData = Maps.newHashMap(); expectedGroupRoles = Maps.newHashMap(); @@ -661,7 +666,7 @@ public class TestSentryServiceImportExport extends SentryServiceIntegrationBase try { client.exportPolicy(ADMIN_USER, "invalidString"); fail("RuntimeException should be thrown."); - } catch (RuntimeException sue) { + } catch (SentryUserException userException) { // excepted exception } }
