public Task <ResponseBase> Handle(HttpInformation context, InfoCommand command)
        {
            SapphireDbContext db = GetContext(command.ContextName);

            KeyValuePair <Type, string> property = db.GetType().GetDbSetType(command.CollectionName);

            if (property.Key != null)
            {
                // if (!property.Key.CanQuery(context, serviceProvider))
                // {
                //     return Task.FromResult(
                //         command.CreateExceptionResponse<InfoResponse>(
                //             "Not allowed to query information for collection"));
                // }

                InfoResponse infoResponse = new InfoResponse
                {
                    PrimaryKeys = property.Key.GetPrimaryKeyNames(db),
                    ReferenceId = command.ReferenceId
                };

                return(Task.FromResult <ResponseBase>(infoResponse));
            }

            return(Task.FromResult(command.CreateExceptionResponse <InfoResponse>("No set for collection was found.")));
        }
Esempio n. 2
0
        public static ResponseBase GetCollection(SapphireDbContext db, QueryCommand command,
                                                 HttpInformation information, IServiceProvider serviceProvider)
        {
            SapphireDatabaseOptions sapphireDatabaseOptions = serviceProvider.GetService <SapphireDatabaseOptions>();

            if (sapphireDatabaseOptions.DisableIncludePrefilter && command.Prefilters.Any(p => p is IncludePrefilter))
            {
                throw new IncludeNotAllowedException(command.CollectionName);
            }

            Type dbContextType = db.GetType();
            KeyValuePair <Type, string> property = dbContextType.GetDbSetType(command.CollectionName);

            if (property.Key == null)
            {
                throw new CollectionNotFoundException(command.CollectionName);
            }

            if (!property.Key.CanQuery(information, serviceProvider))
            {
                throw new UnauthorizedException("Not allowed to query values from collection");
            }

            IQueryable <object> collectionValues = db.GetCollectionValues(property, command.Prefilters);

            QueryResponse queryResponse = new QueryResponse()
            {
                ReferenceId = command.ReferenceId,
            };

            IAfterQueryPrefilter afterQueryPrefilter =
                command.Prefilters.OfType <IAfterQueryPrefilter>().FirstOrDefault();

            if (afterQueryPrefilter != null)
            {
                afterQueryPrefilter.Initialize(property.Key);
                queryResponse.Result = afterQueryPrefilter.Execute(collectionValues);
            }
            else
            {
                IEnumerable <object> values = collectionValues.AsEnumerable();

                ModelAttributesInfo modelAttributesInfo = property.Key.GetModelAttributesInfo();

                if (modelAttributesInfo.QueryEntryAuthAttributes.Any())
                {
                    values = values.Where(value => property.Key.CanQueryEntry(information, serviceProvider, value));
                }

                values = values.Select(v => v.GetAuthenticatedQueryModel(information, serviceProvider));

                queryResponse.Result = values.ToList();
            }

            return(queryResponse);
        }
Esempio n. 3
0
        public static KeyValuePair <Type, string> GetCollectionType(SapphireDbContext db, IQueryCommand command)
        {
            Type dbContextType = db.GetType();
            KeyValuePair <Type, string> property = dbContextType.GetDbSetType(command.CollectionName);

            if (property.Key == null)
            {
                throw new CollectionNotFoundException(command.ContextName, command.CollectionName);
            }

            return(property);
        }
Esempio n. 4
0
        public Task <ResponseBase> Handle(HttpInformation context, CreateRangeCommand command,
                                          ExecutionContext executionContext)
        {
            SapphireDbContext           db       = GetContext(command.ContextName);
            KeyValuePair <Type, string> property = db.GetType().GetDbSetType(command.CollectionName);

            if (property.Key != null)
            {
                return(Task.FromResult(CreateObjects(command, property, context, db)));
            }

            throw new CollectionNotFoundException(command.CollectionName);
        }
Esempio n. 5
0
        public async Task <ResponseBase> Handle(HttpInformation context, UpdateRangeCommand command,
                                                ExecutionContext executionContext)
        {
            SapphireDbContext           db       = GetContext(command.ContextName);
            KeyValuePair <Type, string> property = db.GetType().GetDbSetType(command.CollectionName);

            if (property.Key != null)
            {
                return(await InitializeUpdate(command, property, context, db));
            }

            throw new CollectionNotFoundException(command.CollectionName);
        }
Esempio n. 6
0
        public static ResponseBase GetCollection(SapphireDbContext db, QueryCommand command,
                                                 HttpInformation information, IServiceProvider serviceProvider)
        {
            Type dbContextType = db.GetType();
            KeyValuePair <Type, string> property = dbContextType.GetDbSetType(command.CollectionName);

            if (property.Key != null)
            {
                if (!property.Key.CanQuery(information, serviceProvider))
                {
                    return(command.CreateExceptionResponse <QueryResponse>(
                               "Not allowed to query values from collection"));
                }

                IQueryable <object> collectionValues = db.GetCollectionValues(serviceProvider, information, property, command.Prefilters);

                QueryResponse queryResponse = new QueryResponse()
                {
                    ReferenceId = command.ReferenceId,
                };

                IAfterQueryPrefilter afterQueryPrefilter = command.Prefilters.OfType <IAfterQueryPrefilter>().FirstOrDefault();

                if (afterQueryPrefilter != null)
                {
                    afterQueryPrefilter.Initialize(property.Key);
                    queryResponse.Result = afterQueryPrefilter.Execute(collectionValues);
                }
                else
                {
                    IEnumerable <object> values = collectionValues.AsEnumerable();

                    AuthModelInfo authModelInfo = property.Key.GetAuthModelInfos();

                    if (authModelInfo.QueryEntryAuthAttributes.Any())
                    {
                        values = values.Where(value => property.Key.CanQueryEntry(information, serviceProvider, value));
                    }

                    values = values.Select(v => v.GetAuthenticatedQueryModel(information, serviceProvider));

                    queryResponse.Result = values.ToList();
                }

                return(queryResponse);
            }

            return(command.CreateExceptionResponse <QueryResponse>("No set for collection was found."));
        }
        public Task <ResponseBase> Handle(HttpInformation context, DeleteCommand command)
        {
            SapphireDbContext           db       = GetContext(command.ContextName);
            KeyValuePair <Type, string> property = db.GetType().GetDbSetType(command.CollectionName);

            if (property.Key != null)
            {
                try
                {
                    object[] primaryKeys = property.Key.GetPrimaryKeyValues(db, command.PrimaryKeys);
                    object   value       = db.Find(property.Key, primaryKeys);

                    if (!property.Key.CanRemove(context, value, serviceProvider))
                    {
                        return(Task.FromResult(command.CreateExceptionResponse <DeleteResponse>(
                                                   "The user is not authorized for this action.")));
                    }

                    if (value != null)
                    {
                        property.Key.ExecuteHookMethods <RemoveEventAttribute>(ModelStoreEventAttributeBase.EventType.Before, value, context, serviceProvider);

                        db.Remove(value);

                        property.Key.ExecuteHookMethods <RemoveEventAttribute>(ModelStoreEventAttributeBase.EventType.BeforeSave, value, context, serviceProvider);

                        db.SaveChanges();

                        property.Key.ExecuteHookMethods <RemoveEventAttribute>(ModelStoreEventAttributeBase.EventType.After, value, context, serviceProvider);

                        return(Task.FromResult <ResponseBase>(new DeleteResponse()
                        {
                            ReferenceId = command.ReferenceId
                        }));
                    }

                    return(Task.FromResult(command.CreateExceptionResponse <DeleteResponse>("The value was not found.")));
                }
                catch (Exception ex)
                {
                    return(Task.FromResult(command.CreateExceptionResponse <DeleteResponse>(ex)));
                }
            }

            return(Task.FromResult(command.CreateExceptionResponse <DeleteResponse>("No set for collection was found.")));
        }
        public async Task <ResponseBase> Handle(HttpInformation context, InvokeCommand command, ExecutionContext executionContext)
        {
            SapphireDbContext           db       = GetContext(command.ContextName);
            KeyValuePair <Type, string> property = db.GetType().GetDbSetType(command.CollectionName);

            if (property.Key == null)
            {
                throw new CollectionNotFoundException(command.ContextName, command.CollectionName);
            }

            object[] primaryKeys = property.Key.GetPrimaryKeyValues(db, command.PrimaryKeys);
            object   value       = db.Find(property.Key, primaryKeys);

            if (value == null)
            {
                throw new ValueNotFoundException(command.ContextName, command.CollectionName, primaryKeys);
            }

            MethodInfo methodInfo = ReflectionMethodHelper.GetMethodInfo(property.Key, command.Action);

            if (methodInfo == null)
            {
                throw new MethodNotFoundException(property.Key.Name, command.Action);
            }

            if (methodInfo.GetCustomAttribute <InvokableAttribute>() == null)
            {
                throw new NotInvokableException(command.ContextName, command.CollectionName, command.Action);
            }

            object result = methodInfo.Invoke(value, methodInfo.CreateParameters(context, serviceProvider, command.Parameters, db));

            if (result != null)
            {
                result = await ActionHelper.HandleAsyncResult(result);
            }

            logger.LogInformation("Executed {CollectionName}.{ActionName}. ExecutionId: {ExecutionId}", property.Value, methodInfo.Name, executionContext.Id);

            return(new InvokeResponse()
            {
                ReferenceId = command.ReferenceId,
                Result = result
            });
        }
Esempio n. 9
0
        public async Task <ResponseBase> Handle(HttpInformation context, UpdateRangeCommand command,
                                                ExecutionContext executionContext)
        {
            SapphireDbContext           db       = GetContext(command.ContextName);
            KeyValuePair <Type, string> property = db.GetType().GetDbSetType(command.CollectionName);

            if (property.Key == null)
            {
                throw new CollectionNotFoundException(command.ContextName, command.CollectionName);
            }

            if (property.Key.GetModelAttributesInfo().DisableUpdateAttribute != null)
            {
                throw new OperationDisabledException("Update", command.ContextName, command.CollectionName);
            }

            return(await InitializeUpdate(command, property, context, db));
        }
        public Task <ResponseBase> Handle(HttpInformation context, UpdateCommand command)
        {
            SapphireDbContext           db       = GetContext(command.ContextName);
            KeyValuePair <Type, string> property = db.GetType().GetDbSetType(command.CollectionName);

            if (property.Key != null)
            {
                try
                {
                    return(Task.FromResult(InitializeUpdate(command, property, context, db)));
                }
                catch (Exception ex)
                {
                    return(Task.FromResult(command.CreateExceptionResponse <UpdateResponse>(ex)));
                }
            }

            return(Task.FromResult(command.CreateExceptionResponse <UpdateResponse>("No set for collection was found.")));
        }
Esempio n. 11
0
        public async Task <ResponseBase> Handle(HttpInformation context, UpdateRangeCommand command)
        {
            SapphireDbContext           db       = GetContext(command.ContextName);
            KeyValuePair <Type, string> property = db.GetType().GetDbSetType(command.CollectionName);

            if (property.Key != null)
            {
                try
                {
                    return(await InitializeUpdate(command, property, context, db));
                }
                catch (Exception ex)
                {
                    return(command.CreateExceptionResponse <UpdateRangeResponse>(ex));
                }
            }

            return(command.CreateExceptionResponse <UpdateRangeResponse>(new CollectionNotFoundException()));
        }
        public async Task <ResponseBase> Handle(HttpInformation context, DeleteRangeCommand command,
                                                ExecutionContext executionContext)
        {
            SapphireDbContext           db       = GetContext(command.ContextName);
            KeyValuePair <Type, string> property = db.GetType().GetDbSetType(command.CollectionName);

            if (property.Key == null)
            {
                throw new CollectionNotFoundException(command.ContextName, command.CollectionName);
            }

            if (property.Key.GetModelAttributesInfo().DisableDeleteAttribute != null)
            {
                throw new OperationDisabledException("Delete", command.ContextName, command.CollectionName);
            }

            List <object> removedValues = new List <object>();

            DeleteRangeResponse response;
            bool updateRejected;

            do
            {
                updateRejected = false;

                response = new DeleteRangeResponse
                {
                    ReferenceId = command.ReferenceId,
                    Results     = command.Values.Select(valuePrimaryKeys =>
                    {
                        object[] primaryKeys = property.Key.GetPrimaryKeyValues(db, valuePrimaryKeys);
                        object value         = db.Find(property.Key, primaryKeys);

                        if (value == null)
                        {
                            throw new ValueNotFoundException(command.ContextName, command.CollectionName, primaryKeys);
                        }

                        if (value is SapphireOfflineEntity valueOfflineEntity &&
                            valuePrimaryKeys.TryGetValue("modifiedOn", out JValue modifiedOn))
                        {
                            DateTimeOffset commandModifiedOn = modifiedOn.ToObject <DateTimeOffset>();

                            if (!valueOfflineEntity.ModifiedOn.EqualWithTolerance(commandModifiedOn,
                                                                                  db.Database.ProviderName))
                            {
                                throw new DeleteRejectedException(command.ContextName, command.CollectionName, primaryKeys);
                            }
                        }

                        if (!property.Key.CanDelete(context, value, serviceProvider))
                        {
                            throw new UnauthorizedException("The user is not authorized for this action");
                        }

                        int insteadOfExecuteCount = property.Key.ExecuteHookMethods <DeleteEventAttribute>(
                            ModelStoreEventAttributeBase.EventType.InsteadOf,
                            value, null, context, serviceProvider, db);

                        if (insteadOfExecuteCount > 0)
                        {
                            return(new DeleteResponse());
                        }

                        property.Key.ExecuteHookMethods <DeleteEventAttribute>(
                            ModelStoreEventAttributeBase.EventType.Before, value, null, context, serviceProvider, db);

                        db.Remove(value);

                        property.Key.ExecuteHookMethods <DeleteEventAttribute>(
                            ModelStoreEventAttributeBase.EventType.BeforeSave, value, null, context,
                            serviceProvider, db);

                        removedValues.Add(value);

                        return(new DeleteResponse()
                        {
                            Value = value,
                            ReferenceId = command.ReferenceId
                        });
                    }).ToList()
                };

                try
                {
                    db.SaveChanges();
                }
                catch (DbUpdateConcurrencyException)
                {
                    foreach (EntityEntry entityEntry in db.ChangeTracker.Entries())
                    {
                        await entityEntry.ReloadAsync();
                    }

                    updateRejected = true;
                }
            } while (updateRejected);

            foreach (object value in removedValues)
            {
                property.Key.ExecuteHookMethods <DeleteEventAttribute>(
                    ModelStoreEventAttributeBase.EventType.After, value, null, context, serviceProvider, db);
            }

            return(response);
        }
    }
Esempio n. 13
0
        public async Task <ResponseBase> Handle(HttpInformation context, DeleteRangeCommand command)
        {
            SapphireDbContext           db       = GetContext(command.ContextName);
            KeyValuePair <Type, string> property = db.GetType().GetDbSetType(command.CollectionName);

            if (property.Key != null)
            {
                try
                {
                    List <object> removedValues = new List <object>();

                    DeleteRangeResponse response;
                    bool updateRejected;

                    do
                    {
                        updateRejected = false;

                        response = new DeleteRangeResponse
                        {
                            ReferenceId = command.ReferenceId,
                            Results     = command.Values.Select(valuePrimaryKeys =>
                            {
                                object[] primaryKeys = property.Key.GetPrimaryKeyValues(db, valuePrimaryKeys);
                                object value         = db.Find(property.Key, primaryKeys);

                                if (value != null)
                                {
                                    if (value is SapphireOfflineEntity valueOfflineEntity &&
                                        valuePrimaryKeys.TryGetValue("modifiedOn", out JValue modifiedOn))
                                    {
                                        DateTime commandModifiedOn = modifiedOn.ToObject <DateTime>();

                                        if (valueOfflineEntity.ModifiedOn.RoundToMilliseconds() !=
                                            commandModifiedOn.RoundToMilliseconds())
                                        {
                                            return((DeleteResponse)command.CreateExceptionResponse <DeleteResponse>(
                                                       "Deletion rejected. The object state has changed."));
                                        }
                                    }

                                    if (!property.Key.CanRemove(context, value, serviceProvider))
                                    {
                                        return((DeleteResponse)command.CreateExceptionResponse <DeleteResponse>(
                                                   "The user is not authorized for this action."));
                                    }

                                    property.Key.ExecuteHookMethods <RemoveEventAttribute>(
                                        ModelStoreEventAttributeBase.EventType.Before, value, context, serviceProvider);

                                    db.Remove(value);

                                    property.Key.ExecuteHookMethods <RemoveEventAttribute>(
                                        ModelStoreEventAttributeBase.EventType.BeforeSave, value, context,
                                        serviceProvider);

                                    removedValues.Add(value);

                                    return(new DeleteResponse()
                                    {
                                        Value = value,
                                        ReferenceId = command.ReferenceId
                                    });
                                }

                                return((DeleteResponse)command.CreateExceptionResponse <DeleteResponse>(
                                           "The value was not found."));
                            }).ToList()
                        };

                        try
                        {
                            db.SaveChanges();
                        }
                        catch (DbUpdateConcurrencyException)
                        {
                            foreach (EntityEntry entityEntry in db.ChangeTracker.Entries())
                            {
                                await entityEntry.ReloadAsync();
                            }

                            updateRejected = true;
                        }
                    } while (updateRejected);

                    foreach (object value in removedValues)
                    {
                        property.Key.ExecuteHookMethods <RemoveEventAttribute>(
                            ModelStoreEventAttributeBase.EventType.After, value, context, serviceProvider);
                    }

                    return(response);
                }
                catch (Exception ex)
                {
                    return(command.CreateExceptionResponse <DeleteResponse>(ex));
                }
            }

            return(command.CreateExceptionResponse <DeleteResponse>("No set for collection was found."));
        }