Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
TEIID-4770 TEIID-4771 fixes for ddl vdbs mostly around permissions
# Conflicts:
#	api/src/main/java/org/teiid/connector/DataPlugin.java
#	api/src/main/java/org/teiid/language/SQLConstants.java
#	api/src/main/java/org/teiid/metadata/Database.java
#	api/src/main/resources/org/teiid/connector/i18n.properties
#	engine/src/main/java/org/teiid/query/parser/QueryParser.java
#	engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
#	runtime/src/test/resources/portfolio-vdb.ddl
  • Loading branch information
shawkins committed Feb 28, 2017
1 parent 309dc4d commit a3f5254
Show file tree
Hide file tree
Showing 19 changed files with 357 additions and 234 deletions.
3 changes: 2 additions & 1 deletion api/src/main/java/org/teiid/connector/DataPlugin.java
Expand Up @@ -61,6 +61,7 @@ public static enum Event implements BundleUtil.Event {
TEIID60028,
TEIID60029,
TEIID60030,
TEIID60031
TEIID60035,
TEIID60036
}
}
1 change: 1 addition & 0 deletions api/src/main/java/org/teiid/language/SQLConstants.java
Expand Up @@ -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 {
Expand Down
29 changes: 2 additions & 27 deletions api/src/main/java/org/teiid/metadata/Database.java
Expand Up @@ -24,19 +24,17 @@
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;
import java.util.TreeMap;

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<String, DataWrapper> wrappers = new TreeMap<String, DataWrapper>(String.CASE_INSENSITIVE_ORDER);
protected NavigableMap<String, Server> servers = new TreeMap<String, Server>(String.CASE_INSENSITIVE_ORDER);
Expand Down Expand Up @@ -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<Privilege> 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<Grant> getGrants(){
Expand Down
75 changes: 68 additions & 7 deletions api/src/main/java/org/teiid/metadata/Grant.java
Expand Up @@ -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;
Expand All @@ -40,8 +61,12 @@ public enum Privilege {
private String condition = null;
private Boolean isConstraint;
private EnumSet<Privilege> privileges = EnumSet.noneOf(Privilege.class);
private EnumSet<Privilege> revokePrivileges = EnumSet.noneOf(Privilege.class);

public Database.ResourceType getResourceType() {
if (resourceType == null) {
return ResourceType.DATABASE;
}
return resourceType;
}

Expand Down Expand Up @@ -90,8 +115,18 @@ public EnumSet<Privilege> getPrivileges() {
return privileges;
}

public boolean hasPrivilege(Privilege allow) {
return this.privileges.contains(allow);
public EnumSet<Privilege> 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<Privilege> types) {
Expand All @@ -100,13 +135,21 @@ public void setPrivileges(List<Privilege> types) {
}
this.privileges = EnumSet.copyOf(types);
}

public void setRevokePrivileges(List<Privilege> types) {
if (types == null ||types.isEmpty()) {
return;
}
this.revokePrivileges = EnumSet.copyOf(types);
}

public void appendPrivileges(EnumSet<Privilege> types) {
if (types == null ||types.isEmpty()) {
return;
}
for (Privilege a:types) {
this.privileges.add(a);
this.revokePrivileges.remove(a);
}
}

Expand All @@ -115,16 +158,21 @@ public void removePrivileges(EnumSet<Privilege> 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);
}
}
}
}
Expand Down Expand Up @@ -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;
}
}

Expand Down
120 changes: 81 additions & 39 deletions api/src/main/java/org/teiid/metadata/MetadataStore.java
Expand Up @@ -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.
Expand Down Expand Up @@ -99,6 +98,7 @@ public void merge(MetadataStore store) {
}
addDataTypes(store.getDatatypes().values());
addGrants(store.grants.values());
roles.putAll(store.roles);
}
}

Expand All @@ -111,27 +111,51 @@ void addGrants(Collection<Grant> grants) {
}
}

public void addGrant(Grant grant) {
void addGrant(Grant grant) {
if (grant == null) {
return;
}
Grant previous = this.grants.get(grant.getRole());
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<Permission>(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());
}
}
}

Expand All @@ -140,50 +164,68 @@ public void removeGrant(Grant toRemoveGrant) {
return;
}
Grant previous = this.grants.get(toRemoveGrant.getRole());
if (previous != null) {
for (Permission removePermission : toRemoveGrant.getPermissions()) {
ArrayList<Permission> emptyPermissions = new ArrayList<Permission>();
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<Permission>(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());
}
}
}

public Collection<Grant> 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<Role> getRoles() {
Collection<Role> getRoles() {
return this.roles.values();
}

public Role removeRole(String roleName) {
Role removeRole(String roleName) {
return this.roles.remove(roleName);
}
}
4 changes: 3 additions & 1 deletion api/src/main/resources/org/teiid/connector/i18n.properties
Expand Up @@ -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}''

0 comments on commit a3f5254

Please sign in to comment.