SENTRY-693: The generic model has not successfully revoke part of privileges from existed ALL privilege (Guoquan Shen, reviewed by Colin Ma)
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java
index dab7d74..daeefdf 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java
@@ -34,6 +34,7 @@
import org.apache.sentry.core.model.search.SearchActionFactory;
import org.apache.sentry.provider.db.generic.service.persistent.PrivilegeObject.Builder;
import org.apache.sentry.provider.db.service.model.MSentryGMPrivilege;
+import org.apache.sentry.provider.db.service.model.MSentryPrivilege;
import org.apache.sentry.provider.db.service.model.MSentryRole;
import com.google.common.base.Joiner;
@@ -144,6 +145,8 @@
MSentryGMPrivilege mPrivilege = getPrivilege(convertToPrivilege(privilege), pm);
if (mPrivilege == null) {
mPrivilege = convertToPrivilege(privilege);
+ } else {
+ mPrivilege = (MSentryGMPrivilege) pm.detachCopy(mPrivilege);
}
Set<MSentryGMPrivilege> privilegeGraph = Sets.newHashSet();
@@ -161,10 +164,9 @@
* privilege.removeRole(role) and pm.makePersistent(privilege)
* will remove other roles that shouldn't been removed
*/
- pm.retrieve(persistedPriv);
-
revokeRolePartial(mPrivilege, persistedPriv, role, pm);
}
+ pm.makePersistent(role);
}
/**
@@ -234,10 +236,16 @@
/**
* grant the left privileges to role
*/
- MSentryGMPrivilege leftPriv = new MSentryGMPrivilege(persistedPriv);
- leftPriv.setAction(ac.getValue());
- leftPriv.appendRole(role);
- pm.makePersistent(leftPriv);
+ MSentryGMPrivilege tmpPriv = new MSentryGMPrivilege(persistedPriv);
+ tmpPriv.setAction(ac.getValue());
+ MSentryGMPrivilege leftPersistedPriv = getPrivilege(tmpPriv, pm);
+ if (leftPersistedPriv == null) {
+ //leftPersistedPriv isn't exist
+ leftPersistedPriv = tmpPriv;
+ role.appendGMPrivilege(leftPersistedPriv);
+ }
+ leftPersistedPriv.appendRole(role);
+ pm.makePersistent(leftPersistedPriv);
}
}
} else if (revokeaction.implies(persistedAction)) {
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestPrivilegeOperatePersistence.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestPrivilegeOperatePersistence.java
index 8893391..189eabb 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestPrivilegeOperatePersistence.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/persistent/TestPrivilegeOperatePersistence.java
@@ -497,7 +497,7 @@
String grantor = ADMIN_USER;
PrivilegeObject allPrivilege = new Builder()
.setComponent(SEARCH)
- .setAction(SearchConstants.QUERY)
+ .setAction(SearchConstants.ALL)
.setService(SERVICE)
.setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME), new Field(FIELD_NAME)))
.build();
@@ -525,6 +525,58 @@
sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)));
}
+ /**
+ * Grant update, query and all privilege to role r1
+ * Revoke query privilege from role r1
+ * there is update privilege related to role r1
+ */
+ @Test
+ public void testRevokePrivilegeWithAllPrivilegesGranted() throws Exception {
+ String roleName = "r1";
+ /**
+ * grantor is admin, there is no need to check grant option
+ */
+ String grantor = ADMIN_USER;
+ PrivilegeObject allPrivilege = new Builder()
+ .setComponent(SEARCH)
+ .setAction(SearchConstants.ALL)
+ .setService(SERVICE)
+ .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME), new Field(FIELD_NAME)))
+ .build();
+
+ PrivilegeObject updatePrivilege = new Builder(allPrivilege)
+ .setAction(SearchConstants.UPDATE)
+ .build();
+
+ PrivilegeObject queryPrivilege = new Builder(allPrivilege)
+ .setAction(SearchConstants.QUERY)
+ .build();
+
+ sentryStore.createRole(SEARCH, roleName, grantor);
+ //grant query to role r1
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, queryPrivilege, grantor);
+ assertEquals(Sets.newHashSet(queryPrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)));
+
+ //grant update to role r1
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, updatePrivilege, grantor);
+ assertEquals(Sets.newHashSet(queryPrivilege, updatePrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)));
+ /**
+ * grant all action privilege to role r1, because all action includes query and update action,
+ * The role r1 only has the action all privilege
+ */
+ sentryStore.alterRoleGrantPrivilege(SEARCH, roleName, allPrivilege, grantor);
+ assertEquals(Sets.newHashSet(allPrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)));
+ /**
+ * revoke update privilege from role r1, the query privilege has been left
+ */
+ sentryStore.alterRoleRevokePrivilege(SEARCH, roleName, updatePrivilege, grantor);
+ assertEquals(Sets.newHashSet(queryPrivilege),
+ sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName)));
+ }
+
@Test
public void testRevokeParentPrivilegeWithChildsExist() throws Exception {
String roleName = "r1";