Skip to content

Commit

Permalink
Merge branch 'TEIID-2476'
Browse files Browse the repository at this point in the history
  • Loading branch information
shawkins committed Feb 25, 2016
2 parents fd5791b + 39df485 commit 4409de7
Show file tree
Hide file tree
Showing 23 changed files with 241 additions and 62 deletions.
3 changes: 2 additions & 1 deletion admin/src/main/java/org/teiid/adminapi/DataPolicy.java
Expand Up @@ -35,7 +35,8 @@ public enum Context {
DELETE,
FUNCTION,
ALTER,
STORED_PROCEDURE;
STORED_PROCEDURE,
METADATA;
}

public enum PermissionType {CREATE, READ, UPDATE, DELETE, ALTER, EXECUTE, DROP, LANGUAGE};
Expand Down
2 changes: 1 addition & 1 deletion api/src/main/java/org/teiid/PolicyDecider.java
Expand Up @@ -66,7 +66,7 @@ Set<String> getInaccessibleResources(PermissionType action,
* @param commandContext
* @return true if the access is allowed, otherwise false
*/
boolean isTempAccessable(PermissionType action, String resource,
boolean isTempAccessible(PermissionType action, String resource,
Context context, CommandContext commandContext);

/**
Expand Down
Expand Up @@ -102,7 +102,7 @@ private void validateTemp(DataPolicy.PermissionType action, String resource, boo
Set<String> resources = Collections.singleton(resource);
logRequest(resources, context);

boolean allowed = decider.isTempAccessable(action, schema?resource:null, context, commandContext);
boolean allowed = decider.isTempAccessible(action, schema?resource:null, context, commandContext);

logResult(resources, context, allowed);
if (!allowed) {
Expand Down
Expand Up @@ -24,6 +24,7 @@

import org.teiid.api.exception.query.QueryValidatorException;
import org.teiid.core.TeiidComponentException;
import org.teiid.metadata.AbstractMetadataRecord;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.util.CommandContext;
Expand Down Expand Up @@ -56,11 +57,18 @@ enum CommandType {
boolean validate(String[] originalSql, Command command, QueryMetadataInterface metadata, CommandContext commandContext, CommandType commandType) throws QueryValidatorException, TeiidComponentException;

/**
*
* Uses the context or other information to determine if the current user has the given role name.
* @param roleName
* @param commandContext
* @return true if the current user has the given role
*/
boolean hasRole(String roleName, CommandContext commandContext);

/**
* Determines if the metadata record is accessible in system queries
* @param record
* @param commandContext
* @return
*/
boolean isAccessible(AbstractMetadataRecord record, CommandContext commandContext);
}
Expand Up @@ -130,7 +130,7 @@ public RecordExtractionTable(RecordTable<T> baseTable, List<ElementSymbol> colum
public TupleSource processQuery(Query query, VDBMetaData vdb,
TransformationMetadata metadata, CommandContext cc) {
BaseIndexInfo<?> ii = baseTable.planQuery(query, query.getCriteria(), cc);
final SimpleIterator<T> iter = baseTable.processQuery(vdb, metadata.getMetadataStore(), ii, metadata);
final SimpleIterator<T> iter = baseTable.processQuery(vdb, metadata.getMetadataStore(), ii, metadata, cc);
return new ExtractionTupleSource<T>(ii.getNonCoveredCriteria(), iter, cc, vdb, metadata, this);
}

Expand All @@ -144,17 +144,26 @@ public ChildRecordExtractionTable(RecordTable<P> baseTable, List<ElementSymbol>
this.baseTable = baseTable;
}

protected boolean isValid(T result, CommandContext cc) {
return !(result instanceof AbstractMetadataRecord) || cc.getAuthorizationValidator().isAccessible((AbstractMetadataRecord)result, cc);
}

@Override
public TupleSource processQuery(Query query, VDBMetaData vdb,
final TransformationMetadata metadata, CommandContext cc) {
final TransformationMetadata metadata, final CommandContext cc) {
BaseIndexInfo<?> ii = baseTable.planQuery(query, query.getCriteria(), cc);
final SimpleIterator<P> iter = baseTable.processQuery(vdb, metadata.getMetadataStore(), ii, metadata);
final SimpleIterator<P> iter = baseTable.processQuery(vdb, metadata.getMetadataStore(), ii, metadata, cc);
while (ii.next != null) {
ii = ii.next;
}
return new ExtractionTupleSource<T>(ii.getNonCoveredCriteria(), new ExpandingSimpleIterator<P, T>(iter) {

SimpleIteratorWrapper<T> wrapper = new SimpleIteratorWrapper<T>(null);
SimpleIteratorWrapper<T> wrapper = new SimpleIteratorWrapper<T>(null) {
@Override
protected boolean isValid(T result) {
return ChildRecordExtractionTable.this.isValid(result, cc);
}
};

protected RecordTable.SimpleIterator<T> getChildIterator(P parent) {
Collection<? extends T> children = getChildren(parent);
Expand Down
Expand Up @@ -22,12 +22,11 @@

package org.teiid.dqp.internal.process;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.teiid.CommandContext;
Expand All @@ -49,19 +48,20 @@ public Set<String> getInaccessibleResources(PermissionType action,
if (action == PermissionType.EXECUTE && context == Context.FUNCTION && allowFunctionCallsByDefault) {
return Collections.emptySet();
}
List<DataPolicy> policies = new ArrayList<DataPolicy>(commandContext.getAllowedDataPolicies().values());
Collection<DataPolicy> policies = commandContext.getAllowedDataPolicies().values();
int policyCount = policies.size();
boolean[] exclude = new boolean[policyCount];
outer:for (Iterator<String> iter = resources.iterator(); iter.hasNext();) {
String resource = iter.next();
Arrays.fill(exclude, false);
int excludeCount = 0;
while (resource.length() > 0) {
Iterator<DataPolicy> policyIter = policies.iterator();
for (int j = 0; j < policyCount; j++) {
DataPolicyMetadata policy = (DataPolicyMetadata)policyIter.next();
if (exclude[j]) {
continue;
}
DataPolicyMetadata policy = (DataPolicyMetadata)policies.get(j);
if (policy.isGrantAll()) {
if (policy.getSchemas() == null) {
resources.clear();
Expand Down Expand Up @@ -106,7 +106,7 @@ public boolean hasRole(String roleName, CommandContext context) {
}

@Override
public boolean isTempAccessable(PermissionType action, String resource,
public boolean isTempAccessible(PermissionType action, String resource,
Context context, CommandContext commandContext) {
if (resource != null) {
return getInaccessibleResources(action, new HashSet<String>(Arrays.asList(resource)), context, commandContext).isEmpty();
Expand Down
Expand Up @@ -291,12 +291,12 @@ public void fillRow(List<Object> row, Table table,
systemAdminTables.put(SystemAdminTables.MATVIEWS, new RecordExtractionTable<Table>(new TableSystemTable(1, 2, columns) {
@Override
protected boolean isValid(Table s, VDBMetaData vdb,
List<Object> rowBuffer, Criteria condition)
List<Object> rowBuffer, Criteria condition, CommandContext cc)
throws TeiidProcessingException, TeiidComponentException {
if (s == null || !s.isMaterialized()) {
return false;
}
return super.isValid(s, vdb, rowBuffer, condition);
return super.isValid(s, vdb, rowBuffer, condition, cc);
}
}, columns) {

Expand Down Expand Up @@ -407,8 +407,8 @@ public void fillRow(List<Object> row, FunctionMethod proc,

@Override
public SimpleIterator<Datatype> processQuery(VDBMetaData vdb,
CompositeMetadataStore metadataStore, BaseIndexInfo<?> ii, TransformationMetadata metadata) {
return processQuery(vdb, metadataStore.getDatatypes(), ii);
CompositeMetadataStore metadataStore, BaseIndexInfo<?> ii, TransformationMetadata metadata, CommandContext commandContext) {
return processQuery(vdb, metadataStore.getDatatypes(), ii, commandContext);
}
}, columns) {

Expand Down Expand Up @@ -563,8 +563,8 @@ protected void fillRow(AbstractMetadataRecord s,
@Override
public SimpleIterator<AbstractMetadataRecord> processQuery(
VDBMetaData vdb, CompositeMetadataStore metadataStore,
BaseIndexInfo<?> ii, TransformationMetadata metadata) {
return processQuery(vdb, metadataStore.getOids(), ii);
BaseIndexInfo<?> ii, TransformationMetadata metadata, CommandContext commandContext) {
return processQuery(vdb, metadataStore.getOids(), ii, commandContext);
}

@Override
Expand Down Expand Up @@ -638,12 +638,12 @@ protected Collection<Trigger> getChildren(Table table) {
systemAdminTables.put(SystemAdminTables.VIEWS, new RecordExtractionTable<Table>(new TableSystemTable(1, 2, columns) {
@Override
protected boolean isValid(Table s, VDBMetaData vdb,
List<Object> rowBuffer, Criteria condition)
List<Object> rowBuffer, Criteria condition, CommandContext cc)
throws TeiidProcessingException, TeiidComponentException {
if (s == null || !s.isVirtual()) {
return false;
}
return super.isValid(s, vdb, rowBuffer, condition);
return super.isValid(s, vdb, rowBuffer, condition, cc);
}
}, columns) {

Expand All @@ -662,12 +662,12 @@ public void fillRow(List<Object> row, Table table,
systemAdminTables.put(SystemAdminTables.STOREDPROCEDURES, new RecordExtractionTable<Procedure>(new ProcedureSystemTable(1, 2, columns) {
@Override
protected boolean isValid(Procedure s, VDBMetaData vdb,
List<Object> rowBuffer, Criteria condition)
List<Object> rowBuffer, Criteria condition, CommandContext cc)
throws TeiidProcessingException, TeiidComponentException {
if (s == null || !s.isVirtual()) {
return false;
}
return super.isValid(s, vdb, rowBuffer, condition);
return super.isValid(s, vdb, rowBuffer, condition, cc);
}
}, columns) {

Expand Down Expand Up @@ -754,6 +754,18 @@ protected Collection<KeyRecord> getChildren(Table parent) {
return parent.getAllKeys();
}

@Override
protected boolean isValid(KeyRecord result, CommandContext cc) {
if (!super.isValid(result, cc)) {
return false;
}
//the referenced table must be accessible also
if (result instanceof ForeignKey) {
return cc.getAuthorizationValidator().isAccessible(((ForeignKey)result).getReferenceKey(), cc);
}
return true;
}

});
name = SystemTables.KEYCOLUMNS.name();
columns = getColumns(tm, name);
Expand Down Expand Up @@ -846,8 +858,8 @@ protected void fillRow(AbstractMetadataRecord s,
@Override
public SimpleIterator<AbstractMetadataRecord> processQuery(
VDBMetaData vdb, CompositeMetadataStore metadataStore,
BaseIndexInfo<?> ii, TransformationMetadata metadata) {
return processQuery(vdb, metadataStore.getOids(), ii);
BaseIndexInfo<?> ii, TransformationMetadata metadata, CommandContext commandContext) {
return processQuery(vdb, metadataStore.getOids(), ii, commandContext);
}

@Override
Expand Down
Expand Up @@ -23,18 +23,24 @@
package org.teiid.dqp.internal.process;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.teiid.PolicyDecider;
import org.teiid.adminapi.DataPolicy.Context;
import org.teiid.adminapi.DataPolicy.PermissionType;
import org.teiid.api.exception.query.QueryValidatorException;
import org.teiid.core.CoreConstants;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.types.TransformationException;
import org.teiid.core.util.PropertiesUtils;
import org.teiid.dqp.internal.process.multisource.MultiSourceElement;
import org.teiid.metadata.AbstractMetadataRecord;
import org.teiid.metadata.FunctionMethod;
import org.teiid.metadata.Procedure;
import org.teiid.metadata.Schema;
import org.teiid.query.QueryPlugin;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.metadata.TempMetadataID;
Expand Down Expand Up @@ -133,4 +139,41 @@ public void setPolicyDecider(PolicyDecider policyDecider) {
this.policyDecider = policyDecider;
}

@Override
public boolean isAccessible(AbstractMetadataRecord record,
CommandContext commandContext) {
if (policyDecider == null || !policyDecider.validateCommand(commandContext)
//TODO - schemas cannot be hidden - unless we traverse them and find that nothing is accessible
|| record instanceof Schema) {
return true;
}
AbstractMetadataRecord parent = record;
while (parent.getParent() != null) {
parent = parent.getParent();
if (parent instanceof Procedure) {
return true; //don't check procedure params/rs columns
}
}
if (!(parent instanceof Schema) || (CoreConstants.SYSTEM_MODEL.equalsIgnoreCase(parent.getName()) || CoreConstants.ODBC_MODEL.equalsIgnoreCase(parent.getName()))) {
//access is always allowed to system tables / procedures or unrooted objects
return true;
}
PermissionType action = PermissionType.READ;
if (record instanceof FunctionMethod || record instanceof Procedure) {
action = PermissionType.EXECUTE;
}

//cache permission check
Boolean result = commandContext.isAccessible(record);
if (result != null) {
return result;
}

HashSet<String> resources = new HashSet<String>(2);
resources.add(record.getFullName());
result = this.policyDecider.getInaccessibleResources(action, resources, Context.METADATA, commandContext).isEmpty();
commandContext.setAccessible(record, result);
return result;
}

}
Expand Up @@ -84,12 +84,16 @@ public T next() throws TeiidProcessingException,
TeiidComponentException {
while (iter.hasNext()) {
T result = iter.next();
if (result != null) {
if (result != null && isValid(result)) {
return result;
}
}
return null;
}

protected boolean isValid(T result) {
return true;
}

}

Expand Down Expand Up @@ -165,9 +169,9 @@ public boolean supportsOrdering(int pkIndex, Expression ex) {
return !(ex instanceof ElementSymbol);
}

public abstract SimpleIterator<T> processQuery(final VDBMetaData vdb, CompositeMetadataStore metadataStore, BaseIndexInfo<?> ii, TransformationMetadata metadata);
public abstract SimpleIterator<T> processQuery(final VDBMetaData vdb, CompositeMetadataStore metadataStore, BaseIndexInfo<?> ii, TransformationMetadata metadata, CommandContext commandContext);

public SimpleIterator<T> processQuery(final VDBMetaData vdb, NavigableMap<String, ?> map, BaseIndexInfo<?> ii) {
public SimpleIterator<T> processQuery(final VDBMetaData vdb, NavigableMap<String, ?> map, BaseIndexInfo<?> ii, final CommandContext commandContext) {
final Criteria crit = ii.getCoveredCriteria();
final ArrayList<Object> rowBuffer = new ArrayList<Object>(1);
if (!ii.getValueSet().isEmpty()) {
Expand All @@ -185,7 +189,7 @@ public T next() throws TeiidProcessingException, TeiidComponentException {
continue;
}
T s = extractRecord(fMap.get(key));
if (isValid(s, vdb, rowBuffer, crit)) {
if (isValid(s, vdb, rowBuffer, crit, commandContext)) {
return s;
}
}
Expand All @@ -209,7 +213,7 @@ public T next() throws TeiidProcessingException, TeiidComponentException {
public T next() throws TeiidProcessingException, TeiidComponentException {
while (iter.hasNext()) {
T s = extractRecord(iter.next());
if (isValid(s, vdb, rowBuffer, crit)) {
if (isValid(s, vdb, rowBuffer, crit, commandContext)) {
return s;
}
}
Expand Down Expand Up @@ -240,14 +244,18 @@ public BaseIndexInfo<RecordTable<?>> planQuery(Query query, Criteria condition,
* @param vdb
* @param rowBuffer
* @param condition
* @param commandContext
* @return
* @throws TeiidProcessingException
* @throws TeiidComponentException
*/
protected boolean isValid(T s, VDBMetaData vdb, List<Object> rowBuffer, Criteria condition) throws TeiidProcessingException, TeiidComponentException {
protected boolean isValid(T s, VDBMetaData vdb, List<Object> rowBuffer, Criteria condition, CommandContext commandContext) throws TeiidProcessingException, TeiidComponentException {
if (s == null) {
return false;
}
if (!commandContext.getAuthorizationValidator().isAccessible(s, commandContext)) {
return false;
}
if (condition != null) {
rowBuffer.clear();
fillRow(s, rowBuffer);
Expand Down

0 comments on commit 4409de7

Please sign in to comment.