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

Image validation and size optimization for Profile image upload from both front-end and back-end #513

Open
wants to merge 16 commits into
base: master
Choose a base branch
from

Conversation

jacovkim
Copy link

@jacovkim jacovkim commented Dec 5, 2024

Added validation for extension and file size before reading.
Added validation after reading.
Added file size compression.

Some other considerations:

  1. Crop the image after resizing to preserve the ratio
  2. Placeholder image for missing profiles
  3. Might need to replace the current compression method as it's an iterative approach
  4. (Optional) Change public S3 bucket to private with AWS signing

Things to do:

  1. Should disable the "upload" button when the file exceeds the limit when editing
  2. Also clear form after uploading

Copy link

cypress bot commented Dec 5, 2024

csm_web    Run #383

Run Properties:  status check failed Failed #383  •  git commit afe899f8f4: Image validation and size optimization for Profile image upload from both front-...
Project csm_web
Branch Review feat/profiles2024/images
Run status status check failed Failed #383
Run duration 02m 08s
Commit git commit afe899f8f4: Image validation and size optimization for Profile image upload from both front-...
Committer Jacob Taegon Kim
View all properties for this run ↗︎

Test results
Tests that failed  Failures 10
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 68
View all changes introduced in this branch ↗︎

Tests for review

Failed  student-course.cy.ts • 2 failed tests • Tests on Chrome

View Output

Test Artifacts
... > should be able to enroll in a section Test Replay Screenshots
... > should be able to enroll in a section Test Replay Screenshots
Failed  restricted-courses.cy.ts • 3 failed tests • Tests on Chrome

View Output

Test Artifacts
unwhitelisted courses > should still show unrestricted courses Test Replay Screenshots
whitelisted courses > should see and enroll in whitelisted courses and sections Test Replay Screenshots
whitelisted courses > should see whitelisted courses among unrestricted courses Test Replay Screenshots
Failed  student-course.cy.ts • 2 failed tests • Tests on Firefox

View Output

Test Artifacts
... > should be able to enroll in a section Screenshots
... > should be able to enroll in a section Screenshots
Failed  restricted-courses.cy.ts • 3 failed tests • Tests on Firefox

View Output

Test Artifacts
unwhitelisted courses > should still show unrestricted courses Screenshots
whitelisted courses > should see and enroll in whitelisted courses and sections Screenshots
whitelisted courses > should see whitelisted courses among unrestricted courses Screenshots

Copy link
Member

@smartspot2 smartspot2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just did a cursory skim over the PR, but here's some of the feedback I have so far.

Also, did you mean for the target branch to be master here, or is this supposed to be targeting a main feature branch?

@@ -1 +1 @@
python-3.9.13
python-3.11.7
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably going to break things if left as-is, since ex. pyproject.toml and requirements.txt both have restrictions on the python version required for packages.

If you require Python 3.11+, I'd recommend ensuring that #477 is merged in first, and rebase on top of that. Otherwise, I'd recommend sticking to Python 3.9.

Comment on lines +55 to +58
# output from migrations
- type: bind
source: ./csm_web/scheduler/migrations/
target: /opt/csm_web/csm_web/scheduler/migrations/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to already be in the master branch; perhaps rebase?

Comment on lines +171 to +175
# Check file size
image_file.seek(0, os.SEEK_END)
file_size = image_file.tell()
# reset file pointer
image_file.seek(0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a good way of validating the file size; these lines will read in the entire file, regardless of how big it is. That means that if a user uploads a 100G file (ex. directly through the HTTP endpoint), you'll still end up reading the entire file in.

I'd recommend changing this to read in from a file stream, and manually stopping the stream when it exceeds the file size limit.

Comment on lines +255 to +270
# not very efficient but way to compress image until it meets the file target size.
def compress_image(image, target_size_bytes, img_format):
"""Compress the image until it's smaller than target_size_bytes."""
buffer = BytesIO()
quality = 95 # start with high quality
while True:
buffer.seek(0)
if img_format == "JPEG" or img_format == "JPG":
image.save(buffer, format=img_format, quality=quality)
else:
image.save(buffer, format="PNG", optimze=True)
if buffer.tell() <= target_size_bytes or quality <= 50:
break
quality -= 5 # decrease quality to reduce file size
buffer.seek(0)
return buffer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any particular reason why we're compressing the file? We have a file size limit anyways, which should be sufficient (and can be lowered) if this is for storage concerns.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be tests added for uploading images; in particular one should be added where a request is sent using a file stream that never ends, and ensuring that the request is rejected after only reading in the file size limit.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These migration files should be merged together at the end prior to merging to master, to reduce on the number of migration files in the repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants