Added ratelimiterbackends
This commit is contained in:
		
							parent
							
								
									117c92233d
								
							
						
					
					
						commit
						3c4ed0de1a
					
				
							
								
								
									
										14
									
								
								cps/__init__.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										14
									
								
								cps/__init__.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| 
						 | 
					@ -103,7 +103,7 @@ web_server = WebServer()
 | 
				
			||||||
updater_thread = Updater()
 | 
					updater_thread = Updater()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if limiter_present:
 | 
					if limiter_present:
 | 
				
			||||||
    limiter = Limiter(key_func=True, headers_enabled=True, auto_check=False, swallow_errors=True)
 | 
					    limiter = Limiter(key_func=True, headers_enabled=True, auto_check=False, swallow_errors=False)
 | 
				
			||||||
else:
 | 
					else:
 | 
				
			||||||
    limiter = None
 | 
					    limiter = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -196,8 +196,18 @@ def create_app():
 | 
				
			||||||
                                           config.config_use_goodreads)
 | 
					                                           config.config_use_goodreads)
 | 
				
			||||||
    config.store_calibre_uuid(calibre_db, db.Library_Id)
 | 
					    config.store_calibre_uuid(calibre_db, db.Library_Id)
 | 
				
			||||||
    # Configure rate limiter
 | 
					    # Configure rate limiter
 | 
				
			||||||
 | 
					    # https://limits.readthedocs.io/en/stable/storage.html
 | 
				
			||||||
    app.config.update(RATELIMIT_ENABLED=config.config_ratelimiter)
 | 
					    app.config.update(RATELIMIT_ENABLED=config.config_ratelimiter)
 | 
				
			||||||
    limiter.init_app(app)
 | 
					    if config.config_limiter_uri != "":
 | 
				
			||||||
 | 
					        app.config.update(RATELIMIT_STORAGE_URI=config.config_limiter_uri)
 | 
				
			||||||
 | 
					        if config.config_limiter_options != "":
 | 
				
			||||||
 | 
					            app.config.update(RATELIMIT_STORAGE_OPTIONS=config.config_limiter_options)
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        limiter.init_app(app)
 | 
				
			||||||
 | 
					    except Exception as e:
 | 
				
			||||||
 | 
					        log.error('Wrong Flask Limiter configuration, falling back to default: {}'.format(e))
 | 
				
			||||||
 | 
					        app.config.update(RATELIMIT_STORAGE_URI=None)
 | 
				
			||||||
 | 
					        limiter.init_app(app)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Register scheduled tasks
 | 
					    # Register scheduled tasks
 | 
				
			||||||
    from .schedule import register_scheduled_tasks, register_startup_tasks
 | 
					    from .schedule import register_scheduled_tasks, register_startup_tasks
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								cps/admin.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										4
									
								
								cps/admin.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| 
						 | 
					@ -1706,7 +1706,7 @@ def _db_configuration_update_helper():
 | 
				
			||||||
        return _db_configuration_result('{}'.format(ex), gdrive_error)
 | 
					        return _db_configuration_result('{}'.format(ex), gdrive_error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if db_change or not db_valid or not config.db_configured \
 | 
					    if db_change or not db_valid or not config.db_configured \
 | 
				
			||||||
       or config.config_calibre_dir != to_save["config_calibre_dir"]:
 | 
					        or config.config_calibre_dir != to_save["config_calibre_dir"]:
 | 
				
			||||||
        if not os.path.exists(metadata_db) or not to_save['config_calibre_dir']:
 | 
					        if not os.path.exists(metadata_db) or not to_save['config_calibre_dir']:
 | 
				
			||||||
            return _db_configuration_result(_('DB Location is not Valid, Please Enter Correct Path'), gdrive_error)
 | 
					            return _db_configuration_result(_('DB Location is not Valid, Please Enter Correct Path'), gdrive_error)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
| 
						 | 
					@ -1830,6 +1830,8 @@ def _configuration_update_helper():
 | 
				
			||||||
            return _configuration_result(_('Password length has to be between 1 and 40'))
 | 
					            return _configuration_result(_('Password length has to be between 1 and 40'))
 | 
				
			||||||
        reboot_required |= _config_int(to_save, "config_session")
 | 
					        reboot_required |= _config_int(to_save, "config_session")
 | 
				
			||||||
        reboot_required |= _config_checkbox(to_save, "config_ratelimiter")
 | 
					        reboot_required |= _config_checkbox(to_save, "config_ratelimiter")
 | 
				
			||||||
 | 
					        reboot_required |= _config_string(to_save, "config_limiter_uri")
 | 
				
			||||||
 | 
					        reboot_required |= _config_string(to_save, "config_limiter_options")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Rarfile Content configuration
 | 
					        # Rarfile Content configuration
 | 
				
			||||||
        _config_string(to_save, "config_rarfile_location")
 | 
					        _config_string(to_save, "config_rarfile_location")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -168,6 +168,8 @@ class _Settings(_Base):
 | 
				
			||||||
    config_password_special = Column(Boolean, default=True)
 | 
					    config_password_special = Column(Boolean, default=True)
 | 
				
			||||||
    config_session = Column(Integer, default=1)
 | 
					    config_session = Column(Integer, default=1)
 | 
				
			||||||
    config_ratelimiter = Column(Boolean, default=True)
 | 
					    config_ratelimiter = Column(Boolean, default=True)
 | 
				
			||||||
 | 
					    config_limiter_uri = Column(String, default="")
 | 
				
			||||||
 | 
					    config_limiter_options = Column(String, default="")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __repr__(self):
 | 
					    def __repr__(self):
 | 
				
			||||||
        return self.__class__.__name__
 | 
					        return self.__class__.__name__
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -159,7 +159,7 @@ EXTENSIONS_UPLOAD = {'txt', 'pdf', 'epub', 'kepub', 'mobi', 'azw', 'azw3', 'cbr'
 | 
				
			||||||
_extension = ""
 | 
					_extension = ""
 | 
				
			||||||
if sys.platform == "win32":
 | 
					if sys.platform == "win32":
 | 
				
			||||||
    _extension = ".exe"
 | 
					    _extension = ".exe"
 | 
				
			||||||
SUPPORTED_CALIBRE_BINARIES = {binary:binary + _extension for binary in ["ebook-convert", "calibredb", "ebook-meta"]}
 | 
					SUPPORTED_CALIBRE_BINARIES = {binary:binary + _extension for binary in ["ebook-convert", "calibredb"]}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def has_flag(value, bit_flag):
 | 
					def has_flag(value, bit_flag):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -156,6 +156,9 @@ def requires_kobo_auth(f):
 | 
				
			||||||
                limiter.check()
 | 
					                limiter.check()
 | 
				
			||||||
            except RateLimitExceeded:
 | 
					            except RateLimitExceeded:
 | 
				
			||||||
                return abort(429)
 | 
					                return abort(429)
 | 
				
			||||||
 | 
					            except (ConnectionError, Exception) as e:
 | 
				
			||||||
 | 
					                log.error("Connection error to limiter backend: %s", e)
 | 
				
			||||||
 | 
					                return abort(429)
 | 
				
			||||||
            user = (
 | 
					            user = (
 | 
				
			||||||
                ub.session.query(ub.User)
 | 
					                ub.session.query(ub.User)
 | 
				
			||||||
                .join(ub.RemoteAuthToken)
 | 
					                .join(ub.RemoteAuthToken)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										10
									
								
								cps/templates/config_edit.html
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										10
									
								
								cps/templates/config_edit.html
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| 
						 | 
					@ -372,6 +372,16 @@
 | 
				
			||||||
              <input type="checkbox" id="config_ratelimiter" name="config_ratelimiter" {% if config.config_ratelimiter %}checked{% endif %}>
 | 
					              <input type="checkbox" id="config_ratelimiter" name="config_ratelimiter" {% if config.config_ratelimiter %}checked{% endif %}>
 | 
				
			||||||
              <label for="config_ratelimiter">{{_('Limit failed login attempts')}}</label>
 | 
					              <label for="config_ratelimiter">{{_('Limit failed login attempts')}}</label>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div data-related="ratelimiter_settings">
 | 
				
			||||||
 | 
					               <div class="form-group" style="margin-left:10px;">
 | 
				
			||||||
 | 
					                  <label for="config_calibre">{{_('Configure Backend for Limiter')}}</label>
 | 
				
			||||||
 | 
					                  <input type="text" class="form-control" id="config_limiter_uri" name="config_limiter_uri" value="{% if config.config_limiter_uri != None %}{{ config.config_limiter_uri }}{% endif %}" autocomplete="off">
 | 
				
			||||||
 | 
					               </div>
 | 
				
			||||||
 | 
					               <div class="form-group" style="margin-left:10px;">
 | 
				
			||||||
 | 
					                  <label for="config_calibre">{{_('Options for Limiter')}}</label>
 | 
				
			||||||
 | 
					                  <input type="text" class="form-control" id="config_limiter_options" name="config_limiter_options" value="{% if config.config_limiter_options != None %}{{ config.config_limiter_options }}{% endif %}" autocomplete="off">
 | 
				
			||||||
 | 
					               </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
            <div class="form-group">
 | 
					            <div class="form-group">
 | 
				
			||||||
              <label for="config_session">{{_('Session protection')}}</label>
 | 
					              <label for="config_session">{{_('Session protection')}}</label>
 | 
				
			||||||
                <select name="config_session" id="config_session" class="form-control">
 | 
					                <select name="config_session" id="config_session" class="form-control">
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										10
									
								
								cps/web.py
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								cps/web.py
									
									
									
									
									
								
							| 
						 | 
					@ -1272,6 +1272,10 @@ def register_post():
 | 
				
			||||||
    except RateLimitExceeded:
 | 
					    except RateLimitExceeded:
 | 
				
			||||||
        flash(_(u"Please wait one minute to register next user"), category="error")
 | 
					        flash(_(u"Please wait one minute to register next user"), category="error")
 | 
				
			||||||
        return render_title_template('register.html', config=config, title=_("Register"), page="register")
 | 
					        return render_title_template('register.html', config=config, title=_("Register"), page="register")
 | 
				
			||||||
 | 
					    except (ConnectionError, Exception) as e:
 | 
				
			||||||
 | 
					        log.error("Connection error to limiter backend: %s", e)
 | 
				
			||||||
 | 
					        flash(_("Connection error to limiter backend, please contact your administrator"), category="error")
 | 
				
			||||||
 | 
					        return render_title_template('register.html', config=config, title=_("Register"), page="register")
 | 
				
			||||||
    if current_user is not None and current_user.is_authenticated:
 | 
					    if current_user is not None and current_user.is_authenticated:
 | 
				
			||||||
        return redirect(url_for('web.index'))
 | 
					        return redirect(url_for('web.index'))
 | 
				
			||||||
    if not config.get_mail_server_configured():
 | 
					    if not config.get_mail_server_configured():
 | 
				
			||||||
| 
						 | 
					@ -1370,7 +1374,11 @@ def login_post():
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        limiter.check()
 | 
					        limiter.check()
 | 
				
			||||||
    except RateLimitExceeded:
 | 
					    except RateLimitExceeded:
 | 
				
			||||||
        flash(_(u"Please wait one minute before next login"), category="error")
 | 
					        flash(_("Please wait one minute before next login"), category="error")
 | 
				
			||||||
 | 
					        return render_login(username, form.get("password", ""))
 | 
				
			||||||
 | 
					    except (ConnectionError, Exception) as e:
 | 
				
			||||||
 | 
					        log.error("Connection error to limiter backend: %s", e)
 | 
				
			||||||
 | 
					        flash(_("Connection error to limiter backend, please contact your administrator"), category="error")
 | 
				
			||||||
        return render_login(username, form.get("password", ""))
 | 
					        return render_login(username, form.get("password", ""))
 | 
				
			||||||
    if current_user is not None and current_user.is_authenticated:
 | 
					    if current_user is not None and current_user.is_authenticated:
 | 
				
			||||||
        return redirect(url_for('web.index'))
 | 
					        return redirect(url_for('web.index'))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user