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

Add settingsPermission gate on the frontend #10179

Merged
merged 15 commits into from
Feb 18, 2025

Conversation

Weiko
Copy link
Member

@Weiko Weiko commented Feb 13, 2025

Context

With the new permissions system, we now need to hide some items from the settings navigation and gate some routes so they can't be accessed directly.
To avoid having to set permission gates in all the component pages, I'm introducing wrapper at the route level and in the Navigation. This is not required and is mostly for pages that are strictly mapped to a single permission, for the rest we still need to use the different hooks manually but it should avoid a bit of boilerplate for most of the cases.

  • currentUserWorkspaceState to access settingsPermissions
  • SettingsProtectedRouteWrapper in the router that can take a settingFeature or a featureFlag as a gate logic, if the currentUser does not have access to the settingFeature or the featureFlag is not enabled they will be redirected to the profile page.
  • SettingsNavigationItemWrapper & SettingsNavigationSectionWrapper. The former will check the same logic as SettingsProtectedRouteWrapper and not display the item if needed. The later will check if all SettingsNavigationItemWrapper are not visible and hide itself if that's the case.
  • useHasSettingsPermission to get a specific permission state for the current user
  • useSettingsPermissionMap to get a map of all permissions with their values for the current user
  • useFeatureFlagsMap same but for featureFlags

@Weiko Weiko force-pushed the c--add-settings-permissions-gate-frontend branch from e66cc9a to e689387 Compare February 14, 2025 10:13
@Weiko Weiko marked this pull request as ready for review February 14, 2025 14:24
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

This PR implements a comprehensive settings permission system for controlling access to settings features and routes. Here's a summary of the key changes:

  • Added SettingsProtectedRouteWrapper component to gate access to settings routes based on user permissions and feature flags
  • Introduced SettingsNavigationSectionWrapper and SettingsNavigationItemWrapper to manage visibility of navigation items based on permissions
  • Created new hooks useHasSettingsPermission and useSettingsPermissionMap to check and manage settings permissions
  • Added currentUserWorkspaceState to store user workspace permissions in Recoil state
  • Integrated permission checks in UserProviderEffect and useApolloFactory for proper state management

Key points to review:

  • SettingsNavigationSectionWrapper recursively checks children visibility
  • useHasSettingsPermission follows a secure default-deny pattern
  • Permission gates are now centralized at route/navigation level instead of individual components
  • Mock data structure updated to support testing the new permissions system
  • Proper integration with existing feature flag system through useFeatureFlagsMap

19 file(s) reviewed, 15 comment(s)
Edit PR Review Bot Settings | Greptile

Comment on lines 24 to 26
const requiredFeatureFlagEnabled = useIsFeatureEnabled(
requiresFeatureFlag || null,
);
Copy link
Contributor

Choose a reason for hiding this comment

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

style: useIsFeatureEnabled(null) could have unexpected behavior. Consider adding a guard clause or early return when requiresFeatureFlag is undefined.

Copy link
Contributor

@prastoin prastoin left a comment

Choose a reason for hiding this comment

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

Early reviewing to get your opinions on raised points as it seems to re-occurs later in the review ! From so far good job !


const currentWorkspaceFeatureFlags = currentWorkspace?.featureFlags;

const initialFeatureFlags = Object.fromEntries(
Copy link
Contributor

@prastoin prastoin Feb 17, 2025

Choose a reason for hiding this comment

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

Nitpick: We recently introduced buildRecordFromKeysWithSameValue which could fit our need here and avoid force cast

  const initialPermissions = buildRecordFromKeysWithSameValue(Object.values(SettingsFeatures), false); // strictly typed using predicates
  if (!currentUserWorkspaceSettingsPermissions) {
    return initialPermissions;
  }

I don't know if it's something common in the twenty codebase, if yes then just omit this comment.

Concerns: I'm always fearful to manipulate enums like this. As its reliability only comes from the fact that all entries do have an initializer.

enum FooBar {
    FOO,
    BAR = 'BAR',
}
const entries = Object.values(FooBar);
console.log(entries) // [LOG]: ["FOO", 0, "BAR"] 

Copy link
Collaborator

@ijreilly ijreilly left a comment

Choose a reason for hiding this comment

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

could not reproduce on the main branch so may be related to your changes? :
https://github.com/user-attachments/assets/dd7ed9b9-b660-4348-8392-1c920ce500f7

otherwise works fine !

@Weiko
Copy link
Member Author

Weiko commented Feb 17, 2025

could not reproduce on the main branch so may be related to your changes? : https://github.com/user-attachments/assets/dd7ed9b9-b660-4348-8392-1c920ce500f7

otherwise works fine !

Was fixed on main, I rebased!

isAdvanced?: boolean;
};

export const useSettingsNavigationItems = (): SettingsNavigationSection[] => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Way better thanks ! Also easier for maintaining granular changes about permissions and feature flags

@Weiko Weiko merged commit 2fca604 into main Feb 18, 2025
45 of 47 checks passed
@Weiko Weiko deleted the c--add-settings-permissions-gate-frontend branch February 18, 2025 14:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants