Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove key_file_path field #3959

Merged
merged 3 commits into from
Dec 1, 2021
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
20 changes: 0 additions & 20 deletions cvat-core/src/cloud-storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
key: undefined,
secret_key: undefined,
session_token: undefined,
key_file_path: undefined,
key_file: undefined,
specific_attributes: undefined,
owner: undefined,
Expand Down Expand Up @@ -155,21 +154,6 @@
data.session_token = value;
},
},
/**
* Key file path
* @name keyFilePath
* @type {string}
* @memberof module:API.cvat.classes.CloudStorage
* @instance
* @throws {module:API.cvat.exceptions.ArgumentError}
*/
keyFilePath: {
get: () => data.key_file_path,
set: (value) => {
validateNotEmptyString(value);
data.key_file_path = value;
},
},
/**
* Key file
* @name keyFile
Expand Down Expand Up @@ -433,10 +417,6 @@
data.session_token = cloudStorageInstance.token;
}

if (cloudStorageInstance.keyFilePath) {
data.key_file_path = cloudStorageInstance.keyFilePath;
}

if (cloudStorageInstance.keyFile) {
data.key_file = cloudStorageInstance.keyFile;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import Tooltip from 'antd/lib/tooltip';
import { CombinedState, CloudStorage } from 'reducers/interfaces';
import { createCloudStorageAsync, updateCloudStorageAsync } from 'actions/cloud-storage-actions';
import { ProviderType, CredentialsType } from 'utils/enums';
import { DeleteOutlined, UploadOutlined } from '@ant-design/icons';
import { QuestionCircleOutlined, UploadOutlined } from '@ant-design/icons';
import Upload, { RcFile } from 'antd/lib/upload';
import { Space } from 'antd';
import { AzureProvider, S3Provider, GoogleCloudProvider } from '../../icons';
Expand All @@ -31,8 +31,8 @@ export interface Props {
cloudStorage?: CloudStorage;
}

type CredentialsFormNames = 'key' | 'secret_key' | 'account_name' | 'session_token' | 'key_file_path';
type CredentialsCamelCaseNames = 'key' | 'secretKey' | 'accountName' | 'sessionToken' | 'keyFilePath';
type CredentialsFormNames = 'key' | 'secret_key' | 'account_name' | 'session_token';
type CredentialsCamelCaseNames = 'key' | 'secretKey' | 'accountName' | 'sessionToken';

interface CloudStorageForm {
credentials_type: CredentialsType;
Expand All @@ -44,7 +44,6 @@ interface CloudStorageForm {
key?: string;
secret_key?: string;
SAS_token?: string;
key_file_path?: string;
key_file?: File;
description?: string;
region?: string;
Expand All @@ -53,6 +52,8 @@ interface CloudStorageForm {
manifests: string[];
}

const { Dragger } = Upload;

export default function CreateCloudStorageForm(props: Props): JSX.Element {
const { cloudStorage } = props;
const cloudStorageId = cloudStorage ? cloudStorage.id : null;
Expand All @@ -76,21 +77,18 @@ export default function CreateCloudStorageForm(props: Props): JSX.Element {
sessionToken: 'X'.repeat(300),
key: 'X'.repeat(20),
secretKey: 'X'.repeat(40),
keyFilePath: 'X'.repeat(10),
keyFile: new File([], 'fakeKey.json'),
};

const [keyVisibility, setKeyVisibility] = useState(false);
const [secretKeyVisibility, setSecretKeyVisibility] = useState(false);
const [sessionTokenVisibility, setSessionTokenVisibility] = useState(false);
const [accountNameVisibility, setAccountNameVisibility] = useState(false);
const [keyFilePathVisibility, setKeyFilePathVisibility] = useState(false);

const [manifestNames, setManifestNames] = useState<string[]>([]);

const [keyFilePathIsDisabled, setKeyFilePathIsDisabled] = useState(false);
const [keyFileIsDisabled, setKeyFileIsDisabled] = useState(false);

const [uploadedKeyFile, setUploadedKeyFile] = useState<File | null>(null);
const [isFakeKeyFileAttached, setIsFakeKeyFileAttached] = useState(!!cloudStorage);

function initializeFields(): void {
setManifestNames(cloudStorage.manifests);
Expand All @@ -113,7 +111,7 @@ export default function CreateCloudStorageForm(props: Props): JSX.Element {
fieldsValue.key = fakeCredentialsData.key;
fieldsValue.secret_key = fakeCredentialsData.secretKey;
} else if (cloudStorage.credentialsType === CredentialsType.KEY_FILE_PATH) {
fieldsValue.key_file_path = fakeCredentialsData.keyFilePath;
setUploadedKeyFile(fakeCredentialsData.keyFile);
}

if (cloudStorage.specificAttributes) {
Expand Down Expand Up @@ -142,6 +140,7 @@ export default function CreateCloudStorageForm(props: Props): JSX.Element {
} else {
setManifestNames([]);
setSelectedRegion(undefined);
setUploadedKeyFile(null);
form.resetFields();
}
}
Expand Down Expand Up @@ -228,7 +227,7 @@ export default function CreateCloudStorageForm(props: Props): JSX.Element {

cloudStorageData.specific_attributes = specificAttributes.toString();

if (uploadedKeyFile) {
if (uploadedKeyFile && !isFakeKeyFileAttached) {
cloudStorageData.key_file = uploadedKeyFile;
}

Expand Down Expand Up @@ -259,9 +258,6 @@ export default function CreateCloudStorageForm(props: Props): JSX.Element {
if (cloudStorageData.session_token === fakeCredentialsData.sessionToken) {
delete cloudStorageData.session_token;
}
if (cloudStorageData.key_file_path === fakeCredentialsData.keyFilePath) {
delete cloudStorageData.key_file_path;
}
dispatch(updateCloudStorageAsync(cloudStorageData));
} else {
dispatch(createCloudStorageAsync(cloudStorageData));
Expand All @@ -274,8 +270,8 @@ export default function CreateCloudStorageForm(props: Props): JSX.Element {
secret_key: undefined,
session_token: undefined,
account_name: undefined,
key_file_path: undefined,
});
setUploadedKeyFile(null);
};

const onFocusCredentialsItem = (credential: CredentialsCamelCaseNames, key: CredentialsFormNames): void => {
Expand Down Expand Up @@ -419,64 +415,46 @@ export default function CreateCloudStorageForm(props: Props): JSX.Element {
if (providerType === ProviderType.GOOGLE_CLOUD_STORAGE && credentialsType === CredentialsType.KEY_FILE_PATH) {
return (
<Form.Item
name='key_file'
{...internalCommonProps}
label={(
<Tooltip title='You can specify path to key file or upload key file.
If you leave these fields blank, the environment variable will be used.'
<Tooltip title='You can upload a key file.
If you leave this field blank, the environment variable
GOOGLE_APPLICATION_CREDENTIALS will be used.'
>
Key file
<Button
href='https://cloud.google.com/docs/authentication/getting-started#setting_the_environment_variable'
target='_blank'
type='link'
className='cvat-cloud-storage-help-button'
>
<QuestionCircleOutlined />
</Button>
</Tooltip>

)}
>
<Space align='start' className='cvat-cloud-storage-form-item-key-file'>
<Form.Item
name='key_file_path'
noStyle
<Dragger
accept='.json, application/json'
multiple={false}
maxCount={1}
fileList={
uploadedKeyFile ? [{ uid: '1', name: uploadedKeyFile.name }] : []
}
beforeUpload={(file: RcFile): boolean => {
setIsFakeKeyFileAttached(false);
setUploadedKeyFile(file);
return false;
}}
onRemove={() => setUploadedKeyFile(null)}
>
<Input.Password
visibilityToggle={keyFilePathVisibility}
onChange={(e) => {
setKeyFilePathVisibility(true);
const isDisabled = !!(e.target.value);
setKeyFileIsDisabled(isDisabled);
}}
onFocus={() => onFocusCredentialsItem('keyFilePath', 'key_file_path')}
onBlur={() => onBlurCredentialsItem('keyFilePath', 'key_file_path', setKeyFilePathVisibility)}
disabled={keyFilePathIsDisabled}
/>
</Form.Item>

<Tooltip title='Attach a file'>
<Upload
accept='.json, application/json'
multiple={false}
maxCount={1}
showUploadList={false}
beforeUpload={(file: RcFile): boolean => {
if (form.getFieldValue('key_file_path')) {
form.setFieldsValue({
key_file_path: undefined,
});
}
setKeyFilePathIsDisabled(true);
setUploadedKeyFile(file);
return false;
}}
>
<Button icon={<UploadOutlined />} disabled={keyFileIsDisabled} />
</Upload>
</Tooltip>
<Tooltip title='Delete an uploaded file'>
<Button
icon={<DeleteOutlined />}
disabled={keyFileIsDisabled}
onClick={() => {
setKeyFilePathIsDisabled(false);
setUploadedKeyFile(null);
}}
/>
</Tooltip>
<Space>
Attach a file
<UploadOutlined />
</Space>
</Dragger>
</Space>
</Form.Item>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
:nth-child(1) {
flex-grow: 1;
}

:nth-child(2) {
max-width: 37 * $grid-unit-size;
}
}

> div:not(first-child) {
Expand Down
9 changes: 2 additions & 7 deletions cvat/apps/engine/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,6 @@ class CloudStorageSerializer(serializers.ModelSerializer):
session_token = serializers.CharField(max_length=440, allow_blank=True, required=False)
key = serializers.CharField(max_length=20, allow_blank=True, required=False)
secret_key = serializers.CharField(max_length=40, allow_blank=True, required=False)
key_file_path = serializers.CharField(max_length=64, allow_blank=True, required=False)
key_file = serializers.FileField(required=False)
account_name = serializers.CharField(max_length=24, allow_blank=True, required=False)
manifests = ManifestSerializer(many=True, default=[])
Expand All @@ -809,8 +808,7 @@ class Meta:
fields = (
'provider_type', 'resource', 'display_name', 'owner', 'credentials_type',
'created_date', 'updated_date', 'session_token', 'account_name', 'key',
'secret_key', 'key_file_path', 'key_file', 'specific_attributes',
'description', 'id', 'manifests',
'secret_key', 'key_file', 'specific_attributes', 'description', 'id', 'manifests',
)
read_only_fields = ('created_date', 'updated_date', 'owner')

Expand All @@ -828,8 +826,6 @@ def validate(self, attrs):
if provider_type == models.CloudProviderChoice.AZURE_CONTAINER:
if not attrs.get('account_name', ''):
raise serializers.ValidationError('Account name for Azure container was not specified')
if attrs.get('key_file', '') and attrs.get('key_file_path', ''):
raise serializers.ValidationError('Should be specified key file or key file path')
return attrs

def create(self, validated_data):
Expand All @@ -850,7 +846,7 @@ def create(self, validated_data):
key=validated_data.pop('key', ''),
secret_key=validated_data.pop('secret_key', ''),
session_token=validated_data.pop('session_token', ''),
key_file_path=validated_data.pop('key_file_path', '') or temporary_file,
key_file_path=temporary_file,
credentials_type = validated_data.get('credentials_type')
)
details = {
Expand Down Expand Up @@ -936,7 +932,6 @@ def update(self, instance, validated_data):
with NamedTemporaryFile(mode='wb', prefix='cvat', delete=False) as temp_key:
temp_key.write(key_file.read())
temporary_file = temp_key.name
# pair (key_file, key_file_path) isn't supported by server, so only one value may be specified
credentials_dict['key_file_path'] = temporary_file
key_file.close()
del key_file
Expand Down