< Summary

Information
Class: Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.ImportFiles.ImportFiles
Assembly: Elsa.Workflows.Api
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/ImportFiles/Endpoint.cs
Line coverage
51%
Covered lines: 32
Uncovered lines: 30
Coverable lines: 62
Total lines: 130
Line coverage: 51.6%
Branch coverage
21%
Covered branches: 6
Total branches: 28
Branch coverage: 21.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
Configure()100%11100%
HandleAsync()21.42%341453.33%
ReadWorkflowDefinitionModelsAsync()100%11100%
AuthorizePythonUsageAsync()75%4483.33%
ImportWorkflowDefinitionsAsync()0%4260%
ImportSingleWorkflowDefinitionAsync()0%2040%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/ImportFiles/Endpoint.cs

#LineLine coverage
 1using Elsa.Abstractions;
 2using Elsa.Workflows.Api.Security;
 3using Elsa.Workflows.Management;
 4using Elsa.Workflows.Management.Models;
 5using JetBrains.Annotations;
 6using Microsoft.AspNetCore.Authorization;
 7using Microsoft.AspNetCore.Http;
 8
 9namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.ImportFiles;
 10
 11/// <summary>
 12/// Imports JSON and/or ZIP files containing a workflow definitions.
 13/// </summary>
 14[PublicAPI]
 15internal class ImportFiles : ElsaEndpoint<WorkflowDefinitionModel>
 16{
 17    private readonly IWorkflowDefinitionStore _workflowDefinitionStore;
 18    private readonly IWorkflowDefinitionImporter _workflowDefinitionImporter;
 19    private readonly IApiSerializer _apiSerializer;
 20    private readonly IAuthorizationService _authorizationService;
 21    private readonly WorkflowDefinitionScriptAuthorizationService _scriptAuthorizationService;
 22
 23    /// <inheritdoc />
 424    public ImportFiles(
 425        IWorkflowDefinitionStore workflowDefinitionStore,
 426        IWorkflowDefinitionImporter workflowDefinitionImporter,
 427        IApiSerializer apiSerializer,
 428        IAuthorizationService authorizationService,
 429        WorkflowDefinitionScriptAuthorizationService scriptAuthorizationService)
 30    {
 431        _workflowDefinitionStore = workflowDefinitionStore;
 432        _workflowDefinitionImporter = workflowDefinitionImporter;
 433        _apiSerializer = apiSerializer;
 434        _authorizationService = authorizationService;
 435        _scriptAuthorizationService = scriptAuthorizationService;
 436    }
 37
 38    /// <inheritdoc />
 39    public override void Configure()
 40    {
 341        Post("workflow-definitions/import-files");
 342        ConfigurePermissions("write:workflow-definitions");
 343        AllowFileUploads();
 344    }
 45
 46    /// <inheritdoc />
 47    public override async Task HandleAsync(WorkflowDefinitionModel model, CancellationToken cancellationToken)
 48    {
 149        if (Files.Any())
 50        {
 151            var models = await ReadWorkflowDefinitionModelsAsync(Files, cancellationToken);
 152            if (!await AuthorizePythonUsageAsync(models, cancellationToken))
 053                return;
 54
 155            var authorizationResult = await _authorizationService.AuthorizeWorkflowDefinitionImportsAsync(User, _workflo
 56
 157            if (!authorizationResult.Succeeded)
 58            {
 159                await Send.ForbiddenAsync(cancellationToken);
 160                return;
 61            }
 62
 063            var count = await ImportWorkflowDefinitionsAsync(models, cancellationToken);
 64
 065            if (!ValidationFailed && !HttpContext.Response.HasStarted)
 066                await Send.OkAsync(new { Count = count }, cancellationToken);
 067        }
 68
 069        if (ValidationFailed && !HttpContext.Response.HasStarted)
 070            await Send.ErrorsAsync(400, cancellationToken);
 171    }
 72
 73    private async Task<ICollection<WorkflowDefinitionModel>> ReadWorkflowDefinitionModelsAsync(IFormFileCollection files
 74    {
 375        var models = await WorkflowDefinitionImportFileReader.ReadAsync(files, _apiSerializer, () => HttpContext.Respons
 176        return models.ToList();
 177    }
 78
 79    private async Task<bool> AuthorizePythonUsageAsync(IEnumerable<WorkflowDefinitionModel> models, CancellationToken ca
 80    {
 681        foreach (var model in models)
 82        {
 283            var scriptAuthorizationResult = await _scriptAuthorizationService.AuthorizeAsync(model, User, cancellationTo
 284            if (!scriptAuthorizationResult.Succeeded)
 85            {
 086                await WorkflowDefinitionScriptAuthorizationFailure.SendAsync(scriptAuthorizationResult, Send.ForbiddenAs
 087                return false;
 88            }
 89        }
 90
 191        return true;
 192    }
 93
 94    private async Task<int> ImportWorkflowDefinitionsAsync(IEnumerable<WorkflowDefinitionModel> models, CancellationToke
 95    {
 096        var count = 0;
 097        foreach (var model in models)
 98        {
 099            if (HttpContext.Response.HasStarted)
 0100                return count;
 101
 0102            var result = await ImportSingleWorkflowDefinitionAsync(model, cancellationToken);
 103
 0104            if (result.Succeeded)
 0105                count++;
 106        }
 107
 0108        return count;
 0109    }
 110
 111    private async Task<ImportWorkflowResult> ImportSingleWorkflowDefinitionAsync(WorkflowDefinitionModel model, Cancella
 112    {
 113        // Import workflow
 0114        var saveWorkflowRequest = new SaveWorkflowDefinitionRequest
 0115        {
 0116            Model = model,
 0117            Publish = false,
 0118        };
 119
 0120        var result = await _workflowDefinitionImporter.ImportAsync(saveWorkflowRequest, cancellationToken);
 121
 0122        if (result.Succeeded)
 0123            return result;
 124
 0125        foreach (var validationError in result.ValidationErrors)
 0126            AddError(validationError.Message);
 127
 0128        return result;
 0129    }
 130}