-
Notifications
You must be signed in to change notification settings - Fork 290
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
test(grants): GrantsForUsers tests for Group resource #5443
base: llb-normalized-grants
Are you sure you want to change the base?
test(grants): GrantsForUsers tests for Group resource #5443
Conversation
6bdc21d
to
34114df
Compare
repo := iam.TestRepo(t, conn, wrap) | ||
kmsCache := kms.TestKms(t, conn, wrap) | ||
|
||
grant := "ids=*;type=*;actions=*" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the grant, if we're testing against the groups
resource, we should set set the grant to look like ids=*;type=group;actions=*
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also think we should have multiple grants and multiple roles so we can have multiple grantTuples and assert it's what we expect
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated these tests to only test against the Groups resource
res: perms.Resource{ | ||
ScopeId: directGrantProj1a.PublicId, | ||
Id: "cs_abcd1234", | ||
Type: resource.Credential, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we hae dedicated tests for Groups
resource
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do now 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also have tests against the Groups resource here: Test_MarshalingAndCloning
34114df
to
79b9462
Compare
e7cb846
to
0b6ee1a
Compare
directGrantOrg1, directGrantProj1a, directGrantProj1b := iam.SetupDirectGrantScopes(t, conn, repo) | ||
directGrantOrg1Role := iam.TestRole(t, conn, directGrantOrg1.PublicId) | ||
iam.TestUserRole(t, conn, directGrantOrg1Role.PublicId, user.PublicId) | ||
directGrantOrg1RoleGrant1 := "ids=*;type=group;actions=*" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this direct association only test group
resource? The title of the test just says TestGrantsForUser_DirectAssociation
and the grantString is has type set to "ids=*;type=group;actions=*"
. When we want to test other resource, are you going to use the same test which builds a grantString for each resource or will they be separated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes - only the group resource for now. This function should probably be renamed to something Group-specific if we don't plan on adding subtests for the other differently scoped resources (e.g. Auth Methods, Targets).
I figured we could create a separate function for each differently scoped resource since the scope combinations and actions will be different. For instance - Auth Methods apply to global
and org
scopes only, so we don't need to setup any project
scopes like we do here.
RoleScopeId: directGrantOrg1.PublicId, | ||
RoleParentScopeId: scope.Global.String(), | ||
GrantScopeIds: globals.GrantScopeThis, | ||
Grants: strings.Join([]string{directGrantOrg1RoleGrant1, directGrantOrg1RoleGrant2}, "^"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does ^
do or signify?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like ^
is used as a delimiter to split grant strings/grant scope ids.
The grantsForUser
query pulls in multiple grant strings/grant scope ids, aggregating them into a single string using ^
as a delimiter. In the code, we use strings.Split(..., "^")
to split grant strings/grant scope ids into atomic pieces.
iam.WithGrantScopeIds([]string{ | ||
globals.GrantScopeChildren, | ||
})) | ||
iam.TestUserRole(t, conn, childGrantGlobalRole.PublicId, globals.AnyAuthenticatedUserId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not set the userId
here instead of assigning the role to u_auth
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oof, I didn't notice I was assigning u_auth
to the role here instead of the test user I created.
Pushed a change to use user.PublicId
instead of u_auth
Grants: childGrantGlobalRoleGrant, | ||
}, | ||
} | ||
for i, tuple := range expMultiGrantTuples { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we assign any roles to a different user to user it does not get returned?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realized that did not make sense. I mean do we assign roles to a different user to ensure the only the grants for that 1 particular user gets returned?
In other words, how do we ensure do we have other non-applicable grants that are created but should not be returned because they are not applicable to the user
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good test case - I'll add another user with different grants to each test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK -- I added a second user/group/managed group to each test. I assign them some grants & check that their grants are separate from the grants assigned to the original user/group/managed group
b70e1b4
to
621ecda
Compare
621ecda
to
17ad5c3
Compare
Ensure that non-applicable grants should not be returned because they are not applicable to the user
17ad5c3
to
e8bc074
Compare
@@ -389,3 +394,2026 @@ func TestGrantsForUserRandomized(t *testing.T) { | |||
", roles from ldap managed groups", rolesFromLdapManagedGroups) | |||
} | |||
} | |||
|
|||
func TestGrantsForUser_DirectAssociation(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The general feedback I have on the tests is the setup for the test. It looks like we setup everything in the beginning and then invoke tests below for assertions. I think because we're setting up everything before hand, we have to create a lot of roles and grants.
What do you think about grouping this some more? Maybe have a table test with a setup function like we have here. In the setup
, we can create roles relevant for that function and name the test as well so it's easier for anyone looking at it to follow and understand the test coverage we have. Maybe there might be another way of grouping this better.
I also see some overlap here with @bosorawis PR where Bo has created some helper functions for creating roles and assigning grants to it. For example this for Direct Association, this for Group Association and this for Managed Groups. Bo's PR is still under review and subject to change but I think we could share and use some of those helper functions here to reduce the code we have here and may decide to set things up slightly differently if necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about grouping this some more? Maybe have a table test with a setup function like we have here. In the setup, we can create roles relevant for that function and name the test as well so it's easier for anyone looking at it to follow and understand the test coverage we have.
Pushed what I have so far -- 2882623
Grouped the role granting logic & role-user association call together into a helper function:
func grantRoleAndAssociate(t *testing.T, conn *db.DB, roleId string, roleAssociationFunc func(), grants ...string) {
t.Helper()
for _, grant := range grants {
iam.TestRoleGrant(t, conn, roleId, grant)
}
roleAssociationFunc()
}
The general feedback I have on the tests is the setup for the test. It looks like we setup everything in the beginning and then invoke tests below for assertions. I think because we're setting up everything before hand, we have to create a lot of roles and grants.
...
Maybe there might be another way of grouping this better.
I don't think I can group things together much more with the current test structure. Current top-level test setup:
- Create a few scopes
- Create a couple roles at each scope
- Grant each role
- Associate a user to each role
- Create test cases. For each test case:
- Do a single, big diff/comparison
If I refactor to look more like the other tests, they might look like this:
- Create a few scopes
- Create test cases. For each test case:
- Create a role at a scope
- Grant the role
- Associate a user to the role
- Do a single, small diff/comparison
This might be easier to follow since we'd be able to name each test case after the relationship (e.g. t.Run("direct grant org 1 role 1", ...)
, t.Run("direct grant project 1a role 1", ...)
, etc.). However, I think we'd lose the ability to assign different roles to multiple users in a test case (mentioned in an earlier comment). There might be a way around this with maps, albeit with added complexity
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see what you mean with the way the tests are setup. I think this already looks better. Grouping it might be complicated after looking at the tests some more
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, after looking at this more I realized my tests assert on the created role's PublicId
(via GrantTuple.RoleId
) whereas TestUserDirectGrantsFunc()
doesn't return the id(s) its created role(s)
4c919f4
to
2882623
Compare
2882623
to
debac4a
Compare
Goal: Write direct & indirect tests for the GrantsForUser function against the Group resource
I created one test for each case: one direct test, one group test, and one managed group test (performed via OIDC). All tests contain grants against the Group resource (and its associated actions)