def check_image(self, kw): if self.context.config.MAX_ID_LENGTH > 0: # Check if an image with an uuid exists in storage exists = yield gen.maybe_future( self.context.modules.storage.exists(kw["image"][: self.context.config.MAX_ID_LENGTH]) ) if exists: kw["image"] = kw["image"][: self.context.config.MAX_ID_LENGTH] url = self.request.uri if not self.validate(kw["image"]): self._error(400, "No original image was specified in the given URL") return kw["request"] = self.request kw["image"] = quote(kw["image"].encode("utf-8")) kw["config"] = self.context.config self.context.request = RequestParameters(**kw) has_none = not self.context.request.unsafe and not self.context.request.hash has_both = self.context.request.unsafe and self.context.request.hash if has_none or has_both: self._error(400, "URL does not have hash or unsafe, or has both: %s" % url) return if self.context.request.unsafe and not self.context.config.ALLOW_UNSAFE_URL: self._error(400, "URL has unsafe but unsafe is not allowed by the config: %s" % url) return if self.context.config.USE_BLACKLIST: blacklist = yield self.get_blacklist_contents() if self.context.request.image_url in blacklist: self._error(400, "Source image url has been blacklisted: %s" % self.context.request.image_url) return url_signature = self.context.request.hash if url_signature: signer = self.context.modules.url_signer(self.context.server.security_key) url_to_validate = Url.encode_url(url).replace("/%s/" % self.context.request.hash, "") valid = signer.validate(url_signature, url_to_validate) if not valid and self.context.config.STORES_CRYPTO_KEY_FOR_EACH_IMAGE: # Retrieves security key for this image if it has been seen before security_key = yield gen.maybe_future( self.context.modules.storage.get_crypto(self.context.request.image_url) ) if security_key is not None: signer = self.context.modules.url_signer(security_key) valid = signer.validate(url_signature, url_to_validate) if not valid: self._error(400, "Malformed URL: %s" % url) return self.execute_image_operations()
def check_image(self, kw): if self.context.config.MAX_ID_LENGTH > 0: # Check if an image with an uuid exists in storage exists = yield gen.maybe_future(self.context.modules.storage.exists(kw['image'][:self.context.config.MAX_ID_LENGTH])) if exists: kw['image'] = kw['image'][:self.context.config.MAX_ID_LENGTH] url = self.request.uri if not self.validate(kw['image']): self._error(400, 'No original image was specified in the given URL') return kw['request'] = self.request kw['image'] = quote(kw['image'].encode('utf-8')) self.context.request = RequestParameters(**kw) has_none = not self.context.request.unsafe and not self.context.request.hash has_both = self.context.request.unsafe and self.context.request.hash if has_none or has_both: self._error(400, 'URL does not have hash or unsafe, or has both: %s' % url) return if self.context.request.unsafe and not self.context.config.ALLOW_UNSAFE_URL: self._error(400, 'URL has unsafe but unsafe is not allowed by the config: %s' % url) return if self.context.config.USE_BLACKLIST: blacklist = yield self.get_blacklist_contents() if self.context.request.image_url in blacklist: self._error(400, 'Source image url has been blacklisted: %s' % self.context.request.image_url) return url_signature = self.context.request.hash if url_signature: signer = self.context.modules.url_signer(self.context.server.security_key) url_to_validate = Url.encode_url(url).replace('/%s/' % self.context.request.hash, '') valid = signer.validate(url_signature, url_to_validate) if not valid and self.context.config.STORES_CRYPTO_KEY_FOR_EACH_IMAGE: # Retrieves security key for this image if it has been seen before security_key = yield gen.maybe_future(self.context.modules.storage.get_crypto(self.context.request.image_url)) if security_key is not None: signer = self.context.modules.url_signer(security_key) valid = signer.validate(url_signature, url_to_validate) if not valid: self._error(400, 'Malformed URL: %s' % url) return self.execute_image_operations()
def __init__(self, debug=False, meta=False, trim=None, crop_left=None, crop_top=None, crop_right=None, crop_bottom=None, crop=None, adaptive=False, full=False, fit_in=False, width=0, height=0, horizontal_flip=False, vertical_flip=False, halign='center', valign='middle', filters=None, smart=False, quality=80, image=None, url=None, extension=None, buffer=None, focal_points=None, unsafe=False, hash=None, accepts_webp=False, request=None, max_age=None): self.debug = bool(debug) self.meta = bool(meta) self.trim = trim if trim is not None: trim_parts = trim.split(':') self.trim_pos = trim_parts[1] if len(trim_parts) > 1 else "top-left" self.trim_tolerance = int(trim_parts[2]) if len(trim_parts) > 2 else 0 if crop is not None: self.crop = crop else: self.crop = { 'left': self.int_or_0(crop_left), 'right': self.int_or_0(crop_right), 'top': self.int_or_0(crop_top), 'bottom': self.int_or_0(crop_bottom) } self.should_crop = \ self.crop['left'] > 0 or \ self.crop['top'] > 0 or \ self.crop['right'] > 0 or \ self.crop['bottom'] > 0 self.adaptive = bool(adaptive) self.full = bool(full) self.fit_in = bool(fit_in) self.width = width == "orig" and "orig" or self.int_or_0(width) self.height = height == "orig" and "orig" or self.int_or_0(height) self.horizontal_flip = bool(horizontal_flip) self.vertical_flip = bool(vertical_flip) self.halign = halign or 'center' self.valign = valign or 'middle' self.smart = bool(smart) if filters is None: filters = [] self.filters = filters self.image_url = image self.url = url self.detection_error = None self.quality = quality self.buffer = None if focal_points is None: focal_points = [] self.focal_points = focal_points self.hash = hash self.prevent_result_storage = False self.unsafe = unsafe == 'unsafe' or unsafe is True self.format = None self.accepts_webp = accepts_webp self.max_bytes = None self.max_age = max_age if request: if request.query: self.image_url += '?%s' % request.query self.url = request.path self.accepts_webp = 'image/webp' in request.headers.get('Accept', '') self.image_url = Url.encode_url(self.image_url.encode('utf-8'))
def check_image(self, kw): if self.context.config.MAX_ID_LENGTH > 0: # Check if an image with an uuid exists in storage exists = yield gen.maybe_future(self.context.modules.storage.exists(kw['image'][:self.context.config.MAX_ID_LENGTH])) if exists: kw['image'] = kw['image'][:self.context.config.MAX_ID_LENGTH] url = self.request.uri if not self.validate(kw['image']): self._error(400, 'No original image was specified in the given URL') return kw['request'] = self.request self.context.request = RequestParameters(**kw) has_none = not self.context.request.unsafe and not self.context.request.hash has_both = self.context.request.unsafe and self.context.request.hash if has_none or has_both: self._error(400, 'URL does not have hash or unsafe, or has both: %s' % url) return if self.context.request.unsafe and not self.context.config.ALLOW_UNSAFE_URL: self._error(400, 'URL has unsafe but unsafe is not allowed by the config: %s' % url) return if self.context.config.USE_BLACKLIST: blacklist = yield self.get_blacklist_contents() if self.context.request.image_url in blacklist: self._error(400, 'Source image url has been blacklisted: %s' % self.context.request.image_url ) return url_signature = self.context.request.hash if url_signature: signer = Signer(self.context.server.security_key) url_to_validate = Url.encode_url(url).replace('/%s/' % self.context.request.hash, '') valid = signer.validate(url_signature, url_to_validate) if not valid and self.context.config.STORES_CRYPTO_KEY_FOR_EACH_IMAGE: # Retrieves security key for this image if it has been seen before security_key = yield gen.maybe_future(self.context.modules.storage.get_crypto(self.context.request.image_url)) if security_key is not None: signer = Signer(security_key) valid = signer.validate(url_signature, url_to_validate) if not valid: is_valid = True if self.context.config.ALLOW_OLD_URLS: cr = Cryptor(self.context.server.security_key) options = cr.get_options(self.context.request.hash, self.context.request.image_url) if options is None: is_valid = False else: options['request'] = self.request self.context.request = RequestParameters(**options) logger.warning( 'OLD FORMAT URL DETECTED!!! This format of URL will be discontinued in ' + 'upcoming versions. Please start using the new format as soon as possible. ' + 'More info at https://github.com/globocom/thumbor/wiki/3.0.0-release-changes' ) else: is_valid = False if not is_valid: self._error(400, 'Malformed URL: %s' % url) return self.execute_image_operations()
def check_image(self, kw): if self.context.config.MAX_ID_LENGTH > 0: # Check if an image with an uuid exists in storage exists = yield gen.maybe_future( self.context.modules.storage.exists( kw['image'][:self.context.config.MAX_ID_LENGTH])) if exists: kw['image'] = kw['image'][:self.context.config.MAX_ID_LENGTH] url = self.request.uri if not self.validate(kw['image']): self._error(400, 'No original image was specified in the given URL') return kw['request'] = self.request self.context.request = RequestParameters(**kw) has_none = not self.context.request.unsafe and not self.context.request.hash has_both = self.context.request.unsafe and self.context.request.hash if has_none or has_both: self._error( 400, 'URL does not have hash or unsafe, or has both: %s' % url) return if self.context.request.unsafe and not self.context.config.ALLOW_UNSAFE_URL: self._error( 400, 'URL has unsafe but unsafe is not allowed by the config: %s' % url) return if self.context.config.USE_BLACKLIST: blacklist = yield self.get_blacklist_contents() if self.context.request.image_url in blacklist: self._error( 400, 'Source image url has been blacklisted: %s' % self.context.request.image_url) return url_signature = self.context.request.hash if url_signature: signer = self.context.modules.url_signer( self.context.server.security_key) url_to_validate = Url.encode_url(url).replace( '/%s/' % self.context.request.hash, '') valid = signer.validate(url_signature, url_to_validate) if not valid and self.context.config.STORES_CRYPTO_KEY_FOR_EACH_IMAGE: # Retrieves security key for this image if it has been seen before security_key = yield gen.maybe_future( self.context.modules.storage.get_crypto( self.context.request.image_url)) if security_key is not None: signer = self.context.modules.url_signer(security_key) valid = signer.validate(url_signature, url_to_validate) if not valid: is_valid = True if self.context.config.ALLOW_OLD_URLS: cr = Cryptor(self.context.server.security_key) options = cr.get_options(self.context.request.hash, self.context.request.image_url) if options is None: is_valid = False else: options['request'] = self.request self.context.request = RequestParameters(**options) logger.warning( 'OLD FORMAT URL DETECTED!!! This format of URL will be discontinued in ' + 'upcoming versions. Please start using the new format as soon as possible. ' + 'More info at https://github.com/thumbor/thumbor/wiki/3.0.0-release-changes' ) else: is_valid = False if not is_valid: self._error(400, 'Malformed URL: %s' % url) return self.execute_image_operations()
def __init__(self, debug=False, meta=False, trim=None, crop_left=None, crop_top=None, crop_right=None, crop_bottom=None, crop=None, adaptive=False, full=False, fit_in=False, width=0, height=0, horizontal_flip=False, vertical_flip=False, halign='center', valign='middle', filters=None, smart=False, quality=80, image=None, url=None, extension=None, buffer=None, focal_points=None, unsafe=False, hash=None, accepts_webp=False, request=None, max_age=None): self.debug = bool(debug) self.meta = bool(meta) self.trim = trim if trim is not None: trim_parts = trim.split(':') self.trim_pos = trim_parts[1] if len( trim_parts) > 1 else "top-left" self.trim_tolerance = int( trim_parts[2]) if len(trim_parts) > 2 else 0 if crop is not None: self.crop = crop else: self.crop = { 'left': self.int_or_0(crop_left), 'right': self.int_or_0(crop_right), 'top': self.int_or_0(crop_top), 'bottom': self.int_or_0(crop_bottom) } self.should_crop = \ self.crop['left'] > 0 or \ self.crop['top'] > 0 or \ self.crop['right'] > 0 or \ self.crop['bottom'] > 0 self.adaptive = bool(adaptive) self.full = bool(full) self.fit_in = bool(fit_in) self.width = width == "orig" and "orig" or self.int_or_0(width) self.height = height == "orig" and "orig" or self.int_or_0(height) self.horizontal_flip = bool(horizontal_flip) self.vertical_flip = bool(vertical_flip) self.halign = halign or 'center' self.valign = valign or 'middle' self.smart = bool(smart) if filters is None: filters = [] self.filters = filters self.image_url = image self.url = url self.detection_error = None self.quality = quality self.buffer = None if focal_points is None: focal_points = [] self.focal_points = focal_points self.hash = hash self.prevent_result_storage = False self.unsafe = unsafe == 'unsafe' or unsafe is True self.format = None self.accepts_webp = accepts_webp self.max_bytes = None self.max_age = max_age if request: if request.query: self.image_url += '?%s' % request.query self.url = request.path self.accepts_webp = 'image/webp' in request.headers.get( 'Accept', '') self.image_url = Url.encode_url(self.image_url.encode('utf-8'))
def test_can_encode_url(self): url = '/tes+ t:?%=&()~",\'$' expect(Url.encode_url(url)).to_equal('/tes%2B%20t:?%=&()~",\'$')