Files
edx-platform/openedx
Florian Haas 26281cbe36 Fix profile image URLs for image storage on non-public S3 buckets
In image_helpers.py, the _get_profile_image_urls() method would append
"?v=<version>" to the query string for serving profile images.

This might break serving profile images if

* EDXAPP_PROFILE_IMAGE_BACKEND was configured with its class option
  set to django.storages.s3boto3.S3Boto3Storage (or its deprecated
  predecedessor, django.storages.s3boto.S3BotoStorage), and
* that backend used signed URLs with query-string authentication (i.e.
  was *not* configured with an S3 custom domain).

When both the above conditions are met, then the URL returned by the
storage backend's url() method already contains "?", and
_get_profile_image_urls() would add another. This results in a query
string that doesn't exactly violate RFC 3986, but is discouraged by
it.[1]

Amazon S3 itself may be able to parse these query strings correctly,
but other S3 API implementations (such as Ceph radosgw[2]) may not,
and the problem is easily avoided by just looking for "?" in the
rendered URL, and using "&v=<version>" instead if we find a match.

The proper way of appending the v=<version> query parameter would
probably be to pull the URL and the query string apart and then back
together[3], but that's most likely overdoing it.

[1] https://tools.ietf.org/html/rfc3986#section-3.4 says:
"However, as query components are often used to carry identifying
information in the form of "key=value" pairs and one frequently used
value is a reference to another URI, it is sometimes better for
usability to avoid percent- encoding those characters." ("Those
characters" being "/" and "?".)

[2] https://docs.ceph.com/docs/master/radosgw/s3/

[3] https://docs.python.org/3/library/urllib.parse.html
2020-07-06 11:09:16 +02:00
..

Open edX
--------

This is the root package for Open edX. The intent is that all importable code
from Open edX will eventually live here, including the code in the lms, cms,
and common directories.

If you're adding a new Django app, place it in core/djangoapps. If you're adding
utilities that require Django, place them in core/djangolib.  If you're adding
code that defines no Django models or views of its own but is widely useful, put it
in core/lib.

Note: All new code should be created in this package, and the legacy code will
be moved here gradually. For now the code is not structured like this, and hence
legacy code will continue to live in a number of different packages.