mirror of
				https://github.com/janeczku/calibre-web
				synced 2025-10-31 15:23:02 +00:00 
			
		
		
		
	Added ratelimiterbackends
This commit is contained in:
		
							
								
								
									
										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')) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Ozzie Isaacs
					Ozzie Isaacs