Skip to content

Commit

Permalink
Implement dp so client, add write actions
Browse files Browse the repository at this point in the history
  • Loading branch information
elsand committed Sep 14, 2024
1 parent 3595123 commit 51af01a
Show file tree
Hide file tree
Showing 13 changed files with 5,534 additions and 32 deletions.
2 changes: 1 addition & 1 deletion Auth/DialogTokenAuthentication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public class EdDsaSecurityKeysCacheService : IHostedService, IDisposable
// which we could get from an injected IConfiguration/IOptions
private readonly List<string> _wellKnownEndpoints =
[
"https://localhost:7214/api/v1/.well-known/jwks.json",
//"https://localhost:7214/api/v1/.well-known/jwks.json",
"https://altinn-dev-api.azure-api.net/dialogporten/api/v1/.well-known/jwks.json",
"https://platform.tt02.altinn.no/dialogporten/api/v1/.well-known/jwks.json"
];
Expand Down
28 changes: 28 additions & 0 deletions Clients/ConsoleLoggingMessageHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace Digdir.BDB.Dialogporten.ServiceProvider.Clients;

public class ConsoleLoggingMessageHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// Log the request body
if (request.Content != null)
{
var requestBody = await request.Content.ReadAsStringAsync();
Console.WriteLine("Request:");
Console.WriteLine(requestBody);
}

// Send the request to the next handler in the pipeline
var response = await base.SendAsync(request, cancellationToken);

// Log the response body
if (response.Content != null)
{
var responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine("Response:");
Console.WriteLine(responseBody);
}

return response;
}
}
5,141 changes: 5,141 additions & 0 deletions Clients/DialogportenClient.cs

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions Clients/TokenGeneratorMessageHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Net.Http.Headers;
using Digdir.BDB.Dialogporten.ServiceProvider.Services;

namespace Digdir.BDB.Dialogporten.ServiceProvider.Clients;

public class TokenGeneratorMessageHandler : HttpClientHandler
{
private readonly ITokenGenerator _tokenGenerator;

public TokenGeneratorMessageHandler(ITokenGenerator tokenGenerator)
{
_tokenGenerator = tokenGenerator;
}

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var token = await _tokenGenerator.GetToken();
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
return await base.SendAsync(request, cancellationToken);
}
}
1 change: 1 addition & 0 deletions Clients/generate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
refitter https://altinn-dev-api.azure-api.net/dialogporten/swagger/v1/swagger.json --namespace "Digdir.BDB.Dialogporten.ServiceProvider.Clients" --tag Serviceowner --output DialogportenClient.cs --no-banner --cancellation-tokens --use-api-response
214 changes: 205 additions & 9 deletions Controllers/WriteGuiActionController.cs
Original file line number Diff line number Diff line change
@@ -1,30 +1,226 @@
using Digdir.BDB.Dialogporten.ServiceProvider.Clients;
using Digdir.BDB.Dialogporten.ServiceProvider.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;

namespace Digdir.BDB.Dialogporten.ServiceProvider.Controllers;

[ApiController]
[Route("guiaction/write/{xacmlaction?}")]
[Route("guiaction/write")]
[Authorize(AuthenticationSchemes = "DialogToken")]
[EnableCors("AllowedOriginsPolicy")]
public class WriteGuiActionController : Controller
{
[HttpPost]
public IActionResult Post(string? xacmlaction, [FromQuery] bool isDelayed = false)
private readonly IDialogporten _dialogporten;
private readonly IBackgroundTaskQueue _taskQueue;

public WriteGuiActionController(
IDialogporten dialogporten,
IBackgroundTaskQueue taskQueue)
{
return Ok();
_dialogporten = dialogporten;
_taskQueue = taskQueue;
}

[HttpPut]
public IActionResult Put(string? xacmlaction, [FromQuery] bool isDelayed = false)
[HttpPost]
public async Task<IActionResult> Post(
[FromQuery]string xacmlaction = "write",
[FromQuery]bool isDelayed = false,
[FromQuery]bool addActivity = false,
[FromQuery]bool addTransmission = false,
[FromQuery]bool addAttachment = false,
[FromQuery]DialogStatus_Values? setStatusTo = null,
[FromQuery]bool? setDialogGuiActionsToDeleteOnly = false)
{
return Ok();
if (!HasPermission(xacmlaction))
{
return Forbid();
}

var dialogId = GetDialogId();
var operations = new List<Operation>();

if (addActivity)
{
operations.Add(new Operation
{
Op = "add",
Path = "/activities/-",
Value = new CreateDialogDialogActivityDto
{
Type = DialogActivityType_Values.Information,
PerformedBy = new CreateDialogDialogActivityPerformedByActorDto
{
ActorType = ActorType_Values.PartyRepresentative,
ActorId = GetActorId()
},
Description = new List<LocalizationDto>
{
new () { LanguageCode = "en", Value = "Activity added by dialogporten-serviceprovider"}}
}
}
);
}

if (addTransmission)
{
operations.Add(new Operation
{
Op = "add",
Path = "/transmissions/-",
Value = new CreateDialogDialogTransmissionDto
{
Type = DialogTransmissionType_Values.Information,
Sender = new CreateDialogDialogTransmissionSenderActorDto
{
ActorType = ActorType_Values.PartyRepresentative,
ActorId = GetActorId()
},
Content = new CreateDialogDialogTransmissionContentDto
{
Title = new ContentValueDto
{
MediaType = "text/plain", Value = new List<LocalizationDto>
{
new()
{
LanguageCode = "en", Value = "Transmission title added by dialogporten-serviceprovider"
}
}
},
Summary = new ContentValueDto
{
MediaType = "text/plain", Value = new List<LocalizationDto>
{
new()
{
LanguageCode = "en", Value = "Transmission summary added by dialogporten-serviceprovider"
}
}
},
}
}
});
}

if (addAttachment)
{

}

if (setStatusTo.HasValue)
{
operations.Add(new Operation
{
Op = "replace",
Path = "/status",
Value = setStatusTo.Value
});
}

if (isDelayed)
{
_taskQueue.QueueBackgroundWorkItem(async token =>
{
await Task.Delay(1000, token);
var result = await _dialogporten.Patch(dialogId, operations, null, token);
if (!result.IsSuccessStatusCode)
{
Console.WriteLine(result.Error.Content);
}
});

return StatusCode(202);
}

await _dialogporten.Patch(dialogId, operations, null, CancellationToken.None);
return Created();


/*
var paginatedList = await _dialogporten.GetDialogListSO(
serviceResource: null!,
party: null!,
endUserId: null!,
extendedStatus: null!,
externalReference: null!,
status: null!,
createdAfter: null!,
createdBefore: null!,
updatedAfter: null!,
updatedBefore: null!,
dueAfter: null!,
dueBefore: null!,
visibleAfter: null!,
visibleBefore: null!,
process: null!,
search: null!,
searchLanguageCode: null!,
orderBy: null!,
continuationToken: null!,
limit: null!,
cancellationToken: CancellationToken.None
);
return Ok(paginatedList);
*/
}

[HttpDelete]
public IActionResult Delete(string? xacmlaction, [FromQuery] bool isDelayed = false)
public async Task<IActionResult> Delete(
[FromQuery]string xacmlaction = "write",
[FromQuery]bool isDelayed = false)
{
return Ok();

if (!HasPermission(xacmlaction))
{
return Forbid();
}

var dialogId = GetDialogId();

if (isDelayed)
{
// Start a background task to delete the dialog after 1 second
_taskQueue.QueueBackgroundWorkItem(async token =>
{
await Task.Delay(1000, token);
await _dialogporten.DeleteDialog(dialogId, null, token);
});

return StatusCode(202);
}

// Delete the dialog immediately
await _dialogporten.DeleteDialog(dialogId, null, CancellationToken.None);
return NoContent();
}

private bool HasPermission(string xacmlaction)
{
return User.Claims.Any(c => c.Type == "a" && c.Value.Split(';').Any(x => x == xacmlaction));
}

private Guid GetDialogId()
{
var dialogId = User.Claims.FirstOrDefault(c => c.Type == "i")?.Value;
if (dialogId is null)
{
throw new InvalidOperationException("Dialog id not found in token");
}

return Guid.Parse(dialogId);
}

public string GetActorId()
{
var actorId = User.Claims.FirstOrDefault(c => c.Type == "c")?.Value;
if (actorId is null)
{
throw new InvalidOperationException("Actor id not found in token");
}

return actorId;
}
}
1 change: 1 addition & 0 deletions Digdir.BDB.Dialogporten.ServiceProvider.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<PackageReference Include="Microsoft.AspNetCore.Cors" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.8" />
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="8.0.2" />
<PackageReference Include="Refit.HttpClientFactory" Version="7.1.2" />
<PackageReference Include="ScottBrady.IdentityModel" Version="4.0.0" />
<PackageReference Include="ScottBrady.IdentityModel.AspNetCore" Version="2.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
Expand Down
26 changes: 24 additions & 2 deletions Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using Digdir.BDB.Dialogporten.ServiceProvider.Auth;
using Digdir.BDB.Dialogporten.ServiceProvider.Clients;
using Digdir.BDB.Dialogporten.ServiceProvider.Services;
using Refit;

var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddUserSecrets<Program>();
Expand All @@ -8,10 +13,14 @@
builder.Services
.AddEndpointsApiExplorer()
.AddSwaggerGen()
.AddHttpClient()
.AddIdportenAuthentication(builder.Configuration)
.AddDialogTokenAuthentication()
.AddTransient<TokenGeneratorMessageHandler>()
.AddTransient<ConsoleLoggingMessageHandler>()
.AddSingleton<ITokenGenerator, TokenGenerator>()
.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>()
.AddHostedService<EdDsaSecurityKeysCacheService>()
.AddHostedService<QueuedHostedService>()
.AddCors(options =>
{
options.AddPolicy("AllowedOriginsPolicy", builder =>
Expand All @@ -23,7 +32,20 @@
.AllowAnyMethod()
.SetPreflightMaxAge(TimeSpan.FromMinutes(10));
});
});
})
.AddRefitClient<IDialogporten>(_ => new RefitSettings
{
ContentSerializer = new SystemTextJsonContentSerializer(new JsonSerializerOptions
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
})
})
.ConfigureHttpClient(configuration =>
{
configuration.BaseAddress = new Uri(builder.Configuration["Dialogporten:BaseUrl"]!);
})
.AddHttpMessageHandler<ConsoleLoggingMessageHandler>()
.ConfigurePrimaryHttpMessageHandler<TokenGeneratorMessageHandler>();

var app = builder.Build();

Expand Down
21 changes: 2 additions & 19 deletions Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,16 @@
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5130",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},

"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchBrowser": false,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7247;http://localhost:5130",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Loading

0 comments on commit 51af01a

Please sign in to comment.