Skip to main content

Permission Control and RBAC

Generally, we use Tushan as a solution for quickly building applications, initially designed to handle a single full-control permission scenario.

However, as iterations progress and projects expand, the content and administrators become more complex, necessitating finer control over permissions.

Tushan provides a built-in permission control module within the authProvider. After a successful login, we can define getPermissions to control how we obtain permissions. This function returns a promise, meaning we can also acquire permissions through a secondary request or from the response obtained post-login.

export const authProvider: AuthProvider = {
// ....
getPermissions: () => Promise.resolve(''),
};

You can return any result from getPermissions, as Tushan will not process its content but return it as-is to the user.

Role-Based Access Control (RBAC)

For example, you can return an array of roles as user permissions in getPermissions:

export const authProvider: AuthProvider = {
// ....
getPermissions: () => Promise.resolve(['admin', 'user']), // This is a demo; actual roles can be obtained from a token or an API.
};

Then, control access to resources based on roles. For instance, assuming only admins can access the User module:

<Tushan dataProvider={dataProvider} authProvider={authProvider}>
{({ permissions }) => (
<>
{permissions.includes('admin') && (
<Resource
name="users"
label="User"
icon={<IconUser />}
list={
<ListTable
fields={userFields}
action={{
create: true,
detail: true,
edit: true,
delete: true,
}}
/>
}
/>
)}
</>
)}
</Tushan>

Or for more granular control, where everyone can view users, but only admins can add, edit, or delete:

<Tushan dataProvider={dataProvider} authProvider={authProvider}>
{({ permissions }) => (
<>
<Resource
name="users"
label="User"
icon={<IconUser />}
list={
<ListTable
fields={userFields}
action={{
create: permissions.includes('admin'),
detail: true,
edit: permissions.includes('admin'),
delete: permissions.includes('admin'),
}}
/>
}
/>
</>
)}
</Tushan>

For custom components, you can use usePermissions to access permission data:

import { usePermissions } from 'tushan';

export const MyComponent = () => {
const { permissions } = usePermissions();

if (!permissions.includes('admin')) {
return null;
}

return <div>{/* ... */}</div>;
};

Considerations

When getPermissions fails to retrieve permissions correctly, it should throw an exception or return null, rather than an empty array or another non-permission state.

Tushan checks permissions before and after login. If pre-login permissions are correctly returned, it will not fetch them again post-login.