[SR] Adjust app permissions#39966
Conversation
|
Pinging @elastic/es-ui |
| // Update app state with permissions data | ||
| useEffect( | ||
| () => { | ||
| dispatch({ |
There was a problem hiding this comment.
@elastic/es-ui
I think permissions is a good candidate for the type of data that should be stored in React context. Here, the permissions are fetched when the app mounts and I dispatch the resulting data into the app state so that other components can access it without having to send another request to get permissions info. This can let us get really granular with the way the UI behaves at different permission levels. I've only used it in one section of this app for now, but it would be relatively easy to check for more granular permissions and disable buttons such as Delete and Restore.
What do you think?
There was a problem hiding this comment.
Agreed @jen-huang. And should be a reusable solution across our apps. Once the Provider wraps the app, I see something like this in our components
import { Authorize } from 'plugins/our_shared_es_ui_plugin/permissions';
const SomeComponent = () => (
<Authorize role="someRole">
<EuiButton>Only visible to users with enough privileges</EuiButton>
</Authorize>
)There was a problem hiding this comment.
I think permissions is a good candidate for the type of data that should be stored in React context.
Yes, I agree. I think a compelling rationale is also that this lets us design the app so that users are free to navigate throughout it while the permissions request is still resolving. As you pointed out, discrete parts of the app will be gated on permissions. These specific parts of the UI can show a spinner while the user uses the parts of the app that are not gated on permissions.
EDIT: I re-read your comment and it sounds like maybe we're saying the same thing in different ways. :)
💔 Build Failed |
💚 Build Succeeded |
💔 Build Failed |
|
Retest |
💚 Build Succeeded |
cjcenizal
left a comment
There was a problem hiding this comment.
Tested locally, code LGTM! I found a few typos and had a suggestion for making some code easier to follow.
| }; | ||
|
|
||
| export const APP_PERMISSIONS = ['create_snapshot', 'cluster:admin/repository']; | ||
| export const APP_REQUIRED_CLUSTER_PRIVILAGES = [ |
There was a problem hiding this comment.
Typo nit in a few places: PRIVILAGES -> PRIVILEGES
| // Update app state with permissions data | ||
| useEffect( | ||
| () => { | ||
| dispatch({ |
There was a problem hiding this comment.
I think permissions is a good candidate for the type of data that should be stored in React context.
Yes, I agree. I think a compelling rationale is also that this lets us design the app so that users are free to navigate throughout it while the permissions request is still resolving. As you pointed out, discrete parts of the app will be gated on permissions. These specific parts of the UI can show a spinner while the user uses the parts of the app that are not gated on permissions.
EDIT: I re-read your comment and it sounds like maybe we're saying the same thing in different ways. :)
| method: 'GET', | ||
| }); | ||
|
|
||
| // Check if they have at the required index privilages for at least one index |
There was a problem hiding this comment.
privilages -> privileges
As a side note, the more I read this word, this more it looks wrong to me!
There was a problem hiding this comment.
privileges doesn't feel like a real word to me any more 😆
| method: 'GET', | ||
| }); | ||
|
|
||
| // Check if they have at the required index privilages for at least one index |
| const oneIndexWithAllPrivileges = indices.find(({ privileges }: { privileges: string[] }) => { | ||
| return ( | ||
| privileges.includes('all') || | ||
| APP_RESTORE_INDEX_PRIVILAGES.filter(privilage => !privileges.includes(privilage)).length === 0 |
There was a problem hiding this comment.
I had to read through this a few times to figure out the logic. Could we extract this condition and add a variable to communicate meaning? Here's my suggestion, it's a couple more lines but I find it easier to understand. (Warning, I haven't tested it!)
// Check if they have all the required index privilages for at least one index
const hasIndexWithRestorePrivileges = indices.find(({ privileges }: { privileges: string[] }) => {
if (privileges.includes('all')) {
return true;
}
const indexHasRestorePrivileges = APP_RESTORE_INDEX_PRIVILEGES.every(restorePrivilege => privileges.includes(restorePrivilege));
return indexHasRestorePrivileges;
});I know we could eliminate a line by getting rid of the indexHasRestorePrivileges variable, but its name makes it so much easier for me to follow the logic. :)
💚 Build Succeeded |
* Adjust SR app permissions for new features * Fix app state and reducer typings * Fix i18n key * Fix typos * Make logic more clear
Summary
This PR adjusts the app permissions for Snapshot and Restore to reflect additional features done in #39193.
Overall app permissions now need these cluster privileges because the UI now supports additional actions with snapshots (as opposed to readonly view):
An index privilege is now also checked,
monitor. Not having this privilege on at least one index will not block the user's access to the app, but will block the Restore Status content from being shown. Prior to this PR, the UX was not very nice:Testing
This PR can be tested by creating a new user role (and a user who uses that role plus
kibana_user) and adjusting its privileges to see the various UX changes:Missing cluster privilege, no app access
Missing index privilege, app access but no Recovery Status access
Some indices privilege, app access and Recovery Status access for just those indices
All indices privilege (or superuser), app access and full Recovery Status access