Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import {
import { updateResourceCompactPermissions } from "@js/actions/gnresource";
import {
getCompactPermissions,
getViewedResourceType
getViewedResourceType,
getResourceData,
} from "@js/selectors/resource";
import { getCurrentResourcePermissionsLoading } from "@js/selectors/resourceservice";
import {
Expand All @@ -30,6 +31,8 @@ import {
permissionsCompactToLists,
permissionsListsToCompact,
resourceToPermissionEntry,
canManageAnonymousPermissions,
canManageRegisteredMemberPermissions,
ResourceTypes
} from "@js/utils/ResourceUtils";
import GeoLimits from "./GeoLimits";
Expand Down Expand Up @@ -93,23 +96,26 @@ const Permissions = ({
resourceType,
permissionsLoading,
compactPermissions,
onChangePermissions
onChangePermissions,
resource
}) => {
const enableGeoLimits = resourceType === ResourceTypes.DATASET;
const isMounted = useIsMounted();
const [permissionsObject, setPermissionsObject] = useState({});
const manageAnonymousPermissions = canManageAnonymousPermissions(resource);
const manageRegisteredMemberPermissions = canManageRegisteredMemberPermissions(resource);

useEffect(() => {
getResourceTypes().then((data) => {
const resourceIndex = findIndex(data, { name: resourceType });
let responseOptions;
if (resourceIndex !== -1) {
responseOptions = getResourcePermissions(
data[resourceIndex].allowed_perms.compact
data[resourceIndex].allowed_perms.compact , compactPermissions?.groups ,manageAnonymousPermissions, manageRegisteredMemberPermissions
);
} else {
// set a default permission object
responseOptions = getResourcePermissions(data[0].allowed_perms.compact);
responseOptions = getResourcePermissions(data[0].allowed_perms.compact, compactPermissions?.groups ,manageAnonymousPermissions, manageRegisteredMemberPermissions);
}
isMounted(() => setPermissionsObject(responseOptions));
});
Expand Down Expand Up @@ -144,12 +150,14 @@ export default connect(
[
getCompactPermissions,
getCurrentResourcePermissionsLoading,
getViewedResourceType
getViewedResourceType,
getResourceData,
],
(compactPermissions, permissionsLoading, type) => ({
(compactPermissions, permissionsLoading, type, resource) => ({
compactPermissions,
permissionsLoading,
resourceType: type
resourceType: type,
resource
})
),
{
Expand Down
41 changes: 38 additions & 3 deletions geonode_mapstore_client/client/js/utils/ResourceUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -476,13 +476,48 @@ export const setAvailableResourceTypes = (value) => {
availableResourceTypes = value;
};

export const canManageAnonymousPermissions = (resource) => {
return resourceHasPermission(resource, 'can_manage_anonymous_permissions');
};

export const canManageRegisteredMemberPermissions = (resource) => {
return resourceHasPermission(resource, 'can_manage_registered_member_permissions');
}

/**
* Filters permission options for a group if management is disabled.
* If management is disabled, it restricts the options to only the current permission.
* @param {object} options The permissions options object.
* @param {array} groups The list of groups with their current permissions.
* @param {array} groupNames Array of group names to filter ('anonymous' or 'registered-members').
* @returns {object} Filtered permissions options
*/
const filterGroupPermissions = (options, groups, groupNames) => {
return groupNames.length
? Object.fromEntries(Object.keys(options)
.map((key) => {
if (groupNames.some(name => name === key)) {
const group = groups?.find(g => g.name === key);
const permissionValue = group?.permissions;
const currentPermission = options[key].find(p => p.name === permissionValue);
return currentPermission ? [key, [currentPermission]] : [key, options[key]];
}
return [key, options[key]];
}))
: options;
};

/**
* Extracts lists of permissions into an object for use in the Share plugin select elements
* @param {Object} options Permission Object to extract permissions from
* @returns An object containing permissions for each type of user/group
*/
export const getResourcePermissions = (options) => {
const permissionsOptions = {};
export const getResourcePermissions = (_options , groups, manageAnonymousPermissions=false, manageRegisteredMemberPermissions=false) => {
const options = filterGroupPermissions(_options, groups, [
...(manageAnonymousPermissions ? [] : ['anonymous']),
...(manageRegisteredMemberPermissions? [] : ['registered-members']),
]);
let permissionsOptions = {};
Object.keys(options).forEach((key) => {
const permissions = options[key];
let selectOptions = [];
Expand Down Expand Up @@ -897,4 +932,4 @@ export const canManageResourceSettings = (resource) => {
export const canAccessPermissions = (resource) => {
const { perms } = resource || {};
return perms?.includes('change_resourcebase_permissions');
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ describe('Test Resource Utils', () => {
}
}
}];
const permissionOptions = getResourcePermissions(data[0].allowed_perms.compact);
const groups = [];
const permissionOptions = getResourcePermissions(data[0].allowed_perms.compact, groups);
Comment on lines +116 to +117

Choose a reason for hiding this comment

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

high

The test for getResourcePermissions has been updated for the new function signature, but the new permission filtering logic is not covered by any tests. It is crucial to add tests for this new functionality to ensure it works correctly and to prevent future regressions.

Please add test cases that cover:

  • A user who can manage permissions (options should not be filtered).
  • A user who cannot manage permissions (options should be filtered to only the current permission).
  • Scenarios for both anonymous and registered-members groups.
  • Edge cases, such as when a group's current permission is not set.

expect(permissionOptions).toEqual({
test1: [
{ value: 'none', labelId: `gnviewer.nonePermission`, label: 'None' },
Expand Down