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

feat: roles and permissions setup [SW-601] #4807

Open
wants to merge 42 commits into
base: dev
Choose a base branch
from

Conversation

tmjssz
Copy link
Collaborator

@tmjssz tmjssz commented Jan 21, 2025

What it solves

Resolves SW-601

Introducing a new setup with roles and permissions simplifying the logic to check whether certain actions are allowed for the user.

How this PR fixes it

All logic for the new setup is defined in the @/permissions folder. The permissions that specific roles should have are defined in @/permissions/config.ts. The config defines a function per role that returns a permission set and that expects certain role props, if defined inside the RolePropsMap type in @/permissions/types/RoleProps.ts. These props can be used to define dynamic permission values, depending on certain conditions. Right now, only the SpendingLimitBeneficiary role has a prop object defined, which includes the spendingLimits.

The permission value can be defined in two ways:

  • A simple boolean flag for static permissions
  • A function that expects an object parameter with properties defined @/permissions/types/PermissionProps.ts. Similar to the RoleProps, the permission props can be used to define dynamic permission values. When checking a certain permission, these props are expected as a parameter.

Architecture

The main hook to check for a certain permission is useHasPermission. It expects a permission value and the corresponding permission props (if defined for that permission in the PermissionPropsMap type). Example:

const canCreateSpendingLimitTx = useHasPermission(Permission.CreateSpendingLimitTransaction, { token: selectedToken })

There is also a HOC called withPermission that renders the child component only if the user has a certain permission. Example:

const RandomComponent = () => <div>Hello world.</div>
const WithProposeTxPermission = withPermission(RandomComponent, Permission.ProposeTransaction)
const OuterComponent = () => <WithProposeTxPermission />

Here is an overview of all newly introduced hooks and HOCs used for the permissions architecture:

Role permissions architecture (5)

Usage of the new permission logic

CheckWalletWithPermission

As a first part using the new permissions logic, I added a new CheckWalletWithPermission component that is mostly a copy of CheckWallet, with the only difference that it checks for a certain condition, instead of calling hooks such as useIsSafeOwner or useIsWalletProposer.

CheckWalletWithPermission is now being used by the push notifications related components and replaces the old CheckWallet usage there.

Spending limit checks

  • Updated the CreateTokenTransfer component to use the useHasPermission hook for checking permissions related to creating transactions and spending limit transactions. [1] [2] [3] [4] [5] [6]
  • Modified the SpendingLimitRow component to use the useHasPermission hook for checking spending limit transaction permissions. [1] [2] [3]

How to test it

The only features affected by the new logic so far are:

  • Push notifications settings/renewal
  • Create transactions as a spending limit beneficiary

Both should have the same behaviour as before.

Checklist

  • I've tested the branch on mobile 📱
  • I've documented how it affects the analytics (if at all) 📊
  • I've written a unit/e2e test for it (if applicable) 🧑‍💻

tmjssz added 30 commits January 18, 2025 16:16
Refactor `useIsOnlySpendingLimitBeneficiary` to use the added hook
…nd permission validation

The new component is intended to replace the CheckWallet eventually
…alletWithPermission for enhanced permission validation
…limit transactions in CreateTokenTransfer and SpendingLimitRow components
Copy link

Copy link

github-actions bot commented Jan 21, 2025

Copy link

github-actions bot commented Jan 21, 2025

📦 Next.js Bundle Analysis for @safe-global/web

This analysis was generated by the Next.js Bundle Analysis action. 🤖

⚠️ Global Bundle Size Increased

Page Size (compressed)
global 1.06 MB (🟡 +68.9 KB)
Details

The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.

Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis

If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!

Thirty-two Pages Changed Size

The following pages changed size from the code in this PR compared to its base branch:

Page Size (compressed) First Load
/ 509 B (🟢 -1 B) 1.06 MB
/address-book 23.21 KB (🟡 +143 B) 1.08 MB
/apps 35.97 KB (🟡 +2.25 KB) 1.09 MB
/apps/custom 34.03 KB (🟡 +2.25 KB) 1.09 MB
/apps/open 55.56 KB (🟡 +1.95 KB) 1.11 MB
/balances 30.01 KB (🟡 +314 B) 1.09 MB
/balances/nfts 9.52 KB (🟢 -23 B) 1.07 MB
/bridge 2.55 KB (🟢 -5 B) 1.06 MB
/cookie 8.77 KB (🟡 +1 B) 1.06 MB
/home 61.54 KB (🟡 +2.28 KB) 1.12 MB
/licenses 2.46 KB (🟢 -1 B) 1.06 MB
/new-safe/advanced-create 26.38 KB (🟢 -75 B) 1.08 MB
/new-safe/create 25.52 KB (🟢 -67 B) 1.08 MB
/privacy 14.57 KB (🟡 +2 B) 1.07 MB
/settings/appearance 2.25 KB (🟡 +1 B) 1.06 MB
/settings/cookies 1.87 KB (🟡 +1 B) 1.06 MB
/settings/modules 4.06 KB (🟡 +3 B) 1.06 MB
/settings/notifications 7.52 KB (🟢 -13.8 KB) 1.06 MB
/settings/safe-apps 20.35 KB (🟡 +2.08 KB) 1.08 MB
/settings/security 2.34 KB (🟡 +2 B) 1.06 MB
/settings/setup 30.97 KB (🟡 +246 B) 1.09 MB
/share/safe-app 7.55 KB (🟢 -8 B) 1.06 MB
/stake 617 B (🟢 -2 B) 1.06 MB
/swap 763 B (🟡 +3 B) 1.06 MB
/terms 12.93 KB (🟡 +1 B) 1.07 MB
/transactions 99.45 KB (🟡 +2.88 KB) 1.15 MB
/transactions/history 99.41 KB (🟡 +2.88 KB) 1.15 MB
/transactions/messages 60.25 KB (🟡 +1.95 KB) 1.12 MB
/transactions/msg 56.5 KB (🟡 +1.95 KB) 1.11 MB
/transactions/queue 49.36 KB (🟡 +1.96 KB) 1.1 MB
/transactions/tx 48.71 KB (🟡 +1.95 KB) 1.1 MB
/welcome/accounts 408 B (🟡 +1 B) 1.06 MB
Details

Only the gzipped size is provided here based on an expert tip.

First Load is the size of the global bundle plus the bundle for the individual page. If a user were to show up to your website and land on a given page, the first load size represents the amount of javascript that user would need to download. If next/link is used, subsequent page loads would only need to download that page's bundle (the number in the "Size" column), since the global bundle has already been downloaded.

Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis

Next to the size is how much the size has increased or decreased compared with the base branch of this PR. If this percentage has increased by 20% or more, there will be a red status indicator applied, indicating that special attention should be given to this.

Copy link

github-actions bot commented Jan 21, 2025

Coverage report for apps/web

St.
Category Percentage Covered / Total
🟡 Statements
77.63% (+0.16% 🔼)
14050/18099
🔴 Branches
57.4% (+0.61% 🔼)
3569/6218
🟡 Functions
62.98% (+0.17% 🔼)
2115/3358
🟡 Lines
79.05% (+0.15% 🔼)
12680/16041
Show new covered files 🐣
St.
File Statements Branches Functions Lines
🟢
... / relaying.ts
100% 100% 100% 100%
🟢
... / index.tsx
97.14% 90.48% 100% 100%
🟢
... / useHasPermission.ts
100% 100% 100% 100%
🟢
... / usePermission.ts
100% 100% 100% 100%
🟢
... / useRoles.ts
100% 100% 100% 100%
🟢
... / index.ts
100% 100% 100% 100%
🟢
... / Role.ts
100% 100% 100% 100%
🟢
... / Permission.ts
100% 100% 100% 100%
🟢
... / useRoleProps.ts
100% 100% 100% 100%
🟢
... / getRolePermissions.ts
100% 100% 100% 100%
🔴
... / config.ts
15% 0% 0% 16.67%
🟢
... / useDecodeTx.ts
100% 100% 100% 100%
🟢
... / withPermission.tsx
100% 100% 100% 100%
🟢
... / withRole.tsx
100% 100% 100% 100%
🟢
... / useHasRoles.ts
100% 100% 100% 100%
Show files with reduced coverage 🔻
St.
File Statements Branches Functions Lines
🟡
... / transaction-guards.ts
70.41% (-0.37% 🔻)
42.06% 69.44% 71.28%
🟢
... / extract-migration-data.ts
95%
66.67% (-11.11% 🔻)
100% 94.74%
🟢
... / hooks.ts
80.45% (-0.75% 🔻)
72.09% (-0.88% 🔻)
70% (+3.33% 🔼)
80.83% (-0.48% 🔻)
🟡
... / SafeTxGasForm.tsx
64%
63.64% (-9.09% 🔻)
16.67% 62.5%
🟢
... / SignOrExecuteForm.tsx
89.41%
85.53% (-0.37% 🔻)
50% 88.89%
🟢
... / index.tsx
93.33% (-0.22% 🔻)
70.83% (-2.24% 🔻)
100% 100%
🟡
... / index.tsx
76.47% (-1.65% 🔻)
10.53% (+2.19% 🔼)
100%
75.76% (-1.66% 🔻)
🟡
... / TxNoteForm.tsx
55.56% (-11.11% 🔻)
0% 0%
62.5% (-17.5% 🔻)
🔴
... / SurplusFee.tsx
41.67% (-3.79% 🔻)
0% 0%
45.45% (-4.55% 🔻)
🔴
... / index.tsx
51.72% (-2.12% 🔻)
0% 0%
53.57% (-2.43% 🔻)
🟢
... / index.tsx
100%
88.89% (-11.11% 🔻)
100% 100%

Test suite run success

1832 tests passing in 251 suites.

Report generated by 🧪jest coverage report action from 0e3f32a

@katspaugh katspaugh self-requested a review January 21, 2025 14:45
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.

1 participant