Skip to content

Commit

Permalink
Fixed: Incorrect expiration time was calculated for signed uploads ca…
Browse files Browse the repository at this point in the history
…using the `AuthenticationError: Expired signature` exception
  • Loading branch information
evgkirov committed Sep 8, 2023
1 parent 94474fd commit 38a0a6b
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 6 deletions.
6 changes: 6 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ The format is based on [Keep a
Changelog](https://keepachangelog.com/en/1.0.0/), and this project
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [4.1.2](https://github.com/uploadcare/pyuploadcare/compare/v4.1.1...v4.1.2) - 2023-09-08

### Fixed

- Incorrect expiration time was calculated for signed uploads causing the `AuthenticationError: Expired signature` exception.

## [4.1.1](https://github.com/uploadcare/pyuploadcare/compare/v4.1.0...v4.1.1) - 2023-09-04

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pyuploadcare"
version = "4.1.1"
version = "4.1.2"
description = "Python library for Uploadcare.com"
authors = ["Uploadcare Inc <[email protected]>"]
readme = "README.md"
Expand Down
2 changes: 1 addition & 1 deletion pyuploadcare/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# isort: skip_file
__version__ = "4.1.1"
__version__ = "4.1.2"

from pyuploadcare.resources.file import File # noqa: F401
from pyuploadcare.resources.file_group import FileGroup # noqa: F401
Expand Down
9 changes: 5 additions & 4 deletions pyuploadcare/client.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import socket
from time import time
from typing import (
IO,
Any,
Expand Down Expand Up @@ -373,7 +374,7 @@ def _file_name(file_object, index):
files=files,
store=self._format_store(store),
secure_upload=self.signed_uploads,
expire=self.signed_uploads_ttl,
expire=int(time()) + self.signed_uploads_ttl,
common_metadata=common_metadata,
)
ucare_files = [self.file(response[file_name]) for file_name in files]
Expand Down Expand Up @@ -425,7 +426,7 @@ def multipart_upload( # noqa: C901
content_type=mime_type,
store=self._format_store(store),
secure_upload=self.signed_uploads,
expire=self.signed_uploads_ttl,
expire=int(time()) + self.signed_uploads_ttl,
metadata=metadata,
)

Expand Down Expand Up @@ -495,7 +496,7 @@ def upload_from_url(
filename=filename,
metadata=metadata,
secure_upload=self.signed_uploads,
expire=self.signed_uploads_ttl,
expire=int(time()) + self.signed_uploads_ttl,
check_duplicates=check_duplicates,
save_duplicates=save_duplicates,
)
Expand Down Expand Up @@ -647,7 +648,7 @@ def create_file_group(self, files: List[File]) -> FileGroup:
group_info = self.upload_api.create_group(
files=file_urls,
secure_upload=self.signed_uploads,
expire=self.signed_uploads_ttl,
expire=int(time()) + self.signed_uploads_ttl,
)

group = self.file_group(group_info["id"], group_info)
Expand Down
27 changes: 27 additions & 0 deletions tests/functional/resources/test_resources.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import os
from datetime import datetime, timedelta
from unittest.mock import MagicMock, patch

import pytest

Expand Down Expand Up @@ -134,6 +136,31 @@ def test_file_upload_multiple(small_file, small_file2, uploadcare):
)


@pytest.mark.freeze_time("2021-10-12")
def test_file_upload_signature(small_file, uploadcare, signed_uploads):
assert uploadcare.signed_uploads
fake_response = MagicMock()
fake_response.json.return_value = {
"sample1.txt": "96e0a8f8-91f3-4162-907d-2d67d36ebae8"
}
with open(small_file.name, "rb") as fh:
with patch.object(
uploadcare.upload_api._client, "post", return_value=fake_response
) as mocked_post:
response = uploadcare.upload(fh)

Check notice

Code scanning / CodeQL

Unused local variable Note test

Variable response is not used.

assert mocked_post.called
data = mocked_post.call_args.kwargs["data"]
expected_expire = datetime.now() + timedelta(
seconds=uploadcare.signed_uploads_ttl
)
assert data["expire"] == str(int(expected_expire.timestamp()))
assert (
data["signature"]
== "f7d27174ad85736b9a4ace81a3cf420b99b2ddc78415b00adfc0c326a39cb490"
)


@pytest.mark.vcr
def test_file_create_local_copy(uploadcare):
file = uploadcare.file("35ea470d-216c-4752-91d2-5176b34c1225")
Expand Down

0 comments on commit 38a0a6b

Please sign in to comment.