Пример #1
0
        public async Task ExecuteAsync(QueryContext context)
        {
            var softDelete = _repo.SoftDelete;

            _repo.SoftDelete = context.Descriptor.SoftDelete;
            if (!string.IsNullOrEmpty(context.Params.Id))
            {
                object[] id;
                try
                {
                    id = _repo.ParseId(context.Params.Id);
                }
                catch (Exception ex)
                {
                    throw new QueryException("id format incorrect", QueryErrorCode.BadRequest, ex);
                }

                if (context.Descriptor.OnlyOwnerCanDelete)
                {
                    var authContext = new AuthorizationContext <T>(context);
                    await _repo.RemoveAsync(id,
                                            async (newDto, oldDto, cancellationToken) =>
                    {
                        var authorized = await authContext.AuthorizeAsync(oldDto, context.Descriptor.DeletePolicy);
                        if (authorized)
                        {
                            return(true);
                        }
                        context.Fail(oldDto, QueryErrorCode.Unauthorized, "unauthorized");
                        return(false);
                    },
                                            (dto) => context.Fail(dto, QueryErrorCode.NotFound, "not found"),
                                            context.CancellationToken);
                }
                else
                {
                    await _repo.RemoveAsync(id,
                                            (dto) => context.Fail(dto, QueryErrorCode.NotFound, "not found"),
                                            context.CancellationToken);
                }

                return;
            }

            if (context.IsArrayModel())
            {
                var models = context.ToModels <T>() ?? throw new QueryException("models is required", QueryErrorCode.BadRequest);
                var errors = new List <RecordError>(models.Length);
                if (context.Descriptor.OnlyOwnerCanDelete)
                {
                    var authContext = new AuthorizationContext <T>(context);
                    await _repo.RemoveRangeAsync(models,
                                                 async (newDto, oldDto, index, continuation, cancellationToken) =>
                    {
                        var authorized = await authContext.AuthorizeAsync(oldDto, context.Descriptor.DeletePolicy);
                        if (authorized)
                        {
                            return(true);
                        }

                        errors.Add(new RecordError
                        {
                            ErrorCode        = QueryErrorCode.Unauthorized,
                            ErrorDescription = QueryErrorCode.Unauthorized.ToString(),
                            At = index
                        });
                        continuation.Yes = true;

                        return(false);
                    },
                                                 (dto, index, continuation) =>
                    {
                        errors.Add(new RecordError
                        {
                            ErrorCode        = QueryErrorCode.NotFound,
                            ErrorDescription = QueryErrorCode.NotFound.ToString(),
                            At = index
                        });
                        continuation.Yes = true;
                    }, context.CancellationToken);
                }
                else
                {
                    await _repo.RemoveRangeAsync(models,
                                                 (dto, index, continuation) =>
                    {
                        errors.Add(new RecordError
                        {
                            ErrorCode        = QueryErrorCode.NotFound,
                            ErrorDescription = QueryErrorCode.NotFound.ToString(),
                            At = index
                        });
                        continuation.Yes = true;
                    }, context.CancellationToken);
                }

                if (errors.Count > 0)
                {
                    context.Fail(errors, QueryErrorCode.ValidationError, QueryErrorCode.ValidationError.ToString());
                }
                else
                {
                    context.Succeed(models);
                }
            }
            else
            {
                var model = context.ToModel <T>() ?? throw new QueryException("model is required", QueryErrorCode.BadRequest);

                if (context.Descriptor.OnlyOwnerCanDelete)
                {
                    var authContext = new AuthorizationContext <T>(context);
                    await _repo.RemoveAsync(model,
                                            async (newDto, oldDto, cancellationToken) =>
                    {
                        var authorized = await authContext.AuthorizeAsync(oldDto, context.Descriptor.DeletePolicy);
                        if (authorized)
                        {
                            return(true);
                        }
                        context.Fail(newDto, QueryErrorCode.Unauthorized, "unauthorized");
                        return(false);
                    },
                                            (dto) => context.Fail(dto, QueryErrorCode.NotFound, "not found"),
                                            context.CancellationToken);
                }
                else
                {
                    await _repo.RemoveAsync(model,
                                            (dto) => context.Fail(dto, QueryErrorCode.NotFound, "not found"),
                                            context.CancellationToken);
                }
            }

            _repo.SoftDelete = softDelete;
        }
Пример #2
0
        public async Task ExecuteAsync(QueryContext context)
        {
            if (context.IsArrayModel())
            {
                var models = context.ToModels <T>() ?? throw new QueryException("models is required", QueryErrorCode.BadRequest);
                var errors = new List <RecordError>(models.Length);
                if (context.Descriptor.Validate)
                {
                    var validationContext = new ValidationContext <T>(context);
                    for (var index = 0; index < models.Length; ++index)
                    {
                        var model            = models[index];
                        var validationResult = await validationContext.ValidateAsync(model, context.CancellationToken);

                        if (validationResult.IsValid)
                        {
                            continue;
                        }

                        errors.Add(new RecordError
                        {
                            ErrorCode        = QueryErrorCode.ValidationError,
                            ErrorDescription = QueryErrorCode.ValidationError.ToString(),
                            At      = index,
                            Details = validationResult.Errors
                        });
                    }

                    if (errors.Count > 0)
                    {
                        context.Fail(errors, QueryErrorCode.ValidationError, QueryErrorCode.ValidationError.ToString());
                        return;
                    }
                }

                if (context.Descriptor.OnlyOwnerCanUpdate)
                {
                    var authContext = new AuthorizationContext <T>(context);
                    await _repo.UpdateRangeAsync(models,
                                                 async (newDto, oldDto, index, continuation, cancellationToken) =>
                    {
                        var authorized = await authContext.AuthorizeAsync(oldDto, context.Descriptor.UpdatePolicy);
                        if (authorized)
                        {
                            return(true);
                        }

                        errors.Add(new RecordError
                        {
                            ErrorCode        = QueryErrorCode.Unauthorized,
                            ErrorDescription = QueryErrorCode.Unauthorized.ToString(),
                            At = index
                        });
                        continuation.Yes = true;

                        return(false);
                    },
                                                 (dto, index, continuation) =>
                    {
                        errors.Add(new RecordError
                        {
                            ErrorCode        = QueryErrorCode.NotFound,
                            ErrorDescription = QueryErrorCode.NotFound.ToString(),
                            At = index
                        });
                        continuation.Yes = true;
                    }, context.CancellationToken);
                }
                else
                {
                    await _repo.UpdateRangeAsync(models,
                                                 (dto, index, continuation) =>
                    {
                        errors.Add(new RecordError
                        {
                            ErrorCode        = QueryErrorCode.NotFound,
                            ErrorDescription = QueryErrorCode.NotFound.ToString(),
                            At = index
                        });
                        continuation.Yes = true;
                    }, context.CancellationToken);
                }

                if (errors.Count > 0)
                {
                    context.Fail(errors, QueryErrorCode.UnauthorizedOrNotFound, "unauthorized or not found to update");
                }
                else
                {
                    context.Succeed(models);
                }
            }
            else
            {
                var model = context.ToModel <T>() ?? throw new QueryException("model is required", QueryErrorCode.BadRequest);
                if (context.Descriptor.Validate)
                {
                    var validationContext = new ValidationContext <T>(context);
                    var validationResult  = await validationContext.ValidateAsync(model, context.CancellationToken);

                    if (!validationResult.IsValid)
                    {
                        context.Fail(validationResult.Errors, QueryErrorCode.ValidationError, QueryErrorCode.ValidationError.ToString());
                        return;
                    }
                }

                if (context.Descriptor.OnlyOwnerCanUpdate)
                {
                    var authContext = new AuthorizationContext <T>(context);
                    await _repo.UpdateAsync(model,
                                            async (newDto, oldDto, cancellationToken) =>
                    {
                        var authorized = await authContext.AuthorizeAsync(oldDto, context.Descriptor.UpdatePolicy);
                        if (authorized)
                        {
                            return(true);
                        }
                        context.Fail(newDto, QueryErrorCode.Unauthorized, "unauthorized");
                        return(false);
                    },
                                            (dto) => context.Fail(dto, QueryErrorCode.NotFound, "not found"),
                                            context.CancellationToken);
                }
                else
                {
                    await _repo.UpdateAsync(model,
                                            (dto) => context.Fail(dto, QueryErrorCode.NotFound, "not found"),
                                            context.CancellationToken);
                }

                if (!context.HasError)
                {
                    context.Succeed(model);
                }
            }
        }
Пример #3
0
        public async Task ExecuteAsync(QueryContext context)
        {
            _repo.Apply(context.Descriptor, context.Params);

            if (!string.IsNullOrEmpty(context.Params.Id))
            {
                object[] id;
                try
                {
                    id = _repo.ParseId(context.Params.Id);
                }
                catch (Exception ex)
                {
                    throw new QueryException("id format incorrect", QueryErrorCode.BadRequest, ex);
                }

                var found = await _repo.FindAsync(id, context.CancellationToken);

                if (found == null)
                {
                    context.Succeed(null);
                    return;
                }

                if (context.Descriptor.OnlyOwnerCanRead)
                {
                    var authContext = new AuthorizationContext <T>(context);
                    var authorized  = await authContext.AuthorizeAsync(found, context.Descriptor.DeletePolicy);

                    if (authorized)
                    {
                        context.Succeed(found);
                    }
                    else
                    {
                        context.Fail(null, QueryErrorCode.Unauthorized, "unauthorized");
                    }
                }
                else
                {
                    context.Succeed(found);
                }
            }
            else
            {
                var condition = new Condition();
                Utils.Map(context.Descriptor, context.Params, condition);
                var found = await _repo.FindAsync(condition, context.CancellationToken);

                if (context.Descriptor.OnlyOwnerCanRead)
                {
                    var authContext = new AuthorizationContext <T>(context);
                    var authorized  = await authContext.AuthorizeAsync(found, context.Descriptor.DeletePolicy);

                    if (authorized)
                    {
                        context.Succeed(found);
                    }
                    else
                    {
                        context.Fail(null, QueryErrorCode.Unauthorized, "unauthorized");
                    }
                }
                else
                {
                    context.Succeed(found);
                }
            }
        }
Пример #4
0
        public async Task ExecuteAsync(QueryContext context)
        {
            if (context.IsArrayModel())
            {
                var models = context.ToModels <T>() ?? throw new QueryException("models is required", QueryErrorCode.BadRequest);
                if (context.Descriptor.OnlyOwnerCanCreate)
                {
                    var authContext = new AuthorizationContext <T>(context);
                    var errors      = new List <RecordError>(models.Length);
                    for (var index = 0; index < models.Length; ++index)
                    {
                        var model      = models[index];
                        var authorized = await authContext.AuthorizeAsync(model, context.Descriptor.CreatePolicy);

                        if (authorized)
                        {
                            continue;
                        }

                        errors.Add(new RecordError
                        {
                            ErrorCode        = QueryErrorCode.Unauthorized,
                            ErrorDescription = QueryErrorCode.Unauthorized.ToString(),
                            At = index
                        });
                    }

                    if (errors.Count > 0)
                    {
                        context.Fail(errors, QueryErrorCode.Unauthorized, "unauthorized");
                        return;
                    }
                }

                if (context.Descriptor.Validate)
                {
                    var validationContext = new ValidationContext <T>(context);
                    var errors            = new List <RecordError>(models.Length);
                    for (var index = 0; index < models.Length; ++index)
                    {
                        var model            = models[index];
                        var validationResult = await validationContext.ValidateAsync(model, context.CancellationToken);

                        if (validationResult.IsValid)
                        {
                            continue;
                        }

                        errors.Add(new RecordError
                        {
                            ErrorCode        = QueryErrorCode.ValidationError,
                            ErrorDescription = QueryErrorCode.ValidationError.ToString(),
                            At      = index,
                            Details = validationResult.Errors
                        });
                    }

                    if (errors.Count > 0)
                    {
                        context.Fail(errors, QueryErrorCode.ValidationError, QueryErrorCode.ValidationError.ToString());
                        return;
                    }
                }

                await _repo.AddRangeAsync(models, context.CancellationToken);

                context.Succeed(models);
            }
            else
            {
                var model = context.ToModel <T>() ?? throw new QueryException("model is required", QueryErrorCode.BadRequest);

                if (context.Descriptor.OnlyOwnerCanCreate)
                {
                    var authContext = new AuthorizationContext <T>(context);
                    var authorized  = await authContext.AuthorizeAsync(model, context.Descriptor.CreatePolicy);

                    if (!authorized)
                    {
                        context.Fail(null, QueryErrorCode.Unauthorized, "unauthorized");
                        return;
                    }
                }

                if (context.Descriptor.Validate)
                {
                    var validationContext = new ValidationContext <T>(context);
                    var validationResult  = await validationContext.ValidateAsync(model, context.CancellationToken);

                    if (!validationResult.IsValid)
                    {
                        context.Fail(validationResult.Errors, QueryErrorCode.ValidationError, QueryErrorCode.ValidationError.ToString());
                        return;
                    }
                }

                await _repo.AddAsync(model, context.CancellationToken);

                context.Succeed(model);
            }
        }
Пример #5
0
        public async Task ExecuteAsync(QueryContext context)
        {
            _repo.Apply(context.Descriptor, context.Params);

            if (!string.IsNullOrEmpty(context.Params.Id))
            {
                object[] id;
                try
                {
                    id = _repo.ParseId(context.Params.Id);
                }
                catch (Exception ex)
                {
                    throw new QueryException("id format incorrect", QueryErrorCode.BadRequest, ex);
                }

                var found = await _repo.FindAsync(id, context.CancellationToken);

                if (found == null)
                {
                    context.Succeed(new T[0]);
                    return;
                }

                if (context.Descriptor.OnlyOwnerCanRead)
                {
                    var authContext = new AuthorizationContext <T>(context);
                    var authorized  = await authContext.AuthorizeAsync(found, context.Descriptor.DeletePolicy);

                    if (authorized)
                    {
                        context.Succeed(new [] { found });
                    }
                    else
                    {
                        context.Fail(null, QueryErrorCode.Unauthorized, "unauthorized");
                    }
                }
                else
                {
                    context.Succeed(new[] { found });
                }
            }
            else
            {
                if (context.Params.Page.HasValue || context.Params.Offset.HasValue)
                {
                    var pagination = new Pagination();
                    if (context.Params.Page.HasValue)
                    {
                        pagination.Page = context.Params.Page.Value;
                    }
                    if (context.Params.Offset.HasValue)
                    {
                        pagination.Offset = context.Params.Offset.Value;
                    }
                    if (context.Params.PageSize.HasValue)
                    {
                        pagination.PageSize = context.Params.PageSize.Value;
                    }
                    if (context.Params.Limit.HasValue)
                    {
                        pagination.Limit = context.Params.Limit.Value;
                    }
                    Utils.Map(context.Descriptor, context.Params, pagination);
                    var paged = await _repo.GetPagedAsync(pagination, context.CancellationToken);

                    if (context.Descriptor.OnlyOwnerCanRead)
                    {
                        var authContext = new AuthorizationContext <T>(context);
                        foreach (var record in paged.Records)
                        {
                            var authorized = await authContext.AuthorizeAsync(record, context.Descriptor.DeletePolicy);

                            if (authorized)
                            {
                                continue;
                            }
                            context.Fail(null, QueryErrorCode.Unauthorized, "unauthorized");
                            return;
                        }
                    }
                    else
                    {
                        context.Succeed(paged);
                    }
                }
                else
                {
                    var condition = new Condition();
                    Utils.Map(context.Descriptor, context.Params, condition);
                    var collection = await _repo.ListAsync(condition, context.CancellationToken);

                    if (context.Descriptor.OnlyOwnerCanRead)
                    {
                        var authContext = new AuthorizationContext <T>(context);
                        foreach (var record in collection)
                        {
                            var authorized = await authContext.AuthorizeAsync(record, context.Descriptor.DeletePolicy);

                            if (authorized)
                            {
                                continue;
                            }
                            context.Fail(null, QueryErrorCode.Unauthorized, "unauthorized");
                            return;
                        }
                    }
                    else
                    {
                        context.Succeed(collection);
                    }
                }
            }
        }