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

Bug 1906898: Missing User RoleBindings in the Project Access Web UI #7488

Merged
merged 1 commit into from Jan 12, 2021

Conversation

debsmita1
Copy link
Contributor

@debsmita1 debsmita1 commented Dec 9, 2020

Fixes:
https://issues.redhat.com/browse/ODC-4989
Closes #6836

Analysis / Root cause:
The User info is added in the subjects property of the RoleBinding CR. This subjects is of type array and can have multiple users assigned the same role. So, previously while fetching the users from all the Role Bindings only the first element of subjects was being read

Solution Description:

  • go over all the role binding subjects to fetch users
  • if the role of one of the grouped subjects is changed, then it is deleted from the grouped subjects & a new role binding is created for that user

Screen shots / Gifs for design review:
pa

Unit test coverage report:
Added new tests

Test setup:
NA

Browser conformance:

  • Chrome
  • Firefox
  • Safari
  • Edge

@debsmita1
Copy link
Contributor Author

/kind bug

@openshift-ci-robot openshift-ci-robot added the component/dev-console Related to dev-console label Dec 9, 2020
@openshift-ci-robot openshift-ci-robot added the kind/bug Categorizes issue or PR as related to a bug. label Dec 9, 2020
@debsmita1 debsmita1 changed the title Missing User RoleBindings in the Project Access Web UI Bug 1906898: Missing User RoleBindings in the Project Access Web UI Dec 11, 2020
@openshift-ci-robot openshift-ci-robot added the bugzilla/severity-medium Referenced Bugzilla bug's severity is medium for the branch this PR is targeting. label Dec 11, 2020
@openshift-ci-robot
Copy link
Contributor

@debsmita1: This pull request references Bugzilla bug 1906898, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target release (4.7.0) matches configured target release for branch (4.7.0)
  • bug is in the state NEW, which is one of the valid states (NEW, ASSIGNED, ON_DEV, POST, POST)

In response to this:

Bug 1906898: Missing User RoleBindings in the Project Access Web UI

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@openshift-ci-robot openshift-ci-robot added the bugzilla/valid-bug Indicates that a referenced Bugzilla bug is valid for the branch this PR is targeting. label Dec 11, 2020
@debsmita1
Copy link
Contributor Author

/cc @andrewballantyne

Comment on lines 9 to 16
const users: UserRoleBinding[] = user.subjects?.reduce((acc, obj) => {
acc.push({
roleBindingName: user.metadata.name,
user: obj.name,
role: user.roleRef.name,
});
return acc;
}, []);
Copy link
Member

Choose a reason for hiding this comment

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

Isn't this a map function? :)

},
],
]),
(user: RoleBinding) => (userRoleBindings = [...userRoleBindings, ...getUsersFromSubject(user)]),
Copy link
Member

Choose a reason for hiding this comment

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

Its similar to before, but the result of a map function should be used, otherwise can we switch to a .forEach here? Isn't this similar to this code?

export const getUserRoleBindings = (roleBindings: RoleBinding[]) => {
  const userRoleBindings: UserRoleBinding[] = [];
  roleBindings.forEach(
    (user: RoleBinding) => userRoleBindings.push(...getUsersFromSubject(user)),
  );
  return userRoleBindings;
};

(untested code). Wdyt? :)

Copy link
Contributor Author

@debsmita1 debsmita1 Jan 7, 2021

Choose a reason for hiding this comment

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

used _.flatten here
added the test for this util in project-access-form-utils.spec.ts

let groupedRole: RoleBinding;
_.forEach(roleBindings, (roleBinding: RoleBinding) => {
if (roleBinding.metadata.name === role.roleBindingName && roleBinding.subjects.length > 1) {
_.remove(roleBinding.subjects, (subject) => subject.name === role.user);
Copy link
Member

@jerolimov jerolimov Jan 6, 2021

Choose a reason for hiding this comment

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

Hmm, not a big fan of changing input parameters in a 'get' helper function. Esp. in this case where getGroupedRole was called with some props we should avoid this.

Did you see an option that this method return new values instead of modifying the input variables?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed it

Comment on lines 1 to 20
import { filterRoleBindings, getUserRoleBindings } from '../project-access-form-utils';
import { Roles } from '../project-access-form-utils-types';
import {
roleBindingsResourceData,
roleBindingsWithRequiredRolesResult,
roleBindingsWithRequiredRoles,
roleBindingsWithRequiredAttributes,
} from './project-access-form-data';

describe('Fetch required roles', () => {
it('should fetch the only the required rolebindings', async () => {
const filteredRoleBindings = filterRoleBindings(roleBindingsResourceData, Roles);
expect(filteredRoleBindings).toEqual(roleBindingsWithRequiredRolesResult);
});

it('should consider only the required attributes', async () => {
const userRoleBindings = getUserRoleBindings(roleBindingsWithRequiredRoles);
expect(userRoleBindings).toEqual(roleBindingsWithRequiredAttributes);
});
});
Copy link
Member

Choose a reason for hiding this comment

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

Why remove this unit tests? The util functions still exist and are not changed, or? So I expect this tests would still run fine?

Copy link
Contributor Author

@debsmita1 debsmita1 Jan 7, 2021

Choose a reason for hiding this comment

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

Fixed. Changed the file name to project-access-form-utils.spec.ts

Copy link
Member

@jerolimov jerolimov left a comment

Choose a reason for hiding this comment

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

@debsmita1 Happy new year and sorry for the late review here. I tested the PR locally and it looks like that everything works fine for the user and I like all these new types 👍

I added some small opinionated ideas and questions. Let me know what your opinion on that points.

Copy link
Member

@jerolimov jerolimov left a comment

Choose a reason for hiding this comment

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

(just changed review status)

@@ -73,3 +76,14 @@ export const sendRoleBindingRequest = (verb: string, roles: UserRoleBinding[], r
});
return finalArray;
};

export const getGroupedRole = (role: UserRoleBinding, roleBindings: RoleBinding[]) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Your get method is mutating roleBindings. This is not an expected side-effect of get methods.

Also, as discussed before, please make use of filters and finds instead of custom running your own forEach.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

used find & filter

Comment on lines 9 to 18
const users: UserRoleBinding[] = user.subjects?.reduce((acc, obj) => {
acc.push({
roleBindingName: user.metadata.name,
user: obj.name,
role: user.roleRef.name,
});
return acc;
}, []);

return users;
Copy link
Contributor

Choose a reason for hiding this comment

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

A .reduce into an array .push is just a .map.

Suggested change
const users: UserRoleBinding[] = user.subjects?.reduce((acc, obj) => {
acc.push({
roleBindingName: user.metadata.name,
user: obj.name,
role: user.roleRef.name,
});
return acc;
}, []);
return users;
return user.subjects?.map((obj) => ({
roleBindingName: user.metadata.name,
user: obj.name,
role: user.roleRef.name,
}));

return users;
};

export const getUserRoleBindings = (roleBindings: RoleBinding[]) => {
let userRoleBindings: UserRoleBinding[] = [];
roleBindings.map(
Copy link
Contributor

Choose a reason for hiding this comment

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

For the record (I know this is old code) but .map should always have its response used. Ideally .map has no side-effects if possible.

};

export const getUserRoleBindings = (roleBindings) => {
export const getUsersFromSubject = (user: RoleBinding) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Helps to declare what your returns will be when you're mutating and shifting values around. When it's a straight filter or find, and your input type is your output type, it's less of a concern.

In this case you're taking a RoleBinding and creating UserRoleBinding[]. Makes it easier to consume the method without having to read the method.

Suggested change
export const getUsersFromSubject = (user: RoleBinding) => {
export const getUsersFromSubject = (user: RoleBinding): UserRoleBinding[] => {

},
],
]),
(user: RoleBinding) => (userRoleBindings = [...userRoleBindings, ...getUsersFromSubject(user)]),
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
(user: RoleBinding) => (userRoleBindings = [...userRoleBindings, ...getUsersFromSubject(user)]),
return roleBindings.map((user) => getUsersFromSubject(user)).flat();

Two major things here:

  1. Don't assign in a return statement (we should probably get a linter to stop this)
  2. Avoid mutations in the middle of .map function calls (the purer they are the better they are)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, I could have used flat here to concatenate the sub-array elements. Thanks!

let groupedRole: RoleBinding;
_.forEach(roleBindings, (roleBinding: RoleBinding) => {
if (roleBinding.metadata.name === role.roleBindingName && roleBinding.subjects.length > 1) {
_.remove(roleBinding.subjects, (subject) => subject.name === role.user);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason you need to remove the matching subject?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@andrewballantyne What I am trying to do here is, if I update the role of a user(suppose A) that belongs to grouped subjects(subjects: A, B) then I am removing that user(A) from the group and sending a patch request to update the rolebinding with the user B.

@debsmita1 debsmita1 force-pushed the pa-subject-bug branch 2 times, most recently from 2aa7c88 to b9eeb61 Compare January 7, 2021 06:55
Copy link
Contributor

@andrewballantyne andrewballantyne left a comment

Choose a reason for hiding this comment

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

/lgtm

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Jan 12, 2021
@openshift-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: andrewballantyne, debsmita1

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci-robot openshift-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jan 12, 2021
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jan 12, 2021

@debsmita1: The following test failed, say /retest to rerun all failed tests:

Test name Commit Details Rerun command
ci/prow/kubevirt-plugin 3161484 link /test kubevirt-plugin

Full PR test history. Your PR dashboard.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

@openshift-ci-robot
Copy link
Contributor

@debsmita1: This pull request references Bugzilla bug 1906898, which is valid.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target release (4.7.0) matches configured target release for branch (4.7.0)
  • bug is in the state POST, which is one of the valid states (NEW, ASSIGNED, ON_DEV, POST, POST)

In response to this:

Bug 1906898: Missing User RoleBindings in the Project Access Web UI

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@openshift-merge-robot openshift-merge-robot merged commit e799db7 into openshift:master Jan 12, 2021
@openshift-ci-robot
Copy link
Contributor

@debsmita1: All pull requests linked via external trackers have merged:

Bugzilla bug 1906898 has been moved to the MODIFIED state.

In response to this:

Bug 1906898: Missing User RoleBindings in the Project Access Web UI

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@spadgett spadgett added this to the v4.7 milestone Jan 12, 2021
@debsmita1
Copy link
Contributor Author

/cherry-pick release-4.6

@openshift-cherrypick-robot

@debsmita1: new pull request created: #8034

In response to this:

/cherry-pick release-4.6

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. bugzilla/severity-medium Referenced Bugzilla bug's severity is medium for the branch this PR is targeting. bugzilla/valid-bug Indicates that a referenced Bugzilla bug is valid for the branch this PR is targeting. component/dev-console Related to dev-console kind/bug Categorizes issue or PR as related to a bug. lgtm Indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Missing User RoleBindings in the Project Access Web UI
8 participants