def login(): username = '' password = '' next_url = '' login_error = '' next_url_default = internal_url_for('browse') if request.method == 'POST': try: # Get parameters username = request.form.get('username', '') password = request.form.get('password', '') next_url = request.form.get('next', '') if not password: login_error = 'You must enter your password' if not username: login_error = 'You must enter your username' if not login_error: # Log in user = authenticate_user(username, password, data_engine, logger) if user is not None: if user.status == User.STATUS_ACTIVE: # Success log_in(user) return redirect(next_url or next_url_default) else: login_error = 'Sorry, your account is disabled.' else: login_error = '''Sorry, your username and password were not recognised. Please try again.''' # Slow down scripted attacks logger.warn('Incorrect login for username ' + username) sleep(1) except Exception as e: if not log_security_error(e, request): logger.error('Error performing login: '******'DEBUG']: raise login_error = 'Sorry, an error occurred. Please try again later.' else: # If already logged in, go to the default page if logged_in(): next_url = request.args.get('next', '') return redirect(next_url or next_url_default) # Not logged in, or unsuccessful login return render_template( 'login.html', username=username, next=next_url, err_msg=login_error )
def handle_image_xref(xref): """ Invokes the configured 3rd party URL (if any) for the given tracking reference. """ xurl = app.config['XREF_TRACKING_URL'] if xref and xurl: if xurl.startswith('http'): invoke_http_async( xurl + xref, log_success_fn=logger.debug if app.config['DEBUG'] else None, log_fail_fn=logger.error ) else: logger.warn('XREF_TRACKING_URL must begin with http or https')
def image(): logger.debug(request.method + ' ' + request.url) try: logged_in = session_logged_in() allow_uncache = app.config['BENCHMARKING'] or app.config['DEBUG'] args = request.args # Get URL parameters for the image src = args.get('src', '') page = args.get('page', None) iformat = args.get('format', None) template = args.get('tmp', None) width = args.get('width', None) height = args.get('height', None) halign = args.get('halign', None) valign = args.get('valign', None) autosizefit = args.get('autosizefit', None) rotation = args.get('angle', None) flip = args.get('flip', None) top = args.get('top', None) left = args.get('left', None) bottom = args.get('bottom', None) right = args.get('right', None) autocropfit = args.get('autocropfit', None) fill = args.get('fill', None) quality = args.get('quality', None) sharpen = args.get('sharpen', None) ov_src = args.get('overlay', None) ov_size = args.get('ovsize', None) ov_opacity = args.get('ovopacity', None) ov_pos = args.get('ovpos', None) icc_profile = args.get('icc', None) icc_intent = args.get('intent', None) icc_bpc = args.get('bpc', None) colorspace = args.get('colorspace', None) strip = args.get('strip', None) dpi = args.get('dpi', None) tile = args.get('tile', None) # Get URL parameters for handling options attach = args.get('attach', None) xref = args.get('xref', None) stats = args.get('stats', None) # Get protected admin/internal parameters cache = args.get('cache', '1') if logged_in or allow_uncache else '1' recache = args.get('recache', None) if allow_uncache else None # eRez compatibility mode src = erez_params_compat(src) # Tweak strings as necessary and convert non-string parameters # to the correct data types try: # Image options if page is not None: page = parse_int(page) if iformat is not None: iformat = iformat.lower() if template is not None: template = template.lower() if width is not None: width = parse_int(width) if height is not None: height = parse_int(height) if halign is not None: halign = halign.lower() if valign is not None: valign = valign.lower() if autosizefit is not None: autosizefit = parse_boolean(autosizefit) if rotation is not None: rotation = parse_float(rotation) if flip is not None: flip = flip.lower() if top is not None: top = parse_float(top) if left is not None: left = parse_float(left) if bottom is not None: bottom = parse_float(bottom) if right is not None: right = parse_float(right) if autocropfit is not None: autocropfit = parse_boolean(autocropfit) if fill is not None: fill = parse_colour(fill) if quality is not None: quality = parse_int(quality) if sharpen is not None: sharpen = parse_int(sharpen) if ov_size is not None: ov_size = parse_float(ov_size) if ov_pos is not None: ov_pos = ov_pos.lower() if ov_opacity is not None: ov_opacity = parse_float(ov_opacity) if icc_profile is not None: icc_profile = icc_profile.lower() if icc_intent is not None: icc_intent = icc_intent.lower() if icc_bpc is not None: icc_bpc = parse_boolean(icc_bpc) if colorspace is not None: colorspace = colorspace.lower() if strip is not None: strip = parse_boolean(strip) if dpi is not None: dpi = parse_int(dpi) if tile is not None: tile = parse_tile_spec(tile) # Handling options if attach is not None: attach = parse_boolean(attach) if xref is not None: validate_string(xref, 0, 1024) if stats is not None: stats = parse_boolean(stats) # Admin/internal options if cache is not None: cache = parse_boolean(cache) if recache is not None: recache = parse_boolean(recache) except (ValueError, TypeError) as e: raise httpexc.BadRequest(unicode(e)) # Package and validate the parameters try: # #2694 Enforce public image limits - perform easy parameter checks if not logged_in: width, height, autosizefit = _public_image_limits_pre_image_checks( width, height, autosizefit, tile, template ) # Store and normalise all the parameters image_attrs = ImageAttrs(src, -1, page, iformat, template, width, height, halign, valign, rotation, flip, top, left, bottom, right, autocropfit, autosizefit, fill, quality, sharpen, ov_src, ov_size, ov_pos, ov_opacity, icc_profile, icc_intent, icc_bpc, colorspace, strip, dpi, tile) image_engine.finalise_image_attrs(image_attrs) except ValueError as e: raise httpexc.BadRequest(unicode(e)) # Get/create the database ID (from cache, validating path on create) image_id = data_engine.get_or_create_image_id( image_attrs.filename(), return_deleted=False, on_create=on_image_db_create_anon_history ) if (image_id == 0): raise DoesNotExistError() # Deleted elif (image_id < 0): raise DBError('Failed to add image to database') image_attrs.set_database_id(image_id) # Require view permission or file admin permissions_engine.ensure_folder_permitted( image_attrs.folder_path(), FolderPermission.ACCESS_VIEW, get_session_user() ) # Ditto for overlays if ov_src: permissions_engine.ensure_folder_permitted( filepath_parent(ov_src), FolderPermission.ACCESS_VIEW, get_session_user() ) # v1.17 If this is a conditional request with an ETag, see if we can just return a 304 if 'If-None-Match' in request.headers and not recache: etag_valid, modified_time = _etag_is_valid( image_attrs, request.headers['If-None-Match'], False ) if etag_valid: # Success HTTP 304 return make_304_response(image_attrs, False, modified_time) # Get the requested image data image_wrapper = image_engine.get_image( image_attrs, 'refresh' if recache else cache ) if (image_wrapper is None): raise DoesNotExistError() # #2694 Enforce public image limits - check the dimensions # of images that passed the initial parameter checks if not logged_in: try: _public_image_limits_post_image_checks( image_attrs.width(), image_attrs.height(), image_attrs.template(), image_wrapper.data(), image_wrapper.attrs().format() ) except ValueError as e: raise httpexc.BadRequest(unicode(e)) # As for the pre-check # Success HTTP 200 return make_image_response(image_wrapper, False, stats, attach, xref) except httpexc.HTTPException: # Pass through HTTP 4xx and 5xx raise except ServerTooBusyError: logger.warn(u'503 Too busy for ' + request.url) raise httpexc.ServiceUnavailable() except ImageError as e: logger.warn(u'415 Invalid image file \'' + src + '\' : ' + unicode(e)) raise httpexc.UnsupportedMediaType(unicode(e)) except SecurityError as e: if app.config['DEBUG']: raise log_security_error(e, request) raise httpexc.Forbidden() except DoesNotExistError as e: # First time around the ID will be set. Next time around it # won't but we should check whether the disk file now exists. if image_attrs.database_id() > 0 or path_exists(image_attrs.filename(), require_file=True): image_engine.reset_image(image_attrs) logger.warn(u'404 Not found: ' + unicode(e)) raise httpexc.NotFound(unicode(e)) except Exception as e: if app.config['DEBUG']: raise logger.error(u'500 Error for ' + request.url + '\n' + unicode(e)) raise httpexc.InternalServerError(unicode(e))
def original(): logger.debug('GET ' + request.url) try: # Get URL parameters for the image src = request.args.get('src', '') # Get URL parameters for handling options attach = request.args.get('attach', None) xref = request.args.get('xref', None) stats = request.args.get('stats', None) # Validate the parameters try: if attach is not None: attach = parse_boolean(attach) if xref is not None: validate_string(xref, 0, 1024) if stats is not None: stats = parse_boolean(stats) image_attrs = ImageAttrs(src) image_attrs.validate() except ValueError as e: raise httpexc.BadRequest(unicode(e)) # Get/create the database ID (from cache, validating path on create) image_id = data_engine.get_or_create_image_id( image_attrs.filename(), return_deleted=False, on_create=on_image_db_create_anon_history ) if (image_id == 0): raise DoesNotExistError() # Deleted elif (image_id < 0): raise DBError('Failed to add image to database') image_attrs.set_database_id(image_id) # Require download permission or file admin permissions_engine.ensure_folder_permitted( image_attrs.folder_path(), FolderPermission.ACCESS_DOWNLOAD, get_session_user() ) # v1.17 If this is a conditional request with an ETag, see if we can just return a 304 if 'If-None-Match' in request.headers: etag_valid, modified_time = _etag_is_valid( image_attrs, request.headers['If-None-Match'], True ) if etag_valid: # Success HTTP 304 return make_304_response(image_attrs, True, modified_time) # Read the image file image_wrapper = image_engine.get_image_original( image_attrs ) if (image_wrapper is None): raise DoesNotExistError() # Success HTTP 200 return make_image_response(image_wrapper, True, stats, attach, xref) except httpexc.HTTPException: # Pass through HTTP 4xx and 5xx raise except ServerTooBusyError: logger.warn(u'503 Too busy for ' + request.url) raise httpexc.ServiceUnavailable() except ImageError as e: logger.warn(u'415 Invalid image file \'' + src + '\' : ' + unicode(e)) raise httpexc.UnsupportedMediaType(unicode(e)) except SecurityError as e: if app.config['DEBUG']: raise log_security_error(e, request) raise httpexc.Forbidden() except DoesNotExistError as e: # First time around the ID will be set. Next time around it # won't but we should check whether the disk file now exists. if image_attrs.database_id() > 0 or path_exists(image_attrs.filename(), require_file=True): image_engine.reset_image(image_attrs) logger.warn(u'404 Not found: ' + src) raise httpexc.NotFound(src) except Exception as e: if app.config['DEBUG']: raise logger.error(u'500 Error for ' + request.url + '\n' + unicode(e)) raise httpexc.InternalServerError(unicode(e))