in src/olympia/versions/views.py [0:0]
def download_file(request, file_id, download_type=None, **kwargs):
"""
Download the file identified by `file_id` parameter.
If the file is disabled or belongs to an unlisted version, requires an
add-on developer or appropriate reviewer for the channel. If the file is
deleted or belongs to a deleted version or add-on, reviewers can still
access but developers can't.
"""
def is_appropriate_reviewer(addon, channel):
return (
acl.is_reviewer(request.user, addon)
if channel == amo.CHANNEL_LISTED
else acl.is_unlisted_addons_viewer_or_reviewer(request.user)
)
file_ = get_object_or_404(File.objects, pk=file_id)
# Include deleted add-ons in the queryset, we'll check for that below.
addon = get_object_or_404(
Addon.unfiltered.all().no_transforms(), pk=file_.version.addon_id
)
version = file_.version
channel = version.channel
if version.deleted or addon.is_deleted:
# Only the appropriate reviewer can see deleted things.
require_permission = True
has_permission = is_appropriate_reviewer(addon, channel)
apply_georestrictions = False
elif (
addon.is_disabled
or file_.status == amo.STATUS_DISABLED
or channel == amo.CHANNEL_UNLISTED
):
# Only the appropriate reviewer or developers of the add-on can see
# disabled or unlisted things.
require_permission = True
has_permission = is_appropriate_reviewer(
addon, channel
) or acl.check_addon_ownership(
request.user,
addon,
allow_developer=True,
allow_mozilla_disabled_addon=True,
)
apply_georestrictions = False
else:
# Public case: we're either directly downloading the file or
# redirecting, but in any case we have permission in the general sense,
# though georestrictions are in effect.
require_permission = False
has_permission = True
apply_georestrictions = True
region_code = request.META.get('HTTP_X_COUNTRY_CODE', None)
# Whether to set Content-Disposition: attachment header or not, to force
# the file to be downloaded rather than installed (used by admin/reviewer
# tools).
attachment = download_type == 'attachment'
if not has_permission:
log.debug(
'download file {file_id}: addon/version/file not public and '
'user {user_id} does not have relevant permissions.'.format(
file_id=file_id, user_id=request.user.pk
)
)
response = http.HttpResponseNotFound()
elif (
apply_georestrictions
and region_code
and AddonRegionalRestrictions.objects.filter(
addon=addon, excluded_regions__contains=region_code.upper()
).exists()
):
response = http.HttpResponse(status=451)
url = 'https://www.mozilla.org/about/policy/transparency/'
response['Link'] = f'<{url}>; rel="blocked-by"'
else:
if not file_.file:
raise http.Http404()
# We're returning a X-Accel-Redirect, we can set
# Content-Disposition: attachment ourselves in HttpResponseXSendFile:
# nginx won't override it if present.
response = HttpResponseXSendFile(
request,
file_.file.path,
content_type='application/x-xpinstall',
attachment=attachment,
)
# Always add a few headers to the response (even errors). Don't cache if
# the addon/version required permissions to access though.
if not require_permission:
patch_cache_control(response, max_age=60 * 60 * 24)
patch_vary_headers(response, ['X-Country-Code'])
response['Access-Control-Allow-Origin'] = '*'
return response