Skip to content

Commit

Permalink
Collection upload/deprecate - fix permission checks (#4015) (#4664)
Browse files Browse the repository at this point in the history
* Collection upload/deprecate - fix permission checks

Issue: AAH-2439
Issue: AAH-2853

* CollectionHeader - move actions & permissions to CollectionDropdown

* Search,NamespaceDetail - use CollectionDropdown

* namespace detail respect namespace permissions

* fix delete collectio/ns disabled message, use description

* inline tryOpenDeleteModalWithConfirm

* deleteFn in all 3 dropdowns

* linter fix

* namespace detail - use object permissions for upload,delete,edit

* tests - constistent kebab-toggle click

* cy.openHeaderKebab - and scroll to top first

* Ratings: don't load scores outside community mode

No-Issue

* collection-kebab - switch to data-cy

* scrollTo fix

* aargh, is it a timing bug?

* upload new version is no longer available without permissions

* openHeaderKebab: add comment about the wait

(cherry picked from commit d0ad573)
  • Loading branch information
himdel authored Dec 4, 2023
1 parent 44c15a0 commit 32ebc0d
Show file tree
Hide file tree
Showing 16 changed files with 416 additions and 431 deletions.
1 change: 1 addition & 0 deletions CHANGES/2439.bug
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Collection upload/deprecate - fix permission checks
1 change: 1 addition & 0 deletions CHANGES/2853.bug
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Collection upload/deprecate - fix permission checks
189 changes: 189 additions & 0 deletions src/components/collection-detail/collection-dropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
import { t } from '@lingui/macro';
import { DropdownItem } from '@patternfly/react-core';
import React from 'react';
import { StatefulDropdown } from 'src/components';
import { useContext } from 'src/loaders/app-context';
import { DeleteCollectionUtils } from 'src/utilities';

interface IProps {
collection;
'data-cy'?: string;
deletionBlocked?: boolean;
namespace?;
onCopyVersion?;
onDelete?;
onDeleteVersion?;
onDeprecate?;
onRemove?;
onRemoveVersion?;
onSign?;
onSignVersion?;
onUploadVersion?;
version?: string;
wrapper?;
}

export const CollectionDropdown = ({
collection,
'data-cy': dataCy,
deletionBlocked,
namespace,
onCopyVersion,
onDelete,
onDeleteVersion,
onDeprecate,
onRemove,
onRemoveVersion,
onSign,
onSignVersion,
onUploadVersion,
version,
wrapper,
}: IProps) => {
const {
featureFlags: {
can_create_signatures,
can_upload_signatures,
display_repositories,
},
hasPermission,
user: { is_anonymous, is_superuser },
} = useContext();

const hasObjectPermission = (permission) =>
namespace?.related_fields?.my_permissions?.includes?.(permission);

const hasPerm = (permission) =>
hasPermission(permission) ||
hasObjectPermission(permission) ||
is_superuser;

const canCopy = display_repositories && !is_anonymous;
const canDelete =
hasPerm('ansible.delete_collection') || hasPerm('galaxy.change_namespace');
const canDeprecate = hasPerm('galaxy.change_namespace');
const canRemove = canDelete && display_repositories;
const canSign =
can_create_signatures &&
!can_upload_signatures &&
hasPerm('galaxy.change_namespace') &&
hasPerm('galaxy.upload_to_namespace');
const canUpload = hasPerm('galaxy.upload_to_namespace');

const Wrapper =
wrapper || (({ any, children }) => (any ? <>{children}</> : null));

const DeleteWrapper = ({
addAlert,
caption,
collection,
'data-cy': dataCy,
openModal,
skipCheck,
}: {
addAlert?;
caption: string;
collection?;
'data-cy'?: string;
openModal;
skipCheck?;
}) =>
deletionBlocked ? (
<DropdownItem
isDisabled
description={t`Cannot delete until collections that depend on this collection have been deleted.`}
>
{caption}
</DropdownItem>
) : (
<DropdownItem
data-cy={dataCy}
onClick={() =>
skipCheck
? openModal()
: DeleteCollectionUtils.countUsedbyDependencies(collection)
.then((count) => {
if (count) {
addAlert({
title: t`Cannot delete until collections that depend on this collection have been deleted.`,
variant: 'warning',
});
return;
}

openModal();
})
.catch(addAlert)
}
>
{caption}
</DropdownItem>
);

const dropdownItems = [
canDelete && onDelete && (
<DeleteWrapper
caption={t`Delete collection from system`}
data-cy='delete-collection'
key='delete-collection'
{...onDelete}
/>
),
canRemove && onRemove && (
<DeleteWrapper
caption={t`Remove collection from repository`}
key='remove-collection'
{...onRemove}
/>
),
canDelete && onDeleteVersion && (
<DropdownItem
data-cy='delete-collection-version'
key='delete-collection-version'
onClick={onDeleteVersion}
>
{t`Delete version ${version} from system`}
</DropdownItem>
),
canRemove && onRemoveVersion && (
<DropdownItem key='remove-collection-version' onClick={onRemoveVersion}>
{t`Remove version ${version} from repository`}
</DropdownItem>
),
canSign && onSign && (
<DropdownItem key='sign-collection' onClick={onSign}>
{t`Sign collection`}
</DropdownItem>
),
canSign && onSignVersion && (
<DropdownItem key='sign-collection-version' onClick={onSignVersion}>
{t`Sign version ${version}`}
</DropdownItem>
),
canDeprecate && onDeprecate && (
<DropdownItem onClick={onDeprecate} key='deprecate-collection'>
{collection.is_deprecated ? t`Undeprecate` : t`Deprecate`}
</DropdownItem>
),
canUpload && onUploadVersion && (
<DropdownItem key='upload-collection-version' onClick={onUploadVersion}>
{t`Upload new version`}
</DropdownItem>
),
canCopy && onCopyVersion && (
<DropdownItem
key='copy-collection-version-to-repository-dropdown'
onClick={onCopyVersion}
data-cy='copy-collection-version-to-repository-dropdown'
>
{t`Copy version ${version} to repositories`}
</DropdownItem>
),
].filter(Boolean);

return (
<Wrapper any={dropdownItems.length}>
<StatefulDropdown data-cy={dataCy} items={dropdownItems} />
</Wrapper>
);
};
Loading

0 comments on commit 32ebc0d

Please sign in to comment.