Skip to content

Commit

Permalink
Change deserialization of tokens query to match standard (#952)
Browse files Browse the repository at this point in the history
* fix: make GenericArrayModelBinder actually generic

* feat: use correct deserialization format
  • Loading branch information
tnotheis authored Nov 27, 2024
1 parent a9aea02 commit 08b3a25
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class GenericArrayModelBinder : IModelBinder
public Task BindModelAsync(ModelBindingContext bindingContext)
{
var elementType = bindingContext.ModelType.GetElementType()!;
var templates = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(elementType))!;
var items = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(elementType))!;
var query = bindingContext.HttpContext.Request.Query;

for (var i = 0; ; i++)
Expand All @@ -29,7 +29,7 @@ public Task BindModelAsync(ModelBindingContext bindingContext)
var queryValueFound = false;
foreach (var property in properties)
{
var key = $"templates.{i}.{property.Name.ToLower()}";
var key = $"{bindingContext.ModelName}.{i}.{property.Name.ToLower()}";

if (!query.TryGetValue(key, out var queryValue))
continue;
Expand All @@ -49,14 +49,14 @@ public Task BindModelAsync(ModelBindingContext bindingContext)
if (!queryValueFound)
break;

templates.Add(instance);
items.Add(instance);
}

var resultArray = Array.CreateInstance(elementType, templates.Count);
var resultArray = Array.CreateInstance(elementType, items.Count);

for (var i = 0; i < templates.Count; i++)
for (var i = 0; i < items.Count; i++)
{
resultArray.SetValue(templates[i], i);
resultArray.SetValue(items[i], i);
}

bindingContext.Result = ModelBindingResult.Success(resultArray);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,10 @@ namespace Backbone.Modules.Tokens.ConsumerApi.Controllers;
public class TokensController : ApiControllerBase
{
private readonly ApplicationOptions _options;
private readonly JsonSerializerOptions _jsonSerializerOptions;

public TokensController(IMediator mediator, IOptions<ApplicationOptions> options, IOptions<JsonOptions> jsonOptions) : base(mediator)
public TokensController(IMediator mediator, IOptions<ApplicationOptions> options) : base(mediator)
{
_options = options.Value;
_jsonSerializerOptions = jsonOptions.Value.JsonSerializerOptions;
}

[HttpPost]
Expand All @@ -52,28 +50,14 @@ public async Task<IActionResult> GetToken([FromRoute] string id, [FromQuery] byt

[HttpGet]
[ProducesResponseType(typeof(PagedHttpResponseEnvelope<TokenDTO>), StatusCodes.Status200OK)]
public async Task<IActionResult> ListTokens([FromQuery] PaginationFilter paginationFilter, [FromQuery] string? tokens,
public async Task<IActionResult> ListTokens([FromQuery] PaginationFilter paginationFilter, [FromQuery] ListTokensQueryItem[]? tokens,
[FromQuery] IEnumerable<string> ids, CancellationToken cancellationToken)
{
List<ListTokensQueryItem>? tokenQueryItems;
// We keep this code for backwards compatibility reasons. In a few months the `templates`
// parameter will become required, and the fallback to `ids` will be removed.
tokens = tokens is { Length: > 0 } ? tokens : ids.Select(id => new ListTokensQueryItem { Id = id }).ToArray();

if (tokens != null)
{
try
{
tokenQueryItems = JsonSerializer.Deserialize<List<ListTokensQueryItem>>(tokens, _jsonSerializerOptions);
}
catch (JsonException ex)
{
throw new ApplicationException(GenericApplicationErrors.Validation.InputCannotBeParsed(ex.Message));
}
}
else
{
tokenQueryItems = ids.Select(id => new ListTokensQueryItem { Id = id }).ToList();
}

var request = new ListTokensQuery(paginationFilter, tokenQueryItems);
var request = new ListTokensQuery(paginationFilter, tokens);

paginationFilter.PageSize ??= _options.Pagination.DefaultPageSize;

Expand Down
19 changes: 15 additions & 4 deletions Sdks/ConsumerApi.Sdk/src/Endpoints/Tokens/TokensEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,23 @@ public async Task<ApiResponse<ListTokensResponse>> ListTokens(PaginationFilter?

public async Task<ApiResponse<ListTokensResponse>> ListTokens(IEnumerable<ListTokensQueryItem> queryItems, PaginationFilter? pagination = null)
{
return await _client
var request = _client
.Request<ListTokensResponse>(HttpMethod.Get, $"api/{API_VERSION}/Tokens")
.Authenticate()
.WithPagination(pagination)
.AddQueryParameter("tokens", queryItems)
.Execute();
.WithPagination(pagination);

var i = 0;
foreach (var queryItem in queryItems)
{
request.AddQueryParameter($"tokens.{i}.id", queryItem.Id);

if (queryItem.Password != null)
request.AddQueryParameter($"tokens.{i}.password", queryItem.Password);

i++;
}

return await request.Execute();
}

public async Task<ApiResponse<Token>> GetTokenUnauthenticated(string id)
Expand Down

0 comments on commit 08b3a25

Please sign in to comment.