From 122676e0aaa6ce025f659573484552372f408623 Mon Sep 17 00:00:00 2001 From: Louis des Landes Date: Wed, 6 Mar 2019 14:03:30 +1030 Subject: [PATCH] Create separate endpoint for getting file upload fields. --- missioncontrol/home/models.py | 9 ++++++--- missioncontrol/openapi/openapi.yaml | 28 +++++++++++++++++++++++++++- missioncontrol/tests/test_files.py | 23 +++++++++++++++++++++++ missioncontrol/v0/files.py | 11 ++++++++++- 4 files changed, 66 insertions(+), 5 deletions(-) diff --git a/missioncontrol/home/models.py b/missioncontrol/home/models.py index 6e5fa41..3716bd8 100644 --- a/missioncontrol/home/models.py +++ b/missioncontrol/home/models.py @@ -525,11 +525,14 @@ def get_download_url(self): return url - def get_upload_url(self): + @classmethod + def get_post_data_fields(cls, **kwargs): + # Create the object but don't save it + obj = cls(**kwargs) s3 = boto3.client('s3') post = s3.generate_presigned_post( - Bucket=self.bucket, - Key=self.key, + Bucket=obj.bucket, + Key=obj.key, ) return post diff --git a/missioncontrol/openapi/openapi.yaml b/missioncontrol/openapi/openapi.yaml index aac39f7..0724854 100644 --- a/missioncontrol/openapi/openapi.yaml +++ b/missioncontrol/openapi/openapi.yaml @@ -1160,6 +1160,32 @@ paths: application/json: schema: $ref: '#/components/schemas/Error' + /files/get_post_data_fields/: + get: + tags: ['files'] + description: Get the fields required for uploading a new file + operationId: v0.files.get_post_data_fields + parameters: + - in: query + name: cid + required: true + description: + The content ID of a file (blake2b hash) + schema: + type: string + responses: + 200: + description: The fields required for a file upload + content: + application/json: + schema: + $ref: '#/components/schemas/PostDataFields' + default: + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' /files/{cid}/: get: tags: ['files'] @@ -1546,7 +1572,7 @@ components: type: integer readOnly: true - PostUrlFields: + PostDataFields: properties: url: description: The url to post to diff --git a/missioncontrol/tests/test_files.py b/missioncontrol/tests/test_files.py index e75f1f1..0994396 100644 --- a/missioncontrol/tests/test_files.py +++ b/missioncontrol/tests/test_files.py @@ -182,3 +182,26 @@ def test_version_increment(test_client, simple_file, some_hash, another_hash): assert result1.pop('cid') == some_hash assert result2.pop('cid') == another_hash assert result1 == result2 + +# Still needs a database for the user setup. +@patch('home.models.boto3') +@pytest.mark.django_db +def test_get_post_data_fields(boto3_mock, test_client, some_hash): + post_values = { + 'url': 'https://test.example', + 'url_fields': {}, + } + boto3_mock.client.return_value.generate_presigned_post.return_value = post_values + + response = test_client.get( + f'/api/v0/files/get_post_data_fields/', + query_string={'cid': some_hash} + ) + assert response.status_code == 200, response.get_data() + + assert response.json == post_values + + boto3_mock.client.return_value.generate_presigned_post.assert_called_with( + Bucket=settings.FILE_STORAGE_PATH.split('/')[2], + Key=f'django-file-storage/{some_hash}', + ) \ No newline at end of file diff --git a/missioncontrol/v0/files.py b/missioncontrol/v0/files.py index 40b98a5..a00a496 100644 --- a/missioncontrol/v0/files.py +++ b/missioncontrol/v0/files.py @@ -44,4 +44,13 @@ def put(cid, file_body): ) obj, created = S3File.objects.update_or_create(cid=cid, defaults=file_body) retval = obj.to_dict() - return retval, 201 if created else 200 \ No newline at end of file + return retval, 201 if created else 200 + +def get_post_data_fields(cid): + if S3File.objects.filter(cid=cid).exists(): + raise ProblemException( + status=409, + title='Conflict', + detail='This cid already exists in metadata', + ) + return S3File.get_post_data_fields(cid=cid)