mirror of
https://github.com/strapi/strapi.git
synced 2025-12-27 15:13:21 +00:00
Merge pull request #16343 from strapi/fix/audit-logs-users-permissions
This commit is contained in:
commit
bdb92a93a4
@ -2,7 +2,7 @@ import { useQuery } from 'react-query';
|
||||
import { useNotification, useFetchClient } from '@strapi/helper-plugin';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
const useAuditLogsData = ({ canRead }) => {
|
||||
const useAuditLogsData = ({ canReadAuditLogs, canReadUsers }) => {
|
||||
const { get } = useFetchClient();
|
||||
const { search } = useLocation();
|
||||
const toggleNotification = useNotification();
|
||||
@ -21,7 +21,6 @@ const useAuditLogsData = ({ canRead }) => {
|
||||
};
|
||||
|
||||
const queryOptions = {
|
||||
enabled: canRead,
|
||||
keepPreviousData: true,
|
||||
retry: false,
|
||||
staleTime: 1000 * 20, // 20 seconds
|
||||
@ -32,10 +31,14 @@ const useAuditLogsData = ({ canRead }) => {
|
||||
data: auditLogs,
|
||||
isLoading,
|
||||
isError: isAuditLogsError,
|
||||
} = useQuery(['auditLogs', search], fetchAuditLogsPage, queryOptions);
|
||||
} = useQuery(['auditLogs', search], fetchAuditLogsPage, {
|
||||
...queryOptions,
|
||||
enabled: canReadAuditLogs,
|
||||
});
|
||||
|
||||
const { data: users, isError: isUsersError } = useQuery(['auditLogsUsers'], fetchAllUsers, {
|
||||
...queryOptions,
|
||||
enabled: canReadUsers,
|
||||
staleTime: 2 * (1000 * 60), // 2 minutes
|
||||
});
|
||||
|
||||
|
||||
@ -25,17 +25,27 @@ import Filters from '../../../../../../../admin/src/pages/SettingsPage/component
|
||||
import getDisplayedFilters from './utils/getDisplayedFilters';
|
||||
import useAuditLogsData from './hooks/useAuditLogsData';
|
||||
|
||||
const auditLogsPermissions = {
|
||||
...adminPermissions.settings.auditLogs,
|
||||
readUsers: adminPermissions.settings.users.read,
|
||||
};
|
||||
|
||||
const ListView = () => {
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
const {
|
||||
allowedActions: { canRead },
|
||||
} = useRBAC(adminPermissions.settings.auditLogs);
|
||||
allowedActions: { canRead: canReadAuditLogs, canReadUsers },
|
||||
} = useRBAC(auditLogsPermissions);
|
||||
|
||||
const [{ query }, setQuery] = useQueryParams();
|
||||
const { auditLogs, users, isLoading, hasError } = useAuditLogsData({ canRead });
|
||||
const { auditLogs, users, isLoading, hasError } = useAuditLogsData({
|
||||
canReadAuditLogs,
|
||||
canReadUsers,
|
||||
});
|
||||
|
||||
useFocusWhenNavigate();
|
||||
|
||||
const displayedFilters = getDisplayedFilters({ formatMessage, users });
|
||||
const displayedFilters = getDisplayedFilters({ formatMessage, users, canReadUsers });
|
||||
|
||||
const title = formatMessage({
|
||||
id: 'global.auditLogs',
|
||||
@ -73,7 +83,7 @@ const ListView = () => {
|
||||
})}
|
||||
/>
|
||||
<ActionLayout startActions={<Filters displayedFilters={displayedFilters} />} />
|
||||
<ContentLayout canRead={canRead}>
|
||||
<ContentLayout canRead={canReadAuditLogs}>
|
||||
<DynamicTable
|
||||
contentType="Audit logs"
|
||||
headers={headers}
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
import getDisplayedFilters from '../utils/getDisplayedFilters';
|
||||
|
||||
const mockUsers = {
|
||||
results: [
|
||||
{
|
||||
id: 1,
|
||||
firstname: 'test',
|
||||
lastname: 'tester',
|
||||
username: null,
|
||||
email: 'test@test.com',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
firstname: 'test2',
|
||||
lastname: 'tester2',
|
||||
username: null,
|
||||
email: 'test2@test.com',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
describe('Audit Logs getDisplayedFilters', () => {
|
||||
it('should return all filters when canReadUsers is true', () => {
|
||||
const filters = getDisplayedFilters({
|
||||
users: mockUsers,
|
||||
formatMessage: jest.fn(({ defaultMessage }) => defaultMessage),
|
||||
canReadUsers: true,
|
||||
});
|
||||
const filterNames = filters.map((filter) => filter.name);
|
||||
expect(filterNames).toEqual(['action', 'date', 'user']);
|
||||
});
|
||||
|
||||
it('should not return user filter when canReadUsers is false', () => {
|
||||
const filters = getDisplayedFilters({
|
||||
users: mockUsers,
|
||||
formatMessage: jest.fn(({ defaultMessage }) => defaultMessage),
|
||||
canReadUsers: false,
|
||||
});
|
||||
const filterNames = filters.map((filter) => filter.name);
|
||||
expect(filterNames).toEqual(['action', 'date']);
|
||||
});
|
||||
});
|
||||
@ -12,27 +12,7 @@ const customOperators = [
|
||||
},
|
||||
];
|
||||
|
||||
const getDisplayedFilters = ({ formatMessage, users }) => {
|
||||
const getDisplaynameFromUser = (user) => {
|
||||
if (user.username) {
|
||||
return user.username;
|
||||
}
|
||||
if (user.firstname && user.lastname) {
|
||||
return formatMessage(
|
||||
{
|
||||
id: 'Settings.permissions.auditLogs.user.fullname',
|
||||
defaultMessage: '{firstname} {lastname}',
|
||||
},
|
||||
{
|
||||
firstname: user.firstname,
|
||||
lastname: user.lastname,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return user.email;
|
||||
};
|
||||
|
||||
const getDisplayedFilters = ({ formatMessage, users, canReadUsers }) => {
|
||||
const actionOptions = Object.keys(actionTypes).map((action) => {
|
||||
return {
|
||||
label: formatMessage(
|
||||
@ -46,17 +26,7 @@ const getDisplayedFilters = ({ formatMessage, users }) => {
|
||||
};
|
||||
});
|
||||
|
||||
const userOptions =
|
||||
users &&
|
||||
users.results.map((user) => {
|
||||
return {
|
||||
label: getDisplaynameFromUser(user),
|
||||
// Combobox expects a string value
|
||||
customValue: user.id.toString(),
|
||||
};
|
||||
});
|
||||
|
||||
return [
|
||||
const filters = [
|
||||
{
|
||||
name: 'action',
|
||||
metadatas: {
|
||||
@ -80,20 +50,57 @@ const getDisplayedFilters = ({ formatMessage, users }) => {
|
||||
},
|
||||
fieldSchema: { type: 'datetime' },
|
||||
},
|
||||
{
|
||||
name: 'user',
|
||||
metadatas: {
|
||||
customOperators,
|
||||
label: formatMessage({
|
||||
id: 'Settings.permissions.auditLogs.user',
|
||||
defaultMessage: 'User',
|
||||
}),
|
||||
options: userOptions,
|
||||
customInput: ComboboxFilter,
|
||||
},
|
||||
fieldSchema: { type: 'relation', mainField: { name: 'id' } },
|
||||
},
|
||||
];
|
||||
|
||||
if (canReadUsers && users) {
|
||||
const getDisplayNameFromUser = (user) => {
|
||||
if (user.username) {
|
||||
return user.username;
|
||||
}
|
||||
|
||||
if (user.firstname && user.lastname) {
|
||||
return formatMessage(
|
||||
{
|
||||
id: 'Settings.permissions.auditLogs.user.fullname',
|
||||
defaultMessage: '{firstname} {lastname}',
|
||||
},
|
||||
{
|
||||
firstname: user.firstname,
|
||||
lastname: user.lastname,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return user.email;
|
||||
};
|
||||
|
||||
const userOptions = users.results.map((user) => {
|
||||
return {
|
||||
label: getDisplayNameFromUser(user),
|
||||
// Combobox expects a string value
|
||||
customValue: user.id.toString(),
|
||||
};
|
||||
});
|
||||
|
||||
return [
|
||||
...filters,
|
||||
{
|
||||
name: 'user',
|
||||
metadatas: {
|
||||
customOperators,
|
||||
label: formatMessage({
|
||||
id: 'Settings.permissions.auditLogs.user',
|
||||
defaultMessage: 'User',
|
||||
}),
|
||||
options: userOptions,
|
||||
customInput: ComboboxFilter,
|
||||
},
|
||||
fieldSchema: { type: 'relation', mainField: { name: 'id' } },
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
return filters;
|
||||
};
|
||||
|
||||
export default getDisplayedFilters;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user