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

Fix role descriptor's hashCode, equals and isEmpty implementations #108255

Conversation

slobodanadamovic
Copy link
Contributor

@slobodanadamovic slobodanadamovic commented May 3, 2024

Added missing remoteClusterPermissions to hashCode, equals and isEmpty implementations.

Resolves #108253, #108285

Note: Marking as >non-issue since the PR that introduced remoteClusterPermissions is not released yet.

@slobodanadamovic slobodanadamovic added >non-issue :Security/Authorization Roles, Privileges, DLS/FLS, RBAC/ABAC Team:Security Meta label for security team labels May 3, 2024
@slobodanadamovic slobodanadamovic self-assigned this May 3, 2024
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-security (Team:Security)

@slobodanadamovic
Copy link
Contributor Author

slobodanadamovic commented May 3, 2024

Marking it as draft until I figure out why FileRolesStoreTests is failing now 🤨

@slobodanadamovic slobodanadamovic marked this pull request as draft May 3, 2024 15:18
@slobodanadamovic slobodanadamovic marked this pull request as ready for review May 3, 2024 15:47
@@ -107,15 +106,12 @@ public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RemoteClusterPermissionGroup that = (RemoteClusterPermissionGroup) o;
return Arrays.equals(clusterPrivileges, that.clusterPrivileges)
&& Arrays.equals(remoteClusterAliases, that.remoteClusterAliases)
&& Objects.equals(remoteClusterAliasMatcher, that.remoteClusterAliasMatcher);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had to remove remoteClusterAliasMatcher from both hashCode and equals implementation as it is always wrong due to the nature of Predicate. I'm thinking of not overriding them in StringMatcher to avoid confusion.

var first = StringMatcher.of("remote-*");
var second = StringMatcher.of("remote-*");
first.equals(second); // this will never be true because `Predicate` in `StringMatcher` is different object

Copy link
Contributor

@jakelandis jakelandis May 3, 2024

Choose a reason for hiding this comment

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

weird ... the unit tests extend AbstractXContentSerializingTestCase which in turn tests org.elasticsearch.test.AbstractWireTestCase#testConcurrentEquals.. which should catch things like that.

Taking a deeper look and adding this test:

   assertTrue(StringMatcher.of("*").equals(StringMatcher.of("*"))); //passes
   assertTrue(StringMatcher.of("foo").equals(StringMatcher.of("foo")));//fails

So those equality tests passed since i guess '*' is a special case.

I explicitly added the equals/hash to StringMatcher for this purpose (but only relied on tests from AbstractXContentSerializingTestCase of RemoteClusterPermissionGroup). Can you also remove the equals and hash code, or better update them to always return false with a comment to why (that is super trappy behavior).

Also, can you add a comment we explicitly omit the matcher ? It doesn't need be there and the only reason I included it in the equality was to avoid messages like this since most devs will just let the IDE generate these.

Also thanks for fixing the missing RoleDescriptor equality. I just ran the failing RoleDescriptor test a 1000 times and it only failed 3/1000 of the times (and got it to pass with 0/1000 failures) . We really shouldn't use that much randomization :/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you also remove the equals and hash code, or better update them to always return false with a comment to why (that is super trappy behavior).

Returning false would be wrong when the same object is compared. So I decided to remove them since this is the correct behaviour.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also thanks for fixing the missing RoleDescriptor equality. I just ran the failing RoleDescriptor test a 1000 times and it only failed 3/1000 of the times (and got it to pass with 0/1000 failures) . We really shouldn't use that much randomization :/

This was accidental. I only caught it because isEmpty was failing and I saw that equals was not correct. This then uncovered issue when reloading FileRolesStore.

return Arrays.equals(clusterPrivileges, that.clusterPrivileges)
&& Arrays.equals(remoteClusterAliases, that.remoteClusterAliases)
&& Objects.equals(remoteClusterAliasMatcher, that.remoteClusterAliasMatcher);
// The remoteClusterAliasMatcher is intentionally omitted from equals and hashCode implementation.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: thanks for the comment. however we probably don't need a full explanation, just a mention that it is omitted intentionally. I know it is really pedantic but long comments like this draw your attention as something important to read where all we really need to know is that we intentionally omitted those fields to avoid appearing as a bug and/or accidentally adding those fields here at some point.

Copy link
Contributor

@jakelandis jakelandis left a comment

Choose a reason for hiding this comment

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

LGTM

Thanks for fixing this.

@slobodanadamovic slobodanadamovic added the auto-merge Automatically merge pull request when CI checks pass (NB doesn't wait for reviews!) label May 6, 2024
@elasticsearchmachine elasticsearchmachine merged commit 0378a77 into elastic:main May 6, 2024
20 checks passed
@slobodanadamovic slobodanadamovic deleted the sa-fix-role-descriptor-equals-hashcode-isempty branch May 6, 2024 15:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-merge Automatically merge pull request when CI checks pass (NB doesn't wait for reviews!) >non-issue :Security/Authorization Roles, Privileges, DLS/FLS, RBAC/ABAC Team:Security Meta label for security team v8.15.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[CI] RoleDescriptorTests testIsEmpty failing
3 participants