Skip to content

Commit

Permalink
Handle undefined cacert Credentials field for copy clipboard action
Browse files Browse the repository at this point in the history
When cacert is empty (and set to undefined) then trying to copy the field
value to clipboard causes a NPE.

This is 100% reproducable for all providers.

Fixing that by avoid rendering the copy clipboard component in case of an empty
value field.

Signed-off-by: Sharon Gratch <[email protected]>
  • Loading branch information
sgratch committed Apr 16, 2024
1 parent 61171dd commit 607df96
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 74 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import { useForkliftTranslation } from 'src/utils/i18n';

import { ClipboardCopy, ClipboardCopyVariant, TextInput } from '@patternfly/react-core';

export interface ShowFieldWithClipboardCopyProps {
value: string;
}

/**
* Show a readable field value.
* If value is an empty string, show a field read ony text with a proper text message.
* If value is a non empty string, show a read only field with a copy clipboard button
*
* @property value - field value
*/
export const ShowFieldWithClipboardCopy: React.FC<ShowFieldWithClipboardCopyProps> = ({
value,
}) => {
const { t } = useForkliftTranslation();

return value ? (
<ClipboardCopy
isReadOnly
hoverTip={t('Copy')}
clickTip={t('Copied')}
isCode
variant={value && value.length > 128 ? ClipboardCopyVariant.expansion : undefined}
>
{value}
</ClipboardCopy>
) : (
<TextInput value={'< No value >'} type="text" isDisabled />
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import React from 'react';

import { TextInput } from '@patternfly/react-core';

export const MaskedData: React.FC = () => {
/**
* Show a readable masked (hidden) field value.
*/
export const ShowMaskedField: React.FC = () => {
return <TextInput value="&bull;&bull;&bull;&bull;&bull;" type="text" isDisabled />;
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React from 'react';
import { Base64 } from 'js-base64';
import { ForkliftTrans, useForkliftTranslation } from 'src/utils/i18n';

import { ClipboardCopy, ClipboardCopyVariant, Text, TextVariants } from '@patternfly/react-core';
import { Text, TextVariants } from '@patternfly/react-core';

import { MaskedData } from '../../MaskedData';
import { ShowFieldWithClipboardCopy, ShowMaskedField } from '../../';
import { ListComponentProps } from '../BaseCredentialsSection';

export const OpenshiftCredentialsList: React.FC<ListComponentProps> = ({ secret, reveal }) => {
Expand Down Expand Up @@ -78,19 +78,7 @@ export const OpenshiftCredentialsList: React.FC<ListComponentProps> = ({ secret,
</Text>
</div>
<div className="forklift-page-secret-content-div">
{reveal ? (
<ClipboardCopy
isReadOnly
hoverTip={t('Copy')}
clickTip={t('Copied')}
isCode
variant={value && value.length > 128 ? ClipboardCopyVariant.expansion : undefined}
>
{value}
</ClipboardCopy>
) : (
<MaskedData />
)}
{reveal ? <ShowFieldWithClipboardCopy value={value} /> : <ShowMaskedField />}
</div>
</>,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,9 @@ import { Base64 } from 'js-base64';
import { DetailsItem } from 'src/modules/Providers/utils';
import { ForkliftTrans, useForkliftTranslation } from 'src/utils/i18n';

import {
ClipboardCopy,
ClipboardCopyVariant,
DescriptionList,
Text,
TextVariants,
} from '@patternfly/react-core';
import { DescriptionList, Text, TextVariants } from '@patternfly/react-core';

import { MaskedData } from '../../MaskedData';
import { ShowFieldWithClipboardCopy, ShowMaskedField } from '../../';
import { ListComponentProps } from '../BaseCredentialsSection';

export const OpenstackCredentialsList: React.FC<ListComponentProps> = ({ secret, reveal }) => {
Expand Down Expand Up @@ -256,19 +250,7 @@ export const OpenstackCredentialsList: React.FC<ListComponentProps> = ({ secret,
</Text>
</div>
<div className="forklift-page-secret-content-div">
{reveal ? (
<ClipboardCopy
isReadOnly
hoverTip={t('Copy')}
clickTip={t('Copied')}
isCode
variant={value && value.length > 128 ? ClipboardCopyVariant.expansion : undefined}
>
{value}
</ClipboardCopy>
) : (
<MaskedData />
)}
{reveal ? <ShowFieldWithClipboardCopy value={value} /> : <ShowMaskedField />}
</div>
</>,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,9 @@ import { Base64 } from 'js-base64';
import { DetailsItem } from 'src/modules/Providers/utils';
import { ForkliftTrans, useForkliftTranslation } from 'src/utils/i18n';

import {
ClipboardCopy,
ClipboardCopyVariant,
DescriptionList,
Text,
TextVariants,
} from '@patternfly/react-core';
import { DescriptionList, Text, TextVariants } from '@patternfly/react-core';

import { MaskedData } from '../../MaskedData';
import { ShowFieldWithClipboardCopy, ShowMaskedField } from '../../';
import { ListComponentProps } from '../BaseCredentialsSection';

export const OvirtCredentialsList: React.FC<ListComponentProps> = ({ secret, reveal }) => {
Expand Down Expand Up @@ -97,19 +91,7 @@ export const OvirtCredentialsList: React.FC<ListComponentProps> = ({ secret, rev
</Text>
</div>
<div className="forklift-page-secret-content-div">
{reveal ? (
<ClipboardCopy
isReadOnly
hoverTip={t('Copy')}
clickTip={t('Copied')}
isCode
variant={value && value.length > 128 ? ClipboardCopyVariant.expansion : undefined}
>
{value}
</ClipboardCopy>
) : (
<MaskedData />
)}
{reveal ? <ShowFieldWithClipboardCopy value={value} /> : <ShowMaskedField />}
</div>
</>,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React from 'react';
import { Base64 } from 'js-base64';
import { ForkliftTrans, useForkliftTranslation } from 'src/utils/i18n';

import { ClipboardCopy, ClipboardCopyVariant, Text, TextVariants } from '@patternfly/react-core';
import { Text, TextVariants } from '@patternfly/react-core';

import { MaskedData } from '../../MaskedData';
import { ShowFieldWithClipboardCopy, ShowMaskedField } from '../../';
import { ListComponentProps } from '../BaseCredentialsSection';

export const VSphereCredentialsList: React.FC<ListComponentProps> = ({ secret, reveal }) => {
Expand Down Expand Up @@ -82,19 +82,7 @@ export const VSphereCredentialsList: React.FC<ListComponentProps> = ({ secret, r
</Text>
</div>
<div className="forklift-page-secret-content-div">
{reveal ? (
<ClipboardCopy
isReadOnly
hoverTip={t('Copy')}
clickTip={t('Copied')}
isCode
variant={value && value.length > 128 ? ClipboardCopyVariant.expansion : undefined}
>
{value}
</ClipboardCopy>
) : (
<MaskedData />
)}
{reveal ? <ShowFieldWithClipboardCopy value={value} /> : <ShowMaskedField />}
</div>
</>,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
export * from './components';
export * from './CredentialsSection';
export * from './EsxiCredentialsSection';
export * from './MaskedData';
export * from './OpenshiftCredentialsSection';
export * from './OpenstackCredentialsSection';
export * from './OvirtCredentialsSection';
export * from './ShowFieldWithClipboardCopy';
export * from './ShowMaskedField';
export * from './VCenterCredentialsSection';
// @endindex

0 comments on commit 607df96

Please sign in to comment.