< 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
27%
Covered lines: 16
Uncovered lines: 42
Coverable lines: 58
Total lines: 135
Line coverage: 27.5%
Branch coverage
0%
Covered branches: 0
Total branches: 20
Branch coverage: 0%
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()0%7280%
ImportFilesAsync()0%7280%
ImportJsonStreamAsync()100%210%
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 System.IO.Compression;
 2using Elsa.Abstractions;
 3using Elsa.Workflows.Api.Constants;
 4using Elsa.Workflows.Api.Requirements;
 5using Elsa.Workflows.Management;
 6using Elsa.Workflows.Management.Mappers;
 7using Elsa.Workflows.Management.Models;
 8using JetBrains.Annotations;
 9using Microsoft.AspNetCore.Authorization;
 10using Microsoft.AspNetCore.Http;
 11
 12namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.ImportFiles;
 13
 14/// <summary>
 15/// Imports JSON and/or ZIP files containing a workflow definitions.
 16/// </summary>
 17[PublicAPI]
 18internal class ImportFiles : ElsaEndpoint<WorkflowDefinitionModel>
 19{
 20    private readonly IWorkflowDefinitionService _workflowDefinitionService;
 21    private readonly IWorkflowDefinitionImporter _workflowDefinitionImporter;
 22    private readonly WorkflowDefinitionMapper _workflowDefinitionMapper;
 23    private readonly IApiSerializer _apiSerializer;
 24    private readonly IAuthorizationService _authorizationService;
 25
 26    /// <inheritdoc />
 127    public ImportFiles(
 128        IWorkflowDefinitionService workflowDefinitionService,
 129        IWorkflowDefinitionImporter workflowDefinitionImporter,
 130        WorkflowDefinitionMapper workflowDefinitionMapper,
 131        IApiSerializer apiSerializer,
 132        IAuthorizationService authorizationService)
 33    {
 134        _workflowDefinitionService = workflowDefinitionService;
 135        _workflowDefinitionImporter = workflowDefinitionImporter;
 136        _workflowDefinitionMapper = workflowDefinitionMapper;
 137        _apiSerializer = apiSerializer;
 138        _authorizationService = authorizationService;
 139    }
 40
 41    /// <inheritdoc />
 42    public override void Configure()
 43    {
 144        Post("workflow-definitions/import-files");
 145        ConfigurePermissions("write:workflow-definitions");
 146        AllowFileUploads();
 147    }
 48
 49    /// <inheritdoc />
 50    public override async Task HandleAsync(WorkflowDefinitionModel model, CancellationToken cancellationToken)
 51    {
 052        var authorizationResult = await _authorizationService.AuthorizeAsync(User, new NotReadOnlyResource(), Authorizat
 53
 054        if (!authorizationResult.Succeeded)
 55        {
 056            await Send.ForbiddenAsync(cancellationToken);
 057            return;
 58        }
 59
 060        if (Files.Any())
 61        {
 062            var count = await ImportFilesAsync(Files, cancellationToken);
 63
 064            if (!ValidationFailed)
 065                await Send.OkAsync(new { Count = count }, cancellationToken);
 66        }
 67
 068        if (ValidationFailed)
 069            await Send.ErrorsAsync(400, cancellationToken);
 070    }
 71
 72    private async Task<int> ImportFilesAsync(IFormFileCollection files, CancellationToken cancellationToken)
 73    {
 074        var count = 0;
 75
 076        foreach (var file in files)
 77        {
 078            var fileStream = file.OpenReadStream();
 79
 80            // Check if the file is a JSON file or a ZIP file.
 081            var isJsonFile = file.ContentType == "application/json";
 82
 83            // If the file is a JSON file, read it.
 084            if (isJsonFile)
 85            {
 086                await ImportJsonStreamAsync(fileStream, cancellationToken);
 087                count++;
 88            }
 89            else
 90            {
 91                // If the file is a ZIP file, extract the JSON files and read them.
 092                var zipArchive = new ZipArchive(fileStream, ZipArchiveMode.Read);
 93
 094                foreach (var entry in zipArchive.Entries)
 95                {
 096                    if (!entry.FullName.EndsWith(".json", StringComparison.OrdinalIgnoreCase))
 97                        continue;
 98
 099                    var jsonStream = entry.Open();
 0100                    await ImportJsonStreamAsync(jsonStream, cancellationToken);
 0101                    count++;
 102                }
 103            }
 104        }
 105
 0106        return count;
 0107    }
 108
 109    private async Task ImportJsonStreamAsync(Stream jsonStream, CancellationToken cancellationToken)
 110    {
 0111        var json = await new StreamReader(jsonStream).ReadToEndAsync(cancellationToken);
 0112        var model = _apiSerializer.Deserialize<WorkflowDefinitionModel>(json);
 0113        await ImportSingleWorkflowDefinitionAsync(model, cancellationToken);
 0114    }
 115
 116    private async Task<ImportWorkflowResult> ImportSingleWorkflowDefinitionAsync(WorkflowDefinitionModel model, Cancella
 117    {
 118        // Import workflow
 0119        var saveWorkflowRequest = new SaveWorkflowDefinitionRequest
 0120        {
 0121            Model = model,
 0122            Publish = false,
 0123        };
 124
 0125        var result = await _workflowDefinitionImporter.ImportAsync(saveWorkflowRequest, cancellationToken);
 126
 0127        if (result.Succeeded)
 0128            return result;
 129
 0130        foreach (var validationError in result.ValidationErrors)
 0131            AddError(validationError.Message);
 132
 0133        return result;
 0134    }
 135}