public Permission?ResolveTypePermission(object context) { return(RuleMaps.Aggregate((Permission?)null, (result, ruleMap) => { if (result == null && ruleMap == null) { return null; } return result ?? Permission.None | (ruleMap.ResolveTypePermission(context) ?? Permission.None); })); }
public Permission?ResolveMethodPermission(MethodInfo methodInfo, object context, params Type[] genericArguments) { return(RuleMaps.Aggregate((Permission?)null, (result, ruleMap) => { if (result == null && ruleMap == null) { return null; } return result ?? Permission.None | (ruleMap.ResolveMethodPermission(methodInfo, context, genericArguments) ?? Permission.None); })); }
public object ResolvePropertyCustom(object key, PropertyInfo propertyInfo, object context) { var first = RuleMaps.First(); return(RuleMaps.Skip(1).Aggregate(first.ResolvePropertyCustom(key, propertyInfo, context), (result, ruleMap) => { var expression = ruleMap.ResolvePropertyCustom(key, propertyInfo, context); if (result == null && expression == null) { return null; } if (result == null) { return expression; } if (expression == null) { return result; } return GetInstanceCustomReducer(key)(result, expression); })); }
public Expression ResolveInstancePropertyCustomResolverExpression(PropertyInfo propertyInfo, object key, object context, Expression instanceExpression) { var first = RuleMaps.First(); return(RuleMaps.Skip(1).Aggregate(first.ResolveInstancePropertyCustomResolverExpression(propertyInfo, key, context, instanceExpression), (result, ruleMap) => { var expression = ruleMap.ResolveInstancePropertyCustomResolverExpression(propertyInfo, key, context, instanceExpression); if (result == null && expression == null) { return null; } if (result == null) { return expression; } if (expression == null) { return result; } return ruleMap.GetInstanceCustomExpressionReducer(key)(result, expression); })); }
public Expression GetInstanceCustomResolverExpression(object context, Expression instanceExpression, object key) { var first = RuleMaps.First(); var composedExpression = RuleMaps.Skip(1).Aggregate(first.GetInstanceCustomResolverExpression(context, instanceExpression, key), (result, ruleMap) => { var expression = ruleMap.GetInstanceCustomResolverExpression(context, instanceExpression, key); if (result == null && expression == null) { return(null); } if (result == null) { return(expression); } if (expression == null) { return(result); } return(ruleMap.GetInstanceCustomExpressionReducer(key)(result, expression)); }); return(composedExpression); }
public Expression GetInstancePermissionResolverExpression(object context, Expression instanceExpression) { var first = RuleMaps.First(); var composedExpression = RuleMaps.Skip(1).Aggregate(first.GetInstancePermissionResolverExpression(context, instanceExpression), (result, ruleMap) => { var expression = ruleMap.GetInstancePermissionResolverExpression(context, instanceExpression); if (result == null && expression == null) { return(null); } if (result == null) { return(expression); } if (expression == null) { return(result); } return(Expression.Or(Expression.Convert(result, typeof(int)), Expression.Convert(expression, typeof(int)))); }); return(composedExpression); }
public object ResolveTypeCustom(object key, object context) { var first = RuleMaps.First(); var composedExpression = RuleMaps.Skip(1).Aggregate(first.ResolveTypeCustom(key, context), (result, ruleMap) => { var expression = ruleMap.ResolveTypeCustom(key, context); if (result == null && expression == null) { return(null); } if (result == null) { return(expression); } if (expression == null) { return(result); } return(GetInstanceCustomReducer(key)(result, expression)); }); return(composedExpression); }
public MutationContext Inspect(Type type, JObject jObject, object permissionResolverContext) { var entityType = Model.FindRuntimeEntityType(type); var ruleMap = RuleMaps.FirstOrDefault(rm => rm.CanHandle(type)); var jObjectProperties = jObject.Properties(); var entityPropertyInfos = type.GetProperties(); var entityProperties = entityType.GetProperties(); var tuples = entityProperties.Join(jObjectProperties, entityProperty => entityProperty.Name, jProperty => jProperty.Name.ToPascalCase(), (property, jProperty) => new { Property = property, JProperty = jProperty }); var primaryKey = entityType.FindPrimaryKey(); var primaryKeyTuples = primaryKey.Properties.Select(property => { var jProperty = jObjectProperties.FirstOrDefault(jp => $"@{property.Name.ToCamelCase()}" == jp.Name) ?? jObjectProperties.FirstOrDefault(jp => property.Name == jp.Name.ToPascalCase()); return(new { Property = property, JProperty = jProperty }); }).Where(t => t.JProperty != null).ToArray(); var primaryKeyPairs = primaryKeyTuples.ToDictionary(tuple => tuple.Property, tuple => tuple.JProperty.Value.ToObject(tuple.Property.ClrType)); var isPrimaryKeySet = primaryKeyPairs.Count == primaryKey.Properties.Count; var isDeletion = jObjectProperties.Any(jProperty => jProperty.Name == "$isDeletion" && jProperty.Value.Value <bool>()); var isInsertion = jObjectProperties.Any(jProperty => jProperty.Name == "$isInsertion" && jProperty.Value.Value <bool>()); var permissionType = PermissionEntityTypeBuilder.TypeMap[entityType]; var selfPermissionProperty = PermissionEntityTypeBuilder.TypeMap[entityType].GetProperty("SelfPermission"); var propertiesTuples = entityType.GetProperties().Join( jObjectProperties, p => p.Name, jp => jp.Name.ToPascalCase(), (p, jp) => new PropertyTuple( p, jp, PermissionEntityTypeBuilder.PermissionPropertyMap[p], PermissionEntityTypeBuilder.PropertyMap[p], PermissionResolverExpressionBuilderProvider.GetPermissionResolverExpressionBuilderFor(type, p.PropertyInfo) ?? DefaultPermissionResolverExpressionBuilder ) ).ToArray(); var navigationTuples = entityType.GetNavigations().Join( jObjectProperties, p => p.Name, jp => jp.Name.ToPascalCase(), (p, jp) => new NavigationTuple( p, jp, PermissionEntityTypeBuilder.PermissionPropertyMap[p], PermissionEntityTypeBuilder.PropertyMap[p], PermissionResolverExpressionBuilderProvider.GetPermissionResolverExpressionBuilderFor(type, p.PropertyInfo) ?? DefaultPermissionResolverExpressionBuilder ) ).ToArray(); var allPropertiesTuples = propertiesTuples.Concat(navigationTuples.Select(np => new PropertyTuple( np.Property, np.JProperty, np.PermissionPropertyInfo, np.PermissionNavigationPropertyInfo, np.PermissionResolverExpressionBuilder ))).ToArray(); var allPropertiesTuplesButKey = allPropertiesTuples.Where(pt => { var result = !primaryKey.Properties.Any(pk => pk == pt.Property); //var result = !(pt.Property is IProperty && ((IProperty)pt.Property).ValueGenerated > 0); return(result); }).ToArray(); var collectionNavigationTuples = navigationTuples.Where(t => t.Property.IsCollection()).ToArray(); var scalarNavigationTuples = navigationTuples.Where(t => !t.Property.IsCollection()).ToArray(); MutationContext context = null; if (!isInsertion && isPrimaryKeySet) { var findEntityExpression = BuildFindEntityQuery(entityType, QueryProviderProvider, jObject, primaryKeyPairs); var entityParameterExpression = Expression.Parameter(entityType.ClrType); var selfPermissionMemberBindingExpression = BuildSelfPermissionBinding(entityType, entityParameterExpression, selfPermissionProperty, permissionResolverContext); var memberBindingExpressions = new List <MemberBinding>() { selfPermissionMemberBindingExpression }; Action <object> inspector = null; Action <EntityEntry> entryAction = null; Action <object> postAction = null; if (isDeletion) { //DELETE inspector = new Action <object>(permissionEntity => { var permission = (Permission)selfPermissionProperty.GetValue(permissionEntity); if (!permission.HasFlag(Permission.Delete)) { throw new UnauthorizedAccessException($"You do not have permission to delete on entity type {entityType.Name} with key ({string.Join(", ", primaryKeyPairs.Select(kp => $"{kp.Key.Name}={kp.Value}"))})"); } }); entryAction = new Action <EntityEntry>(entry => entry.State = EntityState.Deleted); postAction = new Action <object>(entity => { }); } else { if (allPropertiesTuplesButKey.Any()) { //UPDATE var permissionPropertiesMemberBindingExpressions = BuildPropertiesPermissionBindings(entityParameterExpression, allPropertiesTuples, permissionResolverContext); var scalarNavigationPropertiesMemberBindingExpressions = BuildScalarNavigationBindings(scalarNavigationTuples, permissionResolverContext); var collectionNavigationPropertiesMemberBindingExpressions = BuildCollectionNavigationBindings(collectionNavigationTuples, permissionResolverContext); memberBindingExpressions.AddRange(permissionPropertiesMemberBindingExpressions); memberBindingExpressions.AddRange(scalarNavigationPropertiesMemberBindingExpressions.Select(r => r.MemberBinding)); memberBindingExpressions.AddRange(collectionNavigationPropertiesMemberBindingExpressions.Select(r => r.MemberBinding)); var selfPermissionCheck = new Action <object>(permissionEntity => { var permission = (Permission)selfPermissionProperty.GetValue(permissionEntity); if (!permission.HasFlag(Permission.Read | Permission.Write)) { throw new UnauthorizedAccessException($"You do not have permission to modify on entity type {entityType.Name} with key ({string.Join(", ", primaryKeyPairs.Select(kp => $"{kp.Key.Name}={kp.Value}"))})"); } }); inspector = new Action <object>(permissionEntity => { if (allPropertiesTuplesButKey.Any()) { foreach (var propertyTuple in allPropertiesTuplesButKey) { if (!((Permission)propertyTuple.PermissionPropertyInfo.GetValue(permissionEntity)).HasFlag(Permission.Write)) { throw new UnauthorizedAccessException($"You are not allowed to modify property {propertyTuple.Property.Name} on entity type {propertyTuple.Property.DeclaringType.Name} with key ({string.Join(", ", primaryKeyPairs.Select(kp => $"{kp.Key.PropertyInfo.Name}={kp.Value}"))})"); } } } foreach (var scalarNavigationPropertiesMemberBindingExpression in scalarNavigationPropertiesMemberBindingExpressions) { scalarNavigationPropertiesMemberBindingExpression.Inspector(permissionEntity); } foreach (var collectionNavigationPropertiesMemberBindingExpression in collectionNavigationPropertiesMemberBindingExpressions) { collectionNavigationPropertiesMemberBindingExpression.Inspector(permissionEntity); } }); entryAction = new Action <EntityEntry>(entry => { //entry.State = EntityState.Modified; foreach (var tuple in allPropertiesTuplesButKey) { var navigation = tuple.Property as INavigation; if (navigation != null) { if (navigation.IsCollection()) { entry.Collection(navigation.Name).IsModified = true; } else { entry.Reference(navigation.Name).IsModified = true; } } else { entry.Property(tuple.Property.Name).IsModified = true; } } foreach (var scalarNavigationPropertiesMemberBindingExpression in scalarNavigationPropertiesMemberBindingExpressions) { scalarNavigationPropertiesMemberBindingExpression.EntryAction(entry); } foreach (var collectionNavigationPropertiesMemberBindingExpression in collectionNavigationPropertiesMemberBindingExpressions) { collectionNavigationPropertiesMemberBindingExpression.EntryAction(entry); } }); postAction = new Action <object>(entity => { foreach (var scalarNavigationPropertiesMemberBindingExpression in scalarNavigationPropertiesMemberBindingExpressions) { scalarNavigationPropertiesMemberBindingExpression.PostAction(entity); } foreach (var collectionNavigationPropertiesMemberBindingExpression in collectionNavigationPropertiesMemberBindingExpressions) { collectionNavigationPropertiesMemberBindingExpression.PostAction(entity); } }); } else { //READ inspector = new Action <object>(permissionEntity => { var permission = (Permission)selfPermissionProperty.GetValue(permissionEntity); if (!permission.HasFlag(Permission.Read)) { throw new UnauthorizedAccessException($"You do not have permission to read on entity type {entityType.Name} with key ({string.Join(", ", primaryKeyPairs.Select(kp => $"{kp.Key.Name}={kp.Value}"))})"); } }); entryAction = new Action <EntityEntry>(entry => { if (entry != null) { entry.State = EntityState.Unchanged; } }); postAction = new Action <object>(entry => { }); } } var newPermissionExpression = BuildNewPermissionMemberInitExpression(permissionType, memberBindingExpressions.ToArray()); var permissionExpression = BuildSelectFirstOrDefaultPermissionEntityExpression(entityType, jObject, findEntityExpression, entityParameterExpression, newPermissionExpression); context = new MutationContext() { PermissionEntityExpression = permissionExpression, Inspector = inspector, EntryAction = entryAction, PostAction = postAction }; } else { //CREATION var memberBindingExpressions = new List <MemberBinding>(); var scalarNavigationPropertiesMemberBindingExpressions = BuildScalarNavigationBindings(scalarNavigationTuples, permissionResolverContext); var collectionNavigationPropertiesMemberBindingExpressions = BuildCollectionNavigationBindings(collectionNavigationTuples, permissionResolverContext); memberBindingExpressions.AddRange(scalarNavigationPropertiesMemberBindingExpressions.Select(r => r.MemberBinding)); memberBindingExpressions.AddRange(collectionNavigationPropertiesMemberBindingExpressions.Select(r => r.MemberBinding)); var newPermissionExpression = BuildNewPermissionMemberInitExpression(permissionType, memberBindingExpressions.ToArray()); var propertiesPermissionCheck = new Action <object>(permissionEntity => { foreach (var scalarNavigationPropertiesMemberBindingExpression in scalarNavigationPropertiesMemberBindingExpressions) { scalarNavigationPropertiesMemberBindingExpression.Inspector(permissionEntity); } foreach (var collectionNavigationPropertiesMemberBindingExpression in collectionNavigationPropertiesMemberBindingExpressions) { collectionNavigationPropertiesMemberBindingExpression.Inspector(permissionEntity); } }); var entryAction = new Action <EntityEntry>(entry => { entry.State = EntityState.Added; foreach (var scalarNavigationPropertiesMemberBindingExpression in scalarNavigationPropertiesMemberBindingExpressions) { scalarNavigationPropertiesMemberBindingExpression.EntryAction(entry); } foreach (var collectionNavigationPropertiesMemberBindingExpression in collectionNavigationPropertiesMemberBindingExpressions) { collectionNavigationPropertiesMemberBindingExpression.EntryAction(entry); } }); var postAction = new Action <object>(entity => { if (ruleMap != null && ruleMap.InsertedAction != null) { ruleMap.InsertedAction(permissionResolverContext, entity); } foreach (var scalarNavigationPropertiesMemberBindingExpression in scalarNavigationPropertiesMemberBindingExpressions) { scalarNavigationPropertiesMemberBindingExpression.PostAction(entity); } foreach (var collectionNavigationPropertiesMemberBindingExpression in collectionNavigationPropertiesMemberBindingExpressions) { collectionNavigationPropertiesMemberBindingExpression.PostAction(entity); } }); context = new MutationContext() { PermissionEntityExpression = newPermissionExpression, Inspector = propertiesPermissionCheck, EntryAction = entryAction, PostAction = postAction }; } return(context); }
public Expression GetDefaultProjectionExpression(object context, Expression argumentExpression, IEnumerable <IRuleMap> ruleMaps) { var result = RuleMaps.First().GetDefaultProjectionExpression(context, argumentExpression, ruleMaps); return(result); }
public bool ShouldFilterForProperty(PropertyInfo propertyInfo, object context) { return(RuleMaps.Aggregate(true, (result, ruleMap) => result && ruleMap.ShouldFilterForProperty(propertyInfo, context))); }
public bool ShouldFilterForMethod(MethodInfo methodInfo, object context, Type[] genericArguments) { return(RuleMaps.Aggregate(true, (result, ruleMap) => result && ruleMap.ShouldFilterForMethod(methodInfo, context, genericArguments))); }
public bool HasAnyInstancePropertyPermissionResolverExpression(PropertyInfo propertyInfo, object key) { return(RuleMaps.Aggregate(false, (result, ruleMap) => result || ruleMap.HasAnyInstancePropertyPermissionResolverExpression(propertyInfo, key))); }