1.remove aws related code

This commit is contained in:
Kent Wang
2025-01-06 14:48:48 +08:00
parent 3bb0e6f5b1
commit 61f3052113
4 changed files with 0 additions and 475 deletions

View File

@@ -1,184 +0,0 @@
import React, { useState } from 'react';
import { Button, Menu, MenuItem, MenuTrigger, Popover } from 'react-aria-components';
import { useFetcher } from 'react-router-dom';
import { type CloudProviderCredential, type CloudProviderName, getProviderDisplayName } from '../../../models/cloud-credential';
import { usePlanData } from '../../hooks/use-plan';
import { useRootLoaderData } from '../../routes/root';
import { Icon } from '../icon';
import { showModal } from '../modals';
import { AskModal } from '../modals/ask-modal';
import { CloudCredentialModal } from '../modals/cloud-credential-modal/cloud-credential-modal';
import { UpgradeNotice } from '../upgrade-notices';
import { NumberSetting } from './number-setting';
interface createCredentialItemType {
name: string;
id: CloudProviderName;
}
const createCredentialItemList: createCredentialItemType[] = [
{
id: 'aws',
name: getProviderDisplayName('aws'),
},
// TODO only support aws for now
// {
// id: 'azure',
// name: getProviderDisplayName('azure'),
// },
// {
// id: 'gcp',
// name: getProviderDisplayName('gcp'),
// },
];
const buttonClassName = 'disabled:opacity-50 h-7 aspect-square aria-pressed:bg-[--hl-sm] rounded-sm text-[--color-font] hover:bg-[--hl-xs] transition-all text-sm py-1 px-2';
export const CloudServiceCredentialList = () => {
const { isOwner, isEnterprisePlan } = usePlanData();
const { cloudCredentials } = useRootLoaderData();
const [modalState, setModalState] = useState<{ show: boolean; provider: CloudProviderName; credential?: CloudProviderCredential }>();
const deleteCredentialFetcher = useFetcher();
const handleDeleteItem = (id: string, name: string) => {
showModal(AskModal, {
title: 'Delete Cloud Credential?',
message: `Are you sure to delete ${name}?`,
onDone: async (isYes: boolean) => {
if (isYes) {
deleteCredentialFetcher.submit({}, {
action: `/cloud-credential/${id}/delete`,
method: 'delete',
});
}
},
});
};
const hideModal = () => {
setModalState(prevState => {
const newState = {
show: false,
provider: prevState!.provider,
credentials: undefined,
};
return newState;
});
};
if (!isEnterprisePlan) {
return (
<UpgradeNotice
isOwner={isOwner}
featureName='Cloud Credentials feature'
newPlan='enterprise'
/>
);
}
return (
<div>
<div className='flex justify-between items-end'>
<h2 className='font-bold text-lg bg-[--color-bg] z-10'>Service Provider Credential List</h2>
<MenuTrigger>
<Button
aria-label="Create in project"
className="flex items-center justify-center px-4 py-2 gap-2 h-full bg-[--hl-xxs] aria-pressed:bg-[--hl-sm] rounded-sm text-[--color-font] hover:bg-[--hl-xs] focus:ring-inset ring-1 ring-transparent focus:ring-[--hl-md] transition-all text-sm"
>
<Icon icon="plus-circle" /> Add Credential
</Button>
<Popover
className="min-w-max"
placement='bottom right'
>
<Menu
aria-label="Create in project actions"
selectionMode="single"
onAction={key => setModalState({ show: true, provider: key as CloudProviderName })}
items={createCredentialItemList}
className="border select-none text-sm min-w-max border-solid border-[--hl-sm] shadow-lg bg-[--color-bg] py-2 rounded-md overflow-y-auto max-h-[85vh] focus:outline-none"
>
{item => (
<MenuItem
key={item.id}
id={item.id}
className="flex gap-2 px-[--padding-md] aria-selected:font-bold items-center text-[--color-font] h-[--line-height-xxs] w-full text-md whitespace-nowrap bg-transparent hover:bg-[--hl-sm] disabled:cursor-not-allowed focus:bg-[--hl-xs] focus:outline-none transition-colors"
aria-label={item.name}
>
<span>{item.name}</span>
</MenuItem>
)}
</Menu>
</Popover>
</MenuTrigger>
</div>
{cloudCredentials.length === 0 ?
<div className="text-center faint italic pad">No cloud servicie provider credentials found</div> :
<table className="table--fancy table--striped table--valign-middle margin-top margin-bottom">
<thead>
<tr>
<th className='normal-case'>Name</th>
<th className='normal-case'>Service Provider</th>
<th className='normal-case'>Action</th>
</tr>
</thead>
<tbody>
{cloudCredentials.map(cloudCred => {
const { _id, name, provider } = cloudCred;
return (
<tr key={_id}>
<td >
{name}
</td>
<td className='w-36'>
{getProviderDisplayName(provider!)}
</td>
<td className='w-52 whitespace-nowrap'>
<div className='flex gap-2'>
<Button
className={`${buttonClassName} w-16`}
onPress={() => setModalState({ show: true, provider: provider!, credential: cloudCred })}
>
<Icon icon="edit" />&nbsp;&nbsp;Edit
</Button>
<Button
className={`${buttonClassName} w-20`}
onPress={() => handleDeleteItem(_id, name)}
>
<Icon icon="trash" />&nbsp;&nbsp;Delete
</Button>
</div>
</td>
</tr>
);
})}
</tbody>
</table>
}
<div>
<h2 className='font-bold pt-5 pb-2 text-lg bg-[--color-bg] z-10'>Cloud Secret Config</h2>
<div className="form-row items-end justify-between">
<NumberSetting
label="Secret Cache Duration(min)"
setting="vaultSecretCacheDuration"
help="Enter the amount of time in minutes external vault secrets are cached in Insomnia. Enter 0 to disable cache. Click the Reset Cache button to clear all cache."
min={0}
max={720}
/>
<button
className="w-32 flex items-center gap-2 border border-solid border-[--hl-lg] px-[--padding-md] h-[--line-height-xs] rounded-[--radius-md] hover:bg-[--hl-xs] pointer mb-[--padding-sm] ml-[--padding-sm]"
onClick={() => window.main.cloudService.clearCache()}
>
Reset Cache
</button>
</div>
</div>
{modalState && modalState.show &&
<CloudCredentialModal
provider={modalState.provider}
providerCredential={modalState.credential}
onClose={hideModal}
/>
}
</div>
);
};

View File

@@ -1,132 +0,0 @@
import React, { useState } from 'react';
import type { AWSSecretConfig } from '../../../../main/ipc/cloud-service-integration/types';
import type { NunjucksParsedTag } from '../../../../templating/utils';
import { HelpTooltip } from '../../help-tooltip';
export interface AWSSecretManagerFormProps {
formData: AWSSecretConfig;
onChange: (newConfig: AWSSecretConfig) => void;
activeTagData: NunjucksParsedTag;
}
const secretTypeOptions = [
{
key: 'plaintext',
label: 'Plaintext',
},
{
key: 'kv',
label: 'Key/Value',
},
];
export const AWSSecretManagerForm = (props: AWSSecretManagerFormProps) => {
const { formData, onChange } = props;
const {
SecretId,
SecretType,
VersionId = '',
VersionStage = '',
SecretKey = '',
} = formData;
const [showSecretKeyInput, setShowSecretKeyInput] = useState(SecretType === 'kv');
const handleOnChange = (name: keyof AWSSecretConfig) => {
const formElement = document.getElementById('aws-secret-manager-form') as HTMLFormElement;
if (formElement) {
const formData = new FormData(formElement);
const newConfig = Object.fromEntries(formData.entries());
if (name === 'SecretType') {
const secretTypeValue = newConfig['SecretType'];
setShowSecretKeyInput(secretTypeValue === 'kv');
if (secretTypeValue === 'plaintext') {
newConfig['SecretKey'] = '';
}
};
onChange(newConfig as unknown as AWSSecretConfig);
}
};
return (
<form id='aws-secret-manager-form'>
<div className="form-row">
<div className="form-control">
<label>
Secret Name Or ARN
<HelpTooltip className="space-left">
The ARN or name of the secret to retrieve. To retrieve a secret from another account, you must use an ARN.
</HelpTooltip>
<input
name='SecretId'
defaultValue={SecretId}
onChange={() => handleOnChange('SecretId')}
/>
</label>
</div>
</div>
<div className="form-row">
<div className="form-control">
<label>
Version Id
<HelpTooltip className="space-left">
Optional unique identifier of the version of the secret to retrieve.
</HelpTooltip>
<input
name='VersionId'
defaultValue={VersionId}
onChange={() => handleOnChange('VersionId')}
/>
</label>
</div>
</div>
<div className="form-row">
<div className="form-control">
<label>
Version Stage
<HelpTooltip className="space-left">
Optional staging label of the version of the secret to retrieve.
</HelpTooltip>
<input
name='VersionStage'
defaultValue={VersionStage}
onChange={() => handleOnChange('VersionStage')}
/>
</label>
</div>
</div>
<div className="form-row">
<div className="form-control">
<label>
Secret Type
<select
name='SecretType'
defaultValue={SecretType || 'plaintext'}
onChange={() => handleOnChange('SecretType')}
>
{secretTypeOptions.map(option => (
<option key={option.key} value={option.key}>
{option.label}
</option>
))}
</select>
</label>
</div>
</div>
{showSecretKeyInput &&
<div className="form-row">
<div className="form-control">
<label>
Secret Key
<HelpTooltip className="space-left">
The Secret Key of the retrived key/value secrets.
</HelpTooltip>
<input
name='SecretKey'
defaultValue={SecretKey}
onChange={() => handleOnChange('SecretKey')}
/>
</label>
</div>
</div>
}
</form>
);
};

View File

@@ -1,60 +0,0 @@
import React, { useState } from 'react';
import { Button } from 'react-aria-components';
import { debounce } from '../../../../common/misc';
import type { AWSSecretConfig } from '../../../../main/ipc/cloud-service-integration/types';
import { type CloudProviderCredential, type CloudProviderName, type } from '../../../../models/cloud-credential';
import { Icon } from '../../icon';
import { CloudCredentialModal } from '../../modals/cloud-credential-modal/cloud-credential-modal';
import type { ArgConfigFormProps } from '../tag-editor-arg-sub-form';
import { AWSSecretManagerForm } from './aws-secret-manager-form';
export const ExternalVaultForm = (props: ArgConfigFormProps) => {
const { onChange, configValue, activeTagData, docs } = props;
const [showModal, setShowModal] = useState(false);
const formData = JSON.parse(configValue) as AWSSecretConfig;
const provider = activeTagData.args[0].value as CloudProviderName;
const selectedCredentialId = activeTagData.args[1].value;
const cloudCredentialDocs = docs[type] as CloudProviderCredential[] || [];
const selectedCredentialDoc = cloudCredentialDocs.find(d => d._id === selectedCredentialId);
const handleFormChange = debounce((newConfig: AWSSecretConfig) => {
const newFormValue = JSON.stringify(newConfig);
onChange(newFormValue);
}, 1000);
let SubForm;
switch (provider) {
case 'aws':
SubForm = <AWSSecretManagerForm
formData={formData}
onChange={handleFormChange}
activeTagData={activeTagData}
/>;
break;
default:
SubForm = null;
};
return (
<>
{selectedCredentialDoc &&
<Button
className="px-2 py-1 mb-[--padding-sm] h-full flex items-center justify-center gap-2 aria-pressed:bg-[--hl-sm] text-[--color-info] text-xs hover:bg-[--hl-xs] focus:ring-inset ring-1 ring-transparent focus:ring-[--hl-md] transition-all"
style={{ marginTop: 'calc(var(--padding-sm) * -1)' }}
onPress={() => setShowModal(true)}
>
<Icon icon="edit" /> Edit Credential
</Button>
}
{SubForm}
{showModal &&
<CloudCredentialModal
provider={provider}
providerCredential={selectedCredentialDoc}
onClose={() => setShowModal(false)}
/>
}
</>
);
};

View File

@@ -7,11 +7,6 @@ import os from 'os';
import { CookieJar } from 'tough-cookie';
import * as uuid from 'uuid';
import type { RenderPurpose } from '../../../common/render';
import type { AWSSecretConfig } from '../../../main/ipc/cloud-service-integration/types';
import * as models from '../../../models';
import type { CloudProviderCredential, CloudProviderName } from '../../../models/cloud-credential';
import { vaultEnvironmentMaskValue } from '../../../models/environment';
import type { Request, RequestParameter } from '../../../models/request';
import type { Response } from '../../../models/response';
import type { TemplateTag } from '../../../plugins';
@@ -21,100 +16,6 @@ import { buildQueryStringFromParams, joinUrlAndQueryString, smartEncodeUrl } fro
import { fakerFunctions } from './faker-functions';
const localTemplatePlugins: { templateTag: PluginTemplateTag }[] = [
{
templateTag: {
name: 'vault',
displayName: 'External Vault',
description: 'Link secret from external vault',
// external vault is an enterprise feature
needsEnterprisePlan: true,
args: [
{
displayName: 'Vault Service Provider',
type: 'enum',
options: [
{ displayName: 'AWS Secrets Manager', value: 'aws' },
],
},
{
displayName: 'Credential For Vault Service Provider',
type: 'model',
modelFilter: (credentialModel, args) => {
const providerNameFromArg = args[0].value;
const { provider } = credentialModel as CloudProviderCredential;
return providerNameFromArg === provider;
},
model: 'CloudCredential',
},
{
type: 'string',
defaultValue: '{}',
requireSubForm: true,
},
],
async run(context, provider: CloudProviderName, credentialId: string, configStr: string) {
if (!provider) {
throw new Error('Vault service provider is required');
}
if (!credentialId) {
throw new Error('Credential is required');
};
const providerCredential = await models.cloudCrendential.getById(credentialId);
if (!providerCredential) {
throw new Error('No Cloud Credential found');
}
const renderContext = context.renderPurpose as RenderPurpose;
// Get secret from external vaults when send request or in tag-preview, otherwise return defautl mask value
if (renderContext === 'preview' || renderContext === 'send') {
let secretConfig = {};
try {
secretConfig = JSON.parse(configStr);
} catch (error) {
throw new Error('Invalid vault secret config');
}
if (provider === 'aws') {
const {
SecretId, VersionId, VersionStage, SecretKey,
SecretType = 'plaintext',
} = secretConfig as AWSSecretConfig;
if (!SecretId) {
throw new Error('Secret Name or ARN is required');
}
const getSecretOption = {
provider,
secretId: SecretId,
config: {
VersionId, VersionStage,
},
credentials: providerCredential.credentials,
};
const secretResult = await window.main.cloudService.getSecret(getSecretOption);
const { success, error, result } = secretResult;
if (success && result) {
const { SecretString } = result!;
let parsedJSON;
if (SecretType === 'plaintext' || !SecretKey) {
return SecretString;
} else {
try {
parsedJSON = JSON.parse(SecretString || '{}');
} catch (error) {
throw new Error(`Secret value ${SecretString} can not parsed to key/value pair, please change Secret Type to plaintext`);
}
if (SecretKey in parsedJSON) {
return parsedJSON[SecretKey];
}
throw new Error(`Secret key ${SecretKey} does not exist in key/value secret ${SecretString}`);
}
} else {
throw new Error(error?.errorMessage);
}
}
}
return vaultEnvironmentMaskValue;
},
},
},
{
templateTag: {
name: 'faker',