/// <inheritdoc/>
        protected override async Task <EventModel> ProtectedHandleAsync(GetByIdQuery request, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var principal = PrincipalProvider.GetPrincipal();

            if (principal == null)
            {
                throw new ForbiddenException("Not authenticated");
            }

            Expression <Func <EventEntity, bool> > expression = PredicateBuilder.Create <EventEntity>(e => e.Id == Guid.Parse(request.Id));

            if (!principal.IsInRole(RoleType.Administrator))
            {
                expression = expression.And(e => e.UserId == principal.Identity.Name);
            }

            var result = Context.EventRepository
                         .GetQuery()
                         .Where(expression)
                         .FirstOrDefault();

            if (result == null)
            {
                throw new NotFoundException(nameof(WebhookEntity), request.Id);
            }

            var model = EventModel.Create(result, Serializer);

            await Task.CompletedTask;

            return(model);
        }
예제 #2
0
        /// <inheritdoc/>
        protected override async Task <ResultModel> ProtectedHandleAsync(GetByIdQuery request, CancellationToken cancellationToken)
        {
            var principal = PrincipalProvider.GetPrincipal();

            if (principal == null)
            {
                throw new ForbiddenException("Not authenticated");
            }

            Expression <Func <ResultEntity, bool> > expression = PredicateBuilder.Create <ResultEntity>(e => e.Id == Guid.Parse(request.Id));

            if (!principal.IsInRole(RoleType.Administrator))
            {
                expression = expression.And(e => e.Task.Object.UserId == principal.Identity.Name);
            }

            var entity = await Context.ResultRepository.GetFirstOrDefaultAsync(expression, cancellationToken);

            if (entity == null)
            {
                throw new NotFoundException(nameof(ResultEntity), request.Id);
            }

            return(ResultModel.Create(entity, Serializer));
        }
        /// <summary>
        /// Asynchronously handles the command request.
        /// </summary>
        /// <param name="request">The command request.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>A task that represents the asynchronous operation.
        /// The task result contains the result of the command request.</returns>
        public async Task <TResponse> Handle(TRequest request, CancellationToken cancellationToken)
        {
            try
            {
                cancellationToken.ThrowIfCancellationRequested();

                var response = await ProtectedHandleAsync(request, cancellationToken);

                if (SubEventType != SubEventType.None)
                {
                    var principal = PrincipalProvider.GetPrincipal();
                    var auditData = new AuditDataModel()
                    {
                        Entity  = response,
                        Command = request
                    };
                    await Audit.AddDefaultEventAsync(principal, auditData, SubEventType);
                }

                return(response);
            }
            catch (Exception)
            {
                Context.RollBackTransaction();

                throw;
            }
        }
예제 #4
0
        /// <inheritdoc/>
        protected override async Task <PaginationResultModel <EventModel> > ProtectedHandleAsync(GetPaginatedQuery request, CancellationToken cancellationToken)
        {
            var principal = PrincipalProvider.GetPrincipal();

            if (principal == null)
            {
                throw new ForbiddenException("Not authenticated");
            }

            Expression <Func <EventEntity, bool> > expression = PredicateBuilder.True <EventEntity>();

            if (!principal.IsInRole(RoleType.Administrator))
            {
                expression = expression.And(e => e.UserId == principal.Identity.Name);
            }

            int total = await Context.EventRepository.CountAsync(expression, cancellationToken);

            var query = Context.EventRepository
                        .GetQuery(expression)
                        .OrderByDescending(e => e.CreatedDate)
                        .Skip(request.Page * request.Limit)
                        .Take(request.Limit);

            var entities = await Context.ToListAsync(query, cancellationToken);

            var models = entities.Select(e => EventModel.Create(e, Serializer));

            return(PaginationResultModel <EventModel> .Create(models, request.Page, request.Limit, total));
        }
예제 #5
0
        /// <inheritdoc/>
        protected override async Task <FileByteResultModel> ProtectedHandleAsync(GetZipQuery request, CancellationToken cancellationToken)
        {
            var principal = PrincipalProvider.GetPrincipal();

            if (principal == null)
            {
                throw new ForbiddenException("Not authenticated");
            }

            Expression <Func <ResultEntity, bool> > expression = PredicateBuilder.Create <ResultEntity>(e => e.Id == Guid.Parse(request.Id));

            if (!principal.IsInRole(RoleType.Administrator))
            {
                expression = expression.And(e => e.Task.Object.UserId == principal.Identity.Name);
            }

            var entity = await Context.ResultRepository.GetFirstOrDefaultAsync(expression, cancellationToken);

            if (entity == null)
            {
                throw new NotFoundException(nameof(ResultEntity), request.Id);
            }

            if (string.IsNullOrWhiteSpace(entity.BasePath))
            {
                throw new UnexpectedNullException($"The base path of result {request.Id} is null.");
            }

            var fs = fileSystemStrategy.Create(configuration.Options.WorkingDirectory);

            if (fs == null)
            {
                throw new UnexpectedNullException("Filesystem could not be created based on the working directory.");
            }

            var fullBasePath = fs.Path.Combine(configuration.Options.WorkingDirectory, entity.BasePath);
            var items        = fs.Directory.EnumerateFiles(fullBasePath, "*.*", SearchOption.TopDirectoryOnly);

            var archive = writer.Create(CompressionType.None);
            await writer.AddFilesAsync(items, dfp => dfp, en => en.Substring(fullBasePath.Length), archive, cancellationToken);

            var stream = new MemoryStream();

            writer.Write(stream, archive);

            var result = new FileByteResultModel()
            {
                FileContents     = stream.ToArray(),
                ContentType      = "application/zip",
                FileDownloadName = $"{Constants.ApplicationNameShort}_{request.Id}_{DateTime.Now.ToString("yyyyMMdd_HHmmss")}.zip"
            };

            return(result);
        }
        /// <inheritdoc/>
        protected override async Task <ObjectModel> ProtectedHandleAsync(GetByIdQuery request, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var principal = PrincipalProvider.GetPrincipal();

            if (principal == null)
            {
                throw new ForbiddenException("Not authenticated");
            }

            Expression <Func <ObjectEntity, bool> > expression = PredicateBuilder.Create <ObjectEntity>(e => e.Id == Guid.Parse(request.Id));

            if (!principal.IsInRole(RoleType.Administrator))
            {
                expression = expression.And(e => e.UserId == principal.Identity.Name);
            }

            var result = Context.ObjectRepository
                         .GetQuery()
                         .Where(expression)
                         .Select(e => new
            {
                Object  = e,
                Tasks   = e.Tasks.OrderByDescending(e1 => e1.CreatedDate).Take(Constants.DefaultPaginationLimit),
                Results = e.Tasks.OrderByDescending(e1 => e1.CreatedDate).Select(e1 => e1.Result).Take(Constants.DefaultPaginationLimit)
            })
                         .FirstOrDefault();

            if (result == null)
            {
                throw new NotFoundException(nameof(ObjectEntity), request.Id);
            }

            var model = ObjectModel.Create(result.Object, result.Tasks, result.Results, Serializer);

            await Task.CompletedTask;

            return(model);
        }
        /// <inheritdoc/>
        protected override async Task <WebhookModel> ProtectedHandleAsync(CreateWebhookCommand request, CancellationToken cancellationToken)
        {
            var principal = PrincipalProvider.GetPrincipal();

            if (principal == null)
            {
                throw new ForbiddenException("Not authenticated");
            }

            int webhookLimit;

            if (principal.IsInRole(RoleType.Administrator))
            {
                webhookLimit = 0;
            }
            else
            {
                webhookLimit = apiConfiguration.Options.WebhookLimit;
            }

            processMutex = new Mutex(false, this.GetMethodName());

            return(await processMutex.Execute(new TimeSpan(0, 0, 2), async() =>
            {
                if (webhookLimit > 0)
                {
                    var count = await Context.WebhookRepository.CountAsync(
                        e => e.UserId == principal.Identity.Name, cancellationToken);
                    if (count >= webhookLimit)
                    {
                        throw new AmiException($"The webhook limit of {webhookLimit} has been reached.");
                    }
                }

                Guid guid = idGenerator.GenerateId();

                string enabledEvents = request.EnabledEvents.Contains(constants.WildcardCharacter) ?
                                       constants.WildcardCharacter.Embed(constants.ValueSeparator) :
                                       request.EnabledEvents.ToArray().ToString(",", constants.ValueSeparator);

                var entity = new WebhookEntity()
                {
                    Id = guid,
                    CreatedDate = DateTime.UtcNow,
                    ModifiedDate = DateTime.UtcNow,
                    Url = request.Url,
                    ApiVersion = request.ApiVersion,
                    Secret = request.Secret,
                    EnabledEvents = enabledEvents,
                    UserId = principal.Identity.Name
                };

                Context.WebhookRepository.Add(entity);

                await Context.SaveChangesAsync(cancellationToken);

                var result = WebhookModel.Create(entity, constants);

                return result;
            }));
        }
예제 #8
0
        /// <inheritdoc/>
        protected override async Task <ObjectModel> ProtectedHandleAsync(CreateObjectCommand request, CancellationToken cancellationToken)
        {
            var principal = PrincipalProvider.GetPrincipal();

            if (principal == null)
            {
                throw new ForbiddenException("Not authenticated");
            }

            int objectLimit = 0;

            if (principal.IsInRole(RoleType.User))
            {
                objectLimit = apiConfiguration.Options.ObjectLimit;
            }
            else
            {
                objectLimit = apiConfiguration.Options.ObjectLimitAnonymous;
            }

            processMutex = new Mutex(false, this.GetMethodName());

            return(await processMutex.Execute(new TimeSpan(0, 0, 2), async() =>
            {
                if (objectLimit > 0)
                {
                    var count = await Context.ObjectRepository.CountAsync(e => e.UserId == principal.Identity.Name, cancellationToken);
                    if (count >= objectLimit)
                    {
                        throw new AmiException($"The object limit of {objectLimit} has been reached.");
                    }
                }

                string fileExtension = fileSystem.Path.GetExtension(request.OriginalFilename);

                Guid guid = idGenerator.GenerateId();
                string path = fileSystem.Path.Combine("Binary", "Objects", guid.ToString());
                string destFilename = string.Concat(guid.ToString(), fileExtension);
                string destPath = fileSystem.Path.Combine(path, destFilename);

                fileSystem.Directory.CreateDirectory(fileSystem.Path.Combine(appConfiguration.Options.WorkingDirectory, path));
                fileSystem.File.Move(request.SourcePath, fileSystem.Path.Combine(appConfiguration.Options.WorkingDirectory, destPath));

                var entity = new ObjectEntity()
                {
                    Id = guid,
                    CreatedDate = DateTime.UtcNow,
                    ModifiedDate = DateTime.UtcNow,
                    OriginalFilename = request.OriginalFilename,
                    SourcePath = destPath,
                    UserId = principal.Identity.Name
                };

                Context.ObjectRepository.Add(entity);

                await Context.SaveChangesAsync(cancellationToken);

                var result = ObjectModel.Create(entity);

                await Events.CreateAsync(entity.UserId, EventType.ObjectCreated, result, cancellationToken);
                await Gateway.NotifyGroupsAsync(entity.UserId, EventType.ObjectCreated, result, cancellationToken);

                return result;
            }));
        }
        /// <inheritdoc/>
        protected override async Task <TaskModel> ProtectedHandleAsync(CreateTaskCommand request, CancellationToken cancellationToken)
        {
            var principal = PrincipalProvider.GetPrincipal();

            if (principal == null)
            {
                throw new ForbiddenException("Not authenticated");
            }

            if (request.Command.CommandType != CommandType.ProcessObjectCommand || request.Command.GetType() != typeof(ProcessObjectCommand))
            {
                throw new NotSupportedException("The provided command type is not supported.");
            }

            var command = request.Command as ProcessObjectCommand;

            Guid objectId      = Guid.Parse(command.Id);
            var  objectOwnerId = Context.ObjectRepository.GetQuery(e => e.Id == objectId).Select(e => e.UserId).FirstOrDefault();

            if (!AuthService.IsAuthorized(objectOwnerId))
            {
                throw new ForbiddenException("Not authorized");
            }

            processMutex = new Mutex(false, this.GetMethodName());

            return(await processMutex.Execute(new TimeSpan(0, 0, 2), async() =>
            {
                var activeCount = await Context.TaskRepository.CountAsync(e =>
                                                                          e.ObjectId == objectId &&
                                                                          (e.Status == (int)Domain.Enums.TaskStatus.Created ||
                                                                           e.Status == (int)Domain.Enums.TaskStatus.Queued ||
                                                                           e.Status == (int)Domain.Enums.TaskStatus.Processing));

                if (activeCount > 0)
                {
                    throw new AmiException("The specified object is already actively being processed.");
                }

                var position = await Context.TaskRepository.CountAsync(e =>
                                                                       e.Status == (int)Domain.Enums.TaskStatus.Queued);

                var entity = new TaskEntity()
                {
                    Id = idGenerator.GenerateId(),
                    CreatedDate = DateTime.UtcNow,
                    ModifiedDate = DateTime.UtcNow,
                    QueuedDate = DateTime.UtcNow,
                    Status = (int)Domain.Enums.TaskStatus.Queued,
                    Progress = 0,
                    Position = position,
                    CommandType = (int)CommandType.ProcessObjectCommand,
                    CommandSerialized = serializer.Serialize(command),
                    UserId = principal.Identity.Name,
                    ObjectId = objectId
                };

                Context.TaskRepository.Add(entity);

                await Context.SaveChangesAsync(cancellationToken);

                var result = await mediator.Send(new GetByIdQuery()
                {
                    Id = entity.Id.ToString()
                });
                if (result == null)
                {
                    throw new UnexpectedNullException($"The task '{entity.Id.ToString()}' could not be retrieved after creating it.");
                }

                if (entity.Object != null)
                {
                    await Events.CreateAsync(entity.Object.UserId, EventType.TaskCreated, result, cancellationToken);
                    await Gateway.NotifyGroupsAsync(entity.Object.UserId, EventType.TaskCreated, result, cancellationToken);
                }

                backgroundService.EnqueueTask(result.Id);

                return result;
            }));
        }