/// <summary> /// In case of a delete command we always filter based on the tenantId /// </summary> private static void InterceptDeleteCommand(DbCommandTreeInterceptionContext interceptionContext, int userId) { var deleteCommand = interceptionContext.Result as DbDeleteCommandTree; if (deleteCommand != null) { var column = TenantAwareAttribute.GetTenantColumnName(deleteCommand.Target.VariableType.EdmType); if (!string.IsNullOrEmpty(column)) { // Create the variable reference in order to create the property var variableReference = DbExpressionBuilder.Variable(deleteCommand.Target.VariableType, deleteCommand.Target.VariableName); // Create the property to which will assign the correct value var tenantProperty = DbExpressionBuilder.Property(variableReference, column); var tenantIdWherePredicate = DbExpressionBuilder.Equal(tenantProperty, DbExpression.FromInt32(userId)); // The initial predicate is the sql where statement var initialPredicate = deleteCommand.Predicate; // Add to the initial statement the tenantId statement which translates in sql AND TenantId = 'value' var finalPredicate = initialPredicate.And(tenantIdWherePredicate); var newDeleteCommand = new DbDeleteCommandTree( deleteCommand.MetadataWorkspace, deleteCommand.DataSpace, deleteCommand.Target, finalPredicate); interceptionContext.Result = newDeleteCommand; } } }
/// <summary> /// In case of an insert command we always assign the correct value to the tenantId /// </summary> private static bool InterceptInsertCommand(DbCommandTreeInterceptionContext interceptionContext, int userId) { var shoolcontextList = interceptionContext.DbContexts.OfType <SchoolContext>(); if (shoolcontextList.Any(x => x.IsSeeding)) { return(true); } var insertCommand = interceptionContext.Result as DbInsertCommandTree; if (insertCommand != null) { var column = TenantAwareAttribute.GetTenantColumnName(insertCommand.Target.VariableType.EdmType); if (!string.IsNullOrEmpty(column)) { // Create the variable reference in order to create the property var variableReference = DbExpressionBuilder.Variable(insertCommand.Target.VariableType, insertCommand.Target.VariableName); // Create the property to which will assign the correct value var tenantProperty = DbExpressionBuilder.Property(variableReference, column); // Create the set clause, object representation of sql insert command var tenantSetClause = DbExpressionBuilder.SetClause(tenantProperty, DbExpression.FromInt32(userId)); // Remove potential assignment of tenantId for extra safety var filteredSetClauses = insertCommand.SetClauses.Cast <DbSetClause>() .Where(sc => ((DbPropertyExpression)sc.Property).Property.Name != column); // Construct the final clauses, object representation of sql insert command values var finalSetClauses = new ReadOnlyCollection <DbModificationClause>(new List <DbModificationClause>(filteredSetClauses) { tenantSetClause }); // Construct the new command var newInsertCommand = new DbInsertCommandTree( insertCommand.MetadataWorkspace, insertCommand.DataSpace, insertCommand.Target, finalSetClauses, insertCommand.Returning); interceptionContext.Result = newInsertCommand; // True means an interception successfully happened so there is no need to continue return(true); } } return(false); }
/// <summary> /// This method called before the one below it when a filtering is already exists in the query (e.g. fetch an entity by id) /// so we apply the dynamic filtering at this level /// </summary> public override DbExpression Visit(DbFilterExpression expression) { var column = TenantAwareAttribute.GetTenantColumnName(expression.Input.Variable.ResultType.EdmType); if (!_injectedDynamicFilter && !string.IsNullOrEmpty(column)) { var newFilterExpression = BuildFilterExpression(expression.Input, expression.Predicate, column); if (newFilterExpression != null) { // If not null, a new DbFilterExpression has been created with our dynamic filters. return(base.Visit(newFilterExpression)); } } return(base.Visit(expression)); }
/// <summary> /// In case of an update command we always filter based on the tenantId /// </summary> private static bool InterceptUpdate(DbCommandTreeInterceptionContext interceptionContext, int userId) { var updateCommand = interceptionContext.Result as DbUpdateCommandTree; if (updateCommand != null) { var column = TenantAwareAttribute.GetTenantColumnName(updateCommand.Target.VariableType.EdmType); if (!string.IsNullOrEmpty(column)) { // Create the variable reference in order to create the property var variableReference = DbExpressionBuilder.Variable(updateCommand.Target.VariableType, updateCommand.Target.VariableName); // Create the property to which will assign the correct value var tenantProperty = DbExpressionBuilder.Property(variableReference, column); // Create the tenantId where predicate, object representation of sql where tenantId = value statement var tenantIdWherePredicate = DbExpressionBuilder.Equal(tenantProperty, DbExpression.FromInt32(userId)); // Remove potential assignment of tenantId for extra safety var filteredSetClauses = updateCommand.SetClauses.Cast <DbSetClause>() .Where(sc => ((DbPropertyExpression)sc.Property).Property.Name != column); // Construct the final clauses, object representation of sql insert command values var finalSetClauses = new ReadOnlyCollection <DbModificationClause>(new List <DbModificationClause>(filteredSetClauses)); // The initial predicate is the sql where statement var initialPredicate = updateCommand.Predicate; // Add to the initial statement the tenantId statement which translates in sql AND TenantId = 'value' var finalPredicate = initialPredicate.And(tenantIdWherePredicate); var newUpdateCommand = new DbUpdateCommandTree( updateCommand.MetadataWorkspace, updateCommand.DataSpace, updateCommand.Target, finalPredicate, finalSetClauses, updateCommand.Returning); interceptionContext.Result = newUpdateCommand; // True means an interception successfully happened so there is no need to continue return(true); } } return(false); }
public override DbExpression Visit(DbScanExpression expression) { var column = TenantAwareAttribute.GetTenantColumnName(expression.Target.ElementType); if (!_injectedDynamicFilter && !string.IsNullOrEmpty(column)) { // Get the current expression var dbExpression = base.Visit(expression); // Get the current expression binding var currentExpressionBinding = DbExpressionBuilder.Bind(dbExpression); var newFilterExpression = BuildFilterExpression(currentExpressionBinding, null, column); if (newFilterExpression != null) { // If not null, a new DbFilterExpression has been created with our dynamic filters. return(base.Visit(newFilterExpression)); } } return(base.Visit(expression)); }