Skip to content

[FEATURE] Update ACL Token List endpoint#592

Merged
marcin-krystianc merged 35 commits intoG-Research:masterfrom
MohamedM216:update-acl-token-list-endpoint
Apr 7, 2026
Merged

[FEATURE] Update ACL Token List endpoint#592
marcin-krystianc merged 35 commits intoG-Research:masterfrom
MohamedM216:update-acl-token-list-endpoint

Conversation

@MohamedM216
Copy link
Copy Markdown
Contributor

Description

[FEATURE] Update ACL Token List endpoint

Related Issues

#531

Additional Context

Checklist

Please make sure to check the following before submitting your pull request:

  • Did you read the contributing guidelines?
  • Did you update the docs?
  • Did you write any tests to validate this change?

@MohamedM216 MohamedM216 force-pushed the update-acl-token-list-endpoint branch from 7e56c96 to ce9d08c Compare March 20, 2026 20:06
{
Skip.If(string.IsNullOrEmpty(TestHelper.MasterToken));
var cutOffVersion = SemanticVersion.Parse("1.7.14");
Skip.If(AgentVersion == cutOffVersion, $"Node Identity is not supported in {AgentVersion}");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally, it is not a good idea to change (or remove) existing tests when implementing new features. It is easier to reason about backwards compatibility if we do not touch exisiting test code.

Consul/Token.cs Outdated
Comment on lines +60 to +102
public TokenEntry()
: this(string.Empty, string.Empty, Array.Empty<PolicyLink>(), Array.Empty<RoleLink>(), Array.Empty<ServiceIdentity>())
: this(string.Empty, string.Empty, Array.Empty<PolicyLink>(), Array.Empty<RoleLink>(), Array.Empty<ServiceIdentity>(), false, Array.Empty<TemplatedPolicy>(), Array.Empty<NodeIdentity>(), null, null)
{
}

public TokenEntry(string description, PolicyLink[] policies)
: this(string.Empty, description, policies, Array.Empty<RoleLink>(), Array.Empty<ServiceIdentity>())
: this(string.Empty, description, policies, Array.Empty<RoleLink>(), Array.Empty<ServiceIdentity>(), false, Array.Empty<TemplatedPolicy>(), Array.Empty<NodeIdentity>(), null, null)
{
}

public TokenEntry(string description, RoleLink[] roles)
: this(string.Empty, description, Array.Empty<PolicyLink>(), roles, Array.Empty<ServiceIdentity>())
: this(string.Empty, description, Array.Empty<PolicyLink>(), roles, Array.Empty<ServiceIdentity>(), false, Array.Empty<TemplatedPolicy>(), Array.Empty<NodeIdentity>(), null, null)
{
}

public TokenEntry(string description, ServiceIdentity[] serviceIdentities)
: this(string.Empty, description, Array.Empty<PolicyLink>(), Array.Empty<RoleLink>(), serviceIdentities)
: this(string.Empty, description, Array.Empty<PolicyLink>(), Array.Empty<RoleLink>(), serviceIdentities, false, Array.Empty<TemplatedPolicy>(), Array.Empty<NodeIdentity>(), null, null)
{
}

public TokenEntry(string accessorId, string description)
: this(accessorId, description, Array.Empty<PolicyLink>(), Array.Empty<RoleLink>(), Array.Empty<ServiceIdentity>())
: this(accessorId, description, Array.Empty<PolicyLink>(), Array.Empty<RoleLink>(), Array.Empty<ServiceIdentity>(), false, Array.Empty<TemplatedPolicy>(), Array.Empty<NodeIdentity>(), null, null)
{
}

public TokenEntry(string accessorId, string description, PolicyLink[] policies, RoleLink[] roles, ServiceIdentity[] serviceIdentities)
public TokenEntry(string accessorId, string description, PolicyLink[] policies, RoleLink[] roles, ServiceIdentity[] serviceIdentities, bool local, TemplatedPolicy[] templatedPolicies, NodeIdentity[] nodeIdentities, DateTime? expirationTime, TimeSpan? expirationTTL)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there's any need to update the constructors here. Ideally, we would remove them entirely, but that should be done in another PR, if at all.

Comment on lines +48 to +50
Task<QueryResult<TokenEntry[]>> List(string policy, string role, string serviceName, string authMethod, CancellationToken ct);
Task<QueryResult<TokenEntry[]>> List(string policy, string role, string serviceName, string authMethod);
Task<QueryResult<TokenEntry[]>> List(string policy, string role, string serviceName, string authMethod, QueryOptions q, CancellationToken ct = default);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a single overload would do:

Suggested change
Task<QueryResult<TokenEntry[]>> List(string policy, string role, string serviceName, string authMethod, CancellationToken ct);
Task<QueryResult<TokenEntry[]>> List(string policy, string role, string serviceName, string authMethod);
Task<QueryResult<TokenEntry[]>> List(string policy, string role, string serviceName, string authMethod, QueryOptions q, CancellationToken ct = default);
Task<QueryResult<TokenEntry[]>> List(string policy, string role, string serviceName, string authMethod, QueryOptions q = QueryOptions.Default, CancellationToken ct = default);

{
public class TemplatedPolicy
{
[JsonProperty("TemplateName")]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that this adds any value:

Suggested change
[JsonProperty("TemplateName")]

[JsonProperty("TemplateName")]
public string TemplateName { get; set; }

[JsonProperty("TemplateVariables")]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that this adds any value:

Suggested change
[JsonProperty("TemplateVariables")]

@MohamedM216 MohamedM216 force-pushed the update-acl-token-list-endpoint branch from 0a31b2a to 44a10c2 Compare March 24, 2026 08:53
@MohamedM216 MohamedM216 force-pushed the update-acl-token-list-endpoint branch from b03daab to 03cd119 Compare March 24, 2026 08:56
Comment on lines +341 to +344
if (matchingToken.Response != null)
await _client.Token.Delete(matchingToken.Response.AccessorID);
if (nonMatchingToken.Response != null)
await _client.Token.Delete(nonMatchingToken.Response.AccessorID);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If matchingToken or nonMatchingToken would be null, it would throw NRE. Thus, the if conditions don't make much sense here.
Let's just get rid of try/finally and complicated cleanup logic.

Comment on lines +2 to +3
// <copyright file="TemplatedPolicy.cs" company="PlayFab Inc">
// Copyright 2015 PlayFab Inc.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// <copyright file="TemplatedPolicy.cs" company="PlayFab Inc">
// Copyright 2015 PlayFab Inc.
// <copyright file="TemplatedPolicy.cs" company="G-Research Limited">
// Copyright 2020 G-Research Limited

Consul/Token.cs Outdated
Comment on lines +67 to +76
public bool ShouldSerializeTemplatedPolicies()
{
return TemplatedPolicies != null && TemplatedPolicies.Length > 0;
}

public bool ShouldSerializeNodeIdentities()
{
return NodeIdentities != null && NodeIdentities.Length > 0;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this methods are needed at all, please remove them:

Suggested change
public bool ShouldSerializeTemplatedPolicies()
{
return TemplatedPolicies != null && TemplatedPolicies.Length > 0;
}
public bool ShouldSerializeNodeIdentities()
{
return NodeIdentities != null && NodeIdentities.Length > 0;
}

Assert.NotEmpty(nonMatchingToken.Response.Description);

// List tokens filtering by the specific Policy ID
var filteredList = await _client.Token.List(policy.Response.ID, null, null, null);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only policyId is tested here, but other filters need to be tested as well.

@MohamedM216 MohamedM216 force-pushed the update-acl-token-list-endpoint branch from 81c540d to 28b79a2 Compare March 24, 2026 11:03
@MohamedM216 MohamedM216 force-pushed the update-acl-token-list-endpoint branch from 28b79a2 to c936662 Compare March 24, 2026 11:05
@MohamedM216 MohamedM216 force-pushed the update-acl-token-list-endpoint branch from 19a276f to 526fe66 Compare March 24, 2026 13:20
@marcin-krystianc
Copy link
Copy Markdown
Contributor

Filtering by AuthMethodTest is not yet tested. Look at the AuthMethodTest to see how to create and use auth methods

Ah, I realised that I pointed you to a broken test example. I've opened a PR to fix it #614. Please try using the code from that PR.

@MohamedM216 MohamedM216 force-pushed the update-acl-token-list-endpoint branch from b6fe02e to ed927a8 Compare March 27, 2026 09:52
@MohamedM216
Copy link
Copy Markdown
Contributor Author

MohamedM216 commented Mar 27, 2026

I've opened a PR to fix it #614. Please try using the code from that PR.

I tried to fix it following your approach, and it worked well for creating a new AuthMethod instance, but now it throws an exception when creating a new token: Consul.ConsulRequestException : Unexpected response, status code InternalServerError: AuthMethod field is disallowed outside of login

what does this message mean?
`

@marcin-krystianc
Copy link
Copy Markdown
Contributor

I've opened a PR to fix it #614. Please try using the code from that PR.

I tried to fix it following your approach, and it worked well for creating a new AuthMethod instance, but now it throws an exception when creating a new token: Consul.ConsulRequestException : Unexpected response, status code InternalServerError: AuthMethod field is disallowed outside of login

what does this message mean? `

Looking at the docs, it is not possible to set the authmethod, when creating the token -> https://developer.hashicorp.com/consul/api-docs/acl/tokens.

@marcin-krystianc
Copy link
Copy Markdown
Contributor

I realised that we need to create the token with AuthMethod.Login(), but that one is implemented but not working properly (#615).

@MohamedM216
Copy link
Copy Markdown
Contributor Author

Yes, that is what I realized too. I tried to use it but it didn't work, throws: Consul.ConsulRequestException : Unexpected response, status code MethodNotAllowed: method PUT not allowed
Should we finish #615 first, then continue the work here?

@marcin-krystianc
Copy link
Copy Markdown
Contributor

marcin-krystianc commented Mar 27, 2026

Yes, that is what I realized too. I tried to use it but it didn't work, throws: Consul.ConsulRequestException : Unexpected response, status code MethodNotAllowed: method PUT not allowed Should we finish #615 first, then continue the work here?

Yes, the #615 needs to be done first. I've pushed commit that kind of does this (just an attempt with an agentic tool). Feel free, use it as a starting point and open a PR to fix it properly.

@MohamedM216
Copy link
Copy Markdown
Contributor Author

There is a small nit in the previous PR, inside AuthMethod_Login(), positions of expected and actual fields were swapped by mistake.

Assert.Equal(res.Response.AuthMethod, authMethodEntry.Name);

So do you recommend to fix it here or open a separate PR for it?

@marcin-krystianc
Copy link
Copy Markdown
Contributor

There is a small nit in the previous PR, inside AuthMethod_Login(), positions of expected and actual fields were swapped by mistake.

Assert.Equal(res.Response.AuthMethod, authMethodEntry.Name);

So do you recommend to fix it here or open a separate PR for it?

Feel, free to open a PR with a fix for that.

Assert.NotEmpty(token3.Response.AccessorID);
Assert.NotEmpty(token3.Response.SecretID);
Assert.Equal(authMethodEntry.Name, token3.Response.AuthMethod);
#endif
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you group all the code into a single conditional compilation block? it will make it more readable.

@MohamedM216 MohamedM216 force-pushed the update-acl-token-list-endpoint branch from 96754bb to 8c4f4e0 Compare April 2, 2026 12:33
@MohamedM216 MohamedM216 force-pushed the update-acl-token-list-endpoint branch from d504119 to 7c3c29d Compare April 3, 2026 16:54
Co-authored-by: Marcin Krystianc <marcin.krystianc@gmail.com>
@marcin-krystianc marcin-krystianc merged commit 5b53e3f into G-Research:master Apr 7, 2026
120 checks passed
@MohamedM216 MohamedM216 deleted the update-acl-token-list-endpoint branch April 9, 2026 21:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants