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

39 informatiecategorieen toekennen #81

Merged
merged 42 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
a0a2713
chore: splits informatiecategorieen en organisaties endpoints
felixcicatt Oct 21, 2024
d9b97b4
feat: endpoint voor infocategorieen gefilterd voor gebruiker
felixcicatt Oct 21, 2024
b6bf90a
Merge branch 'main' into 39-informatiecategorieen-toekennen
nijmra Oct 21, 2024
bfd878c
feat: setup frontend
nijmra Oct 21, 2024
235458e
feat: gekoppelde informatiecategorieen wip
nijmra Oct 21, 2024
9e9735d
feat: mijn informatiecategorieen
nijmra Oct 22, 2024
3386438
Merge branch 'main' into 39-informatiecategorieen-toekennen
nijmra Oct 22, 2024
1d2b62c
feat: changed reponse type
nijmra Oct 22, 2024
6937de0
chore: API_URL config
nijmra Oct 22, 2024
ea038cc
feat: alert when not linked
nijmra Oct 22, 2024
0e47f9d
refactor: moved file
nijmra Oct 22, 2024
d6a441b
informatiecategorieen teruggeven in registrerencontroller
felixcicatt Oct 22, 2024
da8cd8f
cleanup
felixcicatt Oct 22, 2024
b422ce8
chore: removed listener, refactor
nijmra Oct 22, 2024
116f495
Merge branch '39-informatiecategorieen-toekennen' of https://github.c…
nijmra Oct 22, 2024
47d6552
validatie op informatiecategorieen
felixcicatt Oct 22, 2024
13fbd91
Merge branch '39-informatiecategorieen-toekennen' of https://github.c…
felixcicatt Oct 22, 2024
5eb147c
refactor: form validation composable
nijmra Oct 22, 2024
ca03839
Merge branch '39-informatiecategorieen-toekennen' of https://github.c…
nijmra Oct 22, 2024
8739df7
refactor: remove listeners
nijmra Oct 22, 2024
e20a0cd
feat: fixed required on group
nijmra Oct 22, 2024
5095d3c
chore: formatting
nijmra Oct 22, 2024
59df6f2
refactor: form validation
nijmra Oct 22, 2024
3eebff8
status meegeven vanaf de mock
felixcicatt Oct 22, 2024
c7c591b
refactor: small improvement
nijmra Oct 22, 2024
8f09f39
Merge branch '39-informatiecategorieen-toekennen' of https://github.c…
nijmra Oct 22, 2024
fa2b9d5
review comments wip
nijmra Oct 22, 2024
3106326
review comments
nijmra Oct 23, 2024
0271038
feat: checkbox group
nijmra Oct 23, 2024
d63fc89
feat: required check
nijmra Oct 23, 2024
0735be1
feat: simple invalid handler
nijmra Oct 23, 2024
37532a8
refactor: group listeners
nijmra Oct 23, 2024
8ddd5bf
chore: refactor @invalid @change
nijmra Oct 24, 2024
0b6e38d
refactor: moved style and conditional event handling
nijmra Oct 24, 2024
3ceef3c
Merge branch 'main' into 39-informatiecategorieen-toekennen
felixcicatt Oct 24, 2024
a69b316
cleanup
felixcicatt Oct 24, 2024
3575bae
Merge branch '39-informatiecategorieen-toekennen' of https://github.c…
felixcicatt Oct 24, 2024
8d322ea
https://github.com/GeneriekPublicatiePlatformWoo/Openbaar-Documenten-…
felixcicatt Oct 29, 2024
57eb852
chore: minder afhankelijkheid tussen GebruikersgroepDetails en Gebrui…
felixcicatt Oct 29, 2024
a0c32d0
cleanup
felixcicatt Oct 29, 2024
8cd3ea7
cleanup
felixcicatt Oct 29, 2024
48498ed
cleanup
felixcicatt Oct 29, 2024
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
6 changes: 3 additions & 3 deletions ODPC.Server/Apis/Odrc/OdrcClientFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ namespace ODPC.Apis.Odrc
{
public interface IOdrcClientFactory
{
HttpClient Create(OdpUser user, string handeling);
HttpClient Create(string handeling);
}

public class OdrcClientFactory(IHttpClientFactory httpClientFactory, IConfiguration config) : IOdrcClientFactory
public class OdrcClientFactory(IHttpClientFactory httpClientFactory, IConfiguration config, OdpcUser user) : IOdrcClientFactory
{
public HttpClient Create(OdpUser user, string? handeling)
public HttpClient Create(string? handeling)
{
var client = httpClientFactory.CreateClient();
client.BaseAddress = new(config["ODRC_BASE_URL"]!);
Expand Down
2 changes: 1 addition & 1 deletion ODPC.Server/Apis/Odrc/PagedResponseModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{
public class PagedResponseModel<T>
{
public List<T> results { get; set; }
public required IReadOnlyList<T> Results { get; set; }
public int Count { get; set; }
public string? Next { get; set; }
public string? Previous { get; set; }
Expand Down
13 changes: 4 additions & 9 deletions ODPC.Server/Apis/Odrc/WaardelijstResponseModel.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
using System.ComponentModel;
using System.Text.Json.Serialization;

namespace ODPC.Apis.Odrc
namespace ODPC.Apis.Odrc
{
public class WaardelijstResponseModel
{
[JsonPropertyName("uuid")]
public required string Id { get; set; }
[JsonPropertyName("naam")]
public required string Name { get; set; }
{
public required string Uuid { get; set; }
public required string Naam { get; set; }
}
}
6 changes: 3 additions & 3 deletions ODPC.Server/Authentication/AuthenticationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ public static void AddAuth(this IServiceCollection services, Action<AuthOptions>

services.AddHttpContextAccessor();

services.AddScoped<OdpUser>(s =>
services.AddScoped<OdpcUser>(s =>
{
var user = s.GetRequiredService<IHttpContextAccessor>().HttpContext?.User;
var isLoggedIn = user?.Identity?.IsAuthenticated ?? false;
var name = user?.FindFirst(nameClaimType)?.Value;
var id = user?.FindFirst(x => idClaimTypes.Contains(x.Type))?.Value;
var roles = user?.FindAll(roleClaimType).Select(x=> x.Value).ToArray() ?? [];
return new OdpUser { IsLoggedIn = isLoggedIn, FullName = name, Id = id, Roles = roles };
return new OdpcUser { IsLoggedIn = isLoggedIn, FullName = name, Id = id, Roles = roles };
});

var authBuilder = services.AddAuthentication(options =>
Expand Down Expand Up @@ -107,7 +107,7 @@ public static void AddAuth(this IServiceCollection services, Action<AuthOptions>
public static IEndpointRouteBuilder MapOdpcAuthEndpoints(this IEndpointRouteBuilder endpoints)
{
endpoints.MapGet("api/logoff", LogoffAsync).AllowAnonymous();
endpoints.MapGet("api/me", (OdpUser user) => user).AllowAnonymous();
endpoints.MapGet("api/me", (OdpcUser user) => user).AllowAnonymous();
endpoints.MapGet("api/challenge", ChallengeAsync).AllowAnonymous();

return endpoints;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace ODPC.Authentication
{
public record OdpUser
public record OdpcUser
{
public required bool IsLoggedIn { get; init; }
public required string? Id { get; init; }
Expand Down
27 changes: 27 additions & 0 deletions ODPC.Server/Features/GebruikerWaardelijstItemsService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Microsoft.EntityFrameworkCore;
using ODPC.Authentication;
using ODPC.Data;

namespace ODPC.Features
{
public interface IGebruikerWaardelijstItemsService
{
Task<IReadOnlyList<string>> GetAsync(CancellationToken token);
}

public class GebruikerWaardelijstItemsService(OdpcUser user, OdpcDbContext context) : IGebruikerWaardelijstItemsService
{
public async Task<IReadOnlyList<string>> GetAsync(CancellationToken token)
{
var groepIds = context.GebruikersgroepGebruikers
.Where(x => x.GebruikerId == user.Id)
.Select(x => x.GebruikersgroepUuid);

return await context.GebruikersgroepWaardelijsten
.Where(x => groepIds.Contains(x.GebruikersgroepUuid))
.Select(x => x.WaardelijstId)
.Distinct()
.ToListAsync(token);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Text.Json.Nodes;
using Microsoft.AspNetCore.Mvc;
using ODPC.Apis.Odrc;

namespace ODPC.Features.Informatiecategorieen.AlleInformatiecategorieen
{
[ApiController]
public class InformatiecategorieenController(IOdrcClientFactory clientFactory) : ControllerBase
{
[HttpGet("api/v1/informatiecategorieen")]
public async Task<IActionResult> Get([FromQuery] string? page, CancellationToken token)
{
//infocategorien ophalen uit het ODRC
using var client = clientFactory.Create("Alle informatiecategorieen ophalen");
var json = await client.GetFromJsonAsync<PagedResponseModel<JsonNode>>("/api/v1/informatiecategorieen?page=" + page, token);
if (json != null)
{
json.Previous = GetPathAndQuery(json.Previous);
json.Next = GetPathAndQuery(json.Next);
}
return Ok(json);
}

private static string? GetPathAndQuery(string? url) => Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out var uri)
? uri.PathAndQuery
: url;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Runtime.CompilerServices;
using System.Text.Json.Nodes;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using ODPC.Apis.Odrc;

namespace ODPC.Features.Informatiecategorieen.MijnInformatiecategorieen
{
[ApiController]
public class MijnInformatiecategorieenController(IOdrcClientFactory clientFactory, IGebruikerWaardelijstItemsService waardelijstItemsService) : ControllerBase
{
[HttpGet("api/v1/mijn-informatiecategorieen")]
public async IAsyncEnumerable<JsonObject> Get([EnumeratorCancellation] CancellationToken token)
{
var categorieen = await waardelijstItemsService.GetAsync(token);

if (categorieen.Count == 0) yield break;

using var client = clientFactory.Create("Eigen informatiecategorieen ophalen");
var url = "api/v1/informatiecategorieen";

// omdat we zelf moeten filteren obv van de waardelijstitems waar de gebruiker toegang toe heeft,
// kunnen we geen paginering gebruiker. we lopen door alle pagina's van de ODRC
while (!string.IsNullOrWhiteSpace(url))
{
var page = await client.GetFromJsonAsync<PagedResponseModel<JsonObject>>(url, token) ?? new() { Results = [] };
foreach (var item in page.Results)
{
if (item["uuid"]?.GetValue<string>() is string uuid && categorieen.Contains(uuid))
{
yield return item;
}
}
url = page?.Next;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Microsoft.AspNetCore.Mvc;
using ODPC.Apis.Odrc;

namespace ODPC.Features.Organisaties.AlleOrganisaties
{
[ApiController]
public class OrganisatiesController : ControllerBase
{
[HttpGet("api/v1/organisaties")]
public IActionResult Get([FromQuery] string? page) => Ok(new PagedResponseModel<WaardelijstResponseModel>
{
Results = OrganisatiesMock.Organisaties.Values.ToList(),
Count = OrganisatiesMock.Organisaties.Count,
});
}
}
13 changes: 13 additions & 0 deletions ODPC.Server/Features/Organisaties/OrganisatiesMock.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using ODPC.Apis.Odrc;

namespace ODPC.Features.Organisaties
{
public class OrganisatiesMock
{
public static readonly Dictionary<string, WaardelijstResponseModel> Organisaties = new WaardelijstResponseModel[]
{
new() { Uuid = "8f939b51-dad3-436d-a5fa-495b42317d64", Naam = "Organisatie 2" },
new() { Uuid = "5c14e7e2-00a2-4990-adbb-7290cd89fb6e", Naam = "Organisatie 3" }
}.ToDictionary(x => x.Uuid);
}
}
3 changes: 2 additions & 1 deletion ODPC.Server/Features/Publicaties/Publicatie.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public class Publicatie
public string? VerkorteTitel { get; set; }
public string? Omschrijving { get; set; }
public DateTime Registratiedatum { get; set; }
public string Status { get; set; }
public string? Status { get; set; }
public List<string>? GekoppeldeInformatiecategorieen { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@
namespace ODPC.Features.Publicaties.PublicatieBijwerken
{
[ApiController]
public class PublicatieBijwerkenController : ControllerBase
public class PublicatieBijwerkenController(IGebruikerWaardelijstItemsService waardelijstItemsService) : ControllerBase
{
[HttpPut("api/v1/publicaties/{uuid}")]
public IActionResult Put(Guid uuid, Publicatie publicatie)
public async Task<IActionResult> Put(Guid uuid, Publicatie publicatie, CancellationToken token)
{
var categorieen = await waardelijstItemsService.GetAsync(token);
mstokericatt marked this conversation as resolved.
Show resolved Hide resolved

if (publicatie.GekoppeldeInformatiecategorieen != null && publicatie.GekoppeldeInformatiecategorieen.Any(c => !categorieen.Contains(c)))
{
ModelState.AddModelError(nameof(publicatie.GekoppeldeInformatiecategorieen), "Gebruiker is niet geautoriseerd voor deze informatiecategorieën");
return BadRequest(ModelState);
}

PublicatiesMock.Publicaties[uuid] = publicatie;
return Ok(publicatie);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,40 @@
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc;
using ODPC.Apis.Odrc;
using ODPC.Authentication;
using ODPC.Config;

namespace ODPC.Features.Publicaties.PublicatieRegistreren
{
[ApiController]
public class PublicatieRegistrerenController(OdpUser user, IOdrcClientFactory clientFactory) : ControllerBase
public class PublicatieRegistrerenController(IOdrcClientFactory clientFactory, IGebruikerWaardelijstItemsService waardelijstItemsService) : ControllerBase
{
private readonly IOdrcClientFactory _clientFactory = clientFactory;

[HttpPost("api/v1/publicaties")]
public async Task<IActionResult> Post(Publicatie publicatie)
public async Task<IActionResult> Post(Publicatie publicatie, CancellationToken token)
{
publicatie.Uuid = Guid.NewGuid();
publicatie.Registratiedatum = DateTime.Now;
var categorieen = await waardelijstItemsService.GetAsync(token);

//de mock laten we er nog even in totdat ook het ophalen van gegevens via het register verloopt
PublicatiesMock.Publicaties[publicatie.Uuid] = publicatie;
if (publicatie.GekoppeldeInformatiecategorieen != null && publicatie.GekoppeldeInformatiecategorieen.Any(c => !categorieen.Contains(c)))
{
ModelState.AddModelError(nameof(publicatie.GekoppeldeInformatiecategorieen), "Gebruiker is niet geautoriseerd voor deze informatiecategorieën");
return BadRequest(ModelState);
}

var client = _clientFactory.Create(user, "Publicatie geregistreerd");
var client = _clientFactory.Create("Publicatie geregistreerd");
var response = await client.PostAsJsonAsync("/api/v1/publicaties", publicatie, token);

var response = await client.PostAsJsonAsync("/api/v1/publicaties", publicatie, new CancellationToken());

response.EnsureSuccessStatusCode();

var responseBody = await response.Content.ReadAsStringAsync();
var viewModel = await response.Content.ReadFromJsonAsync<Publicatie>(token);

var viewModel = JsonSerializer.Deserialize<Publicatie>(responseBody, JsonSerialization.Options);
// TODO deze regel kan eraf als deze story is geimplementeerd: https://github.com/GeneriekPublicatiePlatformWoo/registratie-component/issues/48
viewModel!.GekoppeldeInformatiecategorieen = publicatie.GekoppeldeInformatiecategorieen;

// TODO deze regel kan eraf als deze story is geimplementeerd: https://github.com/GeneriekPublicatiePlatformWoo/registratie-component/issues/49
viewModel!.Status = publicatie.Status;

// TODO de mock laten we er nog even in totdat ook het ophalen van gegevens via het register verloopt: https://github.com/GeneriekPublicatiePlatformWoo/Openbaar-Documenten-Publicatie-Component/issues/68
PublicatiesMock.Publicaties[viewModel!.Uuid] = viewModel;

return Ok(viewModel);
}

}
}
Loading