Fix custom buttons and widgets with role names or group descriptions that can change#9954
Conversation
Extracted from and for usage in: ManageIQ/manageiq-ui-classic#9954
| _("To All Users") | ||
| else | ||
| _("By %{typ}: %{values}") % {:typ => typ.to_s.titleize, :values => values.join(',')} | ||
| display_values = widget.visibility_values.join(',') |
There was a problem hiding this comment.
uses the method added in ManageIQ/manageiq#23803
There was a problem hiding this comment.
I think you should add some sorting here.
There was a problem hiding this comment.
done... they're IDs now so they'll likely be sorted in creation order. I misspoke. These are coming back with the values so they will be sorted by name.
| end | ||
|
|
||
| it "sets new role and preserves old role for custom button" do | ||
| edit[:new][:roles] = [old_role.id, role.id.to_s] # old roles are represented by int and new ones by string |
There was a problem hiding this comment.
Not sure I understand why new ones are strings?
There was a problem hiding this comment.
This is was part of the last set of changes, see c776fe9, "Consistently use numbers for group/role ids"
Related to manageiq-schema [1] which migrated existing role names to IDs in the visibility column. [1] ManageIQ/manageiq-schema#852 Before: visibility[:roles] stored role names (strings) After: visibility[:roles] stores role IDs (integers) Changes: - Saving: Store IDs directly from form - Loading: Read IDs directly from database - Display: Query role names from IDs for UI
- Fix widget_spec expectation to use group.id instead of group.description - Add test for group visibility display in widget_get_node_info - Remove obvious comments from Cypress tests (kept TODO comment) Related to ManageIQ/manageiq-schema#XXX where we converted visibility from storing role names/group descriptions to storing IDs. This ensures tests properly verify ID-based lookups and display of names/descriptions.
Previously, with the data migration and UI code that stored ids as numbers in the database, the code that lit up the checkboxes failed to match ids as strings with the numbers from the database.
Followup to ManageIQ#23803 Fixes an issue seen when testing UI usage in ManageIQ/manageiq-ui-classic#9954 The client of this code shouldn't need to check if the visibility is missing the roles/groups key.
Followup to ManageIQ#23803 Fixes an issue seen when testing UI usage in ManageIQ/manageiq-ui-classic#9954 The client of this code shouldn't need to check if the visibility is missing the roles/groups key.
fd9260d to
c776fe9
Compare
fd10bef to
d0ead1c
Compare
| roles.push(role.name) if role | ||
| end | ||
| button.visibility[:roles] = roles | ||
| button.visibility[:roles] = @edit[:new][:roles] |
There was a problem hiding this comment.
previous code was doing a lot of work to persist names, now we just persist the ids
| end | ||
| end | ||
| @edit[:new][:roles].sort! if @edit[:new][:roles].present? | ||
| @edit[:new][:roles] = @custom_button.visibility[:roles][0] == "_ALL_" ? ["_ALL_"] : @custom_button.visibility[:roles].sort |
There was a problem hiding this comment.
Again, a lot of lookups by name to push a sorted list of ids, which is what we now have in the db, so this is simpler.
| @sb[:user_roles].push(r.name) if @custom_button.visibility[:roles].include?(r.name) | ||
| end | ||
| role_ids = @custom_button.visibility[:roles] | ||
| @sb[:user_roles] = MiqUserRole.where(:id => role_ids).order(:name).pluck(:name) |
There was a problem hiding this comment.
sanbox needs names, so we pluck the names sorted.
| @sb[:user_roles].push(r.name) if @custom_button.visibility[:roles].include?(r.name) | ||
| end | ||
| role_ids = @custom_button.visibility[:roles] | ||
| @sb[:user_roles] = MiqUserRole.where(:id => role_ids).order(:name).pluck(:name) |
| @sb[:groups].push(r.description) if @widget.visibility[:groups].include?(r.description) | ||
| end | ||
| group_ids = @widget.visibility[:groups] | ||
| @sb[:groups] = Rbac.filtered(MiqGroup.where(:id => group_ids)).order(:description).pluck(:description) |
There was a problem hiding this comment.
again, a bit simpler since we can just check what ids we're allowed to see and pluck their name or description.
| roles = Rbac.filtered(MiqUserRole.where(:name => @widget.visibility[:roles])) | ||
| @edit[:new][:roles] = roles.collect(&:id).sort | ||
| end | ||
| @edit[:new][:roles] = @widget.visibility[:roles][0] == "_ALL_" ? ["_ALL_"] : @widget.visibility[:roles].sort |
There was a problem hiding this comment.
Do we need to do Rbac.filtered here, like we do above?
There was a problem hiding this comment.
presumably the RBAC was already checked?
There was a problem hiding this comment.
I found another. I'll fix this. I don't see how rbac was already checked on these roles/groups so we should probably keep it.
There was a problem hiding this comment.
ok, fixed... this should continue to have the same behavior as it did previously, but now uses IDs. I don't know if it makes sense to do rbac filtering here... I don't think MiqUserRole or MiqGroup participate in rbac... but anyway, the existing behavior is restored, even if it doesn't make sense.
Note, if the user has access to reports tree view and can modify the widgets or similarly, the embedded automate custom button section, they can change what roles/groups have visibility to this since groups and users don't participate in rbac.
I can try to resolve this in a followup PR but for the purposes of this change, it's probably best to keep the existing behavior and only change the names to ids.
| next unless var.starts_with?(prefix) | ||
|
|
||
| name = var.split(prefix).last | ||
| name = var.split(prefix).last.to_i |
There was a problem hiding this comment.
Here's one of the fixes to ensure the "xx_r1" becomes 1 numbers so our checkboxes light up. Keeping track of string vs numeric numbers was confusing for me so I think this just fixes it. I couldn't break the visibility box for either custom buttons or widgets.
The miq_widget factory has separate sequences for both title and description attributes. When tests override :title, they skip the title sequence but the description sequence still increments, causing the sequences to become out of sync (e.g., title='widget_0000000000001', description='widget_0000000000002'). This caused test failures when: 1. A test overrode :title (causing sequence desync) 2. A subsequent test expected title and description to match 3. TreeBuilderReportWidgets uses widget.title for tree node display Fixed by: - Removing unnecessary :title overrides in widget_spec.rb (lines 96, 108, 124) These tests only care about visibility settings, not specific title text - Updating explorer_spec.rb to use widget.title instead of widget.description Added comment explaining TreeBuilderReportWidgets uses title attribute This makes tests resilient to execution order and prevents future sequence desync issues. The factory-generated titles are sufficient for these tests.
d0ead1c to
31b0b39
Compare
| cy.get('#main_div').contains('Test Button'); | ||
| cy.get('#main_div').contains('test_request'); | ||
| cy.get('.visibility').contains('EvmRole-auditor'); | ||
| cy.get('.visibility').contains('EvmRole-desktop'); |
There was a problem hiding this comment.
Note, the cypress test creates button with the visibility values but doesn't go back and edit the form to verify the checkboxes afterwards.
| else | ||
| _("By %{typ}: %{values}") % {:typ => typ.to_s.titleize, :values => values.join(',')} | ||
| display_values = widget.visibility_values.sort.join(', ') | ||
| _("By %{typ}: %{values}") % {:typ => typ.to_s.titleize, :values => display_values} |
There was a problem hiding this comment.
I'm ok with this for this PR, but technically this breaks i18n, becaiuse "By Groups" or "By Roles" can't be translated independently as the translators only see "By %{typ}". However, this was there previously, so it's not changing anything. Something to keep in mind in a future PR.
|
Checked commits jrafanie/manageiq-ui-classic@4934a7e~...f679c1c with ruby 3.3.10, rubocop 1.86.0, haml-lint 0.72.0, and yamllint 1.37.1 |
|
@Fryguy @GilbertCherrie I think this is ready for final review. Both ManageIQ/manageiq-schema#852 and #9954 should be merged together. |
GilbertCherrie
left a comment
There was a problem hiding this comment.
Tested it and it is working as expected after assigning a button/widget to a role and then changing the role name. The button/widget is still assigned to the role with the new name and the checkboxes on the forms show this. Also, tested groups for the widget form which works correctly too even if you change the group name.
|
Backported to |
…-with-role-names-that-can-change Fix custom buttons and widgets with role names or group descriptions that can change (cherry picked from commit 81c6a89)
Replaces #9709 #9710
Depends on:
Previously, custom buttons and widgets stored role names and group descriptions in visibility settings, breaking when these changed.
Now, we store role IDs and group IDs instead. The schema migration above ensures existing data will get migrated to IDs as numbers instead of names/descriptions.
Changes: