Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add EU endpoints for seen log #607

Merged
merged 3 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 176 additions & 8 deletions docs/swagger/V1/swagger.verified.json
Original file line number Diff line number Diff line change
Expand Up @@ -1486,6 +1486,126 @@
]
}
},
"/api/v1/enduser/dialogs/{dialogId}/seenlog": {
"get": {
"tags": [
"Enduser"
],
"summary": "Gets a single dialog seen log record",
"description": "Gets a single dialog seen log record. For more information see the documentation (link TBD).",
"operationId": "SearchDialogSeenLog",
"parameters": [
{
"name": "dialogId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "guid"
}
}
],
"responses": {
"401": {
"description": "Missing or invalid authentication token. Requires a Maskinporten-token with the scope \"digdir:dialogporten\"."
},
"403": {
"description": "Forbidden"
},
"200": {
"description": "Successfully returned the dialog seen log record.",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SearchDialogSeenLogDto"
}
}
}
}
},
"404": {
"description": "The given dialog ID or dialog element ID was not found or was already deleted.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
},
"security": [
{
"JWTBearerAuth": []
}
]
}
},
"/api/v1/enduser/dialogs/{dialogId}/seenlog/{seenLogId}": {
"get": {
"tags": [
"Enduser"
],
"summary": "Gets a single dialog seen log record",
"description": "Gets a single dialog seen log record. For more information see the documentation (link TBD).",
"operationId": "GetDialogSeenLog",
"parameters": [
{
"name": "dialogId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "guid"
}
},
{
"name": "seenLogId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "guid"
}
}
],
"responses": {
"401": {
"description": "Missing or invalid authentication token. Requires a Maskinporten-token with the scope \"digdir:dialogporten\"."
},
"403": {
"description": "Forbidden"
},
"200": {
"description": "Successfully returned the dialog seen log record.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GetDialogSeenLogDto"
}
}
}
},
"404": {
"description": "The given dialog ID or dialog element ID was not found or was already deleted.",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
}
},
"security": [
{
"JWTBearerAuth": []
}
]
}
},
"/api/v1/enduser/dialogs": {
"get": {
"tags": [
Expand Down Expand Up @@ -2606,7 +2726,7 @@
"seenSinceLastUpdate": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SearchDialogDialogSeenRecordDtoSO"
"$ref": "#/components/schemas/SearchDialogDialogSeenLogDtoSO"
}
}
}
Expand All @@ -2626,7 +2746,7 @@
}
}
},
"SearchDialogDialogSeenRecordDtoSO": {
"SearchDialogDialogSeenLogDtoSO": {
"type": "object",
"additionalProperties": false,
"properties": {
Expand Down Expand Up @@ -2756,7 +2876,7 @@
"seenSinceLastUpdate": {
"type": "array",
"items": {
"$ref": "#/components/schemas/GetDialogDialogSeenRecordDtoSO"
"$ref": "#/components/schemas/GetDialogDialogSeenLogDtoSO"
}
}
}
Expand Down Expand Up @@ -2998,7 +3118,7 @@
}
}
},
"GetDialogDialogSeenRecordDtoSO": {
"GetDialogDialogSeenLogDtoSO": {
"type": "object",
"additionalProperties": false,
"properties": {
Expand Down Expand Up @@ -3450,6 +3570,54 @@
}
}
},
"SearchDialogSeenLogDto": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"format": "guid"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"endUserIdHash": {
"type": "string"
},
"endUserName": {
"type": "string",
"nullable": true
},
"isCurrentEndUser": {
"type": "boolean"
}
}
},
"GetDialogSeenLogDto": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"format": "guid"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"endUserIdHash": {
"type": "string"
},
"endUserName": {
"type": "string",
"nullable": true
},
"isCurrentEndUser": {
"type": "boolean"
}
}
},
"PaginatedListOfSearchDialogDto": {
"type": "object",
"additionalProperties": false,
Expand Down Expand Up @@ -3536,7 +3704,7 @@
"seenSinceLastUpdate": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SearchDialogDialogSeenRecordDto"
"$ref": "#/components/schemas/SearchDialogDialogSeenLogDto"
}
}
}
Expand Down Expand Up @@ -3602,7 +3770,7 @@
}
}
},
"SearchDialogDialogSeenRecordDto": {
"SearchDialogDialogSeenLogDto": {
"type": "object",
"additionalProperties": false,
"properties": {
Expand Down Expand Up @@ -3723,7 +3891,7 @@
"seenSinceLastUpdate": {
"type": "array",
"items": {
"$ref": "#/components/schemas/GetDialogDialogSeenRecordDto"
"$ref": "#/components/schemas/GetDialogDialogSeenLogDto"
}
}
}
Expand Down Expand Up @@ -3967,7 +4135,7 @@
}
}
},
"GetDialogDialogSeenRecordDto": {
"GetDialogDialogSeenLogDto": {
"type": "object",
"additionalProperties": false,
"properties": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public static IServiceCollection AddApplication(this IServiceCollection services
.AddScoped<IDialogTokenGenerator, DialogTokenGenerator>()

// Transient
.AddTransient<IStringHasher, RandomSaltStringHasher>()
.AddTransient<IStringHasher, PersistantRandomSaltStringHasher>()
.AddTransient<IUserOrganizationRegistry, UserOrganizationRegistry>()
.AddTransient<IUserResourceRegistry, UserResourceRegistry>()
.AddTransient<IUserNameRegistry, UserNameRegistry>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ internal interface IStringHasher
string? Hash(string? personIdentifier);
}

internal class RandomSaltStringHasher : IStringHasher
internal class PersistantRandomSaltStringHasher : IStringHasher
{
private const int SaltSize = 16;
private readonly Lazy<byte[]> _lazySalt = new(() => RandomNumberGenerator.GetBytes(SaltSize));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Digdir.Domain.Dialogporten.Application.Common.Extensions;
using Digdir.Domain.Dialogporten.Application.Externals;
Expand All @@ -8,9 +9,11 @@ namespace Digdir.Domain.Dialogporten.Application.Common;
public interface IUserNameRegistry
{
bool TryGetCurrentUserPid([NotNullWhen(true)] out string? userPid);
Task<string?> GetCurrentUserName(string personalIdentificationNumber, CancellationToken cancellationToken);
Task<UserInformation?> GetUserInformation(CancellationToken cancellationToken);
}

public record UserInformation(string UserPid, string? UserName);

public class UserNameRegistry : IUserNameRegistry
{
private readonly IUser _user;
Expand All @@ -24,12 +27,22 @@ public UserNameRegistry(IUser user, INameRegistry nameRegistry)

public bool TryGetCurrentUserPid([NotNullWhen(true)] out string? userPid) => _user.TryGetPid(out userPid);

public async Task<string?> GetCurrentUserName(string personalIdentificationNumber, CancellationToken cancellationToken) =>
await _nameRegistry.GetName(personalIdentificationNumber, cancellationToken);
public async Task<UserInformation?> GetUserInformation(CancellationToken cancellationToken)
{
if (!TryGetCurrentUserPid(out var userPid))
{
return null;
}

var userName = await _nameRegistry.GetName(userPid, cancellationToken);
return new(userPid, userName);
}
}

internal sealed class LocalDevelopmentUserNameRegistryDecorator : IUserNameRegistry
{
private const string LocalDevelopmentUserPid = "Local Development User";

private readonly IUserNameRegistry _userNameRegistry;

public LocalDevelopmentUserNameRegistryDecorator(IUserNameRegistry userNameRegistry)
Expand All @@ -40,6 +53,8 @@ public LocalDevelopmentUserNameRegistryDecorator(IUserNameRegistry userNameRegis
public bool TryGetCurrentUserPid([NotNullWhen(true)] out string? userPid) =>
_userNameRegistry.TryGetCurrentUserPid(out userPid);

public async Task<string?> GetCurrentUserName(string personalIdentificationNumber, CancellationToken cancellationToken)
=> await Task.FromResult("Local Development User");
public Task<UserInformation?> GetUserInformation(CancellationToken cancellationToken)
=> _userNameRegistry.TryGetCurrentUserPid(out var userPid)
? Task.FromResult<UserInformation?>(new UserInformation(userPid!, LocalDevelopmentUserPid))
: throw new UnreachableException();
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public interface IDialogDbContext

DbSet<OutboxMessage> OutboxMessages { get; }
DbSet<OutboxMessageConsumer> OutboxMessageConsumers { get; }
DbSet<DialogSeenRecord> DialogSeenLog { get; }
DbSet<DialogSeenLog> DialogSeenLog { get; }

/// <summary>
/// Validate a property on the <typeparamref name="TEntity"/> using a lambda
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Digdir.Domain.Dialogporten.Application.Features.V1.EndUser.DialogSeenLogs.Queries.Get;

public class GetDialogSeenLogDto
{
public Guid Id { get; set; }
public DateTimeOffset CreatedAt { get; set; }

public string EndUserIdHash { get; set; } = null!;

public string? EndUserName { get; set; }

public bool IsCurrentEndUser { get; set; }
}
Loading