Skip to content

Commit

Permalink
Merge branch 'main' into add-text-resource-selector-to-input-table
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasEng authored Dec 13, 2024
2 parents 834b409 + 2345ba1 commit 98ce4f6
Show file tree
Hide file tree
Showing 250 changed files with 4,943 additions and 6,813 deletions.
56 changes: 56 additions & 0 deletions .github/ISSUE_TEMPLATE/user_story.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: User Story 😃
description: Create a new user story
labels: ["kind/user-story", "status/draft"]
body:
- type: markdown
attributes:
value: |
* Please make sure this user story hasn't been already submitted by someone by looking through other open/closed user stories.
* Consider the [INVEST](https://www.pivotaltracker.com/blog/how-to-invest-in-your-user-stories) qualities when writing the story
- type: textarea
id: userstory
attributes:
label: User story
description: Give us a brief WHO, WHAT, and WHY of this user story.
value: As a [persona], I want to [do something] so that [I can achieve a goal].
placeholder: As a [persona], I want to [do something] so that [I can achieve a goal].
validations:
required: true

- type: textarea
id: description
attributes:
label: User story
description: You can provide a more detailed description of the user story here if needed.
placeholder: Describe the user story in more detail

- type: textarea
id: design
attributes:
label: Design - Screenshots and Figma links
description: Add screenshots where relevant, and always link to the Figma design if available.

- type: textarea
id: additional-information
attributes:
label: Additional Information
description: Add more details as needed, like links, open questions, etc.

- type: textarea
id: tasks
attributes:
label: Tasks
description: Add tasks to be done as part of this story.

- type: textarea
id: acceptance-criterias
attributes:
label: Acceptance Criterias
description: Define the acceptance criterias that this user story should testet against

- type: markdown
attributes:
value: |
* Check the [Definition of Ready](https://docs.altinn.studio/community/devops/definition-of-ready/) if you need hints on what to include.
* Remember to add the correct labels (status/*, org/*, ...)
2 changes: 1 addition & 1 deletion .github/workflows/run-playwright-resourceadm-on-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,4 @@ jobs:
if: failure()
with:
name: playwright-resourceadm-screenshots
path: frontend/testing/playwright/test-results
path: frontend/resourceadm/testing/playwright/test-results
2 changes: 1 addition & 1 deletion backend/Migrations.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ ENV OidcLoginSettings__ClientSecret=dummyRequired

RUN dotnet ef migrations script --project src/Designer/Designer.csproj -o /app/migrations.sql

FROM alpine:3.20.3 AS final
FROM alpine:3.21.0 AS final
COPY --from=build /app/migrations.sql migrations.sql
RUN apk --no-cache add postgresql-client

Expand Down
22 changes: 11 additions & 11 deletions backend/packagegroups/NuGet.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

<ItemGroup Label="Altinn specific packages">
<PackageReference Update="Altinn.App.Core" Version="8.0.0-rc1" />
<PackageReference Update="Altinn.Common.AccessToken" Version="4.5.2" />
<PackageReference Update="Altinn.Common.AccessTokenClient" Version="3.0.8" />
<PackageReference Update="Altinn.Common.AccessToken" Version="4.5.4" />
<PackageReference Update="Altinn.Common.AccessTokenClient" Version="3.0.10" />
<PackageReference Update="Altinn.Platform.Storage.Interface" Version="3.34.0" />
</ItemGroup>

Expand All @@ -13,7 +13,7 @@
<PackageReference Update="ini-parser-netstandard" Version="2.5.2" />
<PackageReference Update="JWTCookieAuthentication" Version="4.0.1" />
<!-- Do not upgrade this package unless extensively tested-->
<PackageReference Update="LibGit2Sharp" Version="0.30.0" />
<PackageReference Update="LibGit2Sharp" Version="0.31.0" />
<PackageReference Update="Microsoft.ApplicationInsights.AspNetCore" Version="2.22.0" />
<PackageReference Update="Microsoft.ApplicationInsights.Kubernetes" Version="7.0.0" />
<PackageReference Update="Microsoft.AspNet.WebApi.Client" Version="6.0.0" />
Expand All @@ -29,25 +29,25 @@
<PackageReference Update="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="9.0.0" />
<PackageReference Update="Microsoft.VisualStudio.Web.BrowserLink" Version="2.2.0" />
<PackageReference Update="Microsoft.AspNetCore.OpenApi" Version="9.0.0" />
<PackageReference Update="HtmlAgilityPack" Version="1.11.67" />
<PackageReference Update="HtmlAgilityPack" Version="1.11.71" />
<PackageReference Update="Microsoft.DiaSymReader.Native" Version="1.7.0" />
<PackageReference Update="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.1" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Tools" Version="9.0.0" />
<PackageReference Update="Microsoft.FeatureManagement.AspNetCore" Version="3.5.0" />
<PackageReference Update="Scrutor" Version="4.2.2" />
<PackageReference Update="Polly" Version="8.4.2" />
<PackageReference Update="Polly" Version="8.5.0" />
<PackageReference Update="Altinn.Authorization.ABAC" Version="0.0.8" />
<PackageReference Update="Altinn.ApiClients.Maskinporten" Version="9.2.0" />
<PackageReference Update="MediatR" Version="12.4.1" />
<PackageReference Update="DotNetEnv" Version="3.1.1" />
<PackageReference Update="NuGet.Versioning" Version="6.11.1" />
<PackageReference Update="DistributedLock.Postgres" Version="1.2.0" />
<PackageReference Update="NuGet.Versioning" Version="6.12.1" />
<PackageReference Update="DistributedLock.Postgres" Version="1.2.1" />
</ItemGroup>

<ItemGroup Label="Packages used for testing">
<PackageReference Update="FluentAssertions" Version="6.12.1" />
<PackageReference Update="FluentAssertions" Version="6.12.2" />
<PackageReference Update="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.0" />
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<!-- Do not upgrade Moq version from 4.18.4 -->
<PackageReference Update="Moq" Version="4.18.4" />
<PackageReference Update="xunit" Version="2.9.2" />
Expand All @@ -62,7 +62,7 @@
<PackageReference Update="Testcontainers.PostgreSql" Version="3.10.0" />
<PackageReference Update="Microsoft.AspNetCore.SignalR.Client" Version="9.0.0" />
<PackageReference Update="Microsoft.Extensions.DependencyModel" Version="9.0.0" />
<PackageReference Update="WireMock.Net" Version="1.6.7" />
<PackageReference Update="DistributedLock.FileSystem" Version="1.0.2" />
<PackageReference Update="WireMock.Net" Version="1.6.9" />
<PackageReference Update="DistributedLock.FileSystem" Version="1.0.3" />
</ItemGroup>
</Project>
10 changes: 5 additions & 5 deletions backend/src/Designer/Controllers/DatamodelsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,17 +163,17 @@ public async Task<IActionResult> AddXsd(string org, string repository, [FromForm
Request.EnableBuffering();
Guard.AssertArgumentNotNull(theFile, nameof(theFile));

string fileName = GetFileNameFromUploadedFile(theFile);
Guard.AssertFileExtensionIsOfType(fileName, ".xsd");
string fileNameWithExtension = GetFileNameFromUploadedFile(theFile);
Guard.AssertFileExtensionIsOfType(fileNameWithExtension, ".xsd");

string developer = AuthenticationHelper.GetDeveloperUserName(HttpContext);

var editingContext = AltinnRepoEditingContext.FromOrgRepoDeveloper(org, repository, developer);
var fileStream = theFile.OpenReadStream();
await _modelNameValidator.ValidateModelNameForNewXsdSchemaAsync(fileStream, fileName, editingContext);
string jsonSchema = await _schemaModelService.BuildSchemaFromXsd(editingContext, fileName, theFile.OpenReadStream(), cancellationToken);
await _modelNameValidator.ValidateModelNameForNewXsdSchemaAsync(fileStream, fileNameWithExtension, editingContext);
string jsonSchema = await _schemaModelService.BuildSchemaFromXsd(editingContext, fileNameWithExtension, theFile.OpenReadStream(), cancellationToken);

return Created(Uri.EscapeDataString(fileName), jsonSchema);
return Created(Uri.EscapeDataString(fileNameWithExtension), jsonSchema);
}

/// <summary>
Expand Down
31 changes: 31 additions & 0 deletions backend/src/Designer/Controllers/OptionsController.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -129,6 +130,36 @@ public async Task<ActionResult<Dictionary<string, List<Option>>>> CreateOrOverwr
return Ok(newOptionsList);
}

/// <summary>
/// Updates the name of an options list by changing file name in repo.
/// </summary>
/// <param name="org">Unique identifier of the organisation responsible for the app.</param>
/// <param name="repo">Application identifier which is unique within an organisation.</param>
/// <param name="optionsListId">Name of the options list.</param>
/// <param name="newOptionsListId">New name of options list file.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> that observes if operation is cancelled.</param>
[HttpPut]
[Produces("application/json")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[Route("change-name/{optionsListId}")]
public ActionResult UpdateOptionsListId(string org, string repo, [FromRoute] string optionsListId, [FromBody] string newOptionsListId, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string developer = AuthenticationHelper.GetDeveloperUserName(HttpContext);
var editingContext = AltinnRepoEditingContext.FromOrgRepoDeveloper(org, repo, developer);
try
{
_optionsService.UpdateOptionsListId(editingContext, optionsListId, newOptionsListId, cancellationToken);
}
catch (IOException exception)
{
return BadRequest(exception.Message);
}

return Ok();
}

/// <summary>
/// Create new options list.
/// </summary>
Expand Down
24 changes: 16 additions & 8 deletions backend/src/Designer/Controllers/ResourceAdminController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
using Altinn.Studio.Designer.ModelBinding.Constants;
using Altinn.Studio.Designer.Models;
using Altinn.Studio.Designer.Services.Interfaces;
using Altinn.Studio.Designer.Services.Models;
using Altinn.Studio.Designer.TypedHttpClients.ResourceRegistryOptions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
Expand All @@ -35,7 +34,6 @@ public class ResourceAdminController : ControllerBase
private readonly CacheSettings _cacheSettings;
private readonly IOrgService _orgService;
private readonly IResourceRegistry _resourceRegistry;
private readonly IEnvironmentsService _environmentsService;

public ResourceAdminController(IGitea gitea, IRepository repository, IResourceRegistryOptions resourceRegistryOptions, IMemoryCache memoryCache, IOptions<CacheSettings> cacheSettings, IOrgService orgService, IResourceRegistry resourceRegistry, IEnvironmentsService environmentsService)
{
Expand All @@ -46,7 +44,6 @@ public ResourceAdminController(IGitea gitea, IRepository repository, IResourceRe
_cacheSettings = cacheSettings.Value;
_orgService = orgService;
_resourceRegistry = resourceRegistry;
_environmentsService = environmentsService;
}

[HttpPost]
Expand Down Expand Up @@ -176,7 +173,7 @@ public async Task<ActionResult<List<ListviewServiceResource>>> GetRepositoryReso

if (includeEnvResources)
{
IEnumerable<string> environments = await GetEnvironmentsForOrg(org);
IEnumerable<string> environments = GetEnvironmentsForOrg(org);
foreach (string environment in environments)
{
string cacheKey = $"resourcelist_${environment}";
Expand Down Expand Up @@ -242,7 +239,7 @@ public async Task<ActionResult<ServiceResourceStatus>> GetPublishStatusById(stri
PublishedVersions = []
};

IEnumerable<string> environments = await GetEnvironmentsForOrg(org);
IEnumerable<string> environments = GetEnvironmentsForOrg(org);
foreach (string envir in environments)
{
resourceStatus.PublishedVersions.Add(await AddEnvironmentResourceStatus(envir, id));
Expand Down Expand Up @@ -336,6 +333,13 @@ public async Task<ActionResult> ImportResource(string org, string serviceCode, i
[Route("designer/api/{org}/resources/altinn2/delegationcount/{serviceCode}/{serviceEdition}/{env}")]
public async Task<ActionResult> GetDelegationCount(string org, string serviceCode, int serviceEdition, string env)
{
List<ServiceResource> allResources = await _resourceRegistry.GetResourceList(env.ToLower(), true);
bool serviceExists = allResources.Any(x => x.Identifier.Equals($"se_{serviceCode}_{serviceEdition}"));
if (!serviceExists)
{
return new NotFoundResult();
}

ServiceResource resource = await _resourceRegistry.GetServiceResourceFromService(serviceCode, serviceEdition, env.ToLower());
if (!IsServiceOwner(resource, org))
{
Expand Down Expand Up @@ -648,10 +652,14 @@ private string GetRepositoryName(string org)
return string.Format("{0}-resources", org);
}

private async Task<IEnumerable<string>> GetEnvironmentsForOrg(string org)
private List<string> GetEnvironmentsForOrg(string org)
{
IEnumerable<EnvironmentModel> environments = await _environmentsService.GetOrganizationEnvironments(org);
return environments.Select(environment => environment.Name == "production" ? "prod" : environment.Name);
List<string> environmentsForOrg = ["prod", "tt02"];
if (OrgUtil.IsTestEnv(org))
{
environmentsForOrg.AddRange(["at22", "at23", "at24", "yt01"]);
}
return environmentsForOrg;
}
}
}
29 changes: 16 additions & 13 deletions backend/src/Designer/Helpers/PackageVersionHelper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;
using NuGet.Versioning;
Expand All @@ -7,27 +8,29 @@ namespace Altinn.Studio.Designer.Helpers
{
public static class PackageVersionHelper
{
public static bool TryGetPackageVersionFromCsprojFile(string csprojFilePath, string packageName, out SemanticVersion version)
public static bool TryGetPackageVersionFromCsprojFile(string csprojFilePath, IReadOnlyList<string> packageNames, out SemanticVersion version)
{
version = null;
var doc = XDocument.Load(csprojFilePath);
var packageReferences = doc.XPathSelectElements("//PackageReference")
.Where(element => element.Attribute("Include")?.Value == packageName).ToList();
.Where(element => packageNames.Contains(element.Attribute("Include")?.Value));

if (packageReferences.Count != 1)
foreach (var packageReference in packageReferences)
{
return false;
}

var packageReference = packageReferences.First();
string versionString = packageReference.Attribute("Version")?.Value;
if (string.IsNullOrEmpty(versionString))
{
continue;
}

string versionString = packageReference.Attribute("Version")?.Value;
if (string.IsNullOrEmpty(versionString))
{
return false;
if (SemanticVersion.TryParse(versionString, out version))
{
return true;
}
}

return SemanticVersion.TryParse(versionString, out version);
version = default;
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -712,13 +712,8 @@ public string[] GetOptionsListIds()
throw new NotFoundException("Options folder not found.");
}

string[] fileNames = GetFilesByRelativeDirectory(optionsFolder, "*.json");
List<string> optionsListIds = [];
foreach (string fileName in fileNames.Select(Path.GetFileNameWithoutExtension))
{
optionsListIds.Add(fileName);
}

string[] fileNames = GetFilesByRelativeDirectoryAscSorted(optionsFolder, "*.json");
IEnumerable<string> optionsListIds = fileNames.Select(Path.GetFileNameWithoutExtension);
return optionsListIds.ToArray();
}

Expand Down Expand Up @@ -779,6 +774,18 @@ public void DeleteOptionsList(string optionsListId)
DeleteFileByRelativePath(optionsFilePath);
}

/// <summary>
/// Updates the ID of the option list by updating file name.
/// </summary>
/// <param name="oldOptionsListFileName">The file name of the option list to change filename of.</param>
/// <param name="newOptionsListFileName">The new file name of the option list file.</param>
public void UpdateOptionsListId(string oldOptionsListFileName, string newOptionsListFileName)
{
string currentFilePath = Path.Combine(OptionsFolderPath, oldOptionsListFileName);
string newFilePath = Path.Combine(OptionsFolderPath, newOptionsListFileName);
MoveFileByRelativePath(currentFilePath, newFilePath, newOptionsListFileName);
}

/// <summary>
/// Saves the process definition file on disk.
/// </summary>
Expand Down
13 changes: 13 additions & 0 deletions backend/src/Designer/Infrastructure/GitRepository/GitRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,19 @@ protected string[] GetFilesByRelativeDirectory(string relativeDirectory, string
return Directory.GetFiles(absoluteDirectory, searchPatternMatch, searchOption);
}

/// <summary>
/// Gets all the files within the specified directory in an alphabetically sorted order.
/// </summary>
/// <param name="relativeDirectory">Relative path to a directory within the repository.</param>
/// <param name="patternMatch">An optional pattern that the retrieved files must match</param>
/// <param name="searchInSubdirectories">An optional parameter to also get files in sub directories</param>
protected string[] GetFilesByRelativeDirectoryAscSorted(string relativeDirectory, string patternMatch = null, bool searchInSubdirectories = false)
{
string[] fileNames = GetFilesByRelativeDirectory(relativeDirectory, patternMatch, searchInSubdirectories);

return fileNames.OrderBy(path => path, StringComparer.OrdinalIgnoreCase).ToArray();
}

/// <summary>
/// Gets all the directories within the specified directory.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -538,9 +538,11 @@ public SemanticVersion GetAppLibVersion(AltinnRepoEditingContext altinnRepoEditi

var csprojFiles = altinnAppGitRepository.FindFiles(new[] { "*.csproj" });

string[] packageNames = ["Altinn.App.Api", "Altinn.App.Api.Experimental"];

foreach (string csprojFile in csprojFiles)
{
if (PackageVersionHelper.TryGetPackageVersionFromCsprojFile(csprojFile, "Altinn.App.Api",
if (PackageVersionHelper.TryGetPackageVersionFromCsprojFile(csprojFile, packageNames,
out SemanticVersion version))
{
return version;
Expand Down
Loading

0 comments on commit 98ce4f6

Please sign in to comment.