Merge pull request #24834 from backstage/blam/replace-password-widget

scaffolder: replace `ui:widget: password` with a warning message
This commit is contained in:
Ben Lambert
2024-06-18 10:48:33 +02:00
committed by GitHub
8 changed files with 172 additions and 21 deletions
@@ -33,6 +33,7 @@ import { TemplateGroupFilter } from '@backstage/plugin-scaffolder-react';
import { TemplateParameterSchema } from '@backstage/plugin-scaffolder-react';
import { TemplatePresentationV1beta3 } from '@backstage/plugin-scaffolder-common';
import { UiSchema } from '@rjsf/utils';
import { WidgetProps } from '@rjsf/utils';
// @alpha (undocumented)
export type BackstageOverrides = Overrides & {
@@ -149,6 +150,11 @@ export type ScaffolderReactComponentsNameToClassKey = {
// @alpha (undocumented)
export type ScaffolderReactTemplateCategoryPickerClassKey = 'root' | 'label';
// @alpha
export const SecretWidget: (
props: Pick<WidgetProps, 'name' | 'onChange' | 'schema'>,
) => React_2.JSX.Element;
// @alpha
export const Stepper: (stepperProps: StepperProps) => React_2.JSX.Element;
@@ -0,0 +1,53 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { WidgetProps } from '@rjsf/utils';
import InputLabel from '@material-ui/core/InputLabel';
import Input from '@material-ui/core/Input';
import React from 'react';
import FormHelperText from '@material-ui/core/FormHelperText';
import { MarkdownContent } from '@backstage/core-components';
export const PasswordWidget = (
props: Pick<WidgetProps, 'onChange' | 'schema' | 'value'>,
) => {
const {
value,
onChange,
schema: { title },
} = props;
return (
<>
<InputLabel htmlFor={title}>{title}</InputLabel>
<Input
id={title}
aria-describedby={title}
onChange={e => {
onChange(e.target.value);
}}
value={value}
autoComplete="off"
/>
<FormHelperText error>
<MarkdownContent
content="This widget is insecure. Please use [`ui:field: Secret`](https://backstage.io/docs/features/software-templates/writing-templates/#using-secrets) instead of
`ui:widget: password`"
/>
</FormHelperText>
</>
);
};
@@ -0,0 +1,53 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { WidgetProps } from '@rjsf/utils';
import { useTemplateSecrets } from '@backstage/plugin-scaffolder-react';
import InputLabel from '@material-ui/core/InputLabel';
import Input from '@material-ui/core/Input';
import React from 'react';
/**
* Secret Widget for overriding the default password input widget
* @alpha
*/
export const SecretWidget = (
props: Pick<WidgetProps, 'name' | 'onChange' | 'schema'>,
) => {
const { setSecrets, secrets } = useTemplateSecrets();
const {
name,
onChange,
schema: { title },
} = props;
return (
<>
<InputLabel htmlFor={title}>{title}</InputLabel>
<Input
id={title}
aria-describedby={title}
onChange={e => {
onChange(Array(e.target?.value.length).fill('*').join(''));
setSecrets({ [name]: e.target?.value });
}}
value={secrets[name] ?? ''}
type="password"
autoComplete="off"
/>
</>
);
};
@@ -0,0 +1,16 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export * from './SecretWidget';
@@ -20,7 +20,6 @@ import MuiStep from '@material-ui/core/Step';
import MuiStepLabel from '@material-ui/core/StepLabel';
import Button from '@material-ui/core/Button';
import LinearProgress from '@material-ui/core/LinearProgress';
import { makeStyles } from '@material-ui/core/styles';
import { type IChangeEvent } from '@rjsf/core';
import { ErrorSchema } from '@rjsf/utils';
import React, {
@@ -49,6 +48,8 @@ import {
} from '@backstage/plugin-scaffolder-react';
import { ReviewStepProps } from '@backstage/plugin-scaffolder-react';
import { ErrorListTemplate } from './ErrorListTemplate';
import { makeStyles } from '@material-ui/core/styles';
import { PasswordWidget } from '../PasswordWidget/PasswordWidget';
const useStyles = makeStyles(theme => ({
backButton: {
@@ -232,6 +233,7 @@ export const Stepper = (stepperProps: StepperProps) => {
showErrorList="top"
templates={{ ErrorListTemplate }}
onChange={handleChange}
widgets={{ password: PasswordWidget }}
experimental_defaultFormStateBehavior={{
allOf: 'populateDefaults',
}}
@@ -26,3 +26,4 @@ export * from './TaskLogStream';
export * from './TemplateCategoryPicker';
export * from './ScaffolderPageContextMenu';
export * from './ScaffolderField';
export * from './SecretWidget';