Skip to content

Commit

Permalink
Merge branch 'main' into fix/missing-null-check
Browse files Browse the repository at this point in the history
  • Loading branch information
lassopicasso authored Nov 27, 2024
2 parents 0644b0d + 4a7d1e2 commit 069f95c
Show file tree
Hide file tree
Showing 118 changed files with 2,534 additions and 444 deletions.
1 change: 1 addition & 0 deletions .github/workflows/lint-pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ jobs:
resource-adm
resource-registry
settings
studio-root
subform
testing
text
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ The development environment consist of several services defined in [compose.yaml
- `studio-repos` which is [gitea][14] with some custom config. More [here](gitea/README.md).
- `studio-db` which is a postgres database used by both `studio-designer` and `studio-repos`.
- `database_migrations` which is a one-time task container designed to perform and complete database migrations before exiting.
- `redis` which is a redis cache used by designer.
- `redis-commander` which is a ui for redis cache.

Run all parts of the solution in containers (Make sure docker is running), with docker compose as follows:

Expand Down
3 changes: 2 additions & 1 deletion backend/packagegroups/NuGet.props
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
<PackageReference Update="Microsoft.Azure.Security.KeyVault.Secrets" Version="4.5.0" />
<PackageReference Update="Microsoft.Azure.Services.AppAuthentication" Version="1.6.2" />
<PackageReference Update="Microsoft.Extensions.Configuration.AzureKeyVault" Version="3.1.24" />
<PackageReference Update="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.0" />
<PackageReference Update="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="9.0.0" />
<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" />
Expand All @@ -40,7 +42,6 @@
<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="Community.Microsoft.Extensions.Caching.PostgreSql" Version="4.0.6" />
</ItemGroup>

<ItemGroup Label="Packages used for testing">
Expand Down
23 changes: 23 additions & 0 deletions backend/src/Designer/Configuration/FeedbackFormSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Altinn.Studio.Designer.Configuration.Marker;

namespace Altinn.Studio.Designer.Configuration
{
/// <summary>
/// Class representation for basic FeedbackForm configuration
/// </summary>
public class FeedbackFormSettings : ISettingsMarker
{
/// <summary>
/// Gets or sets the Slack settings
/// </summary>
public SlackSettings SlackSettings { get; set; }
}

public class SlackSettings
{
/// <summary>
/// Gets or sets the WebhookUrl
/// </summary>
public string WebhookUrl { get; set; }
}
}
10 changes: 10 additions & 0 deletions backend/src/Designer/Configuration/RedisCacheSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Altinn.Studio.Designer.Configuration.Marker;

namespace Altinn.Studio.Designer.Configuration;

public class RedisCacheSettings : ISettingsMarker
{
public bool UseRedisCache { get; set; } = false;
public string ConnectionString { get; set; }
public string InstanceName { get; set; }
}
45 changes: 45 additions & 0 deletions backend/src/Designer/Controllers/AnsattPortenController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System.Threading.Tasks;
using Altinn.Studio.Designer.Constants;
using Altinn.Studio.Designer.Models.Dto;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.FeatureManagement.Mvc;

namespace Altinn.Studio.Designer.Controllers;

[FeatureGate(StudioFeatureFlags.AnsattPorten)]
[Route("designer/api/[controller]")]
[ApiController]
public class AnsattPortenController : ControllerBase
{
[Authorize(AnsattPortenConstants.AnsattportenAuthorizationPolicy)]
[HttpGet("login")]
public async Task<IActionResult> Login([FromQuery(Name = "redirect_to")] string redirectTo)
{
await Task.CompletedTask;
if (!Url.IsLocalUrl(redirectTo))
{
return Forbid();
}

return LocalRedirect(redirectTo);
}

[AllowAnonymous]
[HttpGet("auth-status")]
public async Task<IActionResult> AuthStatus()
{
await Task.CompletedTask;
var authenticateResult =
await HttpContext.AuthenticateAsync(AnsattPortenConstants.AnsattportenAuthenticationScheme);

var authStatus = new AuthStatus
{
IsLoggedIn = authenticateResult.Succeeded
};

return Ok(authStatus);
}

}
8 changes: 2 additions & 6 deletions backend/src/Designer/Controllers/AppScopesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ namespace Altinn.Studio.Designer.Controllers;
[ApiController]
[FeatureGate(StudioFeatureFlags.AnsattPorten)]
[Route("designer/api/{org}/{app:regex(^(?!datamodels$)[[a-z]][[a-z0-9-]]{{1,28}}[[a-z0-9]]$)}/app-scopes")]

public class AppScopesController(IMaskinPortenHttpClient maskinPortenHttpClient,
IAppScopesService appScopesService) : ControllerBase
{
Expand All @@ -28,7 +27,7 @@ public async Task<IActionResult> GetScopesFromMaskinPorten(string org, string ap
{
var scopes = await maskinPortenHttpClient.GetAvailableScopes(cancellationToken);

var reponse = new AppScopesResponse()
var response = new AppScopesResponse()
{
Scopes = scopes.Select(x => new MaskinPortenScopeDto()
{
Expand All @@ -37,10 +36,9 @@ public async Task<IActionResult> GetScopesFromMaskinPorten(string org, string ap
}).ToHashSet()
};

return Ok(reponse);
return Ok(response);
}


[Authorize]
[HttpPut]
public async Task UpsertAppScopes(string org, string app, [FromBody] AppScopesUpsertRequest appScopesUpsertRequest,
Expand All @@ -56,7 +54,6 @@ public async Task UpsertAppScopes(string org, string app, [FromBody] AppScopesUp
await appScopesService.UpsertScopesAsync(AltinnRepoEditingContext.FromOrgRepoDeveloper(org, app, developer), scopes, cancellationToken);
}


[Authorize]
[HttpGet]
public async Task<IActionResult> GetAppScopes(string org, string app, CancellationToken cancellationToken)
Expand All @@ -74,5 +71,4 @@ public async Task<IActionResult> GetAppScopes(string org, string app, Cancellati

return Ok(reponse);
}

}
75 changes: 75 additions & 0 deletions backend/src/Designer/Controllers/FeedbackFormController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Altinn.Studio.Designer.Configuration;
using Altinn.Studio.Designer.Models.Dto;
using Altinn.Studio.Designer.TypedHttpClients.Slack;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;

namespace Altinn.Studio.Designer.Controllers;

/// <summary>
/// Controller containing actions related to feedback form
/// </summary>
[Authorize]
[ApiController]
[ValidateAntiForgeryToken]
[Route("designer/api/{org}/{app:regex(^(?!datamodels$)[[a-z]][[a-z0-9-]]{{1,28}}[[a-z0-9]]$)}/feedbackform")]
public class FeedbackFormController : ControllerBase
{
private readonly ISlackClient _slackClient;
private readonly GeneralSettings _generalSettings;

/// <summary>
/// Initializes a new instance of the <see cref="FeedbackFormController"/> class.
/// </summary>
/// <param name="slackClient">A http client to send messages to slack</param>
/// <param name="generalSettings">the general settings</param>
public FeedbackFormController(ISlackClient slackClient, GeneralSettings generalSettings)
{
_slackClient = slackClient;
_generalSettings = generalSettings;
}

/// <summary>
/// Endpoint for submitting feedback
/// </summary>
[HttpPost]
[Route("submit")]
public async Task<IActionResult> SubmitFeedback([FromRoute] string org, [FromRoute] string app, [FromBody] FeedbackForm feedback, CancellationToken cancellationToken)
{
if (feedback == null)
{
return BadRequest("Feedback object is null");
}

if (feedback.Answers == null || feedback.Answers.Count == 0)
{
return BadRequest("Feedback answers are null or empty");
}

if (!feedback.Answers.ContainsKey("org"))
{
feedback.Answers.Add("org", org);
}

if (!feedback.Answers.ContainsKey("app"))
{
feedback.Answers.Add("app", app);
}

if (!feedback.Answers.ContainsKey("env"))
{
feedback.Answers.Add("env", _generalSettings.HostName);
}

await _slackClient.SendMessage(new SlackRequest
{
Text = JsonSerializer.Serialize(feedback.Answers, new JsonSerializerOptions { WriteIndented = true })
}, cancellationToken);

return Ok();
}
}
21 changes: 0 additions & 21 deletions backend/src/Designer/Controllers/ProcessModelingController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,27 +48,6 @@ public FileStreamResult GetProcessDefinition(string org, string repo)
}

[HttpPut("process-definition")]
[Obsolete("This endpoint should be replaced by process-definition-latest, and url fixed after integration with frontend")]
public async Task<IActionResult> SaveProcessDefinition(string org, string repo,
CancellationToken cancellationToken)
{
Request.EnableBuffering();
try
{
await Guard.AssertValidXmlStreamAndRewindAsync(Request.Body);
}
catch (ArgumentException)
{
return BadRequest("BPMN file is not valid XML");
}

string developer = AuthenticationHelper.GetDeveloperUserName(HttpContext);
await _processModelingService.SaveProcessDefinitionAsync(
AltinnRepoEditingContext.FromOrgRepoDeveloper(org, repo, developer), Request.Body, cancellationToken);
return Ok();
}

[HttpPut("process-definition-latest")]
public async Task<IActionResult> UpsertProcessDefinitionAndNotify(string org, string repo, [FromForm] IFormFile content, [FromForm] string metadata, CancellationToken cancellationToken)
{
Request.EnableBuffering();
Expand Down
3 changes: 2 additions & 1 deletion backend/src/Designer/Designer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
<PackageReference Include="Altinn.Common.AccessTokenClient" />
<PackageReference Include="Altinn.Platform.Storage.Interface" />
<PackageReference Include="Azure.Security.KeyVault.Secrets" />
<PackageReference Include="Community.Microsoft.Extensions.Caching.PostgreSql" />
<PackageReference Include="CompilerAttributes" />
<PackageReference Include="DistributedLock.Postgres" />
<PackageReference Include="DotNetEnv" />
Expand All @@ -38,6 +37,7 @@
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" />
<PackageReference Include="Microsoft.Azure.KeyVault" />
<PackageReference Include="Microsoft.Azure.Services.AppAuthentication" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" />
Expand All @@ -46,6 +46,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" />
<PackageReference Include="Microsoft.FeatureManagement.AspNetCore" />
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ private static IServiceCollection AddAnsattPortenAuthentication(this IServiceCol
options.Events.OnRedirectToIdentityProvider = context =>
{

if (!context.Request.Path.StartsWithSegments("/designer/api") ||
!context.Request.Path.Value!.Contains("/maskinporten"))
if (!context.Request.Path.StartsWithSegments("/designer/api/ansattporten/login"))
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
context.HandleResponse();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Linq;
using System.Threading.Tasks;
using Altinn.Studio.Designer.Configuration;
using Altinn.Studio.Designer.Constants;
using Altinn.Studio.Designer.Helpers;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
Expand Down Expand Up @@ -38,6 +39,7 @@ private static IServiceCollection AddGiteaOidcAuthentication(this IServiceCollec
IConfiguration configuration, IWebHostEnvironment env)
{
var oidcSettings = FetchOidcSettingsFromConfiguration(configuration, env);
bool ansattPortenFeatureFlag = configuration.GetSection($"FeatureManagement:{StudioFeatureFlags.AnsattPorten}").Get<bool>();

services
.AddAuthentication(options =>
Expand All @@ -49,7 +51,8 @@ private static IServiceCollection AddGiteaOidcAuthentication(this IServiceCollec
{
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.SameSite = SameSiteMode.Strict;
options.Cookie.SameSite = ansattPortenFeatureFlag ? SameSiteMode.Lax : SameSiteMode.Strict;

options.Cookie.IsEssential = true;

options.ExpireTimeSpan = TimeSpan.FromMinutes(oidcSettings.CookieExpiryTimeInMinutes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ public class EndpointNameSyncEvaluator : IRequestSyncEvaluator
nameof(ProcessModelingController).Replace(RemoveControllerSuffix, string.Empty),
GenerateFrozenSet(
nameof(ProcessModelingController.AddDataTypeToApplicationMetadata),
nameof(ProcessModelingController.DeleteDataTypeFromApplicationMetadata)
nameof(ProcessModelingController.DeleteDataTypeFromApplicationMetadata),
nameof(ProcessModelingController.UpsertProcessDefinitionAndNotify),
nameof(ProcessModelingController.SaveProcessDefinitionFromTemplate)
)
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ public partial class DistributedCacheTable : Migration
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(SqlScriptsReadHelper.ReadSqlScript("DistributedCache/Up/01-setup-distributedcache-table.sql"));
migrationBuilder.Sql(SqlScriptsReadHelper.ReadSqlScript("DistributedCache/Up/02-setup-grants.sql"));
migrationBuilder.Sql(SqlScriptsReadHelper.ReadSqlScript("DistributedCache/Create/01-setup-distributedcache-table.sql"));
migrationBuilder.Sql(SqlScriptsReadHelper.ReadSqlScript("DistributedCache/Create/02-setup-grants.sql"));
}

/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(SqlScriptsReadHelper.ReadSqlScript("DistributedCache/Down/01-drop-distributedcache-table.sql"));
migrationBuilder.Sql(SqlScriptsReadHelper.ReadSqlScript("DistributedCache/Drop/01-drop-distributedcache-table.sql"));
}
}
}
Loading

0 comments on commit 069f95c

Please sign in to comment.