diff --git a/api/src/main/java/org/teiid/connector/DataPlugin.java b/api/src/main/java/org/teiid/connector/DataPlugin.java index edd5abc56b..6a41f2b78e 100644 --- a/api/src/main/java/org/teiid/connector/DataPlugin.java +++ b/api/src/main/java/org/teiid/connector/DataPlugin.java @@ -61,6 +61,7 @@ public static enum Event implements BundleUtil.Event { TEIID60028, TEIID60029, TEIID60030, - TEIID60031 + TEIID60035, + TEIID60036 } } diff --git a/api/src/main/java/org/teiid/language/SQLConstants.java b/api/src/main/java/org/teiid/language/SQLConstants.java index 1396160265..1f95ef27af 100644 --- a/api/src/main/java/org/teiid/language/SQLConstants.java +++ b/api/src/main/java/org/teiid/language/SQLConstants.java @@ -166,6 +166,7 @@ public interface NonReserved { public static final String NONE = "NONE"; //$NON-NLS-1$ public static final String REPOSITORY= "REPOSITORY"; //$NON-NLS-1$ public static final String RENAME = "RENAME"; //$NON-NLS-1$ + public static final String USAGE = "USAGE"; //$NON-NLS-1$ } public interface Reserved { diff --git a/api/src/main/java/org/teiid/metadata/Database.java b/api/src/main/java/org/teiid/metadata/Database.java index 23c6167d17..e559935389 100644 --- a/api/src/main/java/org/teiid/metadata/Database.java +++ b/api/src/main/java/org/teiid/metadata/Database.java @@ -24,7 +24,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.EnumSet; import java.util.List; import java.util.Map; import java.util.NavigableMap; @@ -32,11 +31,10 @@ import org.teiid.connector.DataPlugin; import org.teiid.core.util.StringUtil; -import org.teiid.metadata.Grant.Permission.Privilege; public class Database extends AbstractMetadataRecord { private static final long serialVersionUID = 7595765832848232840L; - public enum ResourceType {DATABASE, SCHEMA, TABLE, PROCEDURE, FUNCTION, COLUMN, SERVER, DATAWRAPPER, PARAMETER, ROLE, GRANT}; + public enum ResourceType {DATABASE, SCHEMA, TABLE, PROCEDURE, FUNCTION, COLUMN, SERVER, DATAWRAPPER, PARAMETER, ROLE, GRANT, LANGUAGE}; protected MetadataStore store = new MetadataStore(); protected NavigableMap wrappers = new TreeMap(String.CASE_INSENSITIVE_ORDER); protected NavigableMap servers = new TreeMap(String.CASE_INSENSITIVE_ORDER); @@ -260,30 +258,7 @@ public void addGrant(Grant grant) { } public void revokeGrant(Grant grant) { - boolean found = false; - for (Grant g : getGrants()) { - if (g.getRole().equalsIgnoreCase(grant.getRole())) { - Database.ResourceType resourceType = grant.getPermissions().iterator().next().getResourceType(); - String resourceName = grant.getPermissions().iterator().next().getResourceName(); - EnumSet allowence = grant.getPermissions().iterator().next().getPrivileges(); - boolean all = allowence.contains(Privilege.ALL_PRIVILEGES); - for (Grant.Permission p : g.getPermissions()) { - if (p.getResourceType() == resourceType && - p.getResourceName().equals(resourceName) && - (all || p.getPrivileges().containsAll(allowence))) { - found = true; - } - } - } - } - if (found) { - this.store.removeGrant(grant); - } else { - throw new MetadataException(DataPlugin.Event.TEIID60031, - DataPlugin.Util.gs(DataPlugin.Event.TEIID60031, grant.getRole(), - grant.getPermissions().iterator().next().getResourceName(), - grant.getPermissions().iterator().next().getResourceType().name())); - } + this.store.removeGrant(grant); } public Collection getGrants(){ diff --git a/api/src/main/java/org/teiid/metadata/Grant.java b/api/src/main/java/org/teiid/metadata/Grant.java index e6ca8f8317..bb54443423 100644 --- a/api/src/main/java/org/teiid/metadata/Grant.java +++ b/api/src/main/java/org/teiid/metadata/Grant.java @@ -26,12 +26,33 @@ import java.util.EnumSet; import java.util.List; +import org.teiid.metadata.Database.ResourceType; + public class Grant extends AbstractMetadataRecord { private static final long serialVersionUID = 3728259393244582775L; public static class Permission { public enum Privilege { - SELECT, INSERT, UPDATE, DELETE, EXECUTE, LANGUAGE, ALTER, DROP, ALL_PRIVILEGES, TEMPORARY_TABLE, CREATE + SELECT, INSERT, UPDATE, DELETE, EXECUTE, + ALTER, DROP, + USAGE, + ALL_PRIVILEGES("ALL PRIVILEGES"), //$NON-NLS-1$ + TEMPORARY_TABLE("TEMPORARY TABLE"), //$NON-NLS-1$ + CREATE; + + private final String toString; + + Privilege(String toString) { + this.toString = toString; + } + + Privilege() { + this.toString = name(); + } + + public String toString() { + return toString; + } } private Database.ResourceType resourceType= null; private String resource = null; @@ -40,8 +61,12 @@ public enum Privilege { private String condition = null; private Boolean isConstraint; private EnumSet privileges = EnumSet.noneOf(Privilege.class); + private EnumSet revokePrivileges = EnumSet.noneOf(Privilege.class); public Database.ResourceType getResourceType() { + if (resourceType == null) { + return ResourceType.DATABASE; + } return resourceType; } @@ -90,8 +115,18 @@ public EnumSet getPrivileges() { return privileges; } - public boolean hasPrivilege(Privilege allow) { - return this.privileges.contains(allow); + public EnumSet getRevokePrivileges() { + return revokePrivileges; + } + + public Boolean hasPrivilege(Privilege allow) { + if (this.privileges.contains(allow)) { + return true; + } + if (this.revokePrivileges.contains(allow)) { + return false; + } + return null; } public void setPrivileges(List types) { @@ -100,6 +135,13 @@ public void setPrivileges(List types) { } this.privileges = EnumSet.copyOf(types); } + + public void setRevokePrivileges(List types) { + if (types == null ||types.isEmpty()) { + return; + } + this.revokePrivileges = EnumSet.copyOf(types); + } public void appendPrivileges(EnumSet types) { if (types == null ||types.isEmpty()) { @@ -107,6 +149,7 @@ public void appendPrivileges(EnumSet types) { } for (Privilege a:types) { this.privileges.add(a); + this.revokePrivileges.remove(a); } } @@ -115,16 +158,21 @@ public void removePrivileges(EnumSet types) { return; } for (Privilege a:types) { - this.privileges.remove(a); + if (!this.privileges.remove(a)) { + this.revokePrivileges.add(a); + } } } private void setAllows(Boolean allow, Privilege privilege) { if(allow!= null) { if (allow) { + this.revokePrivileges.remove(privilege); this.privileges.add(privilege); } else { - this.privileges.remove(privilege); + if (!this.privileges.remove(privilege)) { + this.revokePrivileges.add(privilege); + } } } } @@ -157,14 +205,27 @@ public void setAllowDrop(Boolean allow) { setAllows(allow, Privilege.DROP); } - public void setAllowLanguage(Boolean allow) { - setAllows(allow, Privilege.LANGUAGE); + public void setAllowUsage(Boolean allow) { + setAllows(allow, Privilege.USAGE); } public void setAllowAllPrivileges(Boolean allow) { setAllows(allow, Privilege.ALL_PRIVILEGES); } public void setAllowTemporyTables(Boolean allow) { setAllows(allow, Privilege.TEMPORARY_TABLE); + } + + public boolean resourceMatches(Permission other) { + if (getResourceType() != other.getResourceType()) { + return false; + } + if (resource == null && other.resource == null) { + return true; + } + if (resource != null && other.resource != null && resource.equalsIgnoreCase(other.resource)) { + return true; + } + return false; } } diff --git a/api/src/main/java/org/teiid/metadata/MetadataStore.java b/api/src/main/java/org/teiid/metadata/MetadataStore.java index 43d875273e..33d8609fda 100644 --- a/api/src/main/java/org/teiid/metadata/MetadataStore.java +++ b/api/src/main/java/org/teiid/metadata/MetadataStore.java @@ -33,7 +33,6 @@ import org.teiid.connector.DataPlugin; import org.teiid.metadata.Grant.Permission; -import org.teiid.metadata.Grant.Permission.Privilege; /** * Simple holder for metadata. @@ -99,6 +98,7 @@ public void merge(MetadataStore store) { } addDataTypes(store.getDatatypes().values()); addGrants(store.grants.values()); + roles.putAll(store.roles); } } @@ -111,7 +111,7 @@ void addGrants(Collection grants) { } } - public void addGrant(Grant grant) { + void addGrant(Grant grant) { if (grant == null) { return; } @@ -119,19 +119,43 @@ public void addGrant(Grant grant) { if (previous == null) { this.grants.put(grant.getRole(), grant); } else { - for (Permission newP : grant.getPermissions()) { + for (Permission addPermission : grant.getPermissions()) { boolean found = false; - for (Permission oldP : previous.getPermissions()) { - if (oldP.getResourceName().equalsIgnoreCase(newP.getResourceName()) - && oldP.getResourceType() == newP.getResourceType()) { - oldP.appendPrivileges(newP.getPrivileges()); - found = true; - } - } + for (Permission currentPermission : new ArrayList(previous.getPermissions())) { + if (currentPermission.resourceMatches(addPermission)) { + found = true; + if (addPermission.getMask() != null) { + if (currentPermission.getMask() != null) { + throw new MetadataException(DataPlugin.Event.TEIID60035, DataPlugin.Util.gs(DataPlugin.Event.TEIID60035, addPermission.getMask(), currentPermission.getMask())); + } + currentPermission.setMask(addPermission.getMask()); + currentPermission.setMaskOrder(addPermission.getMaskOrder()); + } + if (addPermission.getCondition() != null) { + if (currentPermission.getCondition() != null) { + throw new MetadataException(DataPlugin.Event.TEIID60036, DataPlugin.Util.gs(DataPlugin.Event.TEIID60036, addPermission.getMask(), currentPermission.getMask())); + } + currentPermission.setCondition(addPermission.getCondition(), addPermission.isConditionAConstraint()); + } + currentPermission.appendPrivileges(addPermission.getPrivileges()); + } + if (currentPermission.getPrivileges().isEmpty() + && currentPermission.getRevokePrivileges().isEmpty() + && currentPermission.getCondition() == null + && currentPermission.getMask() == null) { + previous.removePermission(currentPermission); + } + if (found) { + break; + } + } if (!found) { - previous.addPermission(newP); + previous.addPermission(addPermission); } - } + } + if (previous.getPermissions().isEmpty()) { + this.grants.remove(grant.getRole()); + } } } @@ -140,30 +164,48 @@ public void removeGrant(Grant toRemoveGrant) { return; } Grant previous = this.grants.get(toRemoveGrant.getRole()); - if (previous != null) { - for (Permission removePermission : toRemoveGrant.getPermissions()) { - ArrayList emptyPermissions = new ArrayList(); - for (Permission currentPermission : previous.getPermissions()) { - if (currentPermission.getResourceName().equalsIgnoreCase(removePermission.getResourceName()) - && currentPermission.getResourceType() == removePermission.getResourceType()) { - boolean all = removePermission.getPrivileges().contains(Privilege.ALL_PRIVILEGES); - if (all) { - currentPermission.removePrivileges(currentPermission.getPrivileges()); - } else { - currentPermission.removePrivileges(removePermission.getPrivileges()); - } - } - if (currentPermission.getPrivileges().isEmpty()) { - emptyPermissions.add(currentPermission); + if (previous == null) { + this.grants.put(toRemoveGrant.getRole(), toRemoveGrant); + } else { + for (Permission revokePermission : toRemoveGrant.getPermissions()) { + boolean found = false; + for (Permission currentPermission : new ArrayList(previous.getPermissions())) { + if (currentPermission.resourceMatches(revokePermission)) { + found = true; + if (revokePermission.getMask() != null) { + if (currentPermission.getMask() != null) { + currentPermission.setMask(null); + currentPermission.setMaskOrder(null); + } else { + //TODO: could be exception + } + } + if (revokePermission.getCondition() != null) { + if (currentPermission.getCondition() != null) { + currentPermission.setCondition(null, null); + } else { + //TODO: could be exception + } + } + currentPermission.removePrivileges(revokePermission.getRevokePrivileges()); } - } - for (Permission p:emptyPermissions) { - previous.removePermission(p); - } - } - if (previous.getPermissions().isEmpty()) { - this.grants.remove(toRemoveGrant.getRole()); - } + if (currentPermission.getPrivileges().isEmpty() + && currentPermission.getRevokePrivileges().isEmpty() + && currentPermission.getCondition() == null + && currentPermission.getMask() == null) { + previous.removePermission(currentPermission); + } + if (found) { + break; + } + } + if (!found) { + previous.addPermission(revokePermission); + } + } + if (previous.getPermissions().isEmpty()) { + this.grants.remove(toRemoveGrant.getRole()); + } } } @@ -171,19 +213,19 @@ public Collection getGrants() { return this.grants.values(); } - public void addRole(Role role) { + void addRole(Role role) { this.roles.put(role.getName(), role); } - public Role getRole(String roleName) { + Role getRole(String roleName) { return this.roles.get(roleName); } - public Collection getRoles() { + Collection getRoles() { return this.roles.values(); } - public Role removeRole(String roleName) { + Role removeRole(String roleName) { return this.roles.remove(roleName); } } \ No newline at end of file diff --git a/api/src/main/resources/org/teiid/connector/i18n.properties b/api/src/main/resources/org/teiid/connector/i18n.properties index cbcff0ad72..5968710b38 100644 --- a/api/src/main/resources/org/teiid/connector/i18n.properties +++ b/api/src/main/resources/org/teiid/connector/i18n.properties @@ -57,4 +57,6 @@ file_not_found=File not found {0} TEIID60028=Duplicate Role {0} TEIID60029=Role not found {0} TEIID60030=Role {0} is currently in use with grant on resource {1} of type {2}; revoke the grant first to delete the role. -TEIID60031=Revoke Grant on Role {0} did not find all or some of permissions assigned to resource {1} of type {2}; use REVOKE GRANT .. ALL PRIVILEGES .. to remove all permissions. + +TEIID60035=The granted mask ''{0}'' conflicts with the already defined mask ''{1}'' +TEIID60036=The granted condition ''{0}'' conflicts with the already defined condition ''{1}'' diff --git a/engine/src/main/java/org/teiid/query/metadata/DDLStringVisitor.java b/engine/src/main/java/org/teiid/query/metadata/DDLStringVisitor.java index a65eb79cb9..9ec7e4c0c0 100644 --- a/engine/src/main/java/org/teiid/query/metadata/DDLStringVisitor.java +++ b/engine/src/main/java/org/teiid/query/metadata/DDLStringVisitor.java @@ -167,7 +167,7 @@ public void visit(Database database) { boolean first = true; for (Server s:schema.getServers()) { if (first) { - first = true; + first = false; } else { append(COMMA); } @@ -214,43 +214,59 @@ public void visit(Database database) { private void visit(Grant grant) { for (Permission permission : grant.getPermissions()) { - append(GRANT); - boolean first = true; - for (Privilege allowance:permission.getPrivileges()) { - if (first) { - first = false; - append(SPACE); - } else { - append(COMMA); - } - append(allowance.name()); + if (!permission.getPrivileges().isEmpty() || permission.getMask() != null || permission.getCondition() != null) { + appendGrant(grant, permission, false); } - append(SPACE).append(ON).append(SPACE).append(permission.getResourceType().name()); - if (permission.getResourceName() != null) { - append(SPACE).append(SQLStringVisitor.escapeSinglePart(permission.getResourceName())); + if (!permission.getRevokePrivileges().isEmpty()) { + appendGrant(grant, permission, true); } - - if (permission.getResourceType() == ResourceType.COLUMN) { - - if (permission.getMask() != null) { - append(SPACE).append(MASK); - if (permission.getMaskOrder() != null && permission.getMaskOrder() != -1) { - append(SPACE).append(ORDER).append(SPACE).append(permission.getMaskOrder()); - } - append(SPACE).append(new Constant(permission.getMask())); - } - - if (permission.getCondition() != null) { - append(SPACE).append(CONDITION); - if (permission.isConditionAConstraint() != null && permission.isConditionAConstraint()) { - append(SPACE).append(CONSTRAINT); - } - append(SPACE).append(new Constant(permission.getCondition())); + } + } + + private void appendGrant(Grant grant, Permission permission, boolean revoke) { + EnumSet privileges = revoke?permission.getRevokePrivileges():permission.getPrivileges(); + if (revoke) { + append(REVOKE).append(SPACE); + } + append(GRANT); + boolean first = true; + for (Privilege allowance:privileges) { + if (first) { + first = false; + append(SPACE); + } else { + append(COMMA); + } + append(allowance); + } + if (permission.getResourceType() != ResourceType.DATABASE) { + append(SPACE).append(ON).append(SPACE).append(permission.getResourceType()); + } + + if (permission.getResourceName() != null) { + append(SPACE).append(SQLStringVisitor.escapeSinglePart(permission.getResourceName())); + } + + if (!revoke && permission.getMask() != null) { + append(SPACE).append(MASK); + if (permission.getMaskOrder() != null && permission.getMaskOrder() != -1) { + append(SPACE).append(ORDER).append(SPACE).append(permission.getMaskOrder()); + } + append(SPACE).append(new Constant(permission.getMask())); + } + + if (!revoke && permission.getCondition() != null) { + append(SPACE).append(CONDITION); + if (!revoke) { + if (permission.isConditionAConstraint() != null && permission.isConditionAConstraint()) { + append(SPACE).append(CONSTRAINT); } + append(SPACE).append(new Constant(permission.getCondition())); } - append(SPACE).append(TO).append(SPACE).append(grant.getRole()); - append(SEMICOLON).append(NEWLINE); } + + append(SPACE).append(revoke?FROM:TO).append(SPACE).append(grant.getRole()); + append(SEMICOLON).append(NEWLINE); } private void visit(Role role) { diff --git a/engine/src/main/java/org/teiid/query/metadata/DatabaseStore.java b/engine/src/main/java/org/teiid/query/metadata/DatabaseStore.java index 34e3dd4679..ca3d66a84f 100644 --- a/engine/src/main/java/org/teiid/query/metadata/DatabaseStore.java +++ b/engine/src/main/java/org/teiid/query/metadata/DatabaseStore.java @@ -126,7 +126,7 @@ public void databaseDropped(String dbName, String version) { Database db = this.databases.get(new VDBKey(dbName,version)); if (db == null) { throw new MetadataException(QueryPlugin.Event.TEIID31231, - QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31231, dbName)); + QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31231, dbName, version)); } assertGrant(Grant.Permission.Privilege.DROP, Database.ResourceType.DATABASE, db); @@ -544,7 +544,14 @@ public void addOrSetOption(String recordName, Database.ResourceType type, String } public AbstractMetadataRecord getSchemaRecord(String name, Database.ResourceType type) { - TransformationMetadata qmi = new TransformationMetadata(getCurrentDatabase(), getSystemFunctionManager()); + Database database = getCurrentDatabase(); + + CompositeMetadataStore store = new CompositeMetadataStore(database.getMetadataStore()); + //grants are already stored on the VDBMetaData + store.getGrants().clear(); + TransformationMetadata qmi = new TransformationMetadata(DatabaseUtil.convert(database), store, null, + getSystemFunctionManager().getSystemFunctions(), null); + try { switch (type) { case TABLE: @@ -574,14 +581,9 @@ public AbstractMetadataRecord getSchemaRecord(String name, Database.ResourceType throw new org.teiid.metadata.MetadataException(QueryPlugin.Event.TEIID31223, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31223, name)); } - break; + return c; case DATABASE: - Database db = getCurrentDatabase(); - if (db == null || !db.getName().equals(name)) { - throw new org.teiid.metadata.MetadataException(QueryPlugin.Event.TEIID31231, - QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31231, name)); - } - return db; + return getCurrentDatabase(); case SCHEMA: Schema schema = qmi.getModelID(name); if (schema == null) { @@ -713,6 +715,9 @@ public void grantCreated(Grant grant) { assertGrant(Grant.Permission.Privilege.CREATE, Database.ResourceType.GRANT, grant); for (Grant.Permission p:grant.getPermissions()) { + if (p.getResourceType() == ResourceType.LANGUAGE) { + continue; + } AbstractMetadataRecord record = getSchemaRecord(p.getResourceName(), p.getResourceType()); p.setResourceName(record.getFullName()); } @@ -727,6 +732,9 @@ public void grantRevoked(Grant grant) { assertGrant(Grant.Permission.Privilege.DROP, Database.ResourceType.GRANT, grant); for (Grant.Permission p:grant.getPermissions()) { + if (p.getResourceType() == ResourceType.LANGUAGE) { + continue; + } AbstractMetadataRecord record = getSchemaRecord(p.getResourceName(), p.getResourceType()); p.setResourceName(record.getFullName()); } diff --git a/engine/src/main/java/org/teiid/query/metadata/DatabaseUtil.java b/engine/src/main/java/org/teiid/query/metadata/DatabaseUtil.java index a84ee31e36..8a26385871 100644 --- a/engine/src/main/java/org/teiid/query/metadata/DatabaseUtil.java +++ b/engine/src/main/java/org/teiid/query/metadata/DatabaseUtil.java @@ -164,10 +164,8 @@ private static Permission convert(DataPermission dp) { p.setAllowAlter(dp.getAllowAlter()); p.setAllowDelete(dp.getAllowDelete()); - p.setAllowDrop(false); p.setAllowExecute(dp.getAllowExecute()); p.setAllowInsert(dp.getAllowCreate()); - p.setAllowLanguage(dp.getAllowLanguage()); p.setAllowSelect(dp.getAllowRead()); p.setAllowUpdate(dp.getAllowUpdate()); p.setResourceName(dp.getResourceName()); @@ -176,7 +174,8 @@ private static Permission convert(DataPermission dp) { // this is more of a guessing game here.. if (dp.getAllowLanguage() != null && dp.getAllowLanguage()) { - p.setResourceType(ResourceType.DATABASE); + p.setAllowUsage(true); + p.setResourceType(ResourceType.LANGUAGE); } else if (dotCount == 0) { p.setResourceType(ResourceType.SCHEMA); } else if (dp.getAllowExecute() != null && dp.getAllowExecute()){ @@ -258,28 +257,13 @@ static PermissionMetaData convert(Permission from) { PermissionMetaData pmd = new PermissionMetaData(); pmd.setResourceName(from.getResourceName()); - // NOTE: PMD even though you set false, it can interpret it wrong, use null or true only - if (from.hasPrivilege(Privilege.ALTER)) { - pmd.setAllowAlter(true); - } - if (from.hasPrivilege(Privilege.INSERT)) { - pmd.setAllowCreate(true); - } - if (from.hasPrivilege(Privilege.DELETE)) { - pmd.setAllowDelete(true); - } - if(from.hasPrivilege(Privilege.EXECUTE)) { - pmd.setAllowExecute(true); - } - if (from.hasPrivilege(Privilege.SELECT)) { - pmd.setAllowRead(true); - } - if(from.hasPrivilege(Privilege.UPDATE)) { - pmd.setAllowUpdate(true); - } - if (from.hasPrivilege(Privilege.LANGUAGE)) { - pmd.setAllowLanguage(true); - } + pmd.setAllowAlter(from.hasPrivilege(Privilege.ALTER)); + pmd.setAllowCreate(from.hasPrivilege(Privilege.INSERT)); + pmd.setAllowDelete(from.hasPrivilege(Privilege.DELETE)); + pmd.setAllowExecute(from.hasPrivilege(Privilege.EXECUTE)); + pmd.setAllowRead(from.hasPrivilege(Privilege.SELECT)); + pmd.setAllowUpdate(from.hasPrivilege(Privilege.UPDATE)); + pmd.setAllowLanguage(from.hasPrivilege(Privilege.USAGE)); pmd.setCondition(from.getCondition()); pmd.setConstraint(from.isConditionAConstraint()); @@ -294,10 +278,10 @@ static DataPolicyMetadata convert(Grant from, Role role) { dpm.setName(from.getRole()); for (Permission p : from.getPermissions()) { - if (p.hasPrivilege(Privilege.ALL_PRIVILEGES)) { + if (Boolean.TRUE.equals(p.hasPrivilege(Privilege.ALL_PRIVILEGES))) { dpm.setGrantAll(true); continue; - } else if (p.hasPrivilege(Privilege.TEMPORARY_TABLE)) { + } else if (Boolean.TRUE.equals(p.hasPrivilege(Privilege.TEMPORARY_TABLE))) { dpm.setAllowCreateTemporaryTables(true); continue; } @@ -306,11 +290,9 @@ static DataPolicyMetadata convert(Grant from, Role role) { dpm.addPermission(pmd); } - if (role != null) { - dpm.setDescription(role.getAnnotation()); - } + dpm.setDescription(role.getAnnotation()); - if (role != null && role.getJassRoles() != null && !role.getJassRoles().isEmpty()) { + if (role.getJassRoles() != null && !role.getJassRoles().isEmpty()) { dpm.setMappedRoleNames(role.getJassRoles()); } diff --git a/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java b/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java index 7b07918593..2efca4c292 100644 --- a/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java +++ b/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java @@ -48,6 +48,8 @@ import org.teiid.core.util.LRUCache; import org.teiid.core.util.ObjectConverterUtil; import org.teiid.core.util.StringUtil; +import org.teiid.logging.LogConstants; +import org.teiid.logging.LogManager; import org.teiid.metadata.*; import org.teiid.metadata.BaseColumn.NullType; import org.teiid.metadata.Column.SearchType; @@ -56,7 +58,6 @@ import org.teiid.query.QueryPlugin; import org.teiid.query.function.FunctionLibrary; import org.teiid.query.function.FunctionTree; -import org.teiid.query.function.SystemFunctionManager; import org.teiid.query.mapping.relational.QueryNode; import org.teiid.query.mapping.xml.MappingDocument; import org.teiid.query.mapping.xml.MappingLoader; @@ -187,11 +188,6 @@ public TransformationMetadata(VDBMetaData vdbMetadata, final CompositeMetadataSt } } - public TransformationMetadata(Database database, SystemFunctionManager systemFunctionMgr) { - this(DatabaseUtil.convert(database), new CompositeMetadataStore(database.getMetadataStore()), null, - systemFunctionMgr.getSystemFunctions(), null); - } - private void processGrants(MetadataStore store, Map policies) { if (store.getGrants() == null || store.getGrants().isEmpty() || policies == null) { return; @@ -206,9 +202,7 @@ private void processGrants(MetadataStore store, Map } } } else { - // Convert from Grant to DataPolicyMetadata - dpm = DatabaseUtil.convert(grant, store.getRole(grant.getRole())); - policies.put(grant.getRole(), dpm); + LogManager.logDetail(LogConstants.CTX_RUNTIME, "Permission added to non-existant role", grant.getRole()); //$NON-NLS-1$ } } } diff --git a/engine/src/main/java/org/teiid/query/parser/QueryParser.java b/engine/src/main/java/org/teiid/query/parser/QueryParser.java index 28e47e0056..b3d794a825 100644 --- a/engine/src/main/java/org/teiid/query/parser/QueryParser.java +++ b/engine/src/main/java/org/teiid/query/parser/QueryParser.java @@ -22,16 +22,27 @@ package org.teiid.query.parser; -import static org.teiid.query.parser.SQLParserConstants.tokenImage; -import static org.teiid.query.parser.TeiidSQLParserTokenManager.INVALID_TOKEN; +import static org.teiid.query.parser.SQLParserConstants.*; +import static org.teiid.query.parser.TeiidSQLParserTokenManager.*; import java.io.Reader; import java.io.StringReader; -import java.util.*; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; import org.teiid.api.exception.query.QueryParserException; import org.teiid.language.SQLConstants; -import org.teiid.metadata.*; +import org.teiid.metadata.DataWrapper; +import org.teiid.metadata.Database; +import org.teiid.metadata.Datatype; +import org.teiid.metadata.MetadataException; +import org.teiid.metadata.MetadataFactory; +import org.teiid.metadata.Parser; +import org.teiid.metadata.Server; import org.teiid.query.QueryPlugin; import org.teiid.query.function.SystemFunctionManager; import org.teiid.query.metadata.DatabaseStore; @@ -498,9 +509,6 @@ public SystemFunctionManager getSystemFunctionManager() { store.serverCreated(s); } List servers = Collections.emptyList(); - if (factory.getSchema().isPhysical()){ - servers = Arrays.asList(NONE); - } store.schemaCreated(factory.getSchema(), servers); store.schemaSwitched(factory.getSchema().getName()); try { diff --git a/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj b/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj index 12466671b9..b2847d5000 100644 --- a/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj +++ b/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj @@ -518,6 +518,7 @@ TOKEN : /* NonReserved words */ | | | +| } /* name=all in group identifier @@ -626,7 +627,8 @@ Token nonReserved() : |||||||||| ||||||||||
|| ||||||||||||| - ||||||||||||||||) + |||||||||||||||| + |) { return getToken(0); } @@ -5260,16 +5262,7 @@ void dropRole(DatabaseStore dbStore) : /* name=Create GRANT description=Defines GRANT for a role -example=[source,sql]\n----\nGRANT ( SELECT | INSERT | UPDATE | DELETE | EXECUTE | LANGUAGE | ALTER | DROP | ALL PRIVILEGES | TEMPORARY TABLES ) -ON - ( - DATABASE - TABLE . - PROCEDURE . - SCHEMA - COLUMN .. [MASK [ORDER \d] ] [CONDITION [CONSTRAINT] ] - ) -TO \n----\n +example=[source,sql]\n----\nGRANT SELECT ON TABLE x.y TO role\n----\n */ void grantOption(DatabaseStore dbStore) : { @@ -5285,23 +5278,33 @@ void grantOption(DatabaseStore dbStore) : Grant.Permission permission = new Grant.Permission(); } { - readGrantTypes(privileges) ( readGrantTypes(privileges))* - ( - [resource = id(null)] {on = Database.ResourceType.DATABASE;} | + + (( + [readGrantTypes(privileges) ( readGrantTypes(privileges))*] + ( resource = id(null) {on = Database.ResourceType.TABLE;} [ [ {isConstraint=true;}] condition = stringVal()] | + resource = id(null) {on = Database.ResourceType.FUNCTION;} | resource = id(null) {on = Database.ResourceType.PROCEDURE;} [ [ {isConstraint=true;}] condition = stringVal()] | resource = id(null) {on = Database.ResourceType.SCHEMA;} | resource = id(null) {on = Database.ResourceType.COLUMN;} [ [ maskOrder = intVal()] mask = stringVal()] - [ [ {isConstraint=true;}] condition = stringVal()] - ) + ) + ) + | + ( {privileges.add(Grant.Permission.Privilege.ALL_PRIVILEGES);}) + | + (
{privileges.add(Grant.Permission.Privilege.TEMPORARY_TABLE);}) + | + ( {privileges.add(Grant.Permission.Privilege.USAGE); on = Database.ResourceType.LANGUAGE;} resource=id(null)) + ) ( to = id(null) { - if (resource != null) { - permission.setResourceName(resource); + if (privileges.isEmpty() && condition == null && mask == null) { + throw new MetadataException(QueryPlugin.Util.getString("SQLParser.empty_grant_revoke")); } + permission.setResourceName(resource); permission.setPrivileges(privileges); permission.setResourceType(on); if (mask != null) { @@ -5323,16 +5326,7 @@ void grantOption(DatabaseStore dbStore) : /* name=Revoke GRANT description=Revokes GRANT for a role -example=[source,sql]\n----\nREVOKE GRANT ( SELECT | INSERT | UPDATE | DELETE | EXECUTE | LANGUAGE | ALTER | DROP | ALL PRIVILEGES | TEMPORARY TABLES ) -ON - ( - DATABASE - TABLE . - PROCEDURE . - SCHEMA - COLUMN .. - ) -FROM \n----\n +example=[source,sql]\n----\nREVOKE GRANT SELECT ON TABLE x.y TO role\n----\n */ void revokeGrantOption(DatabaseStore dbStore) : { @@ -5340,41 +5334,46 @@ void revokeGrantOption(DatabaseStore dbStore) : Grant grant = new Grant(); String resource = null; String mask = null; - int maskOrder = -1; String condition = null; - boolean isConstraint = false; String to = null; ArrayList privileges = new ArrayList(); Grant.Permission permission = new Grant.Permission(); } { - readGrantTypes(privileges) ( readGrantTypes(privileges))* - ( - [resource = id(null)] {on = Database.ResourceType.DATABASE;} | + + (( + [readGrantTypes(privileges) ( readGrantTypes(privileges))*] + (
resource = id(null) {on = Database.ResourceType.TABLE;} - [ [ {isConstraint=true;}] condition = stringVal()] | + [ {condition = "";}] | + resource = id(null) {on = Database.ResourceType.FUNCTION;} | resource = id(null) {on = Database.ResourceType.PROCEDURE;} - [ [ {isConstraint=true;}] condition = stringVal()] | + [ {condition = "";} ] | resource = id(null) {on = Database.ResourceType.SCHEMA;} | resource = id(null) {on = Database.ResourceType.COLUMN;} - [ [ maskOrder = intVal()] mask = stringVal()] - [ [ {isConstraint=true;}] condition = stringVal()] - ) + [ {mask = "";} ] + ) + ) + | + ( {privileges.add(Grant.Permission.Privilege.ALL_PRIVILEGES);}) + | + (
{privileges.add(Grant.Permission.Privilege.TEMPORARY_TABLE);}) + | + ( {privileges.add(Grant.Permission.Privilege.USAGE); on = Database.ResourceType.LANGUAGE;} resource=id(null)) + ) ( to = id(null) { - if (resource != null) { - permission.setResourceName(resource); + if (privileges.isEmpty() && condition == null && mask == null) { + throw new MetadataException(QueryPlugin.Util.getString("SQLParser.empty_grant_revoke")); } - permission.setPrivileges(privileges); + permission.setResourceName(resource); + permission.setRevokePrivileges(privileges); permission.setResourceType(on); if (mask != null) { permission.setMask(mask); - if (maskOrder != -1) { - permission.setMaskOrder(maskOrder); - } } if(condition != null) { - permission.setCondition(condition, isConstraint); + permission.setCondition(condition, null); } grant.setRole(to); grant.addPermission(permission); @@ -6539,9 +6538,6 @@ void readGrantTypes(ArrayList privileges) : {privileges.add(Grant.Permission.Privilege.UPDATE);} | {privileges.add(Grant.Permission.Privilege.DELETE);} | {privileges.add(Grant.Permission.Privilege.EXECUTE);} | - {privileges.add(Grant.Permission.Privilege.LANGUAGE);} | {privileges.add(Grant.Permission.Privilege.ALTER);} | - {privileges.add(Grant.Permission.Privilege.DROP);} | - {privileges.add(Grant.Permission.Privilege.ALL_PRIVILEGES);} | -
{privileges.add(Grant.Permission.Privilege.TEMPORARY_TABLE);} + {privileges.add(Grant.Permission.Privilege.DROP);} } \ No newline at end of file diff --git a/engine/src/main/resources/org/teiid/query/i18n.properties b/engine/src/main/resources/org/teiid/query/i18n.properties index 53115462c2..9d2f45639e 100644 --- a/engine/src/main/resources/org/teiid/query/i18n.properties +++ b/engine/src/main/resources/org/teiid/query/i18n.properties @@ -245,6 +245,7 @@ TEIID30372=Error evaluating criteria: {0} ERR.015.009.0002= Error translating criteria on the user''s command, the criteria translated to {0} is not valid TEIID30373=Error simplifying mathematical expression: {0} +SQLParser.empty_grant_revoke=The grant/revoke is invalid as nothing is specified. SQLParser.Aggregate_only_top_level=Aggregate functions are only allowed HAVING/SELECT/ORDER BY clauses. Window functions are only allowed in the SELECT/ORDER BY clauses: {0}. Both require a FROM clause to be present. SQLParser.window_only_top_level=Window functions are not allowed in the HAVING clause: {0} SQLParser.Unknown_agg_func=Unknown aggregate function: {0} diff --git a/engine/src/test/java/org/teiid/query/metadata/TestDDLStringVisitor.java b/engine/src/test/java/org/teiid/query/metadata/TestDDLStringVisitor.java index 472520b1ba..6df11b5f95 100644 --- a/engine/src/test/java/org/teiid/query/metadata/TestDDLStringVisitor.java +++ b/engine/src/test/java/org/teiid/query/metadata/TestDDLStringVisitor.java @@ -454,6 +454,8 @@ public void testGrants() throws Exception { Role role = new Role("admin"); role.setAnyAuthenticated(true); + Role role1 = new Role("uber"); + Grant.Permission permission = new Grant.Permission(); permission.setAllowAlter(true); permission.setAllowSelect(true); @@ -465,19 +467,30 @@ public void testGrants() throws Exception { permission2.setResourceName("schema.tableName"); permission2.setResourceType(ResourceType.TABLE); + Grant.Permission permission3 = new Grant.Permission(); + permission3.setAllowAllPrivileges(true); + + Grant.Permission permission4 = new Grant.Permission(); + permission4.setAllowTemporyTables(true); + Grant g = new Grant(); g.setRole(role.getName()); g.addPermission(permission); + g.addPermission(permission4); Grant g2 = new Grant(); g2.setRole(role.getName()); g2.addPermission(permission2); - g2.addPermission(permission2); + Grant g3 = new Grant(); + g3.setRole("uber"); + g3.addPermission(permission3); db.addRole(role); + db.addRole(role1); db.addGrant(g); db.addGrant(g2); + db.addGrant(g3); String expected = "\n" + @@ -491,7 +504,10 @@ public void testGrants() throws Exception { "\n" + "--############ Roles & Grants ############\n"+ "CREATE ROLE admin WITH ANY AUTHENTICATED;\n" + + "CREATE ROLE uber;\n" + "GRANT SELECT,DELETE,ALTER ON TABLE \"schema.tableName\" TO admin;\n" + + "GRANT TEMPORARY TABLE TO admin;\n\n" + + "GRANT ALL PRIVILEGES TO uber;\n" + "\n" + "\n" + "/*\n" + diff --git a/engine/src/test/java/org/teiid/query/parser/TestDDLParser.java b/engine/src/test/java/org/teiid/query/parser/TestDDLParser.java index f8458f20d9..a2be69c3ec 100644 --- a/engine/src/test/java/org/teiid/query/parser/TestDDLParser.java +++ b/engine/src/test/java/org/teiid/query/parser/TestDDLParser.java @@ -38,6 +38,7 @@ import org.teiid.metadata.Grant.Permission.Privilege; import org.teiid.metadata.Table.TriggerEvent; import org.teiid.query.function.SystemFunctionManager; +import org.teiid.query.metadata.DDLStringVisitor; import org.teiid.query.metadata.DatabaseStore; import org.teiid.query.metadata.MetadataValidator; import org.teiid.query.metadata.SystemMetadata; @@ -1248,7 +1249,7 @@ public void testGrant() throws Exception { assertTrue(p.hasPrivilege(Privilege.INSERT)); assertTrue(p.hasPrivilege(Privilege.DELETE)); assertTrue(p.hasPrivilege(Privilege.UPDATE)); - assertFalse(p.hasPrivilege(Privilege.DROP)); + assertNull(p.hasPrivilege(Privilege.DROP)); } @Test @@ -1261,7 +1262,7 @@ public void testGrantAll() throws Exception { + "SET SCHEMA test;" + "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date);" + "CREATE ROLE superuser WITH JAAS ROLE x,y WITH ANY AUTHENTICATED;" - + "GRANT ALL PRIVILEGES ON TABLE test.G1 TO superuser;"; + + "GRANT ALL PRIVILEGES TO superuser;"; Database db = helpParse(ddl); Role role = db.getRole("superuser"); @@ -1285,7 +1286,7 @@ public void testGrantWithCondition() throws Exception { + "SET SCHEMA test;" + "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date);" + "CREATE ROLE superuser WITH JAAS ROLE x,y WITH ANY AUTHENTICATED;" - + "GRANT ALL PRIVILEGES ON TABLE test.G1 CONDITION CONSTRAINT 'foo=bar' TO superuser;"; + + "GRANT SELECT ON TABLE test.G1 CONDITION CONSTRAINT 'foo=bar' TO superuser;"; Database db = helpParse(ddl); Role role = db.getRole("superuser"); @@ -1296,7 +1297,7 @@ public void testGrantWithCondition() throws Exception { Grant g = grants.iterator().next(); assertEquals(1, g.getPermissions().size()); Permission p = g.getPermissions().iterator().next(); - assertTrue(p.hasPrivilege(Privilege.ALL_PRIVILEGES)); + assertTrue(p.hasPrivilege(Privilege.SELECT)); assertEquals("foo=bar", p.getCondition()); assertTrue(p.isConditionAConstraint()); } @@ -1324,15 +1325,15 @@ public void testRevokeGrant() throws Exception { Grant g = grants.iterator().next(); assertEquals(1, g.getPermissions().size()); Permission p = g.getPermissions().iterator().next(); - assertFalse(p.hasPrivilege(Privilege.SELECT)); + assertNull(p.hasPrivilege(Privilege.SELECT)); assertTrue(p.hasPrivilege(Privilege.INSERT)); assertTrue(p.hasPrivilege(Privilege.DELETE)); assertTrue(p.hasPrivilege(Privilege.UPDATE)); - assertFalse(p.hasPrivilege(Privilege.DROP)); + assertNull(p.hasPrivilege(Privilege.DROP)); } @Test - public void testRevokeALl() throws Exception { + public void testRevokeAll() throws Exception { String ddl = "CREATE DATABASE FOO;" + "USE DATABASE FOO ;" + "CREATE FOREIGN DATA WRAPPER postgresql;" @@ -1343,14 +1344,15 @@ public void testRevokeALl() throws Exception { + "CREATE ROLE superuser WITH JAAS ROLE x,y WITH ANY AUTHENTICATED;" + "GRANT SELECT,INSERT,DELETE ON TABLE G1 TO superuser;" + "GRANT UPDATE ON TABLE test.G1 TO superuser;" - + "REVOKE GRANT ALL PRIVILEGES ON TABLE test.G1 FROM superuser;"; + + "REVOKE GRANT ALL PRIVILEGES FROM superuser;"; Database db = helpParse(ddl); Role role = db.getRole("superuser"); assertNotNull(role); Collection grants = db.getGrants(); - assertEquals(0, grants.size()); + //revoke all privileges will only have an already granted all privileges + assertEquals(1, grants.size()); } @Test diff --git a/runtime/src/test/java/org/teiid/metadatastore/TestDDLMetadataStore.java b/runtime/src/test/java/org/teiid/metadatastore/TestDDLMetadataStore.java index e3dbdd4832..4259aa0002 100644 --- a/runtime/src/test/java/org/teiid/metadatastore/TestDDLMetadataStore.java +++ b/runtime/src/test/java/org/teiid/metadatastore/TestDDLMetadataStore.java @@ -21,18 +21,20 @@ */ package org.teiid.metadatastore; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.fail; +import static org.junit.Assert.*; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; -import java.io.FileWriter; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; -import java.util.*; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import javax.security.auth.Subject; @@ -56,8 +58,12 @@ import org.teiid.core.util.UnitTestUtil; import org.teiid.jdbc.TeiidDriver; import org.teiid.metadata.MetadataRepository; -import org.teiid.runtime.*; +import org.teiid.runtime.EmbeddedAdminImpl; +import org.teiid.runtime.EmbeddedConfiguration; +import org.teiid.runtime.EmbeddedServer; import org.teiid.runtime.EmbeddedServer.ConnectionFactoryProvider; +import org.teiid.runtime.RuntimePlugin; +import org.teiid.runtime.TestEmbeddedServer; import org.teiid.runtime.util.ConvertVDB; import org.teiid.security.Credentials; import org.teiid.security.GSSResult; @@ -278,6 +284,9 @@ public void testConvertVDBXML() throws Exception { String expected = ObjectConverterUtil .convertFileToString(new File(UnitTestUtil.getTestDataPath() + "/" + "portfolio-vdb.ddl")); assertEquals(expected, content); + + //make sure the output is valid + es.deployVDB(new ByteArrayInputStream(content.getBytes("UTF-8")), true); } @Test diff --git a/runtime/src/test/resources/portfolio-converted-vdb.ddl b/runtime/src/test/resources/portfolio-converted-vdb.ddl index 29243a5fc4..5398f3cce3 100644 --- a/runtime/src/test/resources/portfolio-converted-vdb.ddl +++ b/runtime/src/test/resources/portfolio-converted-vdb.ddl @@ -92,9 +92,11 @@ SET SCHEMA Stocks; CREATE ROLE ReadOnly WITH ANY AUTHENTICATED; CREATE ROLE Prices WITH JAAS ROLE prices; CREATE ROLE ReadWrite WITH JAAS ROLE superuser; +REVOKE GRANT SELECT ON SCHEMA Accounts FROM Prices; + GRANT SELECT ON SCHEMA Accounts TO ReadOnly; GRANT ON COLUMN "Accounts.Account.SSN" MASK 'null' TO ReadOnly; -GRANT ON TABLE "Accounts.Customer" TO ReadOnly; +GRANT ON TABLE "Accounts.Customer" CONDITION 'state <> ''New York''' TO ReadOnly; GRANT ON COLUMN "Accounts.Customer.SSN" MASK 'null' TO ReadOnly; GRANT SELECT ON SCHEMA MarketData TO ReadOnly; GRANT SELECT ON SCHEMA Stocks TO ReadOnly; @@ -102,7 +104,7 @@ GRANT ON COLUMN "Stocks.StockPrices.Price" MASK ORDER 1 'CASE WHEN hasRole(''Pri GRANT SELECT,INSERT,UPDATE,DELETE ON SCHEMA Accounts TO ReadWrite; GRANT ON COLUMN "Accounts.Account.SSN" MASK ORDER 1 'SSN' TO ReadWrite; -GRANT ON TABLE "Accounts.Customer" TO ReadWrite; +GRANT ON TABLE "Accounts.Customer" CONDITION 'true' TO ReadWrite; GRANT ON COLUMN "Accounts.Customer.SSN" MASK ORDER 1 'SSN' TO ReadWrite; GRANT SELECT,INSERT,UPDATE,DELETE ON SCHEMA MarketData TO ReadWrite; diff --git a/runtime/src/test/resources/portfolio-vdb.ddl b/runtime/src/test/resources/portfolio-vdb.ddl index 0665523ff6..99a28b4b8b 100644 --- a/runtime/src/test/resources/portfolio-vdb.ddl +++ b/runtime/src/test/resources/portfolio-vdb.ddl @@ -35,7 +35,7 @@ OPTIONS (ANNOTATION 'Returns text files that match the given path and pattern as CREATE FOREIGN PROCEDURE saveFile(IN filePath string, IN file object OPTIONS (ANNOTATION 'The contents to save. Can be one of CLOB, BLOB, or XML')) OPTIONS (ANNOTATION 'Saves the given value to the given path. Any existing file will be overriden.'); --############ Schema:Accounts ############ -CREATE SCHEMA Accounts SERVER "h2-connector" none OPTIONS ("importer.useFullSchemaName" 'false'); +CREATE SCHEMA Accounts SERVER "h2-connector" OPTIONS ("importer.useFullSchemaName" 'false'); SET SCHEMA Accounts; CREATE FOREIGN TABLE ACCOUNT ( @@ -90,9 +90,11 @@ SELECT SP.symbol, SP.price FROM (EXEC MarketData.getTextFiles('*.txt')) AS f, TE CREATE ROLE ReadOnly WITH ANY AUTHENTICATED; CREATE ROLE Prices WITH JAAS ROLE prices; CREATE ROLE ReadWrite WITH JAAS ROLE superuser; +REVOKE GRANT SELECT ON SCHEMA Accounts FROM Prices; + GRANT SELECT ON SCHEMA Accounts TO ReadOnly; GRANT ON COLUMN "Accounts.Account.SSN" MASK 'null' TO ReadOnly; -GRANT ON TABLE "Accounts.Customer" TO ReadOnly; +GRANT ON TABLE "Accounts.Customer" CONDITION 'state <> ''New York''' TO ReadOnly; GRANT ON COLUMN "Accounts.Customer.SSN" MASK 'null' TO ReadOnly; GRANT SELECT ON SCHEMA MarketData TO ReadOnly; GRANT SELECT ON SCHEMA Stocks TO ReadOnly; @@ -100,7 +102,7 @@ GRANT ON COLUMN "Stocks.StockPrices.Price" MASK ORDER 1 'CASE WHEN hasRole(''Pri GRANT SELECT,INSERT,UPDATE,DELETE ON SCHEMA Accounts TO ReadWrite; GRANT ON COLUMN "Accounts.Account.SSN" MASK ORDER 1 'SSN' TO ReadWrite; -GRANT ON TABLE "Accounts.Customer" TO ReadWrite; +GRANT ON TABLE "Accounts.Customer" CONDITION 'true' TO ReadWrite; GRANT ON COLUMN "Accounts.Customer.SSN" MASK ORDER 1 'SSN' TO ReadWrite; GRANT SELECT,INSERT,UPDATE,DELETE ON SCHEMA MarketData TO ReadWrite; diff --git a/runtime/src/test/resources/portfolio-vdb.xml b/runtime/src/test/resources/portfolio-vdb.xml index cd431629be..58413765bc 100644 --- a/runtime/src/test/resources/portfolio-vdb.xml +++ b/runtime/src/test/resources/portfolio-vdb.xml @@ -113,6 +113,11 @@ Allow ReadOnly Operations to see pricing + + Accounts + false + + prices